[Openal-devel] Faster buffer model, and more random stuff

Chris Robinson chris.kcat at gmail.com
Sun Feb 24 22:39:09 PST 2008


On Sunday 24 February 2008 06:04:45 pm Sherief N. Farouk wrote:
> Some musings about that can be found here:
>
> http://www.mganin.com/oal/oal.html

Some interesting ideas.

> 1) The buffer type: ALuint
> Having the buffer type defined as a (hidden, opaque) pointer eliminates all
> need for name lookup. In Chris's OpenAL Soft name lookup is skipped on x86,
> but x64 suffers from a little overhead. A "typedef ALvoid* ALbuffer" works
> better.

ALuint could technically be changed to a long, which is 64-bit on sane 
compilers.. though it would be kind of confusing.

> 2) The "vagueness" of a just-created buffer
> When a buffer is created, nothing is certain. How much can it hold? What
> formats? etc. Buffer creation should specify size, format and frequency. The
> success of a buffer creation should mean no subsequent failures in
> BufferData. BufferData is very crippled form a performance POV, and it has
> its own section later in this document. Buffer USAGE should also be a
> criteria for creation. With concrete buffers, you can safely use them as an
> output target. More on render-to-buffer to come.

The "vagueness" of a just-created buffer is similar to the vagueness of a 
just-created texture in GL. It creates the object, but doesn't allocate any 
storage for it, which is what alBufferData is for.

> 3) BufferData Should be thrown out and left to die. It has one fatal flaw
> that's annoying on low-memory systems: If I'm decoding from a compressed
> file, 2 copies of the uncompressed data have to exist in memory at some
> point, specially at the call to BufferData, since the caller isn't required
> to maiuntain the pointed to data any longer. My proposition is using the
> buffer mapping analogy from OpenGL (and the enhancments in 3.0). A MapBuffer
> call returns a pointer to a memory location with enough storage for the
> buffer size specified to CreateBuffer.

This won't do much for memory requirements, unfortunately. The storage format 
of an OpenAL buffer is completely implementation dependant, so a mapped 
buffer would have to be a seperate memory segment you write to, which would 
then have to be fed/converted to the buffer when unmapped. You'd still have 
two buffers, just that they'd be handled by the implementation instead of one 
in the implementation and one by the user. This is basically what GL does 
with pixel buffer objects and textures/framebuffers.

That said, I'd kinda like a mappable buffer object that could potentially do 
asyncronous server-side copies for alBufferData, and/or that can hold source 
attributes, or something. Also something like alBufferSubData would be nice.

> That allows for more flexibility, as software implementations that keep an
> internal buffer in system ram can return a pointer directly to that to be
> used for the decompression output, and implementations that have on-board
> memory can return a pointer to some system-mapped area for transfer to the
> card.

This would only work when the internal buffer storage is in some 
app-understandable format. The SI for instance has the channels deinterlaced 
and resamples data to the output format when buffered. An app that used that 
would have to be able to write deinterlaced samples at the output frequency. 
OpenAL Soft converts all data to 16-bit, but generally keeps the data 
interlaced at the same channel count and frequency it was buffered with (with 
the exception of AL_FORMAT_REAR*, which it converts to QUAD16 with silent 
front-channels).

That's not even getting into how hardware may be representing it. In GL, you 
can't get directly to texture data for the same reason. You'd map a pixel 
buffer object, read/write it, and call glTexImage*D to transfer/convert from 
the pixel buffer to the texture, server-side.

> Usage flags should be used to allow for read, write, or both.

There's actually already an extension like this: XRAM. It lets you specify a 
buffer's storage type as accessible (dynamic), static, or automatic 
(autoselect). Though it does this with two new functions instead of a simpler 
buffer attribute. It also allows querying how much memory the card has and is 
available.

> 4) Sources should be allowed to target their output to a buffer
> As clear as it is. Some of the things that need to be resolved here is what
> happens when the buffer is full, and how are formats handled.

Taking a queue from GL, we could have a way to select an AL buffer (as 
returned by alGenBuffers), or a new render buffer type object, as a mixer 
target through a "mixer buffer object". For the most part, it shouldn't be 
difficult to mirror the FBO functions, however given OpenAL's async rendering 
nature, actually utilizing them on the API level efficiently would be a task.

> The DSP effect framework will be based on one of the pipelines developed
> for XAL, viewable at http://www.mganin.com/xal/ .

Hmm, well, based on xal_pipeline_1.png, my thinking would be that the 3D 
positioning would be part of the source shader. It would be automatic with 
fixed-function, but a shader would need to manually set local position, 
pitch, etc, given the listener and source attributes. I'm also not sure how 
varyings (if going by the GL term) would apply to the listener shader, as it 
would be analogous to a fragment shader. Though a source shader would still 
need to have a way to set variables for a listener shader. So something like:

        Source and Listener
             Attribs
                |
                V
             Source(1)
             Shader---+
                |     | Varyings
                V     |
    Source->Listener<-+
    Buffer   Shader(2)
                |
                V
              Mixed
              Buffer

1) Source shader gets access to the given source's and its listener/context 
attributes. The shader would be responsible for translating and rotating the 
source position, setting the gain (as determined by distance, cones, etc), 
and the pitch (as determined by velocities). It could also write out pairs of 
attributes that the listener shader would get interpolated (varyings). 
Multi-channel buffers would only be affected by the pitch and gain.

2) The listener shader gets the current sampler position, gain, and can sample 
from the source's buffer. It would be expected to sample from the buffer, 
apply the gain, and write out a sample that is spatialized and mixed. 
Multi-channel buffers would bypass the listener shader completely.


More information about the Openal-devel mailing list