[Mesa-dev] [PATCH] mesa: initial data structures for Uniform Buffer Objects

Vincent Lejeune vljn at ovi.com
Tue Nov 22 13:56:37 PST 2011


   v2:Big cleanup of data structures used
---
 src/mesa/main/config.h            |    4 ++
 src/mesa/main/mtypes.h            |   18 ++++++++
 src/mesa/main/shaderobj.c         |   29 ++++++++++++-
 src/mesa/program/prog_parameter.h |    1 +
 src/mesa/program/prog_uniform.c   |    4 ++
 src/mesa/program/prog_uniform.h   |   88 +++++++++++++++++++++++++++++++++++++
 6 files changed, 143 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 17c645a..8228a71 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -1656,6 +1656,14 @@ struct gl_array_attrib
    struct gl_buffer_object *ElementArrayBufferObj;
 };
 
+/**
+ * UBO state
+ */
+struct gl_ubo_attribs
+{
+    struct gl_buffer_object *UniformObj;
+    struct gl_buffer_object *BindingPoint[MAX_UBO_COUNT];
+};
 
 /**
  * Feedback buffer state
@@ -2121,6 +2129,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;
 };
 
 
@@ -2196,6 +2206,11 @@ struct gl_shader_program
     * \c NULL.
     */
    struct gl_shader *_LinkedShaders[MESA_SHADER_TYPES];
+   /**
+    * Program Scope UBO
+    */
+   struct gl_uniform_buffer_object *UniformBufferObject;
+   unsigned UBOCount;
 };   
 
 
@@ -3236,6 +3251,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 ccf7efd..62cfa86 100644
--- a/src/mesa/main/shaderobj.c
+++ b/src/mesa/main/shaderobj.c
@@ -111,6 +111,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;
@@ -124,8 +125,16 @@ _mesa_new_shader(struct gl_context *ctx, GLuint name, GLenum type)
 static void
 _mesa_delete_shader(struct gl_context *ctx, struct gl_shader *sh)
 {
+   unsigned i,j;
    if (sh->Source)
       free((void *) sh->Source);
+   /** We need to free pointers from strdup */
+   for (i = 0; i < sh->UBOCount; i++) {
+      free(sh->UniformBufferObjects[i].Name);
+      for (j = 0; j < sh->UniformBufferObjects[i].NumberOfVariables;j++) {
+         free(sh->UniformBufferObjects[i].StorageLayout.Compact[j].Name);
+      }
+   }
    _mesa_reference_program(ctx, &sh->Program, NULL);
    ralloc_free(sh);
 }
@@ -290,6 +299,16 @@ _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);
+   free(ubovar);
+}
 
 /**
  * Free all the data that hangs off a shader program object, but not the
@@ -299,7 +318,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);
@@ -337,6 +356,14 @@ _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]));
+      }
+   }
+   free(shProg->UniformBufferObject);
 }
 
 
diff --git a/src/mesa/program/prog_parameter.h b/src/mesa/program/prog_parameter.h
index a6793d0..3b1eb04 100644
--- a/src/mesa/program/prog_parameter.h
+++ b/src/mesa/program/prog_parameter.h
@@ -95,6 +95,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 */
 };
 
 
diff --git a/src/mesa/program/prog_uniform.c b/src/mesa/program/prog_uniform.c
index d0b25e5..e953fee 100644
--- a/src/mesa/program/prog_uniform.c
+++ b/src/mesa/program/prog_uniform.c
@@ -52,6 +52,10 @@ _mesa_free_uniform_list(struct gl_uniform_list *list)
       free((void *) list->Uniforms[i].Name);
    }
    free(list->Uniforms);
+   if(list->IndexedVariableCount) {
+      free(list->IndexedUBOVariables);
+      hash_table_dtor(list->NamedAccessUBOVariables);
+   }
    free(list);
 }
 
diff --git a/src/mesa/program/prog_uniform.h b/src/mesa/program/prog_uniform.h
index 83cd307..7ff4c46 100644
--- a/src/mesa/program/prog_uniform.h
+++ b/src/mesa/program/prog_uniform.h
@@ -32,6 +32,7 @@
 #define PROG_UNIFORM_H
 
 #include "main/glheader.h"
+#include "program/hash_table.h"
 
 
 /**
@@ -54,6 +55,77 @@ struct gl_uniform
    const struct glsl_type *Type;
 };
 
+/**
+ * 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_FLOAT,
+   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 */
+};
 
 /**
  * List of gl_uniforms
@@ -63,6 +135,22 @@ struct gl_uniform_list
    GLuint Size;                 /**< allocated size of Uniforms array */
    GLuint NumUniforms;          /**< number of uniforms in the array */
    struct gl_uniform *Uniforms; /**< Array [Size] */
+
+
+   /** 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_ubo_variable** IndexedUBOVariables; /** 1D array of pointers */
+   /** String to GLuint hashtable, provides a quick access to variable index
+    * from its name.
+    */
+   struct hash_table* NamedAccessUBOVariables;
+
+
 };
 
 
-- 
1.7.7



More information about the mesa-dev mailing list