From d31f98a272e429d5782192919b7628494ad1adf3 Mon Sep 17 00:00:00 2001 From: Iago Toral Quiroga Date: Thu, 1 Oct 2015 10:17:30 +0200 Subject: [PATCH] mesa: Add {Num}UniformBlocks and {Num}ShaderStorageBlocks to gl_shader{_program} MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit These arrays provide backends with separate index spaces for UBOS and SSBOs. Reviewed-by: Kristian Høgsberg --- src/glsl/linker.cpp | 61 +++++++++++++++++++++++++++++ src/glsl/standalone_scaffolding.cpp | 9 +++++ src/mesa/main/mtypes.h | 49 ++++++++++++++++++++++- 3 files changed, 118 insertions(+), 1 deletion(-) diff --git a/src/glsl/linker.cpp b/src/glsl/linker.cpp index 8d30bea8cf0..972bd40fa9f 100644 --- a/src/glsl/linker.cpp +++ b/src/glsl/linker.cpp @@ -3599,6 +3599,42 @@ link_assign_subroutine_types(struct gl_shader_program *prog) } } +static void +split_ubos_and_ssbos(void *mem_ctx, + struct gl_uniform_block *blocks, + unsigned num_blocks, + struct gl_uniform_block ***ubos, + unsigned *num_ubos, + struct gl_uniform_block ***ssbos, + unsigned *num_ssbos) +{ + unsigned num_ubo_blocks = 0; + unsigned num_ssbo_blocks = 0; + + for (unsigned i = 0; i < num_blocks; i++) { + if (blocks[i].IsShaderStorage) + num_ssbo_blocks++; + else + num_ubo_blocks++; + } + + *ubos = ralloc_array(mem_ctx, gl_uniform_block *, num_ubo_blocks); + *num_ubos = 0; + + *ssbos = ralloc_array(mem_ctx, gl_uniform_block *, num_ssbo_blocks); + *num_ssbos = 0; + + for (unsigned i = 0; i < num_blocks; i++) { + if (blocks[i].IsShaderStorage) { + (*ssbos)[(*num_ssbos)++] = &blocks[i]; + } else { + (*ubos)[(*num_ubos)++] = &blocks[i]; + } + } + + assert(*num_ubos + *num_ssbos == num_blocks); +} + void link_shaders(struct gl_context *ctx, struct gl_shader_program *prog) { @@ -4110,6 +4146,31 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog) } } + /* Split BufferInterfaceBlocks into UniformBlocks and ShaderStorageBlocks + * for gl_shader_program and gl_shader, so that drivers that need separate + * index spaces for each set can have that. + */ + for (unsigned i = MESA_SHADER_VERTEX; i <= MESA_SHADER_FRAGMENT; i++) { + if (prog->_LinkedShaders[i] != NULL) { + gl_shader *sh = prog->_LinkedShaders[i]; + split_ubos_and_ssbos(sh, + sh->BufferInterfaceBlocks, + sh->NumBufferInterfaceBlocks, + &sh->UniformBlocks, + &sh->NumUniformBlocks, + &sh->ShaderStorageBlocks, + &sh->NumShaderStorageBlocks); + } + } + + split_ubos_and_ssbos(prog, + prog->BufferInterfaceBlocks, + prog->NumBufferInterfaceBlocks, + &prog->UniformBlocks, + &prog->NumUniformBlocks, + &prog->ShaderStorageBlocks, + &prog->NumShaderStorageBlocks); + /* FINISHME: Assign fragment shader output locations. */ done: diff --git a/src/glsl/standalone_scaffolding.cpp b/src/glsl/standalone_scaffolding.cpp index 59527927776..eccf094b5cd 100644 --- a/src/glsl/standalone_scaffolding.cpp +++ b/src/glsl/standalone_scaffolding.cpp @@ -110,6 +110,15 @@ _mesa_clear_shader_program_data(struct gl_shader_program *shProg) ralloc_free(shProg->BufferInterfaceBlocks); shProg->BufferInterfaceBlocks = NULL; shProg->NumBufferInterfaceBlocks = 0; + + ralloc_free(shProg->UniformBlocks); + shProg->UniformBlocks = NULL; + shProg->NumUniformBlocks = 0; + + ralloc_free(shProg->ShaderStorageBlocks); + shProg->ShaderStorageBlocks = NULL; + shProg->NumShaderStorageBlocks = 0; + for (i = 0; i < MESA_SHADER_STAGES; i++) { ralloc_free(shProg->UniformBlockStageIndex[i]); shProg->UniformBlockStageIndex[i] = NULL; diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index f62ad3416ea..f7118c1e7a6 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -2284,13 +2284,35 @@ struct gl_shader unsigned num_combined_uniform_components; /** - * This shader's uniform block information. + * This shader's uniform/ssbo block information. * * These fields are only set post-linking. + * + * BufferInterfaceBlocks is a list containing both UBOs and SSBOs. This is + * useful during the linking process so that we don't have to handle SSBOs + * specifically. + * + * UniformBlocks is a list of UBOs. This is useful for backends that need + * or prefer to see separate index spaces for UBOS and SSBOs like the GL + * API specifies. + * + * ShaderStorageBlocks is a list of SSBOs. This is useful for backends that + * need or prefer to see separate index spaces for UBOS and SSBOs like the + * GL API specifies. + * + * UniformBlocks and ShaderStorageBlocks only have pointers into + * BufferInterfaceBlocks so the actual resource information is not + * duplicated. */ unsigned NumBufferInterfaceBlocks; struct gl_uniform_block *BufferInterfaceBlocks; + unsigned NumUniformBlocks; + struct gl_uniform_block **UniformBlocks; + + unsigned NumShaderStorageBlocks; + struct gl_uniform_block **ShaderStorageBlocks; + struct exec_list *ir; struct exec_list *packed_varyings; struct glsl_symbol_table *symbols; @@ -2687,9 +2709,34 @@ struct gl_shader_program */ unsigned LastClipDistanceArraySize; + /** + * This shader's uniform/ssbo block information. + * + * BufferInterfaceBlocks is a list containing both UBOs and SSBOs. This is + * useful during the linking process so that we don't have to handle SSBOs + * specifically. + * + * UniformBlocks is a list of UBOs. This is useful for backends that need + * or prefer to see separate index spaces for UBOS and SSBOs like the GL + * API specifies. + * + * ShaderStorageBlocks is a list of SSBOs. This is useful for backends that + * need or prefer to see separate index spaces for UBOS and SSBOs like the + * GL API specifies. + * + * UniformBlocks and ShaderStorageBlocks only have pointers into + * BufferInterfaceBlocks so the actual resource information is not + * duplicated and are only set after linking. + */ unsigned NumBufferInterfaceBlocks; struct gl_uniform_block *BufferInterfaceBlocks; + unsigned NumUniformBlocks; + struct gl_uniform_block **UniformBlocks; + + unsigned NumShaderStorageBlocks; + struct gl_uniform_block **ShaderStorageBlocks; + /** * Indices into the _LinkedShaders's UniformBlocks[] array for each stage * they're used in, or -1. -- 2.30.2