--- tests/shaders/CMakeLists.gl.txt | 1 + tests/shaders/glsl-max-varyings-2.c | 413 +++++++++++++++++++++++++++++++++++ 2 files changed, 414 insertions(+), 0 deletions(-) create mode 100644 tests/shaders/glsl-max-varyings-2.c
diff --git a/tests/shaders/CMakeLists.gl.txt b/tests/shaders/CMakeLists.gl.txt index 9d72260..b00219e 100644 --- a/tests/shaders/CMakeLists.gl.txt +++ b/tests/shaders/CMakeLists.gl.txt @@ -143,6 +143,7 @@ add_executable (vp-ignore-input vp-ignore-input.c) add_executable (glsl-empty-vs-no-fs glsl-empty-vs-no-fs.c) add_executable (glsl-mat-attribute glsl-mat-attribute.c) add_executable (glsl-max-varyings glsl-max-varyings.c) +add_executable (glsl-max-varyings-2 glsl-max-varyings-2.c) add_executable (glsl-useprogram-displaylist glsl-useprogram-displaylist.c) add_executable (glsl-routing glsl-routing.c) add_executable (shader_runner shader_runner.c) diff --git a/tests/shaders/glsl-max-varyings-2.c b/tests/shaders/glsl-max-varyings-2.c new file mode 100644 index 0000000..b020d6c --- /dev/null +++ b/tests/shaders/glsl-max-varyings-2.c @@ -0,0 +1,413 @@ +/* + * Copyright © 2010 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + * Authors: + * Eric Anholt <e...@anholt.net> + * + */ + +/** @file glsl-max-varyings.c + * + * Tests whether GL_MAX_VARYING_FLOATS varying components can be used when packed + * as vec4, vec3, vec2, or float. Drivers have to pack varyings to pass this test. + */ + +#include "piglit-util.h" + +#define MAX_VARYING 128 + +/* 10x10 rectangles with 2 pixels of pad. Deal with up to 32 varyings. */ +int piglit_width = (2 + MAX_VARYING * 12), piglit_height = (2 + MAX_VARYING * 12); +int piglit_window_mode = GLUT_RGB | GLUT_DOUBLE; + + +enum varyings_type { + FLT = 0, + V2 = 1, + V3 = 2, + V4 = 3 +}; + +const unsigned increments[] = { 4, 2, 2, 1 }; + +/* Generate a VS that writes to num_varyings vec4s, and put + * interesting data in data_varying with 0.0 everywhere else. + */ +static GLint get_vs(int num_varyings, int data_varying, enum varyings_type type) +{ + + const char * varying_decl[] = { + "varying float v%d;\n", + "varying vec2 v%d;\n", + "varying vec3 v%d;\n", + "varying vec4 v%d;\n", + }; + + GLuint shader; + unsigned i; + char *code; + char temp[2048]; + + code = malloc(2048 * 4); + code[0] = 0; + for (i = 0; i < num_varyings; i++) { + sprintf(temp, varying_decl[type], i); + strcat(code, temp); + } + + sprintf(temp, + "attribute vec4 green;\n" + "attribute float v_zero;\n" + "void main()\n" + "{\n" + " gl_Position = (gl_ModelViewProjectionMatrix * \n" + " gl_Vertex);\n" + ); + strcat(code, temp); + i = 0; + while (i + increments[type] < num_varyings) { + if (i == data_varying) { + switch (type) { + case FLT: + sprintf(temp, + " v%d = green.x;\n" + " v%d = green.y;\n" + " v%d = green.z;\n" + " v%d = green.w;\n", + i, + i + 1, + i + 2, + i + 3); + break; + case V2: + sprintf(temp, + " v%d = green.xy;\n" + " v%d = green.zw;\n", + i, + i + 1); + break; + case V3: + sprintf(temp, + " v%d = green.xyz;\n" + " v%d.x = green.w;\n", + i, + i + 1); + break; + case V4: + sprintf(temp, " v%d = green;\n", i); + break; + } + i += increments[type]; + } else { + switch (type) { + case FLT: + sprintf(temp, + " v%d = v_zero;\n", i); + break; + case V2: + sprintf(temp, + " v%d.x = v_zero;\n" + " v%d.y = v_zero;\n", i, i); + break; + case V3: + sprintf(temp, + " v%d.x = v_zero;\n" + " v%d.y = v_zero;\n" + " v%d.z = v_zero;\n", + i, i, i); + break; + case V4: + sprintf(temp, + " v%d.x = v_zero;\n" + " v%d.y = v_zero;\n" + " v%d.z = v_zero;\n" + " v%d.w = v_zero;\n", + i, i, i, i); + break; + } + i++; + } + strcat(code, temp); + + } + + sprintf(temp, + "}\n" + ); + strcat(code, temp); + + shader = piglit_compile_shader_text(GL_VERTEX_SHADER, code); + /* printf("%s\n", code); */ + free(code); + + return shader; +} + +/* Generate a FS that does operations on num_varyings, yet makes only + * data_varying contribute to the output. + * + * We could make a single FS per num_varyings that did this by using a + * uniform for data_varying and some multiplication by comparisons + * (see glsl-routing for an example), but since we're linking a new + * shader each time anyway, this produces a simpler FS to read and + * verify. + */ +static GLint get_fs(int num_varyings, int data_varying, enum varyings_type type) +{ + GLuint shader; + unsigned i; + char temp[2048]; + char *code; + + const char * varying_decl[] = { + "varying float v%d;\n", + "varying vec2 v%d;\n", + "varying vec3 v%d;\n", + "varying vec4 v%d;\n", + }; + + code = malloc(2048 * 4); + code[0] = 0; + for (i = 0; i < num_varyings; i++) { + sprintf(temp, varying_decl[type], i); + strcat(code, temp); + } + + sprintf(temp, + "uniform float zero;\n" + "uniform float one;\n" + "void main()\n" + "{\n" + " vec4 val = vec4(0.0);\n" + ); + strcat(code, temp); + + i = 0; + while (i + increments[type] < num_varyings) { + if (i == data_varying) { + switch (type) { + case FLT: + sprintf(temp, + " val.x += one * v%d;\n" + " val.y += one * v%d;\n" + " val.z += one * v%d;\n" + " val.w += one * v%d;\n", + i, + i + 1, + i + 2, + i + 3); + break; + case V2: + sprintf(temp, + " val.xy += one * v%d;\n" + " val.zw += one * v%d;\n", + i, + i + 1); + break; + case V3: + sprintf(temp, + " val.xyz += one * v%d;\n" + " val.w += one * v%d.x;\n", + i, + i + 1); + break; + case V4: + sprintf(temp, + " val += one * v%d;\n", + i); + break; + } + i += increments[type]; + } else { + switch (type) { + case FLT: + sprintf(temp, + " val.x += v%d;\n", i); + break; + case V2: + sprintf(temp, + " val.xy += v%d;\n", i); + break; + case V3: + sprintf(temp, + " val.xyz += v%d;\n", i); + break; + case V4: + sprintf(temp, + " val += v%d;\n", i); + break; + } + i++; + } + strcat(code, temp); + + } + + sprintf(temp, + " gl_FragColor = val;\n" + "}\n" + ); + strcat(code, temp); + /* printf("%s\n", code); */ + shader = piglit_compile_shader_text(GL_FRAGMENT_SHADER, code); + free(code); + + return shader; +} + +static int +coord_from_index(int index) +{ + return 2 + 12 * index; +} + +static void +draw(int num_varyings, enum varyings_type type) +{ + int data_varying; + float green[4][4] = { {0.0, 1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0}, + {0.0, 1.0, 0.0, 0.0} }; + + glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(float), + green); + glVertexAttribPointer(2, 1, GL_FLOAT, GL_FALSE, 4 * sizeof(float), + green); + glEnableVertexAttribArray(1); + glEnableVertexAttribArray(2); + + for (data_varying = 0; data_varying < num_varyings - increments[type]; data_varying ++) { + GLuint prog, vs, fs; + GLint loc; + + vs = get_vs(num_varyings, data_varying, type); + fs = get_fs(num_varyings, data_varying, type); + + prog = glCreateProgram(); + glAttachShader(prog, vs); + glAttachShader(prog, fs); + + glBindAttribLocation(prog, 1, "green"); + glBindAttribLocation(prog, 2, "v_zero"); + + glLinkProgram(prog); + if (!piglit_link_check_status(prog)) + piglit_report_result(PIGLIT_FAIL); + + glUseProgram(prog); + + loc = glGetUniformLocation(prog, "zero"); + if (loc != -1) /* not used for num_varyings == 1 */ + glUniform1f(loc, 0.0); + + loc = glGetUniformLocation(prog, "one"); + assert(loc != -1); /* should always be used */ + glUniform1f(loc, 1.0); + + + piglit_draw_rect(coord_from_index(data_varying), + coord_from_index(type), + 10, + 10); + + glDeleteShader(vs); + glDeleteShader(fs); + glDeleteProgram(prog); + } +} + +enum piglit_result +piglit_display(void) +{ + int max_components, type, col; + int max_varyings[4]; + const char* names[] = { "float", "vec2", "vec3", "vec4" }; + GLboolean pass = GL_TRUE, warned = GL_FALSE; + + piglit_ortho_projection(piglit_width, piglit_height, GL_FALSE); + + glGetIntegerv(GL_MAX_VARYING_FLOATS, &max_components); + + printf("GL_MAX_VARYING_FLOATS = %i\n", max_components); + + if (max_components > MAX_VARYING) { + printf("test not designed to handle >%d varying vec4s.\n" + "(implementation reports %d components)\n", + max_components, MAX_VARYING); + max_components = MAX_VARYING; + warned = GL_TRUE; + } + + max_varyings[FLT] = max_components / 4; + max_varyings[V2] = max_components / 3; + max_varyings[V3] = max_components / 2; + max_varyings[V4] = max_components; + + glClearColor(0.5, 0.5, 0.5, 0.5); + glClear(GL_COLOR_BUFFER_BIT); + + for (type = 0; type < 4; type++) { + draw(max_varyings[type], type); + } + + for (type = 0; type < 4; type++) { + for (col = 0; col < max_varyings[type] - increments[type]; col ++) { + GLboolean ok; + float green[3] = {0.0, 1.0, 0.0}; + + ok = piglit_probe_rect_rgb(coord_from_index(col), + coord_from_index(type), + 10, 10, + green); + if (!ok) { + printf(" Failure with %s varyings used " + "in varying index %d\n", + names[type], col); + pass = GL_FALSE; + break; + } + } + } + + glutSwapBuffers(); + + if (!pass) + return PIGLIT_FAIL; + if (warned) + return PIGLIT_WARN; + else + return PIGLIT_PASS; +} + +void piglit_init(int argc, char **argv) +{ + if (!GLEW_VERSION_2_0) { + printf("Requires OpenGL 2.0\n"); + piglit_report_result(PIGLIT_SKIP); + } + + printf("Vertical axis: Increasing numbers of varyings.\n"); + printf("Horizontal axis: Which of the varyings contains the color.\n"); +} + + -- 1.7.7 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev