[5/5] WineD3D: Implement buffer subrange mapping with GL_APPLE_flush_buffer_range

Stefan Dösinger stefan at codeweavers.com
Wed Dec 16 06:19:14 CST 2009

Am 16.12.2009 um 12:50 schrieb Henri Verbeet:
> What you're doing (or should be doing) is extending the
> "lock_count/dirty_start/dirty_end" scheme to something more detailed.
> I don't think using two different schemes depending on whether the
> buffer is dynamic or not is a good idea.
Sounds great on paper, but there's an issue. The dirty_start, dirty_end and the maps array serve two similar, yet different purposes.

The new maps array works like a stack. I needed this because I have to tell GL to flush the buffer after the app is done writing to it, but only Map() knows the bytes modified. After Unmap() I don't bother about what I just flushed, its GLs business now.

dirty_start and dirty_end are needed in PreLoad. Using the above stack doesn't work as-is. Consider a buffer with 10 bytes:

Map(buffer, start=1, len=1);

Map(buffer, start=5, len=1);
Map(Buffer, start=8, len=1);


By the time I'm done unmaping, the information that byte 5 was mapped and possibly modified is lost in the stack, but PreLoad has to load at least bytes 1, 5 and 8. The current dirty_start and dirty_end loads bytes 1, 2, 3, 4, 5, 6, 7, 8. This is not as efficient as it could be, but I don't think its a problem because those are static buffers anyway.

The best way I see to merge those two tracking mechanisms is to organize them as a list, and upload all modified ranges in PreLoad(), or if the buffer is single buffered and dynamic, flush all the ranges after the last unmap, and clear the list in both PreLoad and unmap. That way we can share the data structure, although it doesn't perfectly fit either purpose. We can also share some of the code. The downside is that GL doesn't start flushing until the final unmap on dynamic buffers.

More information about the wine-devel mailing list