[Mesa-dev] [PATCH 4/9] mesa: Uniform Buffer Objects data structures

Vincent Lejeune vljn at ovi.com
Thu Dec 1 07:35:33 PST 2011


   v2:Big cleanup of data structures used
   v3:Data structures moved to mtypes.h
---
 src/mesa/main/config.h            |    4 ++
 src/mesa/main/mtypes.h            |  109 +++++++++++++++++++++++++++++++++++++
 src/mesa/main/shaderobj.c         |   25 ++++++++-
 src/mesa/program/prog_parameter.h |    1 +
 4 files changed, 138 insertions(+), 1 deletions(-)

diff --git a/src/mesa/main/config.h b/src/mesa/main/config.h
index 7b7740e..1c4c810 100644
--- a/src/mesa/main/config.h
+++ b/src/mesa/main/config.h
@@ -357,5 +357,9 @@
  */
 #define MAX_CLIPPED_VERTICES ((2 * (6 + MAX_CLIP_PLANES))+1)
 
+/**
+ * UBO Variables
+ */
+#define MAX_UBO_COUNT 8
 
 #endif /* MESA_CONFIG_H_INCLUDED */
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index 08cd80a..654ae98 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -1653,6 +1653,14 @@ struct gl_array_attrib
    struct gl_buffer_object *ArrayBufferObj;
 };
 
+/**
+ * UBO state
+ */
+struct gl_ubo_attribs
+{
+    struct gl_buffer_object *UniformObj;
+    struct gl_buffer_object *BindingPoint[MAX_UBO_COUNT];
+};
 
 /**
  * Feedback buffer state
@@ -2127,6 +2135,82 @@ struct gl_sl_pragmas
    GLboolean Debug;     /**< defaults off */
 };
 
+/**
+ * Uniform Buffer Object variable informations.
+ * This come in 2 flavors :
+ * As layout informations (Size,Offset,...) are defined per program and not per shader,
+ * shaders_ubo_variable only store the relevant information to preserve memory.
+ * program_ubo_variable stores everything that can be retrieved by GetActiveUniformsiv
+ * (which makes it bigger than the data it refers to...).
+ */
+
+struct gl_shader_ubo_variable
+{
+   char* Name;
+   const struct glsl_type* Type;
+};
+
+struct gl_program_ubo_variable
+{
+   char* Name;
+   GLenum Type; /** TYPE_ARRAY,TYPE_RECORD,TYPE_FLOAT,TYPE_VEC */
+   GLuint Size; /** In bytes */
+   GLuint Offset; /** In bytes, from start of UBO */
+   GLuint Stride; /** In TYPE_ARRAY case, stride between 2 consecutive elements, undef otherwise */
+   GLuint IndexInUBO; /** Position inside UBO declaration */
+   GLuint ContainedVariablesCount; /** For TYPE_ARRAY and TYPE_RECORD, number of element in ContainedVariables */
+   struct gl_program_ubo_variable* ContainedVariables; /** For TYPE_ARRAY and TYPE_RECORD, array holding child data */
+   struct gl_uniform_buffer_object* UBO; /** Pointer to containing UBO structure inside program */
+};
+
+
+/**
+ * glsl_base_type doesn't have a VEC type,
+ * we have to define our own enum here
+ * FIXME:investigate if glsl_base_type can accept another item ?
+ */
+enum {
+   TYPE_ARRAY,
+   TYPE_RECORD,
+   TYPE_SCALAR,
+   TYPE_VEC,
+};
+
+enum UBOLayout {
+   UBO_LAYOUT_PACKED,
+   UBO_LAYOUT_SHARED,
+   UBO_LAYOUT_SDT140,
+};
+
+enum UBOMatrixLayout {
+   UBO_MATRIX_LAYOUT_ROW_MAJOR,
+   UBO_MATRIX_LAYOUT_COLUMN_MAJOR,
+};
+
+/**
+ * Uniform Buffer Object Information.
+ * This struct is used by shader and program struct ;
+ * For StorageLayout, Compact form is used in shader,
+ * Full form is used in program.
+ */
+
+struct gl_uniform_buffer_object
+{
+   char* Name;
+   GLuint Index;
+   union {
+      struct gl_program_ubo_variable*  Full;  /** Malloced, sefined in program */
+      struct gl_shader_ubo_variable* Compact; /** Ralloced, defined in shader */
+   } StorageLayout; /** array of variables that are part of the UBO  */
+   GLuint Layout; /** packed, shared or std140 */
+   GLuint MatrixLayout; /** rowmajor or columnmajor */
+   GLuint NumberOfVariables; /**< number of UBOVariableInfo in StorageLayout */
+   unsigned ReferencedByVS:1; /** Is it present in VS ? Set at link time */
+   unsigned ReferencedByGS:1; /** Is it present in GS ? Set at link time */
+   unsigned ReferencedByFS:1; /** Is it present in FS ? Set at link time */
+   unsigned Size; /** In bytes, with padding included */
+};
+
 
 /**
  * A GLSL vertex or fragment shader object.
@@ -2162,6 +2246,8 @@ struct gl_shader
    /** Shaders containing built-in functions that are used for linking. */
    struct gl_shader *builtins_to_link[16];
    unsigned num_builtins_to_link;
+   struct gl_uniform_buffer_object* UniformBufferObjects;
+   unsigned UBOCount;
 };
 
 
@@ -2275,6 +2361,26 @@ struct gl_shader_program
     * \c NULL.
     */
    struct gl_shader *_LinkedShaders[MESA_SHADER_TYPES];
+   /**
+    * Program Scope UBO
+    */
+   struct gl_uniform_buffer_object *UniformBufferObject;
+   unsigned UBOCount;
+
+   /** All uniforms (in UBO or not) have to be accessed by a 1D index ;
+    * For classical uniform, index equals location (matches others drivers)
+    * For variables in UBO, we use an array of gl_ubo_variable* pointing to
+    * structures already stored inside program's
+    * gl_uniform_buffer_object.StorageLayout.Full
+    */
+   GLuint IndexedVariableCount;
+   struct gl_program_ubo_variable** IndexedUBOVariables; /** 1D array of pointers */
+   /** String to GLuint hashtable, provides a quick access to (moreless) variable
+    * index from its name.
+    * To leave NULL/index 0 ambiguity, it does not really store a variable's index,
+    * but variable's index + 1 instead.
+    */
+   struct string_to_uint_map* NamedAccessUBOVariables;
 };   
 
 
@@ -3299,6 +3405,9 @@ struct gl_context
    struct gl_pixelstore_attrib	DefaultPacking;	/**< Default params */
    /*@}*/
 
+   /** \name Attributes for UBO */
+   struct gl_ubo_attribs UniformBufferObject;
+
    /** \name Other assorted state (not pushed/popped on attribute stack) */
    /*@{*/
    struct gl_pixelmaps          PixelMaps;
diff --git a/src/mesa/main/shaderobj.c b/src/mesa/main/shaderobj.c
index 454007f..caeed31 100644
--- a/src/mesa/main/shaderobj.c
+++ b/src/mesa/main/shaderobj.c
@@ -110,6 +110,7 @@ _mesa_new_shader(struct gl_context *ctx, GLuint name, GLenum type)
    if (shader) {
       shader->Type = type;
       shader->Name = name;
+      shader->UBOCount = 0;
       _mesa_init_shader(ctx, shader);
    }
    return shader;
@@ -296,6 +297,17 @@ _mesa_clear_shader_program_data(struct gl_context *ctx,
    shProg->InfoLog = ralloc_strdup(shProg, "");
 }
 
+static void
+recursive_free_ubo(struct gl_program_ubo_variable* ubovar)
+{
+   unsigned i;
+   for (i = 0; i < ubovar->ContainedVariablesCount;i++) {
+      recursive_free_ubo(&(ubovar->ContainedVariables[i]));
+   }
+   free(ubovar->Name);
+   if (ubovar->ContainedVariablesCount)
+      free(ubovar->ContainedVariables);
+}
 
 /**
  * Free all the data that hangs off a shader program object, but not the
@@ -305,7 +317,7 @@ void
 _mesa_free_shader_program_data(struct gl_context *ctx,
                                struct gl_shader_program *shProg)
 {
-   GLuint i;
+   GLuint i,j;
    gl_shader_type sh;
 
    assert(shProg->Type == GL_SHADER_PROGRAM_MESA);
@@ -348,6 +360,17 @@ _mesa_free_shader_program_data(struct gl_context *ctx,
 	 shProg->_LinkedShaders[sh] = NULL;
       }
    }
+
+   for (i = 0; i < shProg->UBOCount; i++) {
+      free(shProg->UniformBufferObject[i].Name);
+      for (j = 0; j < shProg->UniformBufferObject[i].NumberOfVariables;j++) {
+         recursive_free_ubo(&(shProg->UniformBufferObject[i].StorageLayout.Full[j]));
+      }
+   }
+
+   if (shProg->UBOCount)
+      free(shProg->UniformBufferObject);
+   shProg->UBOCount = 0;
 }
 
 
diff --git a/src/mesa/program/prog_parameter.h b/src/mesa/program/prog_parameter.h
index 3c6dc8c..9266861 100644
--- a/src/mesa/program/prog_parameter.h
+++ b/src/mesa/program/prog_parameter.h
@@ -100,6 +100,7 @@ struct gl_program_parameter_list
    gl_constant_value (*ParameterValues)[4]; /**< Array [Size] of constant[4] */
    GLbitfield StateFlags; /**< _NEW_* flags indicating which state changes
                                might invalidate ParameterValues[] */
+   GLuint NumUBO; /** Number of UBO in the program */
 };
 
 
-- 
1.7.7



More information about the mesa-dev mailing list