mirror of https://github.com/bjornbytes/lovr.git
Buffers individually keep track of their flush range;
Fixes bugs with attached Mesh attributes, where flushing wasn't happening when it should have.
This commit is contained in:
parent
25606738c5
commit
c473bf50e8
|
@ -1179,7 +1179,7 @@ static int l_lovrGraphicsNewMesh(lua_State* L) {
|
|||
memcpy(vertices, vertexData->blob.data, vertexData->count * vertexData->format.stride);
|
||||
}
|
||||
|
||||
lovrBufferFlush(vertexBuffer, 0, count * format.stride);
|
||||
lovrBufferMarkRange(vertexBuffer, 0, count * format.stride);
|
||||
lovrRelease(vertexBuffer);
|
||||
|
||||
luax_pushobject(L, mesh);
|
||||
|
|
|
@ -139,7 +139,7 @@ int l_lovrMeshSetVertex(lua_State* L) {
|
|||
VertexFormat* format = lovrMeshGetVertexFormat(mesh);
|
||||
VertexPointer vertex = { .raw = lovrBufferMap(buffer, index * format->stride) };
|
||||
luax_setvertex(L, 3, &vertex, format);
|
||||
lovrMeshMarkVertices(mesh, index * format->stride, (index + 1) * format->stride);
|
||||
lovrBufferMarkRange(buffer, index * format->stride, (index + 1) * format->stride);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -168,7 +168,7 @@ int l_lovrMeshSetVertexAttribute(lua_State* L) {
|
|||
Buffer* buffer = lovrMeshGetVertexBuffer(mesh);
|
||||
VertexPointer vertex = { .raw = lovrBufferMap(buffer, vertexIndex * format->stride + attribute.offset) };
|
||||
luax_setvertexattribute(L, 4, &vertex, attribute);
|
||||
lovrMeshMarkVertices(mesh, vertexIndex * format->stride + attribute.offset, vertexIndex * format->stride + attribute.offset + attribute.size);
|
||||
lovrBufferMarkRange(buffer, vertexIndex * format->stride + attribute.offset, vertexIndex * format->stride + attribute.offset + attribute.size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -207,7 +207,7 @@ int l_lovrMeshSetVertices(lua_State* L) {
|
|||
}
|
||||
}
|
||||
|
||||
lovrMeshMarkVertices(mesh, start * format->stride, (start + count) * format->stride);
|
||||
lovrBufferMarkRange(buffer, start * format->stride, (start + count) * format->stride);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -270,7 +270,7 @@ int l_lovrMeshSetVertexMap(lua_State* L) {
|
|||
} else {
|
||||
void* indices = lovrBufferMap(indexBuffer, 0);
|
||||
memcpy(indices, blob->data, blob->size);
|
||||
lovrBufferFlush(indexBuffer, 0, blob->size);
|
||||
lovrBufferMarkRange(indexBuffer, 0, blob->size);
|
||||
}
|
||||
} else {
|
||||
luaL_checktype(L, 2, LUA_TTABLE);
|
||||
|
@ -309,7 +309,7 @@ int l_lovrMeshSetVertexMap(lua_State* L) {
|
|||
}
|
||||
|
||||
lovrMeshSetIndexBuffer(mesh, indexBuffer, count, size);
|
||||
lovrBufferFlush(indexBuffer, 0, count * size);
|
||||
lovrBufferMarkRange(indexBuffer, 0, count * size);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -32,7 +32,7 @@ int l_lovrShaderBlockSend(lua_State* L) {
|
|||
Buffer* buffer = lovrShaderBlockGetBuffer(block);
|
||||
uint8_t* data = lovrBufferMap(buffer, uniform->offset);
|
||||
luax_checkuniform(L, 3, uniform, data, name);
|
||||
lovrBufferFlush(buffer, uniform->offset, uniform->size);
|
||||
lovrBufferMarkRange(buffer, uniform->offset, uniform->size);
|
||||
return 0;
|
||||
} else {
|
||||
Blob* blob = luax_checktype(L, 1, Blob);
|
||||
|
@ -41,7 +41,7 @@ int l_lovrShaderBlockSend(lua_State* L) {
|
|||
size_t bufferSize = lovrBufferGetSize(buffer);
|
||||
size_t copySize = MIN(bufferSize, blob->size);
|
||||
memcpy(data, blob->data, copySize);
|
||||
lovrBufferFlush(buffer, 0, copySize);
|
||||
lovrBufferMarkRange(buffer, 0, copySize);
|
||||
lua_pushinteger(L, copySize);
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -11,3 +11,19 @@ bool lovrBufferIsReadable(Buffer* buffer) {
|
|||
BufferUsage lovrBufferGetUsage(Buffer* buffer) {
|
||||
return buffer->usage;
|
||||
}
|
||||
|
||||
void lovrBufferMarkRange(Buffer* buffer, size_t offset, size_t size) {
|
||||
size_t end = offset + size;
|
||||
buffer->flushFrom = MIN(buffer->flushFrom, offset);
|
||||
buffer->flushTo = MAX(buffer->flushTo, end);
|
||||
}
|
||||
|
||||
void lovrBufferFlush(Buffer* buffer) {
|
||||
if (buffer->flushTo < buffer->flushFrom) {
|
||||
return;
|
||||
}
|
||||
|
||||
lovrBufferFlushRange(buffer, buffer->flushFrom, buffer->flushTo - buffer->flushFrom);
|
||||
buffer->flushFrom = SIZE_MAX;
|
||||
buffer->flushTo = -SIZE_MAX;
|
||||
}
|
||||
|
|
|
@ -24,6 +24,8 @@ typedef struct {
|
|||
Ref ref;
|
||||
void* data;
|
||||
size_t size;
|
||||
size_t flushFrom;
|
||||
size_t flushTo;
|
||||
bool readable;
|
||||
BufferType type;
|
||||
BufferUsage usage;
|
||||
|
@ -37,4 +39,6 @@ size_t lovrBufferGetSize(Buffer* buffer);
|
|||
bool lovrBufferIsReadable(Buffer* buffer);
|
||||
BufferUsage lovrBufferGetUsage(Buffer* buffer);
|
||||
void* lovrBufferMap(Buffer* buffer, size_t offset);
|
||||
void lovrBufferFlush(Buffer* buffer, size_t offset, size_t size);
|
||||
void lovrBufferFlushRange(Buffer* buffer, size_t offset, size_t size);
|
||||
void lovrBufferMarkRange(Buffer* buffer, size_t offset, size_t size);
|
||||
void lovrBufferFlush(Buffer* buffer);
|
||||
|
|
|
@ -65,7 +65,7 @@ static void lovrGraphicsInitBuffers() {
|
|||
state.identityBuffer = lovrBufferCreate(256, NULL, BUFFER_VERTEX, USAGE_STATIC, false);
|
||||
uint8_t* id = lovrBufferMap(state.identityBuffer, 0);
|
||||
for (int i = 0; i < 256; i++) id[i] = i;
|
||||
lovrBufferFlush(state.identityBuffer, 0, 256);
|
||||
lovrBufferFlushRange(state.identityBuffer, 0, 256);
|
||||
|
||||
VertexFormat empty = { .count = 0 };
|
||||
Buffer* vertexBuffer = state.buffers[STREAM_VERTEX];
|
||||
|
@ -743,23 +743,23 @@ void lovrGraphicsFlush() {
|
|||
// Flush vertex buffer
|
||||
if (flushGeometry && batch->vertexCount > 0) {
|
||||
size_t stride = BUFFER_STRIDES[STREAM_VERTEX];
|
||||
lovrBufferFlush(state.buffers[STREAM_VERTEX], batch->vertexStart * stride, batch->vertexCount * stride);
|
||||
lovrBufferFlushRange(state.buffers[STREAM_VERTEX], batch->vertexStart * stride, batch->vertexCount * stride);
|
||||
|
||||
if (!instanced) {
|
||||
lovrBufferFlush(state.buffers[STREAM_DRAW_ID], batch->vertexStart, batch->vertexCount);
|
||||
lovrBufferFlushRange(state.buffers[STREAM_DRAW_ID], batch->vertexStart, batch->vertexCount);
|
||||
}
|
||||
}
|
||||
|
||||
// Flush index buffer
|
||||
if (flushGeometry && batch->indexCount > 0) {
|
||||
size_t stride = BUFFER_STRIDES[STREAM_INDEX];
|
||||
lovrBufferFlush(state.buffers[STREAM_INDEX], batch->indexStart * stride, batch->indexCount * stride);
|
||||
lovrBufferFlushRange(state.buffers[STREAM_INDEX], batch->indexStart * stride, batch->indexCount * stride);
|
||||
}
|
||||
|
||||
// Flush draw data buffer
|
||||
size_t drawDataOffset = batch->drawStart * BUFFER_STRIDES[STREAM_DRAW_DATA];
|
||||
size_t drawDataSize = batch->drawCount * BUFFER_STRIDES[STREAM_DRAW_DATA];
|
||||
lovrBufferFlush(state.buffers[STREAM_DRAW_DATA], drawDataOffset, drawDataSize);
|
||||
lovrBufferFlushRange(state.buffers[STREAM_DRAW_DATA], drawDataOffset, drawDataSize);
|
||||
lovrShaderSetBlock(batch->shader, "lovrDrawData", state.buffers[STREAM_DRAW_DATA], drawDataOffset, state.maxDraws * BUFFER_STRIDES[STREAM_DRAW_DATA], ACCESS_READ);
|
||||
|
||||
// Uniforms
|
||||
|
|
|
@ -25,11 +25,6 @@ size_t lovrMeshGetIndexSize(Mesh* mesh) {
|
|||
return mesh->indexSize;
|
||||
}
|
||||
|
||||
void lovrMeshMarkVertices(Mesh* mesh, size_t start, size_t end) {
|
||||
mesh->flushStart = MIN(mesh->flushStart, start);
|
||||
mesh->flushEnd = MAX(mesh->flushEnd, end);
|
||||
}
|
||||
|
||||
void lovrMeshAttachAttribute(Mesh* mesh, const char* name, MeshAttribute* attribute) {
|
||||
lovrAssert(!map_get(&mesh->attributes, name), "Mesh already has an attribute named '%s'", name);
|
||||
lovrAssert(attribute->divisor >= 0, "Divisor can't be negative");
|
||||
|
|
|
@ -41,8 +41,6 @@ typedef struct {
|
|||
uint32_t vertexCount;
|
||||
uint32_t indexCount;
|
||||
size_t indexSize;
|
||||
size_t flushStart;
|
||||
size_t flushEnd;
|
||||
uint32_t drawStart;
|
||||
uint32_t drawCount;
|
||||
Material* material;
|
||||
|
@ -61,7 +59,6 @@ void lovrMeshSetIndexBuffer(Mesh* mesh, Buffer* buffer, uint32_t indexCount, siz
|
|||
uint32_t lovrMeshGetVertexCount(Mesh* mesh);
|
||||
uint32_t lovrMeshGetIndexCount(Mesh* mesh);
|
||||
size_t lovrMeshGetIndexSize(Mesh* mesh);
|
||||
void lovrMeshMarkVertices(Mesh* mesh, size_t start, size_t end);
|
||||
void lovrMeshAttachAttribute(Mesh* mesh, const char* name, MeshAttribute* attribute);
|
||||
void lovrMeshDetachAttribute(Mesh* mesh, const char* name);
|
||||
MeshAttribute* lovrMeshGetAttribute(Mesh* mesh, const char* name);
|
||||
|
|
|
@ -470,6 +470,7 @@ static void lovrGpuBindMesh(Mesh* mesh, Shader* shader, int divisorMultiplier) {
|
|||
|
||||
if (mesh->indexBuffer && mesh->indexCount > 0) {
|
||||
lovrGpuBindBuffer(BUFFER_INDEX, mesh->indexBuffer->id, true);
|
||||
lovrBufferFlush(mesh->indexBuffer);
|
||||
#ifndef EMSCRIPTEN
|
||||
uint32_t primitiveRestart = (1 << (mesh->indexSize * 8)) - 1;
|
||||
if (state.primitiveRestart != primitiveRestart) {
|
||||
|
@ -479,11 +480,6 @@ static void lovrGpuBindMesh(Mesh* mesh, Shader* shader, int divisorMultiplier) {
|
|||
#endif
|
||||
}
|
||||
|
||||
if (mesh->flushEnd > 0) {
|
||||
lovrBufferFlush(mesh->vertexBuffer, mesh->flushStart, mesh->flushEnd - mesh->flushStart);
|
||||
mesh->flushStart = mesh->flushEnd = 0;
|
||||
}
|
||||
|
||||
while ((key = map_next(&mesh->attributes, &iter)) != NULL) {
|
||||
int location = lovrShaderGetAttributeId(shader, key);
|
||||
|
||||
|
@ -497,6 +493,10 @@ static void lovrGpuBindMesh(Mesh* mesh, Shader* shader, int divisorMultiplier) {
|
|||
MeshAttribute previous = mesh->layout[i];
|
||||
MeshAttribute current = layout[i];
|
||||
|
||||
if (current.enabled) {
|
||||
lovrBufferFlush(current.buffer);
|
||||
}
|
||||
|
||||
if (!memcmp(&previous, ¤t, sizeof(MeshAttribute))) {
|
||||
continue;
|
||||
}
|
||||
|
@ -1577,7 +1577,7 @@ void* lovrBufferMap(Buffer* buffer, size_t offset) {
|
|||
return (uint8_t*) buffer->data + offset;
|
||||
}
|
||||
|
||||
void lovrBufferFlush(Buffer* buffer, size_t offset, size_t size) {
|
||||
void lovrBufferFlushRange(Buffer* buffer, size_t offset, size_t size) {
|
||||
lovrGpuBindBuffer(buffer->type, buffer->id, false);
|
||||
#ifndef EMSCRIPTEN
|
||||
if (GLAD_GL_ARB_buffer_storage) {
|
||||
|
|
Loading…
Reference in New Issue