[Mesa-dev] [PATCH 4/6] glsl: fully split apart buffer block arrays

Timothy Arceri timothy.arceri at collabora.com
Sun Apr 3 11:16:31 UTC 2016


With this chage we create the UBO and SSBO arrays separately from the
beginning rather than putting them into a combined array and splitting
it apart later.
---
 src/compiler/glsl/link_uniform_blocks.cpp       | 204 +++++++++++++-----------
 src/compiler/glsl/link_uniform_initializers.cpp |   4 +-
 src/compiler/glsl/link_uniforms.cpp             |  10 +-
 src/compiler/glsl/linker.cpp                    | 119 +++++++++-----
 src/compiler/glsl/linker.h                      |   7 +-
 src/compiler/glsl/standalone_scaffolding.cpp    |   4 -
 src/mesa/main/mtypes.h                          |  50 +-----
 src/mesa/main/shader_query.cpp                  |   4 +-
 src/mesa/main/shaderapi.c                       |   2 +-
 src/mesa/main/shaderobj.c                       |  10 +-
 src/mesa/main/uniforms.c                        |   8 +-
 11 files changed, 224 insertions(+), 198 deletions(-)

diff --git a/src/compiler/glsl/link_uniform_blocks.cpp b/src/compiler/glsl/link_uniform_blocks.cpp
index c8fa181..3ef1633 100644
--- a/src/compiler/glsl/link_uniform_blocks.cpp
+++ b/src/compiler/glsl/link_uniform_blocks.cpp
@@ -291,13 +291,105 @@ resize_block_array(const glsl_type *type,
    }
 }
 
-unsigned
+static void
+create_buffer_blocks(void *mem_ctx, struct gl_context *ctx,
+                     struct gl_shader_program *prog,
+                     struct gl_uniform_block **out_blks, unsigned num_blocks,
+                     struct hash_table *block_hash, unsigned num_variables,
+                     bool create_ubo_blocks)
+{
+   if (num_blocks == 0) {
+      assert(num_variables == 0);
+      return;
+   }
+
+   assert(num_variables != 0);
+
+   /* Allocate storage to hold all of the informatation related to uniform
+    * blocks that can be queried through the API.
+    */
+   struct gl_uniform_block *blocks = ralloc_array(mem_ctx, gl_uniform_block, num_blocks);
+   gl_uniform_buffer_variable *variables =
+      ralloc_array(blocks, gl_uniform_buffer_variable, num_variables);
+
+   /* Add each variable from each uniform block to the API tracking
+    * structures.
+    */
+   ubo_visitor parcel(blocks, variables, num_variables);
+
+   STATIC_ASSERT(unsigned(GLSL_INTERFACE_PACKING_STD140)
+                 == unsigned(ubo_packing_std140));
+   STATIC_ASSERT(unsigned(GLSL_INTERFACE_PACKING_SHARED)
+                 == unsigned(ubo_packing_shared));
+   STATIC_ASSERT(unsigned(GLSL_INTERFACE_PACKING_PACKED)
+                 == unsigned(ubo_packing_packed));
+   STATIC_ASSERT(unsigned(GLSL_INTERFACE_PACKING_STD430)
+                 == unsigned(ubo_packing_std430));
+
+   unsigned i = 0;
+   struct hash_entry *entry;
+   hash_table_foreach (block_hash, entry) {
+      const struct link_uniform_block_active *const b =
+         (const struct link_uniform_block_active *) entry->data;
+      const glsl_type *block_type = b->type;
+
+      if ((create_ubo_blocks && !b->is_shader_storage) ||
+          (!create_ubo_blocks && b->is_shader_storage)) {
+
+         if (b->array != NULL) {
+            unsigned binding_offset = 0;
+            char *name = ralloc_strdup(NULL,
+                                       block_type->without_array()->name);
+            size_t name_length = strlen(name);
+
+            assert(b->has_instance_name);
+            process_block_array(b->array, &name, name_length, blocks, &parcel,
+                                variables, b, &i, &binding_offset, ctx, prog);
+            ralloc_free(name);
+         } else {
+            blocks[i].Name = ralloc_strdup(blocks, block_type->name);
+            blocks[i].Uniforms = &variables[parcel.index];
+            blocks[i].Binding = (b->has_binding) ? b->binding : 0;
+            blocks[i].UniformBufferSize = 0;
+            blocks[i]._Packing =
+               gl_uniform_block_packing(block_type->interface_packing);
+
+            parcel.process(block_type,
+                           b->has_instance_name ? block_type->name : "");
+
+            blocks[i].UniformBufferSize = parcel.buffer_size;
+
+            /* Check SSBO size is lower than maximum supported size for SSBO
+             */
+            if (b->is_shader_storage &&
+                parcel.buffer_size > ctx->Const.MaxShaderStorageBlockSize) {
+               linker_error(prog, "shader storage block `%s' has size %d, "
+                            "which is larger than than the maximum allowed (%d)",
+                            block_type->name, parcel.buffer_size,
+                            ctx->Const.MaxShaderStorageBlockSize);
+            }
+            blocks[i].NumUniforms = (unsigned)(ptrdiff_t)
+               (&variables[parcel.index] - blocks[i].Uniforms);
+            i++;
+         }
+      }
+   }
+
+   *out_blks = blocks;
+
+   assert(parcel.index == num_variables);
+}
+
+void
 link_uniform_blocks(void *mem_ctx,
                     struct gl_context *ctx,
                     struct gl_shader_program *prog,
                     struct gl_shader **shader_list,
                     unsigned num_shaders,
-                    struct gl_uniform_block **blocks_ret)
+                    struct gl_uniform_block **ubo_blocks,
+                    unsigned *num_ubo_blocks,
+                    struct gl_uniform_block **ssbo_blocks,
+                    unsigned *num_ssbo_blocks)
 {
    /* This hash table will track all of the uniform blocks that have been
     * encountered.  Since blocks with the same block-name must be the same,
@@ -310,7 +402,7 @@ link_uniform_blocks(void *mem_ctx,
    if (block_hash == NULL) {
       _mesa_error_no_memory(__func__);
       linker_error(prog, "out of memory\n");
-      return 0;
+      return;
    }
 
    /* Determine which uniform blocks are active.
@@ -323,8 +415,8 @@ link_uniform_blocks(void *mem_ctx,
    /* Count the number of active uniform blocks.  Count the total number of
     * active slots in those uniform blocks.
     */
-   unsigned num_blocks = 0;
-   unsigned num_variables = 0;
+   unsigned num_ubo_variables = 0;
+   unsigned num_ssbo_variables = 0;
    count_block_size block_size;
    struct hash_entry *entry;
 
@@ -346,97 +438,31 @@ link_uniform_blocks(void *mem_ctx,
 
       if (b->array != NULL) {
          unsigned aoa_size = b->type->arrays_of_arrays_size();
-         num_blocks += aoa_size;
-         num_variables += aoa_size * block_size.num_active_uniforms;
-      } else {
-         num_blocks++;
-         num_variables += block_size.num_active_uniforms;
-      }
-
-   }
-
-   if (num_blocks == 0) {
-      assert(num_variables == 0);
-      _mesa_hash_table_destroy(block_hash, NULL);
-      return 0;
-   }
-
-   assert(num_variables != 0);
-
-   /* Allocate storage to hold all of the informatation related to uniform
-    * blocks that can be queried through the API.
-    */
-   gl_uniform_block *blocks =
-      ralloc_array(mem_ctx, gl_uniform_block, num_blocks);
-   gl_uniform_buffer_variable *variables =
-      ralloc_array(blocks, gl_uniform_buffer_variable, num_variables);
-
-   /* Add each variable from each uniform block to the API tracking
-    * structures.
-    */
-   unsigned i = 0;
-   ubo_visitor parcel(blocks, variables, num_variables);
-
-   STATIC_ASSERT(unsigned(GLSL_INTERFACE_PACKING_STD140)
-                 == unsigned(ubo_packing_std140));
-   STATIC_ASSERT(unsigned(GLSL_INTERFACE_PACKING_SHARED)
-                 == unsigned(ubo_packing_shared));
-   STATIC_ASSERT(unsigned(GLSL_INTERFACE_PACKING_PACKED)
-                 == unsigned(ubo_packing_packed));
-   STATIC_ASSERT(unsigned(GLSL_INTERFACE_PACKING_STD430)
-                 == unsigned(ubo_packing_std430));
-
-   hash_table_foreach (block_hash, entry) {
-      const struct link_uniform_block_active *const b =
-         (const struct link_uniform_block_active *) entry->data;
-      const glsl_type *block_type = b->type;
-
-      if (b->array != NULL) {
-         unsigned binding_offset = 0;
-         char *name = ralloc_strdup(NULL, block_type->without_array()->name);
-         size_t name_length = strlen(name);
-
-         assert(b->has_instance_name);
-         process_block_array(b->array, &name, name_length, blocks, &parcel,
-                             variables, b, &i, &binding_offset, ctx, prog);
-         ralloc_free(name);
+         if (b->is_shader_storage) {
+            *num_ssbo_blocks += aoa_size;
+            num_ssbo_variables += aoa_size * block_size.num_active_uniforms;
+         } else {
+            *num_ubo_blocks += aoa_size;
+            num_ubo_variables += aoa_size * block_size.num_active_uniforms;
+         }
       } else {
-         blocks[i].Name = ralloc_strdup(blocks, block_type->name);
-         blocks[i].Uniforms = &variables[parcel.index];
-         blocks[i].Binding = (b->has_binding) ? b->binding : 0;
-         blocks[i].UniformBufferSize = 0;
-         blocks[i]._Packing =
-            gl_uniform_block_packing(block_type->interface_packing);
-
-         parcel.process(block_type,
-                        b->has_instance_name ? block_type->name : "");
-
-         blocks[i].UniformBufferSize = parcel.buffer_size;
-
-         /* Check SSBO size is lower than maximum supported size for SSBO */
-         if (b->is_shader_storage &&
-             parcel.buffer_size > ctx->Const.MaxShaderStorageBlockSize) {
-            linker_error(prog, "shader storage block `%s' has size %d, "
-                         "which is larger than than the maximum allowed (%d)",
-                         block_type->name,
-                         parcel.buffer_size,
-                         ctx->Const.MaxShaderStorageBlockSize);
+         if (b->is_shader_storage) {
+            (*num_ssbo_blocks)++;
+            num_ssbo_variables += block_size.num_active_uniforms;
+         } else {
+            (*num_ubo_blocks)++;
+            num_ubo_variables += block_size.num_active_uniforms;
          }
-         blocks[i].NumUniforms =
-            (unsigned)(ptrdiff_t)(&variables[parcel.index] - blocks[i].Uniforms);
-
-         blocks[i].IsShaderStorage = b->is_shader_storage;
-
-         i++;
       }
+
    }
 
-   assert(parcel.index == num_variables);
+   create_buffer_blocks(mem_ctx, ctx, prog, ubo_blocks, *num_ubo_blocks,
+                        block_hash, num_ubo_variables, true);
+   create_buffer_blocks(mem_ctx, ctx, prog, ssbo_blocks, *num_ssbo_blocks,
+                        block_hash, num_ssbo_variables, false);
 
    _mesa_hash_table_destroy(block_hash, NULL);
-
-   *blocks_ret = blocks;
-   return num_blocks;
 }
 
 bool
diff --git a/src/compiler/glsl/link_uniform_initializers.cpp b/src/compiler/glsl/link_uniform_initializers.cpp
index 15f9a2f..c6346d5 100644
--- a/src/compiler/glsl/link_uniform_initializers.cpp
+++ b/src/compiler/glsl/link_uniform_initializers.cpp
@@ -159,12 +159,12 @@ set_block_binding(gl_shader_program *prog, const char *block_name,
 {
    unsigned num_blocks = mode == ir_var_uniform ? prog->NumUniformBlocks :
       prog->NumShaderStorageBlocks;
-   struct gl_uniform_block **blks = mode == ir_var_uniform ?
+   struct gl_uniform_block *blks = mode == ir_var_uniform ?
       prog->UniformBlocks : prog->ShaderStorageBlocks;
 
    for (unsigned i = 0; i < num_blocks; i++) {
       if (!strcmp(blks[i].Name, block_name)) {
-         blks[i]->Binding = binding;
+         blks[i].Binding = binding;
          return;
       }
    }
diff --git a/src/compiler/glsl/link_uniforms.cpp b/src/compiler/glsl/link_uniforms.cpp
index 8e30c7b..8db60a3 100644
--- a/src/compiler/glsl/link_uniforms.cpp
+++ b/src/compiler/glsl/link_uniforms.cpp
@@ -462,7 +462,7 @@ public:
 
       buffer_block_index = -1;
       if (var->is_in_buffer_block()) {
-         struct gl_uniform_block **blks = var->is_in_shader_storage_block() ?
+         struct gl_uniform_block *blks = var->is_in_shader_storage_block() ?
             prog->ShaderStorageBlocks : prog->UniformBlocks;
          unsigned num_blks = var->is_in_shader_storage_block() ?
             prog->NumShaderStorageBlocks : prog->NumUniformBlocks;
@@ -471,15 +471,15 @@ public:
             unsigned l = strlen(var->get_interface_type()->name);
 
             for (unsigned i = 0; i < num_blks; i++) {
-               if (strncmp(var->get_interface_type()->name, blks[i]->Name, l)
-                   == 0 && blks[i]->Name[l] == '[') {
+               if (strncmp(var->get_interface_type()->name, blks[i].Name, l)
+                   == 0 && blks[i].Name[l] == '[') {
                   buffer_block_index = i;
                   break;
                }
             }
          } else {
             for (unsigned i = 0; i < num_blks; i++) {
-               if (strcmp(var->get_interface_type()->name, blks[i]->Name) ==
+               if (strcmp(var->get_interface_type()->name, blks[i].Name) ==
                    0) {
                   buffer_block_index = i;
                   break;
@@ -500,7 +500,7 @@ public:
                     var->get_interface_type()->name);
          } else {
             const struct gl_uniform_block *const block =
-               blks[buffer_block_index];
+               &blks[buffer_block_index];
 
             assert(var->data.location != -1);
 
diff --git a/src/compiler/glsl/linker.cpp b/src/compiler/glsl/linker.cpp
index 2f152d6..c071a1c 100644
--- a/src/compiler/glsl/linker.cpp
+++ b/src/compiler/glsl/linker.cpp
@@ -1165,39 +1165,58 @@ cross_validate_uniforms(struct gl_shader_program *prog)
 }
 
 /**
- * Accumulates the array of prog->BufferInterfaceBlocks and checks that all
- * definitons of blocks agree on their contents.
+ * Accumulates the array of buffer blocks and checks that all definitons of
+ * blocks agree on their contents.
  */
 static bool
-interstage_cross_validate_uniform_blocks(struct gl_shader_program *prog)
+interstage_cross_validate_uniform_blocks(struct gl_shader_program *prog,
+                                         bool validate_ssbo)
 {
    int *InterfaceBlockStageIndex[MESA_SHADER_STAGES];
+   struct gl_uniform_block *blks = NULL;
+   unsigned *num_blks = validate_ssbo ? &prog->NumShaderStorageBlocks :
+      &prog->NumUniformBlocks;
 
-   unsigned max_num_uniform_blocks = 0;
+   unsigned max_num_buffer_blocks = 0;
    for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
-      if (prog->_LinkedShaders[i])
-	 max_num_uniform_blocks += prog->_LinkedShaders[i]->NumBufferInterfaceBlocks;
+      if (prog->_LinkedShaders[i]) {
+         if (validate_ssbo) {
+            max_num_buffer_blocks +=
+               prog->_LinkedShaders[i]->NumShaderStorageBlocks;
+         } else {
+            max_num_buffer_blocks +=
+               prog->_LinkedShaders[i]->NumUniformBlocks;
+         }
+      }
    }
 
    for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
       struct gl_shader *sh = prog->_LinkedShaders[i];
 
-      InterfaceBlockStageIndex[i] = new int[max_num_uniform_blocks];
-      for (unsigned int j = 0; j < max_num_uniform_blocks; j++)
+      InterfaceBlockStageIndex[i] = new int[max_num_buffer_blocks];
+      for (unsigned int j = 0; j < max_num_buffer_blocks; j++)
          InterfaceBlockStageIndex[i][j] = -1;
 
       if (sh == NULL)
 	 continue;
 
-      for (unsigned int j = 0; j < sh->NumBufferInterfaceBlocks; j++) {
-	 int index = link_cross_validate_uniform_block(prog,
-						       &prog->BufferInterfaceBlocks,
-						       &prog->NumBufferInterfaceBlocks,
-						       sh->BufferInterfaceBlocks[j]);
+      unsigned sh_num_blocks;
+      struct gl_uniform_block **sh_blks;
+      if (validate_ssbo) {
+         sh_num_blocks = prog->_LinkedShaders[i]->NumShaderStorageBlocks;
+         sh_blks = sh->ShaderStorageBlocks;
+      } else {
+         sh_num_blocks = prog->_LinkedShaders[i]->NumUniformBlocks;
+         sh_blks = sh->UniformBlocks;
+      }
+
+      for (unsigned int j = 0; j < sh_num_blocks; j++) {
+         int index = link_cross_validate_uniform_block(prog, &blks, num_blks,
+                                                       sh_blks[j]);
 
          if (index == -1) {
-            linker_error(prog, "uniform block `%s' has mismatching definitions\n",
-                         sh->BufferInterfaceBlocks[j]->Name);
+            linker_error(prog, "buffer block `%s' has mismatching "
+                         "definitions\n", sh_blks[j]->Name);
 
             for (unsigned k = 0; k <= i; k++) {
                delete[] InterfaceBlockStageIndex[k];
@@ -1213,16 +1232,18 @@ interstage_cross_validate_uniform_blocks(struct gl_shader_program *prog)
     * FIXME: We should be able to free the per stage blocks here.
     */
    for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
-      for (unsigned j = 0; j < prog->NumBufferInterfaceBlocks; j++) {
+      for (unsigned j = 0; j < *num_blks; j++) {
          int stage_index = InterfaceBlockStageIndex[i][j];
 
 	 if (stage_index != -1) {
 	    struct gl_shader *sh = prog->_LinkedShaders[i];
 
-            prog->BufferInterfaceBlocks[j].stageref |= (1 << i);
+            blks[j].stageref |= (1 << i);
+
+            struct gl_uniform_block **sh_blks = validate_ssbo ?
+               sh->ShaderStorageBlocks : sh->UniformBlocks;
 
-            sh->BufferInterfaceBlocks[stage_index] =
-               &prog->BufferInterfaceBlocks[j];
+            sh_blks[stage_index] = &blks[j];
 	 }
       }
    }
@@ -1231,6 +1252,11 @@ interstage_cross_validate_uniform_blocks(struct gl_shader_program *prog)
       delete[] InterfaceBlockStageIndex[i];
    }
 
+   if (validate_ssbo)
+      prog->ShaderStorageBlocks = blks;
+   else
+      prog->UniformBlocks = blks;
+
    return true;
 }
 
@@ -2074,7 +2100,10 @@ link_intrastage_shaders(void *mem_ctx,
 			struct gl_shader **shader_list,
 			unsigned num_shaders)
 {
-   struct gl_uniform_block *uniform_blocks = NULL;
+   struct gl_uniform_block *ubo_blocks = NULL;
+   struct gl_uniform_block *ssbo_blocks = NULL;
+   unsigned num_ubo_blocks = 0;
+   unsigned num_ssbo_blocks = 0;
 
    /* Check that global variables defined in multiple shaders are consistent.
     */
@@ -2090,9 +2119,10 @@ link_intrastage_shaders(void *mem_ctx,
       return NULL;
 
    /* Link up uniform blocks defined within this stage. */
-   const unsigned num_uniform_blocks =
-      link_uniform_blocks(mem_ctx, ctx, prog, shader_list, num_shaders,
-                          &uniform_blocks);
+   link_uniform_blocks(mem_ctx, ctx, prog, shader_list, num_shaders,
+                       &ubo_blocks, &num_ubo_blocks, &ssbo_blocks,
+                       &num_ssbo_blocks);
+
    if (!prog->LinkStatus)
       return NULL;
 
@@ -2159,15 +2189,23 @@ link_intrastage_shaders(void *mem_ctx,
    linked->ir = new(linked) exec_list;
    clone_ir_list(mem_ctx, linked->ir, main->ir);
 
-   linked->BufferInterfaceBlocks =
-      ralloc_array(linked, gl_uniform_block *, num_uniform_blocks);
-
-   ralloc_steal(linked, uniform_blocks);
-   for (unsigned i = 0; i < num_uniform_blocks; i++) {
-      linked->BufferInterfaceBlocks[i] = &uniform_blocks[i];
+   /* Copy ubo blocks to linked shader list */
+   linked->UniformBlocks =
+      ralloc_array(linked, gl_uniform_block *, num_ubo_blocks);
+   ralloc_steal(linked, ubo_blocks);
+   for (unsigned i = 0; i < num_ubo_blocks; i++) {
+      linked->UniformBlocks[i] = &ubo_blocks[i];
    }
+   linked->NumUniformBlocks = num_ubo_blocks;
 
-   linked->NumBufferInterfaceBlocks = num_uniform_blocks;
+   /* Copy ssbo blocks to linked shader list */
+   linked->ShaderStorageBlocks =
+      ralloc_array(linked, gl_uniform_block *, num_ssbo_blocks);
+   ralloc_steal(linked, ssbo_blocks);
+   for (unsigned i = 0; i < num_ssbo_blocks; i++) {
+      linked->ShaderStorageBlocks[i] = &ssbo_blocks[i];
+   }
+   linked->NumShaderStorageBlocks = num_ssbo_blocks;
 
    link_fs_input_layout_qualifiers(prog, linked, shader_list, num_shaders);
    link_tcs_out_layout_qualifiers(prog, linked, shader_list, num_shaders);
@@ -2974,7 +3012,7 @@ check_resources(struct gl_context *ctx, struct gl_shader_program *prog)
    }
 
    for (unsigned i = 0; i < prog->NumUniformBlocks; i++) {
-      if (prog->UniformBlocks[i]->UniformBufferSize >
+      if (prog->UniformBlocks[i].UniformBufferSize >
           ctx->Const.MaxUniformBlockSize) {
          linker_error(prog, "Uniform block %s too big (%d/%d)\n",
                       prog->UniformBlocks[i].Name,
@@ -3806,8 +3844,8 @@ calculate_array_size_and_stride(struct gl_shader_program *shProg,
    char *var_name = get_top_level_name(uni->name);
    char *interface_name =
       get_top_level_name(uni->is_shader_storage ?
-                         shProg->ShaderStorageBlocks[block_index]->Name :
-                         shProg->UniformBlocks[block_index]->Name);
+                         shProg->ShaderStorageBlocks[block_index].Name :
+                         shProg->UniformBlocks[block_index].Name);
 
    if (strcmp(var_name, interface_name) == 0) {
       /* Deal with instanced array of SSBOs */
@@ -3948,8 +3986,8 @@ build_program_resource_list(struct gl_context *ctx,
       int block_index = shProg->UniformStorage[i].block_index;
       if (block_index != -1) {
          stageref |= is_shader_storage ?
-            shProg->ShaderStorageBlocks[block_index]->stageref :
-            shProg->UniformBlocks[block_index]->stageref;
+            shProg->ShaderStorageBlocks[block_index].stageref :
+            shProg->UniformBlocks[block_index].stageref;
       }
 
       GLenum type = is_shader_storage ? GL_BUFFER_VARIABLE : GL_UNIFORM;
@@ -3969,14 +4007,14 @@ build_program_resource_list(struct gl_context *ctx,
    /* Add program uniform blocks. */
    for (unsigned i = 0; i < shProg->NumUniformBlocks; i++) {
       if (!add_program_resource(shProg, GL_UNIFORM_BLOCK,
-          shProg->UniformBlocks[i], 0))
+          &shProg->UniformBlocks[i], 0))
          return;
    }
 
    /* Add program shader storage blocks. */
    for (unsigned i = 0; i < shProg->NumShaderStorageBlocks; i++) {
       if (!add_program_resource(shProg, GL_SHADER_STORAGE_BLOCK,
-          shProg->ShaderStorageBlocks[i], 0))
+          &shProg->ShaderStorageBlocks[i], 0))
          return;
    }
 
@@ -4461,7 +4499,12 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
    if (prog->SeparateShader)
       disable_varying_optimizations_for_sso(prog);
 
-   if (!interstage_cross_validate_uniform_blocks(prog))
+   /* Process UBOs */
+   if (!interstage_cross_validate_uniform_blocks(prog, false))
+      goto done;
+
+   /* Process SSBOs */
+   if (!interstage_cross_validate_uniform_blocks(prog, true))
       goto done;
 
    /* Do common optimization before assigning storage for attributes,
diff --git a/src/compiler/glsl/linker.h b/src/compiler/glsl/linker.h
index 97144df..3a0ec8b 100644
--- a/src/compiler/glsl/linker.h
+++ b/src/compiler/glsl/linker.h
@@ -53,13 +53,16 @@ extern bool
 link_uniform_blocks_are_compatible(const gl_uniform_block *a,
 				   const gl_uniform_block *b);
 
-extern unsigned
+extern void
 link_uniform_blocks(void *mem_ctx,
                     struct gl_context *ctx,
                     struct gl_shader_program *prog,
                     struct gl_shader **shader_list,
                     unsigned num_shaders,
-                    struct gl_uniform_block **blocks_ret);
+                    struct gl_uniform_block **ubo_blocks,
+                    unsigned *num_ubo_blocks,
+                    struct gl_uniform_block **ssbo_blocks,
+                    unsigned *num_ssbo_blocks);
 
 bool
 validate_intrastage_arrays(struct gl_shader_program *prog,
diff --git a/src/compiler/glsl/standalone_scaffolding.cpp b/src/compiler/glsl/standalone_scaffolding.cpp
index 49b4a26..09d7d6e 100644
--- a/src/compiler/glsl/standalone_scaffolding.cpp
+++ b/src/compiler/glsl/standalone_scaffolding.cpp
@@ -105,10 +105,6 @@ _mesa_clear_shader_program_data(struct gl_shader_program *shProg)
    ralloc_free(shProg->InfoLog);
    shProg->InfoLog = ralloc_strdup(shProg, "");
 
-   ralloc_free(shProg->BufferInterfaceBlocks);
-   shProg->BufferInterfaceBlocks = NULL;
-   shProg->NumBufferInterfaceBlocks = 0;
-
    ralloc_free(shProg->UniformBlocks);
    shProg->UniformBlocks = NULL;
    shProg->NumUniformBlocks = 0;
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index e579794..7495f05 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -2295,30 +2295,6 @@ struct gl_shader
     */
    unsigned num_combined_uniform_components;
 
-   /**
-    * 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;
 
@@ -2804,33 +2780,11 @@ 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;
+   struct gl_uniform_block *UniformBlocks;
 
    unsigned NumShaderStorageBlocks;
-   struct gl_uniform_block **ShaderStorageBlocks;
+   struct gl_uniform_block *ShaderStorageBlocks;
 
    /**
     * Map of active uniform names to locations
diff --git a/src/mesa/main/shader_query.cpp b/src/mesa/main/shader_query.cpp
index 1f36dae..2c1a6ee 100644
--- a/src/mesa/main/shader_query.cpp
+++ b/src/mesa/main/shader_query.cpp
@@ -926,10 +926,10 @@ is_resource_referenced(struct gl_shader_program *shProg,
       return RESOURCE_ATC(res)->StageReferences[stage];
 
    if (res->Type == GL_UNIFORM_BLOCK)
-      return shProg->UniformBlocks[index]->stageref & (1 << stage);
+      return shProg->UniformBlocks[index].stageref & (1 << stage);
 
    if (res->Type == GL_SHADER_STORAGE_BLOCK)
-      return shProg->ShaderStorageBlocks[index]->stageref & (1 << stage);
+      return shProg->ShaderStorageBlocks[index].stageref & (1 << stage);
 
    return res->StageReferences & (1 << stage);
 }
diff --git a/src/mesa/main/shaderapi.c b/src/mesa/main/shaderapi.c
index ba26072..b28b5ce 100644
--- a/src/mesa/main/shaderapi.c
+++ b/src/mesa/main/shaderapi.c
@@ -727,7 +727,7 @@ get_programiv(struct gl_context *ctx, GLuint program, GLenum pname,
       for (i = 0; i < shProg->NumUniformBlocks; i++) {
 	 /* Add one for the terminating NUL character.
 	  */
-	 const GLint len = strlen(shProg->UniformBlocks[i]->Name) + 1;
+	 const GLint len = strlen(shProg->UniformBlocks[i].Name) + 1;
 
 	 if (len > max_len)
 	    max_len = len;
diff --git a/src/mesa/main/shaderobj.c b/src/mesa/main/shaderobj.c
index 8b9166c..274cb12 100644
--- a/src/mesa/main/shaderobj.c
+++ b/src/mesa/main/shaderobj.c
@@ -292,9 +292,13 @@ _mesa_clear_shader_program_data(struct gl_shader_program *shProg)
    ralloc_free(shProg->InfoLog);
    shProg->InfoLog = ralloc_strdup(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;
 
    ralloc_free(shProg->AtomicBuffers);
    shProg->AtomicBuffers = NULL;
diff --git a/src/mesa/main/uniforms.c b/src/mesa/main/uniforms.c
index 7dcbdcc..a9308d0 100644
--- a/src/mesa/main/uniforms.c
+++ b/src/mesa/main/uniforms.c
@@ -1016,13 +1016,13 @@ _mesa_UniformBlockBinding(GLuint program,
       return;
    }
 
-   if (shProg->UniformBlocks[uniformBlockIndex]->Binding !=
+   if (shProg->UniformBlocks[uniformBlockIndex].Binding !=
        uniformBlockBinding) {
 
       FLUSH_VERTICES(ctx, 0);
       ctx->NewDriverState |= ctx->DriverFlags.NewUniformBuffer;
 
-      shProg->UniformBlocks[uniformBlockIndex]->Binding = uniformBlockBinding;
+      shProg->UniformBlocks[uniformBlockIndex].Binding = uniformBlockBinding;
    }
 }
 
@@ -1059,13 +1059,13 @@ _mesa_ShaderStorageBlockBinding(GLuint program,
       return;
    }
 
-   if (shProg->ShaderStorageBlocks[shaderStorageBlockIndex]->Binding !=
+   if (shProg->ShaderStorageBlocks[shaderStorageBlockIndex].Binding !=
        shaderStorageBlockBinding) {
 
       FLUSH_VERTICES(ctx, 0);
       ctx->NewDriverState |= ctx->DriverFlags.NewShaderStorageBuffer;
 
-      shProg->ShaderStorageBlocks[shaderStorageBlockIndex]->Binding =
+      shProg->ShaderStorageBlocks[shaderStorageBlockIndex].Binding =
          shaderStorageBlockBinding;
    }
 }
-- 
2.5.5



More information about the mesa-dev mailing list