[Piglit] [PATCH 4/6] gs: Adapt xfb/overflow-edge-cases.c for geometry shaders.
Paul Berry
stereotype441 at gmail.com
Wed Aug 7 13:28:41 PDT 2013
The transform feedback test "overflow-edge-cases" can now be invoked
with a "use_gs" argument, that causes it to use a geometry shader.
---
tests/all.tests | 1 +
.../ext_transform_feedback/overflow-edge-cases.c | 151 +++++++++++++++++----
2 files changed, 122 insertions(+), 30 deletions(-)
diff --git a/tests/all.tests b/tests/all.tests
index 2f32120..b1df541 100644
--- a/tests/all.tests
+++ b/tests/all.tests
@@ -2030,6 +2030,7 @@ for mode in ['output', 'prims_generated', 'prims_written']:
ext_transform_feedback['max-varyings'] = concurrent_test('ext_transform_feedback-max-varyings')
ext_transform_feedback['nonflat-integral'] = concurrent_test('ext_transform_feedback-nonflat-integral')
ext_transform_feedback['overflow-edge-cases'] = concurrent_test('ext_transform_feedback-overflow-edge-cases')
+ext_transform_feedback['overflow-edge-cases use_gs'] = concurrent_test('ext_transform_feedback-overflow-edge-cases use_gs')
ext_transform_feedback['position-readback-bufferbase'] = concurrent_test('ext_transform_feedback-position')
ext_transform_feedback['position-readback-bufferbase-discard'] = concurrent_test('ext_transform_feedback-position discard')
ext_transform_feedback['position-readback-bufferoffset'] = concurrent_test('ext_transform_feedback-position offset')
diff --git a/tests/spec/ext_transform_feedback/overflow-edge-cases.c b/tests/spec/ext_transform_feedback/overflow-edge-cases.c
index a2c6f10..e29e20b 100644
--- a/tests/spec/ext_transform_feedback/overflow-edge-cases.c
+++ b/tests/spec/ext_transform_feedback/overflow-edge-cases.c
@@ -39,14 +39,29 @@
* - The proper values were written to the transform feedback buffer.
* - GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN is set correctly.
* - GL_PRIMITIVES_GENERATED is set correctly.
+ *
+ * The optional argument "use_gs" uses the test to use a geometry
+ * shader. When this argument is given, the number of vertices output
+ * by the geometry shader is in general different from the number of
+ * vertices sent down the pipeline by the glDrawArrays() command.
+ * Thus, the test verifies that the implementation does overflow
+ * checking based on the post-geometry-shader vertex count.
*/
#include "piglit-util-gl-common.h"
+static bool use_gs;
+
PIGLIT_GL_TEST_CONFIG_BEGIN
- config.supports_gl_compat_version = 10;
- config.supports_gl_core_version = 31;
+ use_gs = PIGLIT_STRIP_ARG("use_gs");
+ if (use_gs) {
+ config.supports_gl_compat_version = 32;
+ config.supports_gl_core_version = 32;
+ } else {
+ config.supports_gl_compat_version = 10;
+ config.supports_gl_core_version = 31;
+ }
config.window_width = 16;
config.window_height = 16;
@@ -57,7 +72,10 @@ PIGLIT_GL_TEST_CONFIG_END
#define XFB_BUFFER_SIZE 12
#define MAX_VERTICES 9
-static const char *vstext =
+/**
+ * Vertex shader used when use_gs is false.
+ */
+static const char *vstext_nogs =
"attribute float vertex_num;\n"
"varying float varying1;\n"
"varying float varying2;\n"
@@ -69,35 +87,98 @@ static const char *vstext =
" varying2 = 200.0 + vertex_num;\n"
"}\n";
+/**
+ * Vertex shader used when use_gs is true.
+ */
+static const char *vstext_gs =
+ "#version 150\n"
+ "\n"
+ "void main()\n"
+ "{\n"
+ "}\n";
+
+/**
+ * Geometry shader used when use_gs is true.
+ */
+static const char *gstext_gs =
+ "#version 150\n"
+ "layout(points) in;\n"
+ "layout(%s, max_vertices=9) out;\n"
+ "uniform int num_primitives;\n"
+ "uniform int vertices_per_prim;\n"
+ "out float varying1;\n"
+ "out float varying2;\n"
+ "\n"
+ "void main()\n"
+ "{\n"
+ " int vertex_num = 0;\n"
+ " for (int i = 0; i < num_primitives; i++) {\n"
+ " for (int j = 0; j < vertices_per_prim; j++) {\n"
+ " varying1 = 100.0 + float(vertex_num);\n"
+ " varying2 = 200.0 + float(vertex_num);\n"
+ " vertex_num++;\n"
+ " EmitVertex();\n"
+ " }\n"
+ " EndPrimitive();\n"
+ " }\n"
+ "}\n";
+
+
static const char *varyings[] = { "varying1", "varying2" };
static GLuint xfb_buf, vao, array_buf;
-static GLuint progs[2]; /* indexed by num_varyings - 1 */
+static GLuint progs[3][2]; /* indexed by (mode, num_varyings - 1) */
static GLuint query_prims_generated;
static GLuint query_prims_written;
+static GLenum modes[] = { GL_POINTS, GL_LINES, GL_TRIANGLES };
+static const char *mode_names[] = {
+ "GL_POINTS", "GL_LINES", "GL_TRIANGLES"
+};
+static const char *mode_gs_out_primtypes[] = {
+ "points", "line_strip", "triangle_strip"
+};
+
void
piglit_init(int argc, char **argv)
{
- GLuint vs;
+ GLuint vs, gs;
int num_varyings;
+ int mode;
piglit_require_GLSL();
piglit_require_transform_feedback();
- vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vstext);
- for (num_varyings = 1; num_varyings <= 2; ++num_varyings) {
- GLuint prog = glCreateProgram();
- glAttachShader(prog, vs);
- glBindAttribLocation(prog, 0, "vertex_num");
- glTransformFeedbackVaryings(prog, num_varyings, varyings,
- GL_INTERLEAVED_ATTRIBS);
- glLinkProgram(prog);
- if (!piglit_link_check_status(prog)) {
- glDeleteProgram(prog);
- piglit_report_result(PIGLIT_FAIL);
+ for (mode = 0; mode < ARRAY_SIZE(modes); mode++) {
+ if (use_gs) {
+ char *gstext;
+ vs = piglit_compile_shader_text(GL_VERTEX_SHADER,
+ vstext_gs);
+ asprintf(&gstext, gstext_gs,
+ mode_gs_out_primtypes[mode]);
+ gs = piglit_compile_shader_text(GL_GEOMETRY_SHADER,
+ gstext);
+ } else {
+ vs = piglit_compile_shader_text(GL_VERTEX_SHADER,
+ vstext_nogs);
+ }
+ for (num_varyings = 1; num_varyings <= 2; ++num_varyings) {
+ GLuint prog = glCreateProgram();
+ glAttachShader(prog, vs);
+ if (use_gs)
+ glAttachShader(prog, gs);
+ else
+ glBindAttribLocation(prog, 0, "vertex_num");
+ glTransformFeedbackVaryings(prog, num_varyings,
+ varyings,
+ GL_INTERLEAVED_ATTRIBS);
+ glLinkProgram(prog);
+ if (!piglit_link_check_status(prog)) {
+ glDeleteProgram(prog);
+ piglit_report_result(PIGLIT_FAIL);
+ }
+ progs[mode][num_varyings - 1] = prog;
}
- progs[num_varyings - 1] = prog;
}
glGenBuffers(1, &xfb_buf);
@@ -110,10 +191,6 @@ piglit_init(int argc, char **argv)
}
}
-static GLenum modes[] = { GL_POINTS, GL_LINES, GL_TRIANGLES };
-static const char *mode_names[] = {
- "GL_POINTS", "GL_LINES", "GL_TRIANGLES"
-};
static int mode_vertices_per_prim[] = { 1, 2, 3 };
static GLboolean
@@ -132,20 +209,29 @@ test(int bind_size, int num_varyings, int num_primitives, int mode_index)
GLboolean pass = GL_TRUE;
float expected_xfb_results[XFB_BUFFER_SIZE];
float *readback;
+ GLuint prog;
printf("size=%d, num_varyings=%d, num_primitives=%d, mode=%s: ",
bind_size, num_varyings, num_primitives,
mode_names[mode_index]);
/* Setup program and initial buffer contents */
- glUseProgram(progs[num_varyings - 1]);
- for (i = 0; i < MAX_VERTICES; ++i)
- vertex_data[i] = i;
- glBindBuffer(GL_ARRAY_BUFFER, array_buf);
- glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_data), &vertex_data,
- GL_STATIC_DRAW);
- glVertexAttribPointer(0, 1, GL_FLOAT, GL_FALSE, sizeof(float), NULL);
- glEnableVertexAttribArray(0);
+ prog = progs[mode_index][num_varyings - 1];
+ glUseProgram(prog);
+ if (use_gs) {
+ glUniform1i(glGetUniformLocation(prog, "num_primitives"),
+ num_primitives);
+ glUniform1i(glGetUniformLocation(prog, "vertices_per_prim"),
+ vertices_per_prim);
+ } else {
+ for (i = 0; i < MAX_VERTICES; ++i)
+ vertex_data[i] = i;
+ glBindBuffer(GL_ARRAY_BUFFER, array_buf);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_data),
+ &vertex_data, GL_STATIC_DRAW);
+ glVertexAttribPointer(0, 1, GL_FLOAT, GL_FALSE, sizeof(float), NULL);
+ glEnableVertexAttribArray(0);
+ }
for (i = 0; i < XFB_BUFFER_SIZE; ++i)
initial_xfb_buf[i] = 0.0;
glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, xfb_buf);
@@ -161,7 +247,12 @@ test(int bind_size, int num_varyings, int num_primitives, int mode_index)
glBeginTransformFeedback(modes[mode_index]);
/* Draw */
- glDrawArrays(modes[mode_index], 0, num_primitives * vertices_per_prim);
+ if (use_gs) {
+ glDrawArrays(GL_POINTS, 0, 1);
+ } else {
+ glDrawArrays(modes[mode_index], 0,
+ num_primitives * vertices_per_prim);
+ }
/* Stop XFB and check queries */
glEndTransformFeedback();
--
1.8.3.4
More information about the Piglit
mailing list