Gawain: Add UBOs to shader interface.

This commit is contained in:
Clément Foucault 2017-10-06 14:57:21 +02:00
parent ea606a7847
commit f94f141f24
3 changed files with 37 additions and 2 deletions

View File

@ -49,6 +49,7 @@ typedef struct Gwn_ShaderInterface {
uint32_t name_buffer_offset;
Gwn_ShaderInput* attrib_buckets[GWN_NUM_SHADERINTERFACE_BUCKETS];
Gwn_ShaderInput* uniform_buckets[GWN_NUM_SHADERINTERFACE_BUCKETS];
Gwn_ShaderInput* ubo_buckets[GWN_NUM_SHADERINTERFACE_BUCKETS];
Gwn_ShaderInput* builtin_uniforms[GWN_NUM_UNIFORMS];
char* name_buffer;
} Gwn_ShaderInterface;
@ -58,4 +59,5 @@ void GWN_shaderinterface_discard(Gwn_ShaderInterface*);
const Gwn_ShaderInput* GWN_shaderinterface_uniform(const Gwn_ShaderInterface*, const char* name);
const Gwn_ShaderInput* GWN_shaderinterface_uniform_builtin(const Gwn_ShaderInterface*, Gwn_UniformBuiltin);
const Gwn_ShaderInput* GWN_shaderinterface_ubo(const Gwn_ShaderInterface*, const char* name);
const Gwn_ShaderInput* GWN_shaderinterface_attr(const Gwn_ShaderInterface*, const char* name);

View File

@ -198,9 +198,14 @@ Gwn_ShaderInterface* GWN_shaderinterface_create(GLint program)
glGetProgramiv(program, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &max_attrib_name_len);
glGetProgramiv(program, GL_ACTIVE_ATTRIBUTES, &attrib_ct);
const uint32_t name_buffer_len = attrib_ct * max_attrib_name_len;
GLint max_ubo_name_len, ubo_ct;
glGetProgramiv(program, GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH, &max_ubo_name_len);
glGetProgramiv(program, GL_ACTIVE_UNIFORM_BLOCKS, &ubo_ct);
const uint32_t name_buffer_len = attrib_ct * max_attrib_name_len + ubo_ct * max_ubo_name_len;
shaderface->name_buffer = malloc(name_buffer_len);
// Attributes
for (uint32_t i = 0; i < attrib_ct; ++i)
{
Gwn_ShaderInput* input = malloc(sizeof(Gwn_ShaderInput));
@ -218,6 +223,27 @@ Gwn_ShaderInterface* GWN_shaderinterface_create(GLint program)
shader_input_to_bucket(input, shaderface->attrib_buckets);
#if DEBUG_SHADER_INTERFACE
printf("attrib[%u] '%s' at location %d\n", i, name, input->location);
#endif
}
// Uniform Blocks
for (uint32_t i = 0; i < ubo_ct; ++i)
{
Gwn_ShaderInput* input = malloc(sizeof(Gwn_ShaderInput));
GLsizei remaining_buffer = name_buffer_len - shaderface->name_buffer_offset;
char* name = shaderface->name_buffer + shaderface->name_buffer_offset;
GLsizei name_len = 0;
glGetActiveUniformBlockName(program, i, remaining_buffer, &name_len, name);
input->location = i;
set_input_name(shaderface, input, name, name_len);
shader_input_to_bucket(input, shaderface->ubo_buckets);
#if DEBUG_SHADER_INTERFACE
printf("attrib[%u] '%s' at location %d\n", i, name, input->location);
#endif
@ -231,6 +257,7 @@ void GWN_shaderinterface_discard(Gwn_ShaderInterface* shaderface)
// Free memory used by buckets and has entries.
buckets_free(shaderface->uniform_buckets);
buckets_free(shaderface->attrib_buckets);
buckets_free(shaderface->ubo_buckets);
// Free memory used by name_buffer.
free(shaderface->name_buffer);
// Free memory used by shader interface by its self.
@ -266,6 +293,11 @@ const Gwn_ShaderInput* GWN_shaderinterface_uniform_builtin(const Gwn_ShaderInter
return (input->location != -1) ? input : NULL;
}
const Gwn_ShaderInput* GWN_shaderinterface_ubo(const Gwn_ShaderInterface* shaderface, const char* name)
{
return buckets_lookup(shaderface->ubo_buckets, shaderface->name_buffer, name);
}
const Gwn_ShaderInput* GWN_shaderinterface_attr(const Gwn_ShaderInterface* shaderface, const char* name)
{
return buckets_lookup(shaderface->attrib_buckets, shaderface->name_buffer, name);

View File

@ -561,7 +561,8 @@ int GPU_shader_get_uniform_block(GPUShader *shader, const char *name)
{
BLI_assert(shader && shader->program);
return glGetUniformBlockIndex(shader->program, name);
const Gwn_ShaderInput *ubo = GWN_shaderinterface_ubo(shader->interface, name);
return ubo ? ubo->location : -1;
}
void *GPU_fx_shader_get_interface(GPUShader *shader)