diff options
author | Andres Gomez <agomez@igalia.com> | 2016-04-18 18:53:01 +0300 |
---|---|---|
committer | Alejandro Piñeiro <apinheiro@igalia.com> | 2016-05-17 10:38:12 +0200 |
commit | 290650cf00dae9238804e552feb4751cc4090a58 (patch) | |
tree | 2e5d593084ee52c93957b0d6164631126f5ceca6 | |
parent | 6c44530bfc29bd48b600723d2a58dab28c68f767 (diff) |
util: Add array_index support to [vertex data] (v2)
This allows data to be set for arbitrary array sized attributes in
shader runner.
For example to set mat2x3[2]:
attname[0]/mat2x3/3/1 attname[0]/mat2x3/3/2 attname[1]/mat2x3/3/1 attname[1]/mat2x3/3/2
The syntax has been extended so the recommended type to specify in the
[vertex data] header line is the GLSL corresponding one, not just
"float", "double", "int" or "uint".
In any case, the extended syntax is backward compatible so it is still
possible to specify a vec3 attribute like:
attname/float/3
In addition to the now recommended format:
attname/vec3/3
v2: Added more verbose comments and documentation as requested by
Alejandro Piñeiro.
Reviewed-by: Alejandro Piñeiro <apinheiro@igalia.com>
Signed-off-by: Andres Gomez <agomez@igalia.com>
-rw-r--r-- | tests/util/piglit-vbo.cpp | 167 |
1 files changed, 133 insertions, 34 deletions
diff --git a/tests/util/piglit-vbo.cpp b/tests/util/piglit-vbo.cpp index 514723417..1bdd9da11 100644 --- a/tests/util/piglit-vbo.cpp +++ b/tests/util/piglit-vbo.cpp @@ -1,5 +1,5 @@ /* - * Copyright © 2011 Intel Corporation + * Copyright © 2011, 2016 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -28,29 +28,42 @@ * tests using a columnar text format, for example: * * \verbatim - * vertex/float/3 foo/uint/1 bar/int/2 - * 0.0 0.0 0.0 10 0 0 # comment - * 0.0 1.0 0.0 5 1 1 - * 1.0 1.0 0.0 0 0 1 + * vertex/vec3/3 foo/uint/1 bar[0]/int/1 bar[1]/int/1 + * 0.0 0.0 0.0 10 0 0 # comment + * 0.0 1.0 0.0 5 1 1 + * 1.0 1.0 0.0 0 0 1 * \endverbatim * * The format consists of a row of column headers followed by any * number of rows of data. Each column header has the form - * "ATTRNAME/TYPE/COUNT/MATRIX_COLUMN", where ATTRNAME is the name of - * the vertex attribute to be bound to this column, TYPE is the type - * of data that follows ("float", "int", or "uint"), COUNT is the - * vector length of the data (e.g. "3" for vec3 data) and - * MATRIX_COLUMN is the column number of the data in case of being a - * matrix. MATRIX_COLUMN can also be used for arrays of - * arrays. MATRIX_COLUMN doesn't need to be be specified if it is not - * a matrix column as in the example before. So another example, if - * you want to specify the data of a mat2x3: + * "ATTRNAME[ARRAY_INDEX]/TYPE/COUNT/MATRIX_COLUMN", where ATTRNAME is + * the name of the vertex attribute to be bound to this column, + * ARRAY_INDEX is the index, TYPE is the GLSL type of data that + * follows ("float", "double", "int", "uint" or any derived type like + * vec2, dmat4, etc.), COUNT is the vector length of the data + * (e.g. "3" for vec3 data or "2" for mat4x2) and MATRIX_COLUMN is the + * column number of the data in case of being a matrix. [ARRAY_INDEX] + * is optional and needs to be specified only in case of array + * attributes. COUNT is a redundant value that is already specified in + * the data type but that has been kept for backward + * compatibility. MATRIX_COLUMN doesn't need to be specified if it is + * not a matrix column as in the example before. So another example, + * if you want to specify the data of a mat2x3: * - * \verbatim - * foomatrix/float/3/0 foomatrix/float/3/1 - * 0.0 1.0 2.0 3.0 4.0 5.0 - * 6.0 7.0 8.0 9.0 10.0 11.0 - * \endverbatim + * \verbatim + * foomatrix/mat2x3/3/0 foomatrix/mat2x3/3/1 + * 0.0 1.0 2.0 3.0 4.0 5.0 + * 6.0 7.0 8.0 9.0 10.0 11.0 + * \endverbatim + * + * The same example, using the deprecated but compatible syntax would + * be: + * + * \verbatim + * foomatrix/float/3/0 foomatrix/float/3/1 + * 0.0 1.0 2.0 3.0 4.0 5.0 + * 6.0 7.0 8.0 9.0 10.0 11.0 + * \endverbatim * * The data follows the column headers in space-separated form. "#" * can be used for comments, as in shell scripts. @@ -95,6 +108,23 @@ * glEnableVertexAttribArray(foo_index); * glEnableVertexAttribArray(bar_index); * \endcode + * + * Which could correspond to a vertex shader of this type: + * + * \code + * in vec3 vertex; + * in uint foo; + * in int bar[2]; + * + * void main() + * { + * if (bar[0] + bar[1] == foo) { + * gl_Position = vec4(vertex, 1.0); + * } else { + * gl_Position = vec4(1.0, vertex); + * } + * } + * \endcode */ #include <string> @@ -117,7 +147,7 @@ const int ATTRIBUTE_SIZE = 4; * Convert a type name string to a GLenum. */ GLenum -decode_type(const char *type) +decode_type(const char *type, size_t *rows, size_t *cols) { static struct type_table_entry { const char *type; /* NULL means end of table */ @@ -127,13 +157,44 @@ decode_type(const char *type) { "uint", GL_UNSIGNED_INT }, { "float", GL_FLOAT }, { "double", GL_DOUBLE }, + { "ivec", GL_INT }, + { "uvec", GL_UNSIGNED_INT }, + { "vec", GL_FLOAT }, + { "dvec", GL_DOUBLE }, + { "mat", GL_FLOAT }, + { "dmat", GL_DOUBLE }, { NULL, 0 } }; for (int i = 0; type_table[i].type; ++i) { - if (0 == strcmp(type, type_table[i].type)) + if (0 == strncmp(type, type_table[i].type, strlen(type_table[i].type))) { + /* In case of vectors or matrices, let's + * calculate rows and columns, if needed. + */ + if (i > 3 && (rows || cols)) { + size_t type_len = strlen(type); + size_t the_rows = type[type_len - 1] - '0'; + if (rows) + *rows = the_rows; + if (cols) { + /* In case of matrices, let's + * calculate the columns. + */ + if (i > 7) + *cols = type[type_len - 2] == 'x' ? + type[type_len - 3] - '0' : the_rows; + else + *cols = 1; + } + } else { + if (rows) + *rows = 1; + if (cols) + *cols = 1; + } return type_table[i].enum_value; + } } printf("Unrecognized type: %s\n", type); @@ -158,6 +219,11 @@ public: GLenum data_type; /** + * Number of columns in the data type of this attribute. + */ + size_t data_type_cols; + + /** * Vector length of this attribute. */ size_t count; @@ -168,6 +234,11 @@ public: size_t matrix_index; /** + * Index of the array for this attribute. + */ + size_t array_index; + + /** * Index of this vertex attribute in the linked program. */ GLuint index; @@ -185,25 +256,50 @@ public: vertex_attrib_description::vertex_attrib_description(GLuint prog, const char *text) { - /* Split the column header into name/type/count fields */ + /* Split the column header into + * name[array_index]/type/count/matrix_column fields. + */ const char *first_slash = strchr(text, '/'); if (first_slash == NULL) { - printf("Column headers must be in the form name/type/count/matrix_column.\n" - "Note: matrix_column is optional.\n" + printf("Column headers must be in the form" + " name[array_index]/type/count/matrix_column.\n" + "Note: [array_index] and matrix_column are optional.\n" "Got: %s\n", text); piglit_report_result(PIGLIT_FAIL); } + std::string name(text, first_slash); + + /* If the attrib is an array, strip the index */ + if (name[name.size() - 1] == ']') { + std::string::size_type n = name.find('['); + if (n == std::string::npos) { + printf("Column header looked like an array" + " but couldn't parse it.\n" + "Got: %s\n", + text); + piglit_report_result(PIGLIT_FAIL); + } else { + this->array_index = strtoul(name.substr(n + 1).c_str(), NULL, 0); + name.resize(n); + } + } else { + this->array_index = 0; + } + const char *second_slash = strchr(first_slash + 1, '/'); if (second_slash == NULL) { - printf("Column headers must be in the form name/type/count/matrix_column.\n" + printf("Column headers must be in the form" + " name[array_index]/type/count/matrix_column.\n" + "Note: [array_index] and matrix_column are optional.\n" "Got: %s\n", text); piglit_report_result(PIGLIT_FAIL); } std::string type_str(first_slash + 1, second_slash); - this->data_type = decode_type(type_str.c_str()); + this->data_type = decode_type(type_str.c_str(), + &this->count, &this->data_type_cols); char *endptr; this->count = strtoul(second_slash + 1, &endptr, 10); @@ -218,8 +314,9 @@ vertex_attrib_description::vertex_attrib_description(GLuint prog, } if (*endptr != '\0') { - printf("Column headers must be in the form name/type/matrix_column.\n" - "Note: matrix_column is optional.\n" + printf("Column headers must be in the form" + " name[array_index]/type/count/matrix_column.\n" + "Note: [array_index] and matrix_column are optional.\n" "Got: %s\n", text); piglit_report_result(PIGLIT_FAIL); @@ -324,9 +421,11 @@ void vertex_attrib_description::setup(size_t *offset, size_t stride) const { int attribute_size = ATTRIBUTE_SIZE; + GLuint actual_index = this->index + this->matrix_index + + this->array_index * this->data_type_cols; switch (this->data_type) { case GL_FLOAT: - glVertexAttribPointer(this->index + this->matrix_index, this->count, + glVertexAttribPointer(actual_index, this->count, this->data_type, GL_FALSE, stride, (void *) *offset); break; @@ -335,9 +434,9 @@ vertex_attrib_description::setup(size_t *offset, size_t stride) const fprintf(stderr,"vertex_attrib_description fail. no 64-bit float support\n"); return; } - glVertexAttribLPointer(this->index + this->matrix_index, this->count, - this->data_type, stride, - (void *) *offset); + glVertexAttribLPointer(actual_index, this->count, + this->data_type, stride, + (void *) *offset); attribute_size *= 2; break; default: @@ -345,12 +444,12 @@ vertex_attrib_description::setup(size_t *offset, size_t stride) const fprintf(stderr,"vertex_attrib_description fail. no int support\n"); return; } - glVertexAttribIPointer(this->index + this->matrix_index, this->count, + glVertexAttribIPointer(actual_index, this->count, this->data_type, stride, (void *) *offset); break; } - glEnableVertexAttribArray(index + this->matrix_index); + glEnableVertexAttribArray(actual_index); *offset += attribute_size * this->count; } |