[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