ShaderBlocks use Buffers;

This commit is contained in:
bjorn 2018-12-06 16:34:14 -08:00
parent ac33b8b085
commit 9a0f7c919a
4 changed files with 21 additions and 45 deletions

View File

@ -10,7 +10,8 @@ int l_lovrShaderBlockIsWritable(lua_State* L) {
int l_lovrShaderBlockGetSize(lua_State* L) { int l_lovrShaderBlockGetSize(lua_State* L) {
ShaderBlock* block = luax_checktype(L, 1, ShaderBlock); ShaderBlock* block = luax_checktype(L, 1, ShaderBlock);
lua_pushinteger(L, lovrShaderBlockGetSize(block)); Buffer* buffer = lovrShaderBlockGetBuffer(block);
lua_pushinteger(L, lovrBufferGetSize(buffer));
return 1; return 1;
} }
@ -28,15 +29,19 @@ int l_lovrShaderBlockSend(lua_State* L) {
const char* name = luaL_checkstring(L, 2); const char* name = luaL_checkstring(L, 2);
const Uniform* uniform = lovrShaderBlockGetUniform(block, name); const Uniform* uniform = lovrShaderBlockGetUniform(block, name);
lovrAssert(uniform, "Unknown uniform for ShaderBlock '%s'", name); lovrAssert(uniform, "Unknown uniform for ShaderBlock '%s'", name);
uint8_t* data = ((uint8_t*) lovrShaderBlockMap(block)) + uniform->offset; Buffer* buffer = lovrShaderBlockGetBuffer(block);
uint8_t* data = lovrBufferMap(buffer, uniform->offset);
luax_checkuniform(L, 3, uniform, data, name); luax_checkuniform(L, 3, uniform, data, name);
lovrBufferFlush(buffer, uniform->offset, uniform->size);
return 0; return 0;
} else { } else {
Blob* blob = luax_checktype(L, 1, Blob); Blob* blob = luax_checktype(L, 1, Blob);
void* data = lovrShaderBlockMap(block); Buffer* buffer = lovrShaderBlockGetBuffer(block);
size_t blockSize = lovrShaderBlockGetSize(block); void* data = lovrBufferMap(buffer, 0);
size_t copySize = MIN(blockSize, blob->size); size_t bufferSize = lovrBufferGetSize(buffer);
size_t copySize = MIN(bufferSize, blob->size);
memcpy(data, blob->data, copySize); memcpy(data, blob->data, copySize);
lovrBufferFlush(buffer, 0, copySize);
lua_pushinteger(L, copySize); lua_pushinteger(L, copySize);
return 1; return 1;
} }

View File

@ -14,7 +14,7 @@ Buffer* lovrBufferCreate(size_t size, void* data, BufferUsage usage);
void lovrBufferDestroy(void* ref); void lovrBufferDestroy(void* ref);
size_t lovrBufferGetSize(Buffer* buffer); size_t lovrBufferGetSize(Buffer* buffer);
BufferUsage lovrBufferGetUsage(Buffer* buffer); BufferUsage lovrBufferGetUsage(Buffer* buffer);
void* lovrBufferMap(Buffer* buffer, size_t offset, size_t size); void* lovrBufferMap(Buffer* buffer, size_t offset);
void lovrBufferFlush(Buffer* buffer, size_t offset, size_t size); void lovrBufferFlush(Buffer* buffer, size_t offset, size_t size);
void lovrBufferLock(Buffer* buffer); void lovrBufferLock(Buffer* buffer);
void lovrBufferUnlock(Buffer* buffer); void lovrBufferUnlock(Buffer* buffer);

View File

@ -92,14 +92,10 @@ struct Buffer {
struct ShaderBlock { struct ShaderBlock {
Ref ref; Ref ref;
BlockType type; BlockType type;
BufferUsage usage;
vec_uniform_t uniforms; vec_uniform_t uniforms;
map_int_t uniformMap; map_int_t uniformMap;
uint32_t buffer;
GLenum target; GLenum target;
size_t size; Buffer* buffer;
void* data;
bool mapped;
uint8_t incoherent; uint8_t incoherent;
}; };
@ -1549,7 +1545,7 @@ BufferUsage lovrBufferGetUsage(Buffer* buffer) {
return buffer->usage; return buffer->usage;
} }
void* lovrBufferMap(Buffer* buffer, size_t offset, size_t size) { void* lovrBufferMap(Buffer* buffer, size_t offset) {
return (uint8_t*) buffer->data + offset; return (uint8_t*) buffer->data + offset;
} }
@ -2071,8 +2067,7 @@ void lovrShaderBind(Shader* shader) {
bool writable = type == BLOCK_STORAGE && block->access != ACCESS_READ; bool writable = type == BLOCK_STORAGE && block->access != ACCESS_READ;
block->source->incoherent |= writable ? (1 << BARRIER_BLOCK) : 0; block->source->incoherent |= writable ? (1 << BARRIER_BLOCK) : 0;
vec_push(&state.incoherents[BARRIER_BLOCK], block->source); vec_push(&state.incoherents[BARRIER_BLOCK], block->source);
lovrShaderBlockUnmap(block->source); lovrGpuBindBlockBuffer(type, block->source->buffer->id, block->slot);
lovrGpuBindBlockBuffer(type, block->source->buffer, block->slot);
} else { } else {
lovrGpuBindBlockBuffer(type, 0, block->slot); lovrGpuBindBlockBuffer(type, 0, block->slot);
} }
@ -2189,7 +2184,7 @@ ShaderBlock* lovrShaderBlockCreate(vec_uniform_t* uniforms, BlockType type, Buff
size_t size = 0; size_t size = 0;
vec_foreach_ptr(&block->uniforms, uniform, i) { vec_foreach_ptr(&block->uniforms, uniform, i) {
// Calculate size and offset // Calculate size and offset based on the cryptic std140 rules
size_t align; size_t align;
if (uniform->count > 1 || uniform->type == UNIFORM_MATRIX) { if (uniform->count > 1 || uniform->type == UNIFORM_MATRIX) {
align = 16 * (uniform->type == UNIFORM_MATRIX ? uniform->components : 1); align = 16 * (uniform->type == UNIFORM_MATRIX ? uniform->components : 1);
@ -2211,13 +2206,7 @@ ShaderBlock* lovrShaderBlockCreate(vec_uniform_t* uniforms, BlockType type, Buff
block->target = block->type == BLOCK_UNIFORM ? GL_UNIFORM_BUFFER : GL_SHADER_STORAGE_BUFFER; block->target = block->type == BLOCK_UNIFORM ? GL_UNIFORM_BUFFER : GL_SHADER_STORAGE_BUFFER;
#endif #endif
block->type = type; block->type = type;
block->usage = usage; block->buffer = lovrBufferCreate(size, NULL, usage);
block->size = size;
block->data = calloc(1, size);
glGenBuffers(1, &block->buffer);
glBindBuffer(block->target, block->buffer);
glBufferData(block->target, size, NULL, convertBufferUsage(block->usage));
return block; return block;
} }
@ -2225,21 +2214,17 @@ ShaderBlock* lovrShaderBlockCreate(vec_uniform_t* uniforms, BlockType type, Buff
void lovrShaderBlockDestroy(void* ref) { void lovrShaderBlockDestroy(void* ref) {
ShaderBlock* block = ref; ShaderBlock* block = ref;
lovrGpuDestroySyncResource(block, block->incoherent); lovrGpuDestroySyncResource(block, block->incoherent);
glDeleteBuffers(1, &block->buffer); lovrRelease(block->buffer);
vec_deinit(&block->uniforms); vec_deinit(&block->uniforms);
map_deinit(&block->uniformMap); map_deinit(&block->uniformMap);
free(block->data);
free(block); free(block);
} }
size_t lovrShaderBlockGetSize(ShaderBlock* block) {
return block->size;
}
BlockType lovrShaderBlockGetType(ShaderBlock* block) { BlockType lovrShaderBlockGetType(ShaderBlock* block) {
return block->type; return block->type;
} }
// TODO use sds!
char* lovrShaderBlockGetShaderCode(ShaderBlock* block, const char* blockName, size_t* length) { char* lovrShaderBlockGetShaderCode(ShaderBlock* block, const char* blockName, size_t* length) {
// Calculate // Calculate
@ -2287,20 +2272,8 @@ const Uniform* lovrShaderBlockGetUniform(ShaderBlock* block, const char* name) {
return &block->uniforms.data[*index]; return &block->uniforms.data[*index];
} }
void* lovrShaderBlockMap(ShaderBlock* block) { Buffer* lovrShaderBlockGetBuffer(ShaderBlock* block) {
block->mapped = true; return block->buffer;
return block->data;
}
void lovrShaderBlockUnmap(ShaderBlock* block) {
if (!block->mapped) {
return;
}
glBindBuffer(block->target, block->buffer);
glBufferData(block->target, block->size, NULL, convertBufferUsage(block->usage));
glBufferSubData(block->target, 0, block->size, block->data);
block->mapped = false;
} }
// Mesh // Mesh

View File

@ -104,9 +104,7 @@ void lovrShaderSetBlock(Shader* shader, const char* name, ShaderBlock* block, Un
ShaderBlock* lovrShaderBlockCreate(vec_uniform_t* uniforms, BlockType type, BufferUsage usage); ShaderBlock* lovrShaderBlockCreate(vec_uniform_t* uniforms, BlockType type, BufferUsage usage);
void lovrShaderBlockDestroy(void* ref); void lovrShaderBlockDestroy(void* ref);
size_t lovrShaderBlockGetSize(ShaderBlock* block);
BlockType lovrShaderBlockGetType(ShaderBlock* block); BlockType lovrShaderBlockGetType(ShaderBlock* block);
char* lovrShaderBlockGetShaderCode(ShaderBlock* block, const char* blockName, size_t* length); char* lovrShaderBlockGetShaderCode(ShaderBlock* block, const char* blockName, size_t* length);
const Uniform* lovrShaderBlockGetUniform(ShaderBlock* block, const char* name); const Uniform* lovrShaderBlockGetUniform(ShaderBlock* block, const char* name);
void* lovrShaderBlockMap(ShaderBlock* block); Buffer* lovrShaderBlockGetBuffer(ShaderBlock* block);
void lovrShaderBlockUnmap(ShaderBlock* block);