[Mesa-dev] [PATCH 2/4] mesa: Add {Num}UniformBlocks and {Num}ShaderStorageBlocks to gl_shader{_program}

Iago Toral Quiroga itoral at igalia.com
Fri Oct 9 06:23:35 PDT 2015


These arrays provide backends with separate index spaces for UBOS and SSBOs.
---
 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 8d30bea..972bd40 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 5952792..eccf094 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 347da14..178478f 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -2286,13 +2286,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;
@@ -2689,9 +2711,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.
-- 
1.9.1



More information about the mesa-dev mailing list