[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