void piglit_init(int argc, char **argv) { static const char *varyings[] = { "valOut1", "valOut2" }; GLint inAttrib; /* Check the driver. */ piglit_require_extension("GL_ARB_transform_feedback3"); piglit_require_extension("GL_ARB_direct_state_access"); /* Create shaders. */ prog = piglit_build_simple_program_unlinked(vstext, NULL); glTransformFeedbackVaryings(prog, 2, varyings, GL_SEPARATE_ATTRIBS); glLinkProgram(prog); if (!piglit_link_check_status(prog)) { glDeleteProgram(prog); piglit_report_result(PIGLIT_FAIL); } glUseProgram(prog); /* Set up the Vertex Array Buffer */ glEnable(GL_VERTEX_ARRAY); glGenVertexArrays(1, &vao); glBindVertexArray(vao); /* Set up the input data buffer */ glGenBuffers(1, &input_buf); glBindBuffer(GL_ARRAY_BUFFER, input_buf); glBufferData(GL_ARRAY_BUFFER, sizeof(inputs), inputs, GL_STATIC_DRAW); inAttrib = glGetAttribLocation(prog, "valIn"); piglit_check_gl_error(GL_NO_ERROR); glVertexAttribPointer(inAttrib, 1, GL_FLOAT, GL_FALSE, 0, 0); glEnableVertexAttribArray(inAttrib); }
void piglit_init(int argc, char **argv) { bool pass = true; const GLint *readback; GLuint buf; void *initial_data; int i; GLuint prog = piglit_build_simple_program_unlinked(vs_text, NULL); glTransformFeedbackVaryings(prog, ARRAY_SIZE(varyings), varyings, GL_INTERLEAVED_ATTRIBS); glLinkProgram(prog); if (!piglit_link_check_status(prog) || !piglit_check_gl_error(GL_NO_ERROR)) { piglit_report_result(PIGLIT_FAIL); } glUseProgram(prog); /* Create transform feedback buffer and pre-load it with * garbage. */ glGenBuffers(1, &buf); initial_data = malloc(sizeof(expected_xfb_result)); memset(initial_data, 0xcc, sizeof(expected_xfb_result)); glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, buf); glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, sizeof(expected_xfb_result), initial_data, GL_STREAM_READ); free(initial_data); /* Run the test */ glEnable(GL_RASTERIZER_DISCARD); glBeginTransformFeedback(GL_POINTS); glDrawArrays(GL_POINTS, 0, 1); glEndTransformFeedback(); /* Check output */ readback = glMapBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, sizeof(expected_xfb_result), GL_MAP_READ_BIT); for (i = 0; i < ARRAY_SIZE(expected_xfb_result); i++) { if (readback[i] != expected_xfb_result[i]) { printf("XFB[%i] == %i, expected %i\n", i, readback[i], expected_xfb_result[i]); pass = false; } } glUnmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER); pass = piglit_check_gl_error(GL_NO_ERROR) && pass; piglit_report_result(pass ? PIGLIT_PASS : PIGLIT_FAIL); }
void piglit_init(int argc, char **argv) { piglit_require_gl_version(30); piglit_require_extension("GL_ARB_uniform_buffer_object"); prog = piglit_build_simple_program_unlinked(vstext, fstext); glTransformFeedbackVaryings(prog, 1, varyings, GL_INTERLEAVED_ATTRIBS); glLinkProgram(prog); if (!piglit_link_check_status(prog)) { glDeleteProgram(prog); piglit_report_result(PIGLIT_FAIL); } glGenBuffers(2, bufs); }
void piglit_init(int argc, char **argv) { GLuint prog, shader; unsigned i; bool pass = true; piglit_require_extension("GL_ARB_program_interface_query"); piglit_require_extension("GL_ARB_explicit_attrib_location"); piglit_require_extension("GL_ARB_explicit_uniform_location"); /* Test invalid program. */ glGetProgramResourceLocation(42, GL_UNIFORM, "name"); if (!piglit_check_gl_error(GL_INVALID_VALUE)) { piglit_report_subtest_result(PIGLIT_FAIL, "invalid program test 1"); pass = false; } /* Test passing a shader, not program. */ shader = piglit_compile_shader_text(GL_VERTEX_SHADER, vs_loc); glGetProgramResourceLocation(shader, GL_UNIFORM, "name"); if (!piglit_check_gl_error(GL_INVALID_OPERATION)) { piglit_report_subtest_result(PIGLIT_FAIL, "invalid program test 2"); pass = false; } prog = piglit_build_simple_program_unlinked(vs_loc, fs_loc); if (!piglit_check_gl_error(GL_NO_ERROR)) piglit_report_result(PIGLIT_FAIL); /* Test unlinked program. */ glGetProgramResourceLocation(prog, GL_UNIFORM, "name"); if (!piglit_check_gl_error(GL_INVALID_OPERATION)) { piglit_report_subtest_result(PIGLIT_FAIL, "invalid program test 3"); pass = false; } if (pass) piglit_report_subtest_result(PIGLIT_PASS, "invalid program tests"); if (!piglit_check_gl_error(GL_NO_ERROR)) piglit_report_result(PIGLIT_FAIL); /* Test a linked program. */ glLinkProgram(prog); glUseProgram(prog); /* Iterate through all valid enums passing invalid name. */ for (i = 0; i < (sizeof(valid_enums)/sizeof(GLenum)); i++) { glGetProgramResourceLocation(prog, valid_enums[i], "name"); if (!piglit_check_gl_error(GL_NO_ERROR)) piglit_report_result(PIGLIT_FAIL); } /* Test invalid enum, there is no defined error by the spec. */ glGetProgramResourceLocation(prog, GL_ATOMIC_COUNTER_BUFFER, "name"); if (glGetError() == GL_NO_ERROR) { piglit_report_subtest_result(PIGLIT_FAIL, "invalid enum test"); pass = false; } else { piglit_report_subtest_result(PIGLIT_PASS, "invalid enum test"); } /* Test 3 illegal array cases referenced in the spec as 'bug 9254'. */ if (glGetProgramResourceLocation(prog, GL_UNIFORM, "array[+1]") != -1) { piglit_report_subtest_result(PIGLIT_FAIL, "array case 1"); pass = false; } if (glGetProgramResourceLocation(prog, GL_UNIFORM, "array[01]") != -1) { piglit_report_subtest_result(PIGLIT_FAIL, "array case 2"); pass = false; } if (glGetProgramResourceLocation(prog, GL_UNIFORM, "array[ 0]") != -1) { piglit_report_subtest_result(PIGLIT_FAIL, "array case 3"); pass = false; } if (pass) piglit_report_subtest_result(PIGLIT_PASS, "invalid array input"); /* Valid inputs. */ validate_location(prog, GL_UNIFORM, "color", 9); validate_location(prog, GL_PROGRAM_INPUT, "input0", 3); validate_location(prog, GL_PROGRAM_INPUT, "input1", 6); validate_location(prog, GL_PROGRAM_OUTPUT, "output0", 1); validate_location(prog, GL_PROGRAM_OUTPUT, "output1", 0); /* Array indexing cases. */ validate_location(prog, GL_UNIFORM, "array", 1); validate_location(prog, GL_UNIFORM, "array[0]", 1); validate_location(prog, GL_UNIFORM, "array[1]", 2); /* All valid inputs succeeded if we got this far. */ piglit_report_subtest_result(PIGLIT_PASS, "valid inputs"); if (!piglit_check_gl_error(GL_NO_ERROR)) piglit_report_result(PIGLIT_FAIL); /* Tests that require GL_ARB_shader_subroutine. */ pass = test_subroutine_stages_vs_fs_gs() && pass; pass = test_subroutine_stages_tcs_tes() && pass; pass = test_subroutine_stages_compute() && pass; piglit_report_result(pass ? PIGLIT_PASS : PIGLIT_FAIL); }
void compile_shader(void) { GLuint element_buf; unsigned int indices[6] = { 0, 1, 2, 0, 2, 3 }; float vertex_data[4][11] = { /* vertex color0:green color1:blue color2:yellow */ {-1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0}, {-1.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0}, { 1.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0}, { 1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0}}; static const char *vert_template = "#version 130\n" "%s\n" "out vec4 color;\n" "uniform int x;\n" "void main()\n" "{\n" " gl_Position =vec4(vertex, 0, 1);\n" " switch(x) {\n" " case 0:\n" " color =vec4(color0, 1.0);\n" " break;\n" " case 1:\n" " color = vec4(color1, 1.0);\n" " break;\n" " case 2:\n" " color = vec4(color2, 1.0);\n" " break;\n" " default:\n" " color = vec4(1.0);;\n" " }\n" "}\n"; static const char *frag = "#version 130\n" "in vec4 color;\n" "out vec4 out_color;\n" "void main()\n" "{\n" " out_color = color;\n" "}\n"; char *vert; (void)!asprintf(&vert, vert_template, locations_in_shader ? "#extension GL_ARB_explicit_attrib_location : require\n" "layout (location = 0) in vec2 vertex;\n" "layout (location = 1) in vec3 color0;\n" "layout (location = 1) in vec3 color1;\n" "layout (location = 1) in vec3 color2;\n" : "in vec2 vertex;\n" "in vec3 color0;\n" "in vec3 color1;\n" "in vec3 color2;\n"); prog = piglit_build_simple_program_unlinked(vert, frag); if (!locations_in_shader) { glBindAttribLocation(prog, 0, "vertex"); glBindAttribLocation(prog, 1, "color0"); glBindAttribLocation(prog, 1, "color1"); glBindAttribLocation(prog, 1, "color2"); } glLinkProgram(prog); if (!piglit_link_check_status(prog)) piglit_report_result(PIGLIT_FAIL); /* Set up vertex array object */ glGenVertexArrays(1, &vao); glBindVertexArray(vao); /* Set up vertex input buffer */ glGenBuffers(1, &vertex_buf); glBindBuffer(GL_ARRAY_BUFFER, vertex_buf); glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_data), vertex_data, GL_STREAM_DRAW); glEnableVertexAttribArray(0); glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 11*sizeof(float), (void *) 0); glEnableVertexAttribArray(1); /* Set up element input buffer to tessellate a quad into * triangles */ glGenBuffers(1, &element_buf); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, element_buf); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); }
void load_compare_program(struct texture_format *format) { static struct { GLuint prog; GLuint tex1; GLuint tex2; GLuint tex_size; GLuint samples; } comp, ucomp, icomp, *compare; char *fs_src, *gtype; switch (format->format) { case GL_RED_INTEGER: case GL_RG_INTEGER: case GL_RGB_INTEGER: case GL_RGBA_INTEGER: case GL_BGRA_INTEGER: case GL_STENCIL_INDEX: switch (format->data_type) { case GL_BYTE: case GL_SHORT: case GL_INT: compare = &icomp; break; case GL_UNSIGNED_BYTE: case GL_UNSIGNED_SHORT: case GL_UNSIGNED_INT: compare = &ucomp; break; default: assert(!"Invalid data type"); } break; case GL_RED: case GL_RG: case GL_RGB: case GL_RGBA: case GL_BGRA: case GL_ALPHA: case GL_LUMINANCE: case GL_LUMINANCE_ALPHA: case GL_INTENSITY: case GL_DEPTH_COMPONENT: compare = ∁ break; default: assert(!"Invalid Format"); } if (!compare->prog) { if (compare == &comp) { gtype = ""; } else if (compare == &ucomp) { gtype = "u"; } else if (compare == &icomp) { gtype = "i"; } else { assert(!"Invalid comparison fucntion"); gtype = ""; } /* The generated source will be shorter because we replace * a bunch of "%s" with "u", "i", or "" */ fs_src = malloc(sizeof(ms_compare_fs_source)); snprintf(fs_src, sizeof(ms_compare_fs_source), ms_compare_fs_source, gtype, gtype, gtype, gtype); compare->prog = piglit_build_simple_program_unlinked( ms_compare_vs_source, fs_src); glBindAttribLocation(compare->prog, 0, "vertex"); glLinkProgram(compare->prog); piglit_link_check_status(compare->prog); compare->tex1 = glGetUniformLocation(compare->prog, "tex1"); compare->tex2 = glGetUniformLocation(compare->prog, "tex2"); compare->tex_size = glGetUniformLocation(compare->prog, "tex_size"); compare->samples = glGetUniformLocation(compare->prog, "samples"); } glUseProgram(compare->prog); glUniform1i(compare->tex1, 0); glUniform1i(compare->tex2, 1); glUniform2i(compare->tex_size, TEX_SIZE, TEX_SIZE); glUniform1i(compare->samples, samples); }
void piglit_init(int argc, char **argv) { unsigned glsl_version; GLuint vs_prog_3_out; GLuint vs_prog_1_out; GLuint fs_prog_3_in; GLuint fs_prog_1_in; GLuint vs_fs_prog_separate_inactive; char *vs_source; char *fs_source; GLint max_varying; bool pass = true; piglit_require_vertex_shader(); piglit_require_fragment_shader(); piglit_require_GLSL_version(130); /* Support layout index on output color */ piglit_require_extension("GL_ARB_separate_shader_objects"); piglit_require_extension("GL_ARB_explicit_attrib_location"); piglit_require_extension("GL_ARB_blend_func_extended"); glsl_version = pick_a_glsl_version(); glGetIntegerv(GL_MAX_VARYING_COMPONENTS, &max_varying); max_varying = (max_varying / 4u) - 1u; /* * Program compilation and link */ printf("Compile vs_prog_3_out\n"); vs_prog_3_out = format_and_link_program(GL_VERTEX_SHADER, vs_code_3_out_template, glsl_version); printf("Compile vs_prog_1_out\n"); vs_prog_1_out = format_and_link_program(GL_VERTEX_SHADER, vs_code_1_out_template, glsl_version); printf("Compile fs_prog_3_in\n"); fs_prog_3_in = format_and_link_program(GL_FRAGMENT_SHADER, fs_code_3_in_template, glsl_version); printf("Compile fs_prog_1_in\n"); fs_prog_1_in = format_and_link_program(GL_FRAGMENT_SHADER, fs_code_1_in_template, glsl_version); (void)!asprintf(&vs_source, vs_code_inactive_template, glsl_version, max_varying); (void)!asprintf(&fs_source, fs_code_inactive_template, glsl_version, max_varying); pass &= piglit_check_gl_error(0); printf("Compile vs_fs_prog_separate_inactive\n"); vs_fs_prog_separate_inactive = piglit_build_simple_program_unlinked(vs_source, fs_source); /* Manual linking so we can pack 2 separate-aware shaders into a single program */ glProgramParameteri(vs_fs_prog_separate_inactive, GL_PROGRAM_SEPARABLE, GL_TRUE); glLinkProgram(vs_fs_prog_separate_inactive); if (!piglit_link_check_status(vs_fs_prog_separate_inactive)) { piglit_report_subtest_result(PIGLIT_SKIP, "Unactive varying optimization in multi-shade separated program"); vs_fs_prog_separate_inactive = 0; // Skip program piglit_reset_gl_error(); // Clear pending error } free(vs_source); free(fs_source); /* * Pipeline creation */ glGenProgramPipelines(1, &pipeline_3_out_1_in); glGenProgramPipelines(1, &pipeline_1_out_3_in); glBindProgramPipeline(pipeline_3_out_1_in); glUseProgramStages(pipeline_3_out_1_in, GL_VERTEX_SHADER_BIT, vs_prog_3_out); glUseProgramStages(pipeline_3_out_1_in, GL_FRAGMENT_SHADER_BIT, fs_prog_1_in); glBindProgramPipeline(pipeline_1_out_3_in); glUseProgramStages(pipeline_1_out_3_in, GL_VERTEX_SHADER_BIT, vs_prog_1_out); glUseProgramStages(pipeline_1_out_3_in, GL_FRAGMENT_SHADER_BIT, fs_prog_3_in); if (vs_fs_prog_separate_inactive) { glGenProgramPipelines(1, &pipeline_inactive); glBindProgramPipeline(pipeline_inactive); glUseProgramStages(pipeline_inactive, GL_VERTEX_SHADER_BIT | GL_FRAGMENT_SHADER_BIT, vs_fs_prog_separate_inactive); } else { pipeline_inactive = 0; // Skip the test } if (!piglit_check_gl_error(0) || !pass) piglit_report_result(PIGLIT_FAIL); }
void piglit_init(int argc, char **argv) { GLuint buf; void *initial_data; bool pass = true; enum test_mode_enum test_mode; GLuint prog; GLuint vao, vbo_attrs, vbo_indices; GLuint query; if (argc != 2) print_usage_and_exit(argv[0]); if (strcmp(argv[1], "generated") == 0) test_mode = TEST_MODE_GENERATED; else if (strcmp(argv[1], "written") == 0) test_mode = TEST_MODE_WRITTEN; else if (strcmp(argv[1], "flush") == 0) test_mode = TEST_MODE_FLUSH; else print_usage_and_exit(argv[0]); prog = piglit_build_simple_program_unlinked(vs_text, NULL); glTransformFeedbackVaryings(prog, 1, varyings, GL_INTERLEAVED_ATTRIBS); glBindAttribLocation(prog, 0, "x_in"); glLinkProgram(prog); if (!piglit_link_check_status(prog) || !piglit_check_gl_error(GL_NO_ERROR)) { piglit_report_result(PIGLIT_FAIL); } glUseProgram(prog); /* Create transform feedback buffer and pre-load it with * garbage. */ glGenBuffers(1, &buf); initial_data = malloc(sizeof(expected_xfb_result)); memset(initial_data, 0xcc, sizeof(expected_xfb_result)); glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, buf); glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, sizeof(expected_xfb_result), initial_data, GL_STREAM_READ); free(initial_data); /* Set up VAO/VBO */ glGenVertexArrays(1, &vao); glBindVertexArray(vao); glGenBuffers(1, &vbo_attrs); glBindBuffer(GL_ARRAY_BUFFER, vbo_attrs); glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_attrs), vertex_attrs, GL_STREAM_DRAW); glVertexAttribIPointer(0, 1, GL_INT, 0, NULL); glEnableVertexAttribArray(0); glGenBuffers(1, &vbo_indices); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo_indices); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STREAM_DRAW); /* Misc setup */ glEnable(GL_RASTERIZER_DISCARD); glEnable(GL_PRIMITIVE_RESTART); glPrimitiveRestartIndex(0xff); glGenQueries(1, &query); switch (test_mode) { case TEST_MODE_GENERATED: glBeginQuery(GL_PRIMITIVES_GENERATED, query); glBeginTransformFeedback(GL_TRIANGLES); glDrawElements(GL_TRIANGLE_STRIP, 9, GL_UNSIGNED_BYTE, NULL); glEndTransformFeedback(); glEndQuery(GL_PRIMITIVES_GENERATED); pass = check_query_result(query, 4); break; case TEST_MODE_WRITTEN: glBeginQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, query); glBeginTransformFeedback(GL_TRIANGLES); glDrawElements(GL_TRIANGLE_STRIP, 9, GL_UNSIGNED_BYTE, NULL); glEndTransformFeedback(); glEndQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN); pass = check_query_result(query, 4); break; case TEST_MODE_FLUSH: glBeginTransformFeedback(GL_TRIANGLES); glDrawElements(GL_TRIANGLE_STRIP, 9, GL_UNSIGNED_BYTE, NULL); glFlush(); glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_BYTE, (void *) (9 * sizeof(GLubyte))); glEndTransformFeedback(); pass = check_xfb_result(); break; } pass = piglit_check_gl_error(GL_NO_ERROR) && pass; piglit_report_result(pass ? PIGLIT_PASS : PIGLIT_FAIL); }
void piglit_init(int argc, char **argv) { static const char *varyings[] = { "valOut1", "valOut2" }; GLuint size, start; GLint inAttrib; int i; /* Check the driver. */ piglit_require_extension("GL_ARB_transform_feedback3"); piglit_require_extension("GL_ARB_direct_state_access"); /* Create shaders. */ prog = piglit_build_simple_program_unlinked(vstext, NULL); glTransformFeedbackVaryings(prog, 2, varyings, GL_SEPARATE_ATTRIBS); glLinkProgram(prog); if (!piglit_link_check_status(prog)) { glDeleteProgram(prog); piglit_report_result(PIGLIT_FAIL); } glUseProgram(prog); /* Set up the Vertex Array Buffer */ glEnable(GL_VERTEX_ARRAY); glGenVertexArrays(1, &vao); glBindVertexArray(vao); /* Set up the input data buffer */ glGenBuffers(1, &input_buf); glBindBuffer(GL_ARRAY_BUFFER, input_buf); glBufferData(GL_ARRAY_BUFFER, sizeof(inputs), inputs, GL_STATIC_DRAW); inAttrib = glGetAttribLocation(prog, "valIn"); piglit_check_gl_error(GL_NO_ERROR); glVertexAttribPointer(inAttrib, 1, GL_FLOAT, GL_FALSE, 0, 0); glEnableVertexAttribArray(inAttrib); /* set the initial state */ ctx.active = false; ctx.paused = false; for (i = 0; i < 3; i++) { ctx.bo_state[i].binding = 0; ctx.bo_state[i].start = 0; ctx.bo_state[i].size = 0; } check_active_paused_state("initial state"); check_binding_state("initial state"); /* Set up the transform feedback buffer */ glGenBuffers(3, xfb_buf); for (i = 0; i < 2; i++) { start = rand() & 0xFC; size = 0x100 + (rand() & 0xFFC); glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, xfb_buf[i]); piglit_check_gl_error(GL_NO_ERROR); glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, size, NULL, GL_STREAM_READ); piglit_check_gl_error(GL_NO_ERROR); glTransformFeedbackBufferRange(0, i, xfb_buf[i], start, size); piglit_check_gl_error(GL_NO_ERROR); ctx.bo_state[i].binding = xfb_buf[i]; ctx.bo_state[i].start = start; ctx.bo_state[i].size = size; } check_binding_state("post-binding state"); }
void piglit_init(int argc, char **argv) { static const char *varyings[] = {"x"}; GLuint buffers[3]; GLuint vao; GLuint prog; GLuint queries[4]; GLuint xfb[2]; bool pass = true; #ifdef PIGLIT_USE_OPENGL piglit_require_transform_feedback(); piglit_require_GLSL_version(130); piglit_require_extension("GL_ARB_vertex_array_object"); piglit_require_extension("GL_ARB_transform_feedback2"); #endif /* This is all just the boot-strap work for the test. */ glGenTransformFeedbacks(ARRAY_SIZE(xfb), xfb); glGenBuffers(ARRAY_SIZE(buffers), buffers); glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, buffers[0]); glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, 1024, NULL, GL_STREAM_READ); glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, buffers[1]); glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, 1024, NULL, GL_STREAM_READ); glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, 0); glGenVertexArrays(1, &vao); glBindVertexArray(vao); glBindBuffer(GL_ARRAY_BUFFER, buffers[2]); glBufferData(GL_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW); glVertexAttribPointer(0, 1, GL_FLOAT, GL_FALSE, 1 * sizeof(GLfloat), 0); glEnableVertexAttribArray(0); glGenQueries(ARRAY_SIZE(queries), queries); prog = piglit_build_simple_program_unlinked(vstext, fstext); glTransformFeedbackVaryings(prog, 1, varyings, GL_INTERLEAVED_ATTRIBS); glLinkProgram(prog); if (!piglit_link_check_status(prog)) { pass = false; goto done; } glUseProgram(prog); glEnable(GL_RASTERIZER_DISCARD); /* Here's the actual test. */ glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, xfb[0]); glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, buffers[0]); glBeginTransformFeedback(GL_POINTS); glBeginQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, queries[0]); glDrawArrays(GL_POINTS, 0, 4); glEndQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN); glPauseTransformFeedback(); pass = piglit_check_gl_error(GL_NO_ERROR) && pass; glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, xfb[1]); glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, buffers[1]); glBeginTransformFeedback(GL_POINTS); pass = piglit_check_gl_error(GL_NO_ERROR) && pass; glBeginQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, queries[1]); glDrawArrays(GL_POINTS, 4, 2); glEndQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN); glPauseTransformFeedback(); pass = piglit_check_gl_error(GL_NO_ERROR) && pass; glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, xfb[0]); glResumeTransformFeedback(); pass = piglit_check_gl_error(GL_NO_ERROR) && pass; glBeginQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, queries[2]); glDrawArrays(GL_POINTS, 6, 4); glEndQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN); glEndTransformFeedback(); pass = piglit_check_gl_error(GL_NO_ERROR) && pass; glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, xfb[1]); glResumeTransformFeedback(); pass = piglit_check_gl_error(GL_NO_ERROR) && pass; glBeginQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, queries[3]); glDrawArrays(GL_POINTS, 10, 2); glEndQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN); glEndTransformFeedback(); pass = piglit_check_gl_error(GL_NO_ERROR) && pass; glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0); glBindVertexArray(0); /* The first XFB should have 8 primitives generated, and the buffer * object should contain the values {1.0, 2.0, 3.0, 4.0, 7.0, 8.0, * 9.0, 10.0}. */ { static const float expected_xfb_data[] = { 1.0, 2.0, 3.0, 4.0, 7.0, 8.0, 9.0, 10.0 }; glBindBuffer(GL_ARRAY_BUFFER, buffers[0]); pass = check_results(1, ARRAY_SIZE(expected_xfb_data), expected_xfb_data, queries[0], queries[2]) && pass; } /* The second XFB should have 4 primitives generated, and the buffer * object should contain the values {5.0, 6.0, 11.0, 12.0}. */ { static const float expected_xfb_data[] = { 5.0, 6.0, 11.0, 12.0 }; glBindBuffer(GL_ARRAY_BUFFER, buffers[1]); pass = check_results(2, ARRAY_SIZE(expected_xfb_data), expected_xfb_data, queries[1], queries[3]) && pass; } glBindBuffer(GL_ARRAY_BUFFER, 0); done: glBindVertexArray(0); glDeleteVertexArrays(1, &vao); glDeleteBuffers(ARRAY_SIZE(buffers), buffers); glDeleteQueries(ARRAY_SIZE(queries), queries); glDeleteTransformFeedbacks(ARRAY_SIZE(xfb), xfb); glUseProgram(0); glDeleteProgram(prog); piglit_report_result(pass ? PIGLIT_PASS : PIGLIT_FAIL); }