[Piglit] [PATCH 1/3] GL_ARB_uniform_buffer_object: shader_runner support

Vincent Lejeune vljn at ovi.com
Sat Mar 24 11:13:49 PDT 2012


---
 tests/shaders/shader_runner.c |  245 +++++++++++++++++++++++++++++++++++++++++
 1 files changed, 245 insertions(+), 0 deletions(-)

diff --git a/tests/shaders/shader_runner.c b/tests/shaders/shader_runner.c
index 56881b8..6843c89 100644
--- a/tests/shaders/shader_runner.c
+++ b/tests/shaders/shader_runner.c
@@ -524,6 +524,34 @@ leave_state(enum states state, const char *line)
 	}
 }
 
+static GLuint bind_point_to_buffer[256];
+static GLuint bind_point_to_ubo[256];
+static GLuint bind_point_count = 0;
+
+static void
+init_ubo(GLint prog)
+{
+   int i;
+   GLint ubo_counts;
+   piglit_GetProgramiv(prog, GL_ACTIVE_UNIFORM_BLOCKS, &ubo_counts);
+   for (i = 0; i < ubo_counts; i ++) {
+      GLsizei uniformBlockSize;
+
+      glGenBuffers(1, &bind_point_to_buffer[bind_point_count]);
+      glBindBuffer(GL_UNIFORM_BUFFER, bind_point_to_buffer[bind_point_count]);
+
+      bind_point_to_ubo[bind_point_count] = i;
+      glGetActiveUniformBlockiv(prog, bind_point_to_ubo[bind_point_count],
+                                   GL_UNIFORM_BLOCK_DATA_SIZE,
+                                   &uniformBlockSize);
+      glBufferData(GL_UNIFORM_BUFFER, uniformBlockSize,
+                   NULL, GL_DYNAMIC_DRAW);
+
+      glBindBufferBase(GL_UNIFORM_BUFFER, bind_point_count, bind_point_to_buffer[bind_point_count]);
+      glUniformBlockBinding(prog, bind_point_to_ubo[bind_point_count], bind_point_count);
+      bind_point_count ++;
+   }
+}
 
 void
 link_and_use_shaders(void)
@@ -599,6 +627,9 @@ link_and_use_shaders(void)
 
 		piglit_report_result(PIGLIT_FAIL);
 	}
+
+      if (gl_version >= 3.1)
+         init_ubo(prog);
 }
 
 
@@ -882,6 +913,218 @@ set_uniform(const char *line)
 	return;
 }
 
+static void
+populate_matrix(float* f, unsigned cols, unsigned rows, unsigned offset, unsigned stride)
+{
+   unsigned c;
+
+   for (c = 0; c < cols; c++) {
+      glBufferSubData(GL_UNIFORM_BUFFER, offset + c * stride, rows * sizeof(float), (const GLvoid *) &f[rows * c]);
+   }
+}
+
+struct ubo_content {
+   enum {
+      BOOL,
+      UNSIGNED,
+      INT,
+      FLOAT,
+      MATRIX,
+   } base_type;
+   unsigned vector_elements:3;
+   unsigned columns;
+   unsigned array_length;
+};
+
+static
+struct ubo_content retrieve_contents(const char *type)
+{
+   unsigned array_length;
+   struct ubo_content result;
+
+   if (string_match("float", type)) {
+      result.base_type = FLOAT;
+      result.vector_elements = 1;
+      if (type[5] == '[') {
+         sscanf(type + 5, "[%d]", &array_length);
+      } else {
+         array_length = 1;
+      }
+      result.array_length = array_length;
+      return result;
+   }
+
+   if (string_match("int", type)) {
+      result.base_type = INT;
+      result.vector_elements = 1;
+      if (type[3] == '[') {
+         sscanf(type + 3, "[%d]", &array_length);
+      } else {
+         array_length = 1;
+      }
+      result.array_length = array_length;
+      return result;
+   }
+
+   if (string_match("uint", type)) {
+      result.base_type = UNSIGNED;
+      result.vector_elements = 1;
+      if (type[4] == '[') {
+         sscanf(type + 4, "[%d]", &array_length);
+      } else {
+         array_length = 1;
+      }
+      result.array_length = array_length;
+      return result;
+   }
+
+   if (string_match("vec", type)) {
+      result.base_type = FLOAT;
+      result.vector_elements = type[3] - '0';
+      if (type[4] == '[') {
+         sscanf(type + 4, "[%d]", &array_length);
+      } else {
+         array_length = 1;
+      }
+      result.array_length = array_length;
+      return result;
+   }
+
+   if (string_match("ivec", type)) {
+      result.base_type = INT;
+      result.vector_elements = type[4] - '0';
+      if (type[5] == '[') {
+         sscanf(type + 5, "[%d]", &array_length);
+      } else {
+         array_length = 1;
+      }
+      result.array_length = array_length;
+      return result;
+   }
+
+   if (string_match("uvec", type)) {
+      result.base_type = UNSIGNED;
+      result.vector_elements = type[4] - '0';
+      if (type[5] == '[') {
+         sscanf(type + 5, "[%d]", &array_length);
+      } else {
+         array_length = 1;
+      }
+      result.array_length = array_length;
+      return result;
+   }
+
+   if (string_match("mat", type)) {
+      unsigned rows, cols;
+      result.base_type = MATRIX;
+      sscanf(type, "mat%dx%d", &rows, &cols);
+      if (type[6] == '[') {
+         sscanf(type + 6, "[%d]", &array_length);
+      } else {
+         array_length = 1;
+      }
+      result.vector_elements = rows;
+      result.columns = cols;
+      result.array_length = array_length ;
+      return result;
+   }
+
+   piglit_report_result(PIGLIT_FAIL);
+   return result;
+}
+
+void
+set_ubo_uniform(const char *line)
+{
+   char name[512];
+   float f[16];
+   int ints[16];
+   unsigned uints[16], i;
+   GLuint prog;
+   GLint offset, size, stride, matrix_stride;
+   const char *type;
+   struct ubo_content ubo_type;
+
+   glGetIntegerv(GL_CURRENT_PROGRAM, (GLint *) &prog);
+
+   type = eat_whitespace(line);
+   line = eat_text(type);
+
+   line = strcpy_to_space(name, eat_whitespace(line));
+
+   {
+      GLuint idx;
+      GLint block_index, bind_point;
+      char *charbuffer;
+
+      charbuffer = strdup(name);
+      glGetUniformIndices(prog, 1, (const char **)&charbuffer, &idx);
+      free(charbuffer);
+      if (idx == GL_INVALID_INDEX) {
+         printf("cannot get location of ubo uniform \"%s\"\n",
+                name);
+         piglit_report_result(PIGLIT_FAIL);
+      }
+      glGetActiveUniformsiv(prog, 1, &idx,
+                            GL_UNIFORM_OFFSET, &offset);
+
+      glGetActiveUniformsiv(prog, 1, &idx,
+                            GL_UNIFORM_SIZE, &size);
+      glGetActiveUniformsiv(prog, 1, &idx,
+                            GL_UNIFORM_BLOCK_INDEX, &block_index);
+      glGetActiveUniformsiv(prog, 1, &idx,
+                            GL_UNIFORM_ARRAY_STRIDE, &stride);
+
+      glGetActiveUniformsiv(prog, 1, &idx,
+                            GL_UNIFORM_MATRIX_STRIDE, &matrix_stride);
+
+      glGetActiveUniformBlockiv(prog, block_index,
+                                GL_UNIFORM_BLOCK_BINDING, &bind_point);
+      glBindBuffer(GL_UNIFORM_BUFFER, bind_point_to_buffer[bind_point]);
+   }
+
+   ubo_type = retrieve_contents(type);
+
+   if (ubo_type.base_type == FLOAT) {
+      get_floats(line, f, ubo_type.vector_elements * ubo_type.array_length);
+      for (i = 0; i < ubo_type.array_length; i++) {
+         glBufferSubData(GL_UNIFORM_BUFFER, offset + i * stride, ubo_type.vector_elements * sizeof(float), (const GLvoid *) &f[i * ubo_type.vector_elements]);
+      }
+      return;
+   }
+
+   if (ubo_type.base_type == INT) {
+      get_ints(line, ints, ubo_type.vector_elements * ubo_type.array_length);
+      for (i = 0; i < ubo_type.array_length; i++) {
+         glBufferSubData(GL_UNIFORM_BUFFER, offset + i * stride, ubo_type.vector_elements * sizeof(int), (const GLvoid *) &ints[i * ubo_type.vector_elements]);
+      }
+      return;
+   }
+
+   if (ubo_type.base_type == UNSIGNED) {
+      get_uints(line, uints, ubo_type.vector_elements * ubo_type.array_length);
+      for (i = 0; i < ubo_type.array_length; i++) {
+         glBufferSubData(GL_UNIFORM_BUFFER, offset + i * stride, ubo_type.vector_elements * sizeof(unsigned), (const GLvoid *) &uints[i * ubo_type.vector_elements]);
+      }
+      return;
+   }
+
+   if (ubo_type.base_type == MATRIX) {
+      get_floats(line, f, ubo_type.vector_elements * ubo_type.columns * ubo_type.array_length);
+      for (i = 0; i < ubo_type.array_length; i++) {
+         populate_matrix(f, ubo_type.columns, ubo_type.vector_elements, offset + i * stride, matrix_stride);
+      }
+      return;
+   }
+
+   strcpy_to_space(name, type);
+   printf("unknown uniform type \"%s\"", name);
+   piglit_report_result(PIGLIT_FAIL);
+
+   return;
+
+}
+
 void
 set_parameter(const char *line)
 {
@@ -1317,6 +1560,8 @@ piglit_display(void)
 			handle_texparameter(GL_TEXTURE_1D_ARRAY, line + strlen("texparameter1DArray "));
 		} else if (string_match("uniform", line)) {
 			set_uniform(line + 7);
+            } else if (string_match("ubo-uniform", line)) {
+                  set_ubo_uniform(line + 11);
 		} else if (string_match("parameter ", line)) {
 			set_parameter(line + strlen("parameter "));
 		} else if ((line[0] != '\n') && (line[0] != '\0')
-- 
1.7.7



More information about the Piglit mailing list