rm persistent mapping; sync Mesh and ShaderBlock;

This commit is contained in:
bjorn 2020-08-17 03:29:30 -06:00
parent 810086e1ba
commit 82159a9885
6 changed files with 29 additions and 40 deletions

View File

@ -1294,7 +1294,7 @@ static int l_lovrGraphicsNewMesh(lua_State* L) {
});
if (dataIndex) {
AttributeData data = { .raw = lovrBufferMap(vertexBuffer, 0) };
AttributeData data = { .raw = lovrBufferMap(vertexBuffer, 0, false) };
if (blob) {
memcpy(data.raw, blob->data, count * stride);

View File

@ -139,7 +139,7 @@ static int l_lovrMeshGetVertex(lua_State* L) {
}
lovrAssert(lovrBufferIsReadable(buffer), "Mesh:getVertex can only be used if the Mesh was created with the readable flag");
AttributeData data = { .raw = lovrBufferMap(buffer, index * firstAttribute->stride) };
AttributeData data = { .raw = lovrBufferMap(buffer, index * firstAttribute->stride, false) };
int components = 0;
for (uint32_t i = 0; i < attributeCount; i++) {
@ -176,7 +176,7 @@ static int l_lovrMeshSetVertex(lua_State* L) {
}
size_t stride = firstAttribute->stride;
AttributeData data = { .raw = lovrBufferMap(buffer, index * stride) };
AttributeData data = { .raw = lovrBufferMap(buffer, index * stride, false) };
int component = 0;
for (uint32_t i = 0; i < attributeCount; i++) {
const MeshAttribute* attribute = lovrMeshGetAttribute(mesh, i);
@ -219,7 +219,7 @@ static int l_lovrMeshGetVertexAttribute(lua_State* L) {
lovrAssert(vertexIndex < lovrMeshGetVertexCount(mesh), "Invalid mesh vertex: %d", vertexIndex + 1);
const MeshAttribute* attribute = lovrMeshGetAttribute(mesh, attributeIndex);
lovrAssert(attribute && attribute->buffer == buffer, "Invalid mesh attribute: %d", attributeIndex + 1);
AttributeData data = { .raw = lovrBufferMap(buffer, vertexIndex * attribute->stride + attribute->offset) };
AttributeData data = { .raw = lovrBufferMap(buffer, vertexIndex * attribute->stride + attribute->offset, false) };
for (unsigned i = 0; i < attribute->components; i++) {
switch (attribute->type) {
case I8: lua_pushinteger(L, *data.i8++); break;
@ -243,7 +243,7 @@ static int l_lovrMeshSetVertexAttribute(lua_State* L) {
lovrAssert(vertexIndex < lovrMeshGetVertexCount(mesh), "Invalid mesh vertex: %d", vertexIndex + 1);
const MeshAttribute* attribute = lovrMeshGetAttribute(mesh, attributeIndex);
lovrAssert(attribute && attribute->buffer == buffer, "Invalid mesh attribute: %d", attributeIndex + 1);
AttributeData data = { .raw = lovrBufferMap(buffer, vertexIndex * attribute->stride + attribute->offset) };
AttributeData data = { .raw = lovrBufferMap(buffer, vertexIndex * attribute->stride + attribute->offset, false) };
for (unsigned i = 0; i < attribute->components; i++) {
int index = 4 + i;
if (table) {
@ -298,7 +298,7 @@ static int l_lovrMeshSetVertices(lua_State* L) {
if (blob) {
count = MIN(count, blob->size / stride);
lovrAssert(start + count <= capacity, "Overflow in Mesh:setVertices: Mesh can only hold %d vertices", capacity);
void* data = lovrBufferMap(buffer, start * stride);
void* data = lovrBufferMap(buffer, start * stride, false);
memcpy(data, blob->data, count * stride);
lovrBufferFlush(buffer, start * stride, count * stride);
return 0;
@ -308,7 +308,7 @@ static int l_lovrMeshSetVertices(lua_State* L) {
count = MIN(count, lua_objlen(L, 2));
lovrAssert(start + count <= capacity, "Overflow in Mesh:setVertices: Mesh can only hold %d vertices", capacity);
AttributeData data = { .raw = lovrBufferMap(buffer, start * stride) };
AttributeData data = { .raw = lovrBufferMap(buffer, start * stride, false) };
for (uint32_t i = 0; i < count; i++) {
lua_rawgeti(L, 2, i + 1);
@ -355,7 +355,7 @@ static int l_lovrMeshGetVertexMap(lua_State* L) {
}
lovrAssert(lovrBufferIsReadable(buffer), "Mesh:getVertexMap can only be used if the Mesh was created with the readable flag");
union { void* raw; uint16_t* shorts; uint32_t* ints; } indices = { .raw = lovrBufferMap(buffer, 0) };
union { void* raw; uint16_t* shorts; uint32_t* ints; } indices = { .raw = lovrBufferMap(buffer, 0, false) };
if (lua_istable(L, 2)) {
lua_settop(L, 2);
@ -400,7 +400,7 @@ static int l_lovrMeshSetVertexMap(lua_State* L) {
indexBuffer = lovrBufferCreate(blob->size, blob->data, BUFFER_INDEX, usage, readable);
lovrMeshSetIndexBuffer(mesh, indexBuffer, count, size, 0);
} else {
void* indices = lovrBufferMap(indexBuffer, 0);
void* indices = lovrBufferMap(indexBuffer, 0, false);
memcpy(indices, blob->data, blob->size);
lovrBufferFlush(indexBuffer, 0, blob->size);
}
@ -418,7 +418,7 @@ static int l_lovrMeshSetVertexMap(lua_State* L) {
indexBuffer = lovrBufferCreate(count * size, NULL, BUFFER_INDEX, usage, readable);
}
union { void* raw; uint16_t* shorts; uint32_t* ints; } indices = { .raw = lovrBufferMap(indexBuffer, 0) };
union { void* raw; uint16_t* shorts; uint32_t* ints; } indices = { .raw = lovrBufferMap(indexBuffer, 0, false) };
for (uint32_t i = 0; i < count; i++) {
lua_rawgeti(L, 2, i + 1);

View File

@ -33,14 +33,14 @@ static int l_lovrShaderBlockSend(lua_State* L) {
const Uniform* uniform = lovrShaderBlockGetUniform(block, name);
lovrAssert(uniform, "Unknown uniform for ShaderBlock '%s'", name);
Buffer* buffer = lovrShaderBlockGetBuffer(block);
uint8_t* data = lovrBufferMap(buffer, uniform->offset);
uint8_t* data = lovrBufferMap(buffer, uniform->offset, false);
luax_checkuniform(L, 3, uniform, data, name);
lovrBufferFlush(buffer, uniform->offset, uniform->size);
return 0;
} else {
Blob* blob = luax_checktype(L, 2, Blob);
Buffer* buffer = lovrShaderBlockGetBuffer(block);
void* data = lovrBufferMap(buffer, 0);
void* data = lovrBufferMap(buffer, 0, false);
size_t bufferSize = lovrBufferGetSize(buffer);
size_t copySize = MIN(bufferSize, blob->size);
memcpy(data, blob->data, copySize);
@ -57,7 +57,7 @@ static int l_lovrShaderBlockRead(lua_State* L) {
lovrAssert(uniform, "Unknown uniform for ShaderBlock '%s'", name);
Buffer* buffer = lovrShaderBlockGetBuffer(block);
lovrAssert(lovrBufferIsReadable(buffer), "ShaderBlock:read requires the ShaderBlock to be created with the readable flag");
union { float* floats; int* ints; } data = { .floats = lovrBufferMap(buffer, uniform->offset) };
union { float* floats; int* ints; } data = { .floats = lovrBufferMap(buffer, uniform->offset, false) };
int components = uniform->components;
if (uniform->type == UNIFORM_MATRIX) {

View File

@ -24,7 +24,7 @@ void lovrBufferDestroy(void* ref);
size_t lovrBufferGetSize(Buffer* buffer);
bool lovrBufferIsReadable(Buffer* buffer);
BufferUsage lovrBufferGetUsage(Buffer* buffer);
void* lovrBufferMap(Buffer* buffer, size_t offset);
void* lovrBufferMap(Buffer* buffer, size_t offset, bool unsynchronized);
void lovrBufferFlush(Buffer* buffer, size_t offset, size_t size);
void lovrBufferUnmap(Buffer* buffer);
void lovrBufferDiscard(Buffer* buffer);

View File

@ -184,7 +184,7 @@ static void* lovrGraphicsMapBuffer(StreamType type, uint32_t count) {
state.head[type] = 0;
}
return lovrBufferMap(state.buffers[type], state.head[type] * bufferStride[type]);
return lovrBufferMap(state.buffers[type], state.head[type] * bufferStride[type], true);
}
// Base
@ -240,7 +240,7 @@ void lovrGraphicsCreateWindow(WindowFlags* flags) {
// The identity buffer is used for autoinstanced meshes and instanced primitives and maps the
// instance ID to a vertex attribute. Its contents never change, so they are initialized here.
state.identityBuffer = lovrBufferCreate(MAX_DRAWS * sizeof(uint8_t), NULL, BUFFER_VERTEX, USAGE_STATIC, false);
uint8_t* id = lovrBufferMap(state.identityBuffer, 0);
uint8_t* id = lovrBufferMap(state.identityBuffer, 0, true);
for (int i = 0; i < MAX_DRAWS; i++) id[i] = i;
lovrBufferFlush(state.identityBuffer, 0, MAX_DRAWS);
lovrBufferUnmap(state.identityBuffer);

View File

@ -2199,13 +2199,7 @@ Buffer* lovrBufferCreate(size_t size, void* data, BufferType type, BufferUsage u
memcpy(buffer->data, data, size);
}
#else
if (GLAD_GL_ARB_buffer_storage) {
GLbitfield flags = GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | (readable ? GL_MAP_READ_BIT : 0);
glBufferStorage(glType, size, data, flags);
buffer->data = glMapBufferRange(glType, 0, size, flags | GL_MAP_FLUSH_EXPLICIT_BIT);
} else {
glBufferData(glType, size, data, convertBufferUsage(usage));
}
glBufferData(glType, size, data, convertBufferUsage(usage));
#endif
return buffer;
@ -2234,13 +2228,15 @@ BufferUsage lovrBufferGetUsage(Buffer* buffer) {
return buffer->usage;
}
void* lovrBufferMap(Buffer* buffer, size_t offset) {
void* lovrBufferMap(Buffer* buffer, size_t offset, bool unsynchronized) {
#ifndef LOVR_WEBGL
if (!GLAD_GL_ARB_buffer_storage && !buffer->mapped) {
if (!buffer->mapped) {
buffer->mapped = true;
lovrGpuBindBuffer(buffer->type, buffer->id);
lovrAssert(!buffer->readable || !unsynchronized, "Readable Buffers must be mapped with synchronization");
GLbitfield flags = GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT;
flags |= buffer->readable ? GL_MAP_READ_BIT : GL_MAP_UNSYNCHRONIZED_BIT;
flags |= buffer->readable ? GL_MAP_READ_BIT : 0;
flags |= unsynchronized ? GL_MAP_UNSYNCHRONIZED_BIT : 0;
buffer->data = glMapBufferRange(convertBufferType(buffer->type), 0, buffer->size, flags);
}
#endif
@ -2260,17 +2256,15 @@ void lovrBufferUnmap(Buffer* buffer) {
glBufferSubData(convertBufferType(buffer->type), buffer->flushFrom, buffer->flushTo - buffer->flushFrom, data);
}
#else
if (buffer->mapped || GLAD_GL_ARB_buffer_storage) {
if (buffer->mapped) {
lovrGpuBindBuffer(buffer->type, buffer->id);
if (buffer->flushTo > buffer->flushFrom) {
glFlushMappedBufferRange(convertBufferType(buffer->type), buffer->flushFrom, buffer->flushTo - buffer->flushFrom);
}
if (buffer->mapped) {
glUnmapBuffer(convertBufferType(buffer->type));
buffer->mapped = false;
}
glUnmapBuffer(convertBufferType(buffer->type));
buffer->mapped = false;
}
#endif
buffer->flushFrom = SIZE_MAX;
@ -2278,25 +2272,20 @@ void lovrBufferUnmap(Buffer* buffer) {
}
void lovrBufferDiscard(Buffer* buffer) {
lovrAssert(!buffer->readable, "Readable Buffers can not be discarded");
lovrGpuBindBuffer(buffer->type, buffer->id);
GLenum glType = convertBufferType(buffer->type);
#ifdef LOVR_WEBGL
glBufferData(glType, buffer->size, NULL, convertBufferUsage(buffer->usage));
#else
// We unmap even if persistent mapping is supported
if (buffer->mapped || GLAD_GL_ARB_buffer_storage) {
if (buffer->mapped) {
glUnmapBuffer(glType);
buffer->mapped = false;
}
GLbitfield flags = GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT;
flags |= buffer->readable ? GL_MAP_READ_BIT : (GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
flags |= GLAD_GL_ARB_buffer_storage ? GL_MAP_PERSISTENT_BIT : 0;
GLbitfield flags = GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_INVALIDATE_BUFFER_BIT;
buffer->data = glMapBufferRange(glType, 0, buffer->size, flags);
if (!GLAD_GL_ARB_buffer_storage) {
buffer->mapped = true;
}
buffer->mapped = true;
#endif
}