mirror of https://github.com/bjornbytes/lovr.git
Fix buffer flushing;
lovrGraphicsMapBuffer had the potential to cause a flush. Flushing unmaps buffers. This meant that during any of the calls to map while creating a Batch, it was possible to cause a flush and unmap other buffers that expected to be mapped. This caused writes to unmapped pointers and subsequent skipping of calls to glFlushMappedBufferRange. The fix is to figure out if we need to flush upfront and get it out of the way before mapping any buffers.
This commit is contained in:
parent
931147531a
commit
38875cb399
|
@ -178,7 +178,7 @@ static void* lovrGraphicsMapBuffer(StreamType type, uint32_t count) {
|
|||
lovrAssert(count <= bufferCount[type], "Whoa there! Tried to get %d elements from a buffer that only has %d elements.", count, bufferCount[type]);
|
||||
|
||||
if (state.head[type] + count > bufferCount[type]) {
|
||||
lovrGraphicsFlush();
|
||||
lovrAssert(state.batchCount == 0, "Internal error: Batches still exist during Buffer reset");
|
||||
lovrBufferDiscard(state.buffers[type]);
|
||||
state.tail[type] = 0;
|
||||
state.head[type] = 0;
|
||||
|
@ -626,6 +626,23 @@ next:
|
|||
// write the ids much later.
|
||||
uint8_t* ids = NULL;
|
||||
|
||||
// Figure out if a flush is necessary before mapping buffers for vertex data or UBOs.
|
||||
// - A flush is necessary if vertices are about to be written (during the first element of an
|
||||
// instanced batch or any element of a stream batch) and any of the ranges go past the end.
|
||||
// - If a new batch is required but there isn't space for it, flush to make space.
|
||||
// - If a new batch is required, make sure there is space for the matrix/color UBO streams.
|
||||
// It's important to flush before mapping any streams, because flushing unmaps all streams.
|
||||
bool needFlush = false;
|
||||
bool hasVertices = req->vertexCount > 0 && (!req->instanced || !batch);
|
||||
bool hasIndices = hasVertices && req->indexCount > 0;
|
||||
needFlush = needFlush || (hasVertices && state.head[STREAM_VERTEX] + req->vertexCount > bufferCount[STREAM_VERTEX]);
|
||||
needFlush = needFlush || (hasVertices && state.head[STREAM_DRAWID] + req->vertexCount > bufferCount[STREAM_DRAWID]);
|
||||
needFlush = needFlush || (hasIndices && state.head[STREAM_INDEX] + req->indexCount > bufferCount[STREAM_INDEX]);
|
||||
needFlush = needFlush || (!batch && state.batchCount >= MAX_BATCHES);
|
||||
needFlush = needFlush || (!batch && state.head[STREAM_MODEL] + MAX_DRAWS > bufferCount[STREAM_MODEL]);
|
||||
needFlush = needFlush || (!batch && state.head[STREAM_COLOR] + MAX_DRAWS > bufferCount[STREAM_COLOR]);
|
||||
if (needFlush) lovrGraphicsFlush();
|
||||
|
||||
if (req->vertexCount > 0 && (!req->instanced || !batch)) {
|
||||
*(req->vertices) = lovrGraphicsMapBuffer(STREAM_VERTEX, req->vertexCount);
|
||||
ids = lovrGraphicsMapBuffer(STREAM_DRAWID, req->vertexCount);
|
||||
|
@ -638,10 +655,6 @@ next:
|
|||
|
||||
// Start a new batch
|
||||
if (!batch || state.batchCount == 0) {
|
||||
if (state.batchCount >= MAX_BATCHES) {
|
||||
lovrGraphicsFlush();
|
||||
}
|
||||
|
||||
float* transforms = lovrGraphicsMapBuffer(STREAM_MODEL, MAX_DRAWS);
|
||||
Color* colors = lovrGraphicsMapBuffer(STREAM_COLOR, MAX_DRAWS);
|
||||
|
||||
|
|
|
@ -2265,6 +2265,7 @@ void* lovrBufferMap(Buffer* buffer, size_t offset, bool unsynchronized) {
|
|||
}
|
||||
|
||||
void lovrBufferFlush(Buffer* buffer, size_t offset, size_t size) {
|
||||
lovrAssert(size == 0 || buffer->mapped, "Attempt to flush unmapped Buffer");
|
||||
buffer->flushFrom = MIN(buffer->flushFrom, offset);
|
||||
buffer->flushTo = MAX(buffer->flushTo, offset + size);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue