glsl: Propagate uniform block information into gl_uniform_storage.
authorEric Anholt <eric@anholt.net>
Tue, 1 May 2012 20:59:31 +0000 (13:59 -0700)
committerEric Anholt <eric@anholt.net>
Fri, 20 Jul 2012 17:43:47 +0000 (10:43 -0700)
Now we can actually return information on uniforms in uniform blocks
in the new queries.

Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
src/glsl/ir_uniform.h
src/glsl/link_uniforms.cpp

index 225da3fc5efaab02530b7498dd1512ea14ad27d1..913c5377359d4a831c47d54fce5ee5953eb3d449 100644 (file)
@@ -119,6 +119,40 @@ struct gl_uniform_storage {
     * uniform if the \c ::driver_storage interface is not used.
     */
    union gl_constant_value *storage;
+
+   /** Fields for GL_ARB_uniform_buffer_object
+    * @{
+    */
+
+   /**
+    * GL_UNIFORM_BLOCK_INDEX: index of the uniform block containing
+    * the uniform, or -1 for the default uniform block.  Note that the
+    * index is into the linked program's UniformBlocks[] array, not
+    * the linked shader's.
+    */
+   int block_index;
+
+   /** GL_UNIFORM_OFFSET: byte offset within the uniform block, or -1. */
+   int offset;
+
+   /**
+    * GL_UNIFORM_MATRIX_STRIDE: byte stride between columns or rows of
+    * a matrix.  Set to 0 for non-matrices in UBOs, or -1 for uniforms
+    * in the default uniform block.
+    */
+   int matrix_stride;
+
+   /**
+    * GL_UNIFORM_ARRAY_STRIDE: byte stride between elements of the
+    * array.  Set to zero for non-arrays in UBOs, or -1 for uniforms
+    * in the default uniform block.
+    */
+   int array_stride;
+
+   /** GL_UNIFORM_ROW_MAJOR: true iff it's a row-major matrix in a UBO */
+   bool row_major;
+
+   /** @} */
 };
 
 #ifdef __cplusplus
index ff75b8919e9fdb7e59d8e26a1f12e583a890f67a..4cc97cead80156becb737cd57fe57365760ae304 100644 (file)
@@ -217,6 +217,28 @@ public:
       this->shader_shadow_samplers = 0;
    }
 
+   void set_and_process(struct gl_shader_program *prog,
+                       ir_variable *var)
+   {
+      ubo_var = NULL;
+      if (var->uniform_block != -1) {
+        struct gl_uniform_block *block =
+           &prog->UniformBlocks[var->uniform_block];
+
+        ubo_block_index = var->uniform_block;
+        ubo_var_index = var->location;
+        ubo_var = &block->Uniforms[var->location];
+        ubo_byte_offset = ubo_var->Offset;
+      }
+
+      process(var);
+   }
+
+   struct gl_uniform_buffer_variable *ubo_var;
+   int ubo_block_index;
+   int ubo_var_index;
+   int ubo_byte_offset;
+
 private:
    virtual void visit_field(const glsl_type *type, const char *name)
    {
@@ -292,6 +314,23 @@ private:
       this->uniforms[id].num_driver_storage = 0;
       this->uniforms[id].driver_storage = NULL;
       this->uniforms[id].storage = this->values;
+      if (this->ubo_var) {
+        this->uniforms[id].block_index = this->ubo_block_index;
+
+        /* FINISHME: Actual std140 offset assignment. */
+        this->uniforms[id].offset = this->ubo_byte_offset;
+        this->ubo_byte_offset += 4 * type->components();
+        this->uniforms[id].array_stride = 0;
+        this->uniforms[id].matrix_stride = 0;
+        this->uniforms[id].row_major = base_type->is_matrix() &&
+           ubo_var->RowMajor;
+      } else {
+        this->uniforms[id].block_index = -1;
+        this->uniforms[id].offset = -1;
+        this->uniforms[id].array_stride = -1;
+        this->uniforms[id].matrix_stride = -1;
+        this->uniforms[id].row_major = false;
+      }
 
       this->values += values_for_type(type);
    }
@@ -518,7 +557,7 @@ link_assign_uniform_locations(struct gl_shader_program *prog)
         if (strncmp("gl_", var->name, 3) == 0)
            continue;
 
-        parcel.process(var);
+        parcel.set_and_process(prog, var);
       }
 
       prog->_LinkedShaders[i]->active_samplers = parcel.shader_samplers_used;