Mesa (master): glsl: store stage reference in gl_uniform_block

Timothy Arceri tarceri at kemper.freedesktop.org
Sat Apr 2 06:12:05 UTC 2016


Module: Mesa
Branch: master
Commit: 1265e1c4e17dec5c9931fda8b6d44a4006ed1a4c
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=1265e1c4e17dec5c9931fda8b6d44a4006ed1a4c

Author: Timothy Arceri <timothy.arceri at collabora.com>
Date:   Sat Apr  2 12:51:12 2016 +1100

glsl: store stage reference in gl_uniform_block

This allows us to simplify the code and drop InterfaceBlockStageIndex
which is a per stage array of integers the size of all blocks in the
program combined including duplicates across stages. Adding a stage
ref per block will use less memory.

Reviewed-by: Kenneth Graunke <kenneth at whitecape.org>

---

 src/compiler/glsl/linker.cpp                 | 37 +++++++++++++++++-----------
 src/compiler/glsl/standalone_scaffolding.cpp |  7 ------
 src/mesa/main/mtypes.h                       | 13 +++-------
 src/mesa/main/shader_query.cpp               |  2 +-
 src/mesa/main/shaderobj.c                    |  4 ---
 5 files changed, 26 insertions(+), 37 deletions(-)

diff --git a/src/compiler/glsl/linker.cpp b/src/compiler/glsl/linker.cpp
index f440dbc..f750f5b 100644
--- a/src/compiler/glsl/linker.cpp
+++ b/src/compiler/glsl/linker.cpp
@@ -1171,6 +1171,8 @@ cross_validate_uniforms(struct gl_shader_program *prog)
 static bool
 interstage_cross_validate_uniform_blocks(struct gl_shader_program *prog)
 {
+   int *InterfaceBlockStageIndex[MESA_SHADER_STAGES];
+
    unsigned max_num_uniform_blocks = 0;
    for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
       if (prog->_LinkedShaders[i])
@@ -1180,10 +1182,9 @@ interstage_cross_validate_uniform_blocks(struct gl_shader_program *prog)
    for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
       struct gl_shader *sh = prog->_LinkedShaders[i];
 
-      prog->InterfaceBlockStageIndex[i] = ralloc_array(prog, int,
-                                                       max_num_uniform_blocks);
+      InterfaceBlockStageIndex[i] = new int[max_num_uniform_blocks];
       for (unsigned int j = 0; j < max_num_uniform_blocks; j++)
-	 prog->InterfaceBlockStageIndex[i][j] = -1;
+         InterfaceBlockStageIndex[i][j] = -1;
 
       if (sh == NULL)
 	 continue;
@@ -1194,13 +1195,17 @@ interstage_cross_validate_uniform_blocks(struct gl_shader_program *prog)
 						       &prog->NumBufferInterfaceBlocks,
 						       sh->BufferInterfaceBlocks[j]);
 
-	 if (index == -1) {
-	    linker_error(prog, "uniform block `%s' has mismatching definitions\n",
-			 sh->BufferInterfaceBlocks[j]->Name);
-	    return false;
-	 }
+         if (index == -1) {
+            linker_error(prog, "uniform block `%s' has mismatching definitions\n",
+                         sh->BufferInterfaceBlocks[j]->Name);
+
+            for (unsigned k = 0; k <= i; k++) {
+               delete[] InterfaceBlockStageIndex[k];
+            }
+            return false;
+         }
 
-	 prog->InterfaceBlockStageIndex[i][index] = j;
+         InterfaceBlockStageIndex[i][index] = j;
       }
    }
 
@@ -1209,18 +1214,23 @@ interstage_cross_validate_uniform_blocks(struct gl_shader_program *prog)
     */
    for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
       for (unsigned j = 0; j < prog->NumBufferInterfaceBlocks; j++) {
-	 int stage_index =
-            prog->InterfaceBlockStageIndex[i][j];
+         int stage_index = InterfaceBlockStageIndex[i][j];
 
 	 if (stage_index != -1) {
 	    struct gl_shader *sh = prog->_LinkedShaders[i];
 
+            prog->BufferInterfaceBlocks[j].stageref |= (1 << i);
+
             sh->BufferInterfaceBlocks[stage_index] =
                &prog->BufferInterfaceBlocks[j];
 	 }
       }
    }
 
+   for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
+      delete[] InterfaceBlockStageIndex[i];
+   }
+
    return true;
 }
 
@@ -3933,10 +3943,7 @@ build_program_resource_list(struct gl_context *ctx,
       /* Add stagereferences for uniforms in a uniform block. */
       int block_index = shProg->UniformStorage[i].block_index;
       if (block_index != -1) {
-         for (unsigned j = 0; j < MESA_SHADER_STAGES; j++) {
-             if (shProg->InterfaceBlockStageIndex[j][block_index] != -1)
-                stageref |= (1 << j);
-         }
+         stageref |= shProg->BufferInterfaceBlocks[block_index].stageref;
       }
 
       bool is_shader_storage =  shProg->UniformStorage[i].is_shader_storage;
diff --git a/src/compiler/glsl/standalone_scaffolding.cpp b/src/compiler/glsl/standalone_scaffolding.cpp
index e350f70..49b4a26 100644
--- a/src/compiler/glsl/standalone_scaffolding.cpp
+++ b/src/compiler/glsl/standalone_scaffolding.cpp
@@ -96,8 +96,6 @@ _mesa_delete_shader(struct gl_context *ctx, struct gl_shader *sh)
 void
 _mesa_clear_shader_program_data(struct gl_shader_program *shProg)
 {
-   unsigned i;
-
    shProg->NumUniformStorage = 0;
    shProg->UniformStorage = NULL;
    shProg->NumUniformRemapTable = 0;
@@ -119,11 +117,6 @@ _mesa_clear_shader_program_data(struct gl_shader_program *shProg)
    shProg->ShaderStorageBlocks = NULL;
    shProg->NumShaderStorageBlocks = 0;
 
-   for (i = 0; i < MESA_SHADER_STAGES; i++) {
-      ralloc_free(shProg->InterfaceBlockStageIndex[i]);
-      shProg->InterfaceBlockStageIndex[i] = NULL;
-   }
-
    ralloc_free(shProg->AtomicBuffers);
    shProg->AtomicBuffers = NULL;
    shProg->NumAtomicBuffers = 0;
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index f2cb4cb..e579794 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -2529,6 +2529,9 @@ struct gl_uniform_block
     */
    bool IsShaderStorage;
 
+   /** Stages that reference this block */
+   uint8_t stageref;
+
    /**
     * Layout specified in the shader
     *
@@ -2830,16 +2833,6 @@ struct gl_shader_program
    struct gl_uniform_block **ShaderStorageBlocks;
 
    /**
-    * Indices into the BufferInterfaceBlocks[] array for each stage they're
-    * used in, or -1.
-    *
-    * This is used to maintain the Binding values of the stage's
-    * BufferInterfaceBlocks[] and to answer the
-    * GL_UNIFORM_BLOCK_REFERENCED_BY_*_SHADER queries.
-    */
-   int *InterfaceBlockStageIndex[MESA_SHADER_STAGES];
-
-   /**
     * Map of active uniform names to locations
     *
     * Maps any active uniform that is not an array element to a location.
diff --git a/src/mesa/main/shader_query.cpp b/src/mesa/main/shader_query.cpp
index 4650a5c..4ef6a81 100644
--- a/src/mesa/main/shader_query.cpp
+++ b/src/mesa/main/shader_query.cpp
@@ -926,7 +926,7 @@ is_resource_referenced(struct gl_shader_program *shProg,
       return RESOURCE_ATC(res)->StageReferences[stage];
 
    if (res->Type == GL_UNIFORM_BLOCK || res->Type == GL_SHADER_STORAGE_BLOCK)
-      return shProg->InterfaceBlockStageIndex[stage][index] != -1;
+      return shProg->BufferInterfaceBlocks[index].stageref & (1 << stage);
 
    return res->StageReferences & (1 << stage);
 }
diff --git a/src/mesa/main/shaderobj.c b/src/mesa/main/shaderobj.c
index 9a4eb6b..8b9166c 100644
--- a/src/mesa/main/shaderobj.c
+++ b/src/mesa/main/shaderobj.c
@@ -295,10 +295,6 @@ _mesa_clear_shader_program_data(struct gl_shader_program *shProg)
    ralloc_free(shProg->BufferInterfaceBlocks);
    shProg->BufferInterfaceBlocks = NULL;
    shProg->NumBufferInterfaceBlocks = 0;
-   for (i = 0; i < MESA_SHADER_STAGES; i++) {
-      ralloc_free(shProg->InterfaceBlockStageIndex[i]);
-      shProg->InterfaceBlockStageIndex[i] = NULL;
-   }
 
    ralloc_free(shProg->AtomicBuffers);
    shProg->AtomicBuffers = NULL;




More information about the mesa-commit mailing list