GPUShaderInterface: Change builtin array to array of location/bind

This reduce the base size of the shaderinterface from 400 to 136 bytes.
Improves memory usage and cache coherency when querying a lot of uniforms
at once.
This commit is contained in:
Clément Foucault 2020-06-04 14:15:25 +02:00
parent 5837de6879
commit 10b34ad697
5 changed files with 41 additions and 53 deletions

View File

@ -92,9 +92,8 @@ typedef struct GPUShaderInterface {
uint16_t enabled_ubo_mask;
uint64_t enabled_tex_mask;
/** Opengl Location of builtin uniforms. Fast access, no lookup needed. */
/* TODO replace by location only array. */
GPUShaderInput builtins[GPU_NUM_UNIFORMS];
GPUShaderInput builtin_blocks[GPU_NUM_UNIFORM_BLOCKS];
int32_t builtins[GPU_NUM_UNIFORMS];
int32_t builtin_blocks[GPU_NUM_UNIFORM_BLOCKS];
/** Flat array. In this order: Attributes, Ubos, Uniforms. */
GPUShaderInput inputs[0];
} GPUShaderInterface;
@ -103,10 +102,10 @@ GPUShaderInterface *GPU_shaderinterface_create(int32_t program_id);
void GPU_shaderinterface_discard(GPUShaderInterface *);
const GPUShaderInput *GPU_shaderinterface_uniform(const GPUShaderInterface *, const char *name);
const GPUShaderInput *GPU_shaderinterface_uniform_builtin(const GPUShaderInterface *shaderface,
GPUUniformBuiltin builtin);
const GPUShaderInput *GPU_shaderinterface_block_builtin(const GPUShaderInterface *shaderface,
GPUUniformBlockBuiltin builtin);
int32_t GPU_shaderinterface_uniform_builtin(const GPUShaderInterface *shaderface,
GPUUniformBuiltin builtin);
int32_t GPU_shaderinterface_block_builtin(const GPUShaderInterface *shaderface,
GPUUniformBlockBuiltin builtin);
const GPUShaderInput *GPU_shaderinterface_ubo(const GPUShaderInterface *, const char *name);
const GPUShaderInput *GPU_shaderinterface_attr(const GPUShaderInterface *, const char *name);

View File

@ -857,12 +857,10 @@ void immUniform4iv(const char *name, const int data[4])
void immUniformColor4f(float r, float g, float b, float a)
{
const GPUShaderInput *uniform = GPU_shaderinterface_uniform_builtin(imm.shader_interface,
GPU_UNIFORM_COLOR);
#if TRUST_NO_ONE
assert(uniform != NULL);
#endif
glUniform4f(uniform->location, r, g, b, a);
int32_t uniform_loc = GPU_shaderinterface_uniform_builtin(imm.shader_interface,
GPU_UNIFORM_COLOR);
BLI_assert(uniform_loc != -1);
glUniform4f(uniform_loc, r, g, b, a);
}
void immUniformColor4fv(const float rgba[4])

View File

@ -654,63 +654,59 @@ void GPU_matrix_bind(const GPUShaderInterface *shaderface)
* call glUseProgram before this, as glUniform expects program to be bound
*/
const GPUShaderInput *MV = GPU_shaderinterface_uniform_builtin(shaderface,
GPU_UNIFORM_MODELVIEW);
const GPUShaderInput *P = GPU_shaderinterface_uniform_builtin(shaderface,
GPU_UNIFORM_PROJECTION);
const GPUShaderInput *MVP = GPU_shaderinterface_uniform_builtin(shaderface, GPU_UNIFORM_MVP);
int32_t MV = GPU_shaderinterface_uniform_builtin(shaderface, GPU_UNIFORM_MODELVIEW);
int32_t P = GPU_shaderinterface_uniform_builtin(shaderface, GPU_UNIFORM_PROJECTION);
int32_t MVP = GPU_shaderinterface_uniform_builtin(shaderface, GPU_UNIFORM_MVP);
const GPUShaderInput *N = GPU_shaderinterface_uniform_builtin(shaderface, GPU_UNIFORM_NORMAL);
const GPUShaderInput *MV_inv = GPU_shaderinterface_uniform_builtin(shaderface,
GPU_UNIFORM_MODELVIEW_INV);
const GPUShaderInput *P_inv = GPU_shaderinterface_uniform_builtin(shaderface,
GPU_UNIFORM_PROJECTION_INV);
int32_t N = GPU_shaderinterface_uniform_builtin(shaderface, GPU_UNIFORM_NORMAL);
int32_t MV_inv = GPU_shaderinterface_uniform_builtin(shaderface, GPU_UNIFORM_MODELVIEW_INV);
int32_t P_inv = GPU_shaderinterface_uniform_builtin(shaderface, GPU_UNIFORM_PROJECTION_INV);
if (MV) {
if (MV != -1) {
#if DEBUG_MATRIX_BIND
puts("setting MV matrix");
#endif
glUniformMatrix4fv(MV->location, 1, GL_FALSE, (const float *)GPU_matrix_model_view_get(NULL));
glUniformMatrix4fv(MV, 1, GL_FALSE, (const float *)GPU_matrix_model_view_get(NULL));
}
if (P) {
if (P != -1) {
#if DEBUG_MATRIX_BIND
puts("setting P matrix");
#endif
glUniformMatrix4fv(P->location, 1, GL_FALSE, (const float *)GPU_matrix_projection_get(NULL));
glUniformMatrix4fv(P, 1, GL_FALSE, (const float *)GPU_matrix_projection_get(NULL));
}
if (MVP) {
if (MVP != -1) {
#if DEBUG_MATRIX_BIND
puts("setting MVP matrix");
#endif
glUniformMatrix4fv(
MVP->location, 1, GL_FALSE, (const float *)GPU_matrix_model_view_projection_get(NULL));
MVP, 1, GL_FALSE, (const float *)GPU_matrix_model_view_projection_get(NULL));
}
if (N) {
if (N != -1) {
#if DEBUG_MATRIX_BIND
puts("setting normal matrix");
#endif
glUniformMatrix3fv(N->location, 1, GL_FALSE, (const float *)GPU_matrix_normal_get(NULL));
glUniformMatrix3fv(N, 1, GL_FALSE, (const float *)GPU_matrix_normal_get(NULL));
}
if (MV_inv) {
if (MV_inv != -1) {
Mat4 m;
GPU_matrix_model_view_get(m);
invert_m4(m);
glUniformMatrix4fv(MV_inv->location, 1, GL_FALSE, (const float *)m);
glUniformMatrix4fv(MV_inv, 1, GL_FALSE, (const float *)m);
}
if (P_inv) {
if (P_inv != -1) {
Mat4 m;
GPU_matrix_projection_get(m);
invert_m4(m);
glUniformMatrix4fv(P_inv->location, 1, GL_FALSE, (const float *)m);
glUniformMatrix4fv(P_inv, 1, GL_FALSE, (const float *)m);
}
gpu_matrix_state_active_set_dirty(false);

View File

@ -735,15 +735,13 @@ int GPU_shader_get_uniform(GPUShader *shader, const char *name)
int GPU_shader_get_builtin_uniform(GPUShader *shader, int builtin)
{
BLI_assert(shader && shader->program);
const GPUShaderInput *uniform = GPU_shaderinterface_uniform_builtin(shader->interface, builtin);
return uniform->location;
return GPU_shaderinterface_uniform_builtin(shader->interface, builtin);
}
int GPU_shader_get_builtin_block(GPUShader *shader, int builtin)
{
BLI_assert(shader && shader->program);
const GPUShaderInput *uniform = GPU_shaderinterface_block_builtin(shader->interface, builtin);
return uniform->binding;
return GPU_shaderinterface_block_builtin(shader->interface, builtin);
}
int GPU_shader_get_uniform_block(GPUShader *shader, const char *name)
@ -856,10 +854,9 @@ void GPU_shader_uniform_int(GPUShader *UNUSED(shader), int location, int value)
void GPU_shader_set_srgb_uniform(const GPUShaderInterface *interface)
{
const GPUShaderInput *srgb_uniform = GPU_shaderinterface_uniform_builtin(
interface, GPU_UNIFORM_SRGB_TRANSFORM);
if (srgb_uniform) {
glUniform1i(srgb_uniform->location, g_shader_builtin_srgb_transform);
int32_t loc = GPU_shaderinterface_uniform_builtin(interface, GPU_UNIFORM_SRGB_TRANSFORM);
if (loc != -1) {
glUniform1i(loc, g_shader_builtin_srgb_transform);
}
}

View File

@ -367,15 +367,13 @@ GPUShaderInterface *GPU_shaderinterface_create(int32_t program)
/* Builtin Uniforms */
for (GPUUniformBuiltin u = 0; u < GPU_NUM_UNIFORMS; u++) {
shaderface->builtins[u].location = glGetUniformLocation(program, BuiltinUniform_name(u));
shaderface->builtins[u].binding = -1;
shaderface->builtins[u] = glGetUniformLocation(program, BuiltinUniform_name(u));
}
/* Builtin Uniforms Blocks */
for (GPUUniformBlockBuiltin u = 0; u < GPU_NUM_UNIFORM_BLOCKS; u++) {
const GPUShaderInput *block = GPU_shaderinterface_ubo(shaderface, BuiltinUniformBlock_name(u));
shaderface->builtin_blocks[u].location = -1;
shaderface->builtin_blocks[u].binding = (block != NULL) ? block->binding : -1;
shaderface->builtin_blocks[u] = (block != NULL) ? block->binding : -1;
}
/* Batches ref buffer */
@ -477,18 +475,18 @@ const GPUShaderInput *GPU_shaderinterface_uniform(const GPUShaderInterface *shad
return input_lookup(shaderface, shaderface->inputs + ofs, shaderface->uniform_len, name);
}
const GPUShaderInput *GPU_shaderinterface_uniform_builtin(const GPUShaderInterface *shaderface,
GPUUniformBuiltin builtin)
int32_t GPU_shaderinterface_uniform_builtin(const GPUShaderInterface *shaderface,
GPUUniformBuiltin builtin)
{
BLI_assert(builtin >= 0 && builtin < GPU_NUM_UNIFORMS);
return &shaderface->builtins[builtin];
return shaderface->builtins[builtin];
}
const GPUShaderInput *GPU_shaderinterface_block_builtin(const GPUShaderInterface *shaderface,
GPUUniformBlockBuiltin builtin)
int32_t GPU_shaderinterface_block_builtin(const GPUShaderInterface *shaderface,
GPUUniformBlockBuiltin builtin)
{
BLI_assert(builtin >= 0 && builtin < GPU_NUM_UNIFORM_BLOCKS);
return &shaderface->builtin_blocks[builtin];
return shaderface->builtin_blocks[builtin];
}
void GPU_shaderinterface_add_batch_ref(GPUShaderInterface *shaderface, GPUBatch *batch)