[Piglit] [PATCH] varying: Checks if driver can handle MAX_VARYING_FLOATS in mixed float, vec*.

Vincent Lejeune vljn at ovi.com
Sat Feb 11 15:12:01 PST 2012


   v2: - Rewrite the test, following Paul Berry recommandations.
---
 tests/all.tests                         |    6 +
 tests/shaders/CMakeLists.gl.txt         |    1 +
 tests/shaders/glsl-max-varyings-mixed.c |  330 +++++++++++++++++++++++++++++++
 3 files changed, 337 insertions(+), 0 deletions(-)
 create mode 100644 tests/shaders/glsl-max-varyings-mixed.c

diff --git a/tests/all.tests b/tests/all.tests
index d0f18b4..a787822 100644
--- a/tests/all.tests
+++ b/tests/all.tests
@@ -431,6 +431,12 @@ add_plain_test(shaders, 'glsl-fs-texturelod-01')
 add_plain_test(shaders, 'glsl-fs-user-varying-ff')
 add_plain_test(shaders, 'glsl-mat-attribute')
 add_plain_test(shaders, 'glsl-max-varyings')
+shaders['glsl-max-varyings-mixed floats'] = PlainExecTest('glsl-max-varyings-mixed 1.0 0.0 0.0 0.0 -auto')
+shaders['glsl-max-varyings-mixed floats vec2s'] = PlainExecTest('glsl-max-varyings-mixed 0.5 0.5 0.0 0.0 -auto')
+shaders['glsl-max-varyings-mixed floats vec2s vec3s'] = PlainExecTest('glsl-max-varyings-mixed 0.3 0.3 0.3 0.0 -auto')
+shaders['glsl-max-varyings-mixed float vec3s full'] = PlainExecTest('glsl-max-varyings-mixed 0.0 1.0 0.0 -auto')
+shaders['glsl-max-varyings-mixed float vec2s vec3s vec4'] = PlainExecTest('glsl-max-varyings-mixed 0.25 0.25 0.25 0.25 -auto')
+shaders['glsl-max-varyings-mixed float vec2s vec3s vec4 full'] = PlainExecTest('glsl-max-varyings-mixed 0.25 0.25 0.25 -auto')
 add_plain_test(shaders, 'glsl-orangebook-ch06-bump')
 add_plain_test(shaders, 'glsl-routing')
 add_plain_test(shaders, 'glsl-vs-arrays')
diff --git a/tests/shaders/CMakeLists.gl.txt b/tests/shaders/CMakeLists.gl.txt
index 9d72260..c606ecb 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-mixed glsl-max-varyings-mixed.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-mixed.c b/tests/shaders/glsl-max-varyings-mixed.c
new file mode 100644
index 0000000..2a1b44c
--- /dev/null
+++ b/tests/shaders/glsl-max-varyings-mixed.c
@@ -0,0 +1,330 @@
+/*
+ * 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 <eric at anholt.net>
+ *    Vincent Lejeune <vljn at ovi.com>
+ *
+ */
+
+/** @file glsl-max-varyings-mixed.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.
+ *
+ * This test takes 3 or 4 args : the ratio of float, vec2, vec3, vec4 components in the
+ * shaders. These are ratio because the max amount of components is hardware
+ * specific. If the float ratio is not set, floats varyings will fill varying components
+ * up to GL_MAX_VARYING_FLOATS.
+ */
+
+#include "piglit-util.h"
+
+int piglit_width = 24, piglit_height = 24;
+int piglit_window_mode = GLUT_RGB | GLUT_DOUBLE;
+
+
+enum varyings_type {
+   FLT = 0,
+   V2 = 1,
+   V3 = 2,
+   V4 = 3
+};
+
+const char* glsl_type_names[] = { "float", "vec2", "vec3", "vec4" };
+
+bool variable_float_varying_amount;
+float ratio[4];
+
+
+static void generate_varyings_decl(char* code, unsigned amounts[4])
+{
+   char temp[128];
+   unsigned index = 0, i, type;
+      
+   for (type = 0; type < 4; type ++) {
+	for (i = 0; i < amounts[type]; i++) {
+	   sprintf(temp, "varying %s v%d;\n", glsl_type_names[type], index);
+	   strcat(code, temp);
+	   index++;
+	}
+   }
+      
+   return;
+}
+
+static void
+vs_write_varying(char *code, unsigned amounts[4])
+{
+   char temp[128];
+   unsigned index = 0, i;
+   float component_content = 0.;
+   
+   for (i = 0; i < amounts[FLT]; i++) {
+	sprintf(temp,"	v%d = %f;\n", index, component_content);
+	strcat(code, temp);
+	index ++, component_content += 1.;
+   }
+   for (i = 0; i < amounts[V2]; i++) {
+	sprintf(temp,"	v%d = vec2(%f, %f);\n", index, component_content, component_content + 1.);
+	strcat(code, temp);
+	index ++, component_content += 2.;
+   }
+   for (i = 0; i < amounts[V3]; i++) {
+	sprintf(temp,"	v%d = vec3(%f, %f, %f);\n", index, component_content, component_content + 1., component_content + 2.);
+	strcat(code, temp);
+	index ++, component_content += 3.;
+   }
+   for (i = 0; i < amounts[V4]; i++) {
+	sprintf(temp,"	v%d = vec4(%f, %f, %f, %f);\n", index, component_content, component_content + 1, component_content + 2., component_content + 3.);
+	strcat(code, temp);
+	index ++, component_content += 4.;
+   }
+}
+
+/* Generate a VS that writes to amounts[type] varyings for each type.
+ */
+static GLint get_vs(unsigned amounts[4])
+{
+	char temp[128];
+	GLuint shader;
+	char *code;
+
+	code =  malloc(2048 * 4);
+	code[0] = 0;
+	
+	generate_varyings_decl(code, amounts);
+
+	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);
+
+	vs_write_varying(code, amounts);
+
+	sprintf(temp,
+		"}\n"
+		);
+	strcat(code, temp);
+
+	shader = piglit_compile_shader_text(GL_VERTEX_SHADER, code);
+      /* printf("%s\n", code); */
+      free(code);
+
+	return shader;
+}
+
+static void
+fs_read_varying(char *code, unsigned amounts[4])
+{
+   char temp[128];
+   unsigned index = 0, i;
+   float component_content = 0.;
+   
+   for (i = 0; i < amounts[FLT]; i++) {
+	sprintf(temp,"	v%d == %f &&\n", index, component_content);
+	strcat(code, temp);
+	index ++, component_content += 1.;
+   }
+   for (i = 0; i < amounts[V2]; i++) {
+	sprintf(temp,"	v%d == vec2(%f, %f) &&\n", index, component_content, component_content + 1.);
+	strcat(code, temp);
+	index ++, component_content += 2.;
+   }
+   for (i = 0; i < amounts[V3]; i++) {
+	sprintf(temp,"	v%d == vec3(%f, %f, %f) &&\n", index, component_content, component_content + 1., component_content + 2.);
+	strcat(code, temp);
+	index ++, component_content += 3.;
+   }
+   for (i = 0; i < amounts[V4]; i++) {
+	sprintf(temp,"	v%d == vec4(%f, %f, %f,%f) &&\n", index, component_content, component_content + 1, component_content + 2., component_content + 3.);
+	strcat(code, temp);
+	index ++, component_content += 4.;
+   }
+}
+
+/* Generate a FS that compares each varying with
+ * the expected content.
+ */
+static GLint get_fs(unsigned amounts[4])
+{
+	GLuint shader;
+	char temp[2048];
+	char *code;
+
+	code = malloc(2048 * 4);
+	code[0] = 0;
+	
+	generate_varyings_decl(code, amounts);
+
+	sprintf(temp,
+		"void main()\n"
+		"{\n"
+		"	if ("
+		);
+	strcat(code, temp);
+
+	fs_read_varying(code, amounts);
+
+	sprintf(temp,
+		" 1.0 == 1.0)\n"
+		"	gl_FragColor = vec4(0.0,1.0,0.0,1.0);\n"
+		" else \n"
+		"	gl_FragColor = vec4(1.0,0.0,0.0,1.0);\n"
+		"}\n"
+		);
+	strcat(code, temp);
+      /* printf("%s\n", code);  */
+	shader = piglit_compile_shader_text(GL_FRAGMENT_SHADER, code);
+	free(code);
+
+	return shader;
+}
+
+static void
+draw(unsigned amounts[4])
+{
+   GLuint prog, vs, fs;
+   
+   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);
+   
+   vs = get_vs(amounts);
+   fs = get_fs(amounts);
+   
+   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);
+   
+   piglit_draw_rect(12, 12, 10, 10);
+   
+   glDeleteShader(vs);
+   glDeleteShader(fs);
+   glDeleteProgram(prog);
+   
+}
+
+enum piglit_result
+      piglit_display(void)
+{
+   int max_components;
+   unsigned amounts[4];
+   float green[3] = {0.0, 1.0, 0.0};
+   GLboolean pass = GL_TRUE;
+   
+   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);
+   
+
+   amounts[V2] = (max_components * ratio[V2]) / 2;
+   amounts[V3] = (max_components * ratio[V3]) / 3;
+   amounts[V4] = (max_components * ratio[V4]) /4;
+   if (variable_float_varying_amount) {
+	amounts[FLT] = max_components - 2 * amounts[V2] - 3 * amounts[V3] - 4 * amounts[V4];
+   } else {
+      amounts[FLT] = max_components * ratio[FLT];
+   }
+   
+   
+   glClearColor(0.5, 0.5, 0.5, 0.5);
+   glClear(GL_COLOR_BUFFER_BIT);
+   
+   draw(amounts);
+   
+   pass = piglit_probe_rect_rgb(12, 12, 10, 10, green);
+
+   glutSwapBuffers();
+   
+   if (!pass)
+	return PIGLIT_FAIL;
+   else
+	return PIGLIT_PASS;
+}
+
+void piglit_init(int argc, char **argv)
+{
+   unsigned i, j;
+   
+   piglit_require_gl_version(20);
+   
+   if (argc < 4) {
+	fprintf(stderr, "Not enough args.\n");
+	exit(1);
+   }
+   
+   if (argc > 5) {
+	fprintf(stderr, "Too many args.\n");
+	exit(1);
+   }
+   
+   if (argc == 4) {
+	variable_float_varying_amount = true;
+	ratio[FLT] = 0;
+	j = 1;
+   } else {
+	j = 0;
+   }
+   
+   for (i = 1; i < argc; i++, j++) {
+	sscanf(argv[i], "%f",&ratio[j]);
+   }
+   
+   for (i = 0; i < 4; i++) {
+	if (ratio[i] < 0) {
+	   fprintf(stderr, "Ratio must be positive.\n");
+	   exit(1);
+	}
+   }
+   
+   if (ratio[FLT] + ratio[V2] + ratio[V3] + ratio[V4] > 1.0) {
+	fprintf(stderr, "Ratio are not normalised.\n");
+	exit(1);
+   }
+}
+
+
-- 
1.7.7



More information about the Piglit mailing list