[Openal-devel] Faster buffer model, and more random stuff
Chris Robinson
chris.kcat at gmail.com
Mon Feb 25 17:33:05 PST 2008
On Monday 25 February 2008 03:29:21 pm Sherief N. Farouk wrote:
> >>: We’re still having communication problems. There exists, at most, one
> >>: memory buffer at any given time using the map buffer model. Think of
> >>: this: When I call alBufferData, where does the implementation store the
> >>: data? First, it MUST either transfer immediately to HW or make its own
> >>: copy of it, because I might (and most likely will) follow the
> >>: BufferData call with a delete[]. So, if I'm decoding OGG and
> >>: transferring it to OpenAL under the current model, the flow is like
> >>: this:
>
> Byte* Data = allocate_space_for_pcm();
> OGGFile->DecodeInto(Data);
> alBufferData(Data, ...); //A copy or stall must ensue here
> delete [] Data;
>
> Now, the few performance considerations: First, the copy/stall is
> UNAVOIDABLE. Second, the buffer size isn't fixed, so a new alloc or at
> least some if statements go through every time BufferData is called. When
> I'm using all my buffers to stream OGG, this code is executed a lot. So, my
> main game loop has too many allocations/deallocations, most audio related
> once can be avoided via the immutable buffer model.
When buffering data, an implementation is free to not resize the memory
segment if the new data is smaller than the current, as long as it'll behave
as expected. And even if it did, decreasing a memory segment's size is very
cheap. And as I'd be hard pressed to believe someone would need to update a
buffer queue more than 5 to 10 times a second, this isn't going to be a
bottleneck compared to the actual audio mixing or Ogg decoding.
> Now for the shadow buffer: IT DOESN'T EXIST. IT NEEDN'T BE THERE. Simply
> put, here's what a most-converged implementation of MapBuffer should do: If
> buffer is on card, and the mapping is write only, and the buffer has no
> pending render commands, return pointer to card mapped memory space.
Then how do you deal with the fact that data may not be in a format known by
the app? It couldn't know the mapped buffer is, eg. 24-bit signed integer
with 8-bit padding, as opposed to the float-32 it created the buffer with, or
that the data is deinterlaced and possibly in completely different memory
segments. Converting on (un)map, I think is beyond the scope of what mapping
is for, let alone that it wouldn't even be possible if the mapped buffer
memory is smaller than the pre-converted data.
> And since buffer memory consumption is known
> upfront, you can make the decision whether to copy and work in parallel or
> wait, depending on available scratch pool memory. You can't simply do that
> with BufferData.
With BufferData though, you know exactly what it's going to do at any given
time: (re)allocate buffer storage for itself, and copy/convert the given
buffer data to an internal representation.
> >>>: And if you had quoted the sentence after "plain and simple.", you'll
> >>>: find that it says " Although I recommend a more forgiving strategy of
> >>>: convert-on-mapping-to-read. Keep in mind that this is how GL does it
> >>>: for RGBA8 (cards store natively in ABGR, for nvidia, IIRC).". That's
> >>>: what I recommend, render to whatever you prefer internally,
> >>>: convert-on-read.
The mixer already "converts" from Windows' mixed up channel ordering on read.
AL_FORMAT_51CHN* needs the data in Windows' ordering, and any data in its
buffer needs to be the same. If a mixer wrote non-Windows ordering, mixing
the resulting buffer would get the channel order wrong, which is why it needs
to be written correctly. You'd need a new format type for a different
ordering for the mixer to recognize it, but that raises the complexity of the
mixer since it can currently assume a specific channel order and data layout
for any given channel count.
In GL, this is why you don't get direct access to texture memory. You can
specify RGB8, but it can store it in X2BGR10, or XBGR8, or whatever it feels
like as long as it has the expected precision and functionality. A pixel
buffer object is not converted when you map/unmap it, but the corresponding
gl[Get]TexImage* when reading from/writing to it does convert it.
More information about the Openal-devel
mailing list