[Piglit] [PATCH 2/3] GL_ARB_uniform_buffer_object: shader_runner support
Vincent Lejeune
vljn at ovi.com
Mon Apr 23 16:17:32 PDT 2012
v2: Fix indent
---
tests/shaders/shader_runner.c | 285 +++++++++++++++++++++++++++++++++++++++++
1 files changed, 285 insertions(+), 0 deletions(-)
diff --git a/tests/shaders/shader_runner.c b/tests/shaders/shader_runner.c
index 2d5c52d..676943c 100644
--- a/tests/shaders/shader_runner.c
+++ b/tests/shaders/shader_runner.c
@@ -884,6 +884,285 @@ set_uniform(const char *line)
return;
}
+static GLuint ubo_buffer_count = 0;
+static GLuint ubo_buffer_name[256];
+static GLuint ubo_shader_name[256];
+
+static void
+generate_ubo_buffer(const char *line)
+{
+ GLuint prog;
+ GLuint uniformBlockSize;
+ const char buffer_name[256];
+
+ glGetIntegerv(GL_CURRENT_PROGRAM, (GLint *) &prog);
+
+ line = strcpy_to_space(buffer_name, eat_whitespace(line));
+
+ ubo_shader_name[ubo_buffer_count] = glGetUniformBlockIndex(prog, buffer_name);
+
+ glGenBuffers(1, &ubo_buffer_name[ubo_buffer_count]);
+ glBindBuffer(GL_UNIFORM_BUFFER, ubo_buffer_name[ubo_buffer_count]);
+
+ glGetActiveUniformBlockiv(prog, ubo_shader_name[ubo_buffer_count], GL_UNIFORM_BLOCK_DATA_SIZE, &uniformBlockSize);
+ glBufferData(GL_UNIFORM_BUFFER, uniformBlockSize, NULL, GL_DYNAMIC_DRAW);
+
+ ubo_buffer_count ++;
+}
+
+static void
+bind_ubo(const char *buffer)
+{
+ GLuint prog;
+ const char *buffer_name = eat_whitespace(buffer);
+ GLuint buffer_id = atoi(buffer_name);
+
+ glGetIntegerv(GL_CURRENT_PROGRAM, (GLint *) &prog);
+
+ glBindBufferBase(GL_UNIFORM_BUFFER, buffer_id, ubo_buffer_name[buffer_id]);
+ glUniformBlockBinding(prog, ubo_shader_name[buffer_id], buffer_id);
+}
+
+
+// content is seen as an array of {size} matrix
+static void
+write_data_to_ubo_f(float* f, unsigned rows, unsigned cols, unsigned size, unsigned offset, unsigned matrix_stride, unsigned array_stride)
+{
+ unsigned element;
+ unsigned column;
+
+ for (element = 0; element < size; element ++) {
+ for (column = 0; column < cols; column ++) {
+ glBufferSubData(GL_UNIFORM_BUFFER,
+ offset + (column * matrix_stride) + (element * array_stride),
+ rows * sizeof(float),
+ (const GLvoid *) &f[rows * column + element * cols * rows]);
+ }
+ }
+}
+
+static void
+write_data_to_ubo_i(int* f, unsigned rows, unsigned size, unsigned offset, unsigned array_stride)
+{
+ unsigned element;
+
+ for (element = 0; element < size; element ++) {
+ glBufferSubData(GL_UNIFORM_BUFFER,
+ offset + (element * array_stride),
+ rows * sizeof(int),
+ (const GLvoid *) &f[rows * element]);
+ }
+}
+
+static void
+write_data_to_ubo_u(unsigned* f, unsigned rows, unsigned size, unsigned offset, unsigned array_stride)
+{
+ unsigned element;
+
+ for (element = 0; element < size; element ++) {
+ glBufferSubData(GL_UNIFORM_BUFFER,
+ offset + (element * array_stride),
+ rows * sizeof(unsigned),
+ (const GLvoid *) &f[rows * element]);
+ }
+}
+
+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_typeinfo(const char *type)
+{
+ unsigned array_length;
+ struct ubo_content result;
+
+ if (string_match("float", type)) {
+ result.base_type = FLOAT;
+ result.vector_elements = 1;
+ result.columns = 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;
+ result.columns = 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;
+ result.columns = 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.columns = 1;
+ 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.columns = 1;
+ 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.columns = 1;
+ 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];
+ GLuint prog;
+ GLint offset, size, stride, matrix_stride;
+ GLuint buffer_id;
+ const char *type;
+ struct ubo_content ubo_type;
+
+ glGetIntegerv(GL_CURRENT_PROGRAM, (GLint *) &prog);
+
+ line = eat_whitespace(line);
+ buffer_id = atoi(line);
+ line = eat_text(line);
+
+ 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, ubo_buffer_name[buffer_id]);
+ }
+
+ ubo_type = retrieve_typeinfo(type);
+
+ if (ubo_type.base_type == FLOAT) {
+ get_floats(line, f, ubo_type.vector_elements * ubo_type.array_length);
+ write_data_to_ubo_f(f, ubo_type.vector_elements, ubo_type.columns, ubo_type.array_length, offset, 0, stride);
+ return;
+ }
+
+ if (ubo_type.base_type == INT) {
+ get_ints(line, ints, ubo_type.vector_elements * ubo_type.array_length);
+ write_data_to_ubo_i(ints, ubo_type.vector_elements, ubo_type.array_length, offset, stride);
+ return;
+ }
+
+ if (ubo_type.base_type == UNSIGNED) {
+ get_uints(line, uints, ubo_type.vector_elements * ubo_type.array_length);
+ write_data_to_ubo_u(uints, ubo_type.vector_elements, ubo_type.array_length, offset, stride);
+ return;
+ }
+
+ if (ubo_type.base_type == MATRIX) {
+ get_floats(line, f, ubo_type.vector_elements * ubo_type.columns * ubo_type.array_length);
+ write_data_to_ubo_f(f, ubo_type.vector_elements, ubo_type.columns, ubo_type.array_length, offset, matrix_stride, 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)
{
@@ -1366,6 +1645,12 @@ piglit_display(void)
handle_texparameter(line + strlen("texparameter "));
} else if (string_match("uniform", line)) {
set_uniform(line + 7);
+ } else if (string_match("ubo-buffer", line)) {
+ generate_ubo_buffer(line + 10);
+ } else if (string_match("ubo-bind", line)) {
+ bind_ubo(line + 8);
+ } 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