Skip to content

Commit

Permalink
gs: Adapt xfb/overflow-edge-cases.c for geometry shaders.
Browse files Browse the repository at this point in the history
The transform feedback test "overflow-edge-cases" can now be invoked
with a "use_gs" argument, that causes it to use a geometry shader.

Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
  • Loading branch information
stereotype441 committed Aug 17, 2013
1 parent 79ebdc3 commit 8832056
Show file tree
Hide file tree
Showing 2 changed files with 122 additions and 30 deletions.
1 change: 1 addition & 0 deletions tests/all.tests
Original file line number Diff line number Diff line change
Expand Up @@ -2048,6 +2048,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')
Expand Down
151 changes: 121 additions & 30 deletions tests/spec/ext_transform_feedback/overflow-edge-cases.c
Original file line number Diff line number Diff line change
Expand Up @@ -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" causes 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;
Expand All @@ -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"
Expand All @@ -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);
Expand All @@ -111,10 +192,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
Expand All @@ -133,20 +210,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);
Expand All @@ -162,7 +248,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();
Expand Down

0 comments on commit 8832056

Please sign in to comment.