@@ -40,6 +40,7 @@
#include "piglit-util-gl.h"
#define MAX_VARYING 32
+#define AOA_OUTER_DIM 2
/* 10x10 rectangles with 2 pixels of pad. Deal with up to 32 varyings. */
@@ -54,6 +55,7 @@ PIGLIT_GL_TEST_CONFIG_BEGIN
PIGLIT_GL_TEST_CONFIG_END
static const char *xfb_varying_array[MAX_VARYING];
+static const char *xfb_varying_aoa[MAX_VARYING];
static GLuint xfb_buf;
/* Generate a VS that writes to a varying vec4[num_varyings] called
@@ -84,6 +86,49 @@ get_vs(int num_varyings)
return shader;
}
+static GLint
+get_vs_aoa(int num_varyings)
+{
+ GLuint shader;
+ char vstext[2048];
+ int inner_dim = num_varyings / AOA_OUTER_DIM;
+
+ /* If there is an odd number of varyings add one more */
+ char *extra_varying;
+ char *extra_statement;
+ if (num_varyings % 2 != 0) {
+ extra_varying = "varying vec4 y;";
+ extra_statement = "y = 4.0*(offset+j) + vec4(0.0, 1.0, 2.0, 3.0);";
+ } else {
+ extra_varying = "";
+ extra_statement = "";
+ }
+
+ sprintf(vstext,
+ "#version 120\n"
+ "#extension GL_ARB_arrays_of_arrays : enable\n"
+ "varying vec4[%d][%d] v;\n"
+ "%s\n"
+ "\n"
+ "void main()\n"
+ "{\n"
+ " int offset;\n"
+ " int j;\n"
+ " gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n"
+ " for (int i = 0; i < v.length(); ++i) {\n"
+ " offset = i * v[i].length();\n"
+ " for (j = 0; j < v[i].length(); ++j) {\n"
+ " v[i][j] = 4.0*(offset+j) + vec4(0.0, 1.0, 2.0, 3.0);\n"
+ " }\n"
+ " }\n"
+ " %s\n"
+ "}\n", AOA_OUTER_DIM, inner_dim, extra_varying, extra_statement);
+
+ shader = piglit_compile_shader_text(GL_VERTEX_SHADER, vstext);
+
+ return shader;
+}
+
/* Generate a FS that checks all the varyings written by the VS, and
* outputs green if they are all correct.
*/
@@ -111,14 +156,77 @@ get_fs(int num_varyings)
return shader;
}
+static GLint
+get_fs_aoa(int num_varyings)
+{
+ GLuint shader;
+ char fstext[2048];
+ int inner_dim = num_varyings / AOA_OUTER_DIM;
+
+ /* If there is an odd number of varyings add one more */
+ char *extra_varying;
+ char *extra_statement;
+ if (num_varyings % 2 != 0) {
+ extra_varying = "varying vec4 y;";
+ extra_statement = "failed = failed || (y != 4.0*(offset+j) + vec4(0.0, 1.0, 2.0, 3.0));";
+
+ } else {
+ extra_varying = "";
+ extra_statement = "";
+ }
+
+ sprintf(fstext,
+ "#version 120\n"
+ "#extension GL_ARB_arrays_of_arrays : enable\n"
+ "varying vec4[%d][%d] v;\n"
+ "%s\n"
+ "\n"
+ "void main()\n"
+ "{\n"
+ " bool failed = false;\n"
+ " int offset;\n"
+ " int j;\n"
+ " for(int i = 0; i < v.length(); ++i) {\n"
+ " offset = i * v[i].length();\n"
+ " for (j = 0; j < v[i].length(); ++j) {\n"
+ " failed = failed || (v[i][j] != 4.0*(offset+j) + vec4(0.0, 1.0, 2.0, 3.0));\n"
+ " }\n"
+ " }\n"
+ " %s\n"
+ " gl_FragColor = vec4(float(failed), 1.0 - float(failed), 0.0, 1.0);\n"
+ "}\n", AOA_OUTER_DIM, inner_dim, extra_varying, extra_statement);
+
+ shader = piglit_compile_shader_text(GL_FRAGMENT_SHADER, fstext);
+
+ return shader;
+}
+
/**
* Initialize xfb_varying_array to contain the names of the varyings
* used by get_vs and get_fs.
*/
static void
-init_xfb_varying_array()
+init_xfb_varyings(int max_varyings)
{
- int i;
+ int i, j;
+ int inner_dim = max_varyings / AOA_OUTER_DIM;
+ int count = 0;
+
+ /* Initialise arrays of arrays */
+ for (i = 0; i < AOA_OUTER_DIM; ++i) {
+ for (j = 0; j < inner_dim; ++j) {
+ char *buf = malloc(8);
+ sprintf(buf, "v[%d][%d]", i, j);
+ xfb_varying_aoa[count++] = buf;
+ }
+ }
+ if (max_varyings % 2 != 0) {
+ char *buf = malloc(8);
+ sprintf(buf, "y");
+ xfb_varying_aoa[count++] = buf;
+ }
+
+ /* Initialise singlie dimension array */
for (i = 0; i < MAX_VARYING; ++i) {
char *buf = malloc(6);
sprintf(buf, "v[%d]", i);
@@ -173,7 +281,8 @@ check_xfb_output(int max_varyings, int num_xfb_varyings, int offset)
}
static GLboolean
-draw(GLuint vs, GLuint fs, int num_xfb_varyings, int max_varyings)
+draw(GLuint vs, GLuint fs, int num_xfb_varyings,
+ int max_varyings, const char **xfb_varyings)
{
GLboolean pass = GL_TRUE;
int offset;
@@ -187,7 +296,7 @@ draw(GLuint vs, GLuint fs, int num_xfb_varyings, int max_varyings)
glAttachShader(prog, fs);
glTransformFeedbackVaryings(prog, num_xfb_varyings,
- xfb_varying_array + offset,
+ xfb_varyings + offset,
GL_INTERLEAVED_ATTRIBS);
glLinkProgram(prog);
@@ -219,20 +328,58 @@ draw(GLuint vs, GLuint fs, int num_xfb_varyings, int max_varyings)
return pass;
}
+static GLboolean
+run_subtest(GLuint vs, GLuint fs, int max_xfb_varyings,
+ int max_varyings, const char **xfb_varyings)
+{
+ GLboolean pass = GL_TRUE;
+ int row, col;
+
+ glClearColor(0.5, 0.5, 0.5, 0.5);
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ for (row = 0; row < max_xfb_varyings; row++) {
+ pass = draw(vs, fs, row + 1, max_varyings, xfb_varyings) &&
+ pass;
+ }
+
+ for (row = 0; row < max_xfb_varyings; row++) {
+ for (col = 0; col < max_varyings - row; col++) {
+ GLboolean ok;
+ float green[3] = {0.0, 1.0, 0.0};
+
+ ok = piglit_probe_rect_rgb(coord_from_index(col),
+ coord_from_index(row),
+ 10, 10,
+ green);
+ if (!ok) {
+ printf(" Failure with %d vec4 varyings"
+ " captured and offset %d\n",
+ row + 1, col);
+ pass = GL_FALSE;
+ break;
+ }
+ }
+ }
+ return pass;
+}
+
enum piglit_result
piglit_display(void)
{
GLint max_components;
- int max_varyings, row, col;
+ int max_varyings;
int max_xfb_varyings = 0;
GLint max_xfb_components;
- GLboolean pass = GL_TRUE, warned = GL_FALSE;
+ GLboolean pass;
+ enum piglit_result status = PIGLIT_PASS;
GLuint vs, fs;
piglit_ortho_projection(piglit_width, piglit_height, GL_FALSE);
glGetIntegerv(GL_MAX_VARYING_FLOATS, &max_components);
max_varyings = max_components / 4;
+ init_xfb_varyings(max_varyings);
printf("GL_MAX_VARYING_FLOATS = %i\n", max_components);
@@ -241,7 +388,7 @@ piglit_display(void)
"(implementation reports %d components)\n",
max_components, MAX_VARYING);
max_varyings = MAX_VARYING;
- warned = GL_TRUE;
+ status = PIGLIT_WARN;
}
glGetIntegerv(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS,
@@ -251,43 +398,34 @@ piglit_display(void)
printf("GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS = %i\n",
max_xfb_components);
+ /* Test single dimension array */
vs = get_vs(max_varyings);
fs = get_fs(max_varyings);
-
- glClearColor(0.5, 0.5, 0.5, 0.5);
- glClear(GL_COLOR_BUFFER_BIT);
-
- for (row = 0; row < max_xfb_varyings; row++) {
- pass = draw(vs, fs, row + 1, max_varyings) && pass;
+ pass = run_subtest(vs, fs, max_xfb_varyings,
+ max_varyings, xfb_varying_array);
+ if (!pass) {
+ status = PIGLIT_FAIL;
}
-
- for (row = 0; row < max_xfb_varyings; row++) {
- for (col = 0; col < max_varyings - row; col++) {
- GLboolean ok;
- float green[3] = {0.0, 1.0, 0.0};
-
- ok = piglit_probe_rect_rgb(coord_from_index(col),
- coord_from_index(row),
- 10, 10,
- green);
- if (!ok) {
- printf(" Failure with %d vec4 varyings"
- " captured and offset %d\n",
- row + 1, col);
- pass = GL_FALSE;
- break;
- }
+ piglit_report_subtest_result(status,
+ "max-varying-single-dimension-array");
+
+ /* Test arrays of arrays */
+ if (piglit_is_extension_supported("GL_ARB_arrays_of_arrays")) {
+ bool subtest_result;
+ vs = get_vs_aoa(max_varyings);
+ fs = get_fs_aoa(max_varyings);
+ subtest_result = run_subtest(vs, fs, max_xfb_varyings,
+ max_varyings, xfb_varying_aoa);
+ if (!subtest_result) {
+ status = PIGLIT_FAIL;
+ pass = false;
}
+ piglit_report_subtest_result(status,
+ "max-varying-arrays-of-arrays");
}
-
piglit_present_results();
- if (!pass)
- return PIGLIT_FAIL;
- if (warned)
- return PIGLIT_WARN;
- else
- return PIGLIT_PASS;
+ return status;
}
void piglit_init(int argc, char **argv)
@@ -295,7 +433,6 @@ void piglit_init(int argc, char **argv)
piglit_require_gl_version(20);
piglit_require_GLSL_version(120);
piglit_require_transform_feedback();
- init_xfb_varying_array();
glGenBuffers(1, &xfb_buf);
printf("Vertical axis: Increasing numbers of varyings captured by "