enum piglit_result piglit_display(void) { GLint input_index = glGetAttribLocation(prog, "input_uint"); GLuint *readback; GLuint buffer[BUFFER_SIZE]; GLuint expected[BUFFER_SIZE]; int i; GLboolean pass = GL_TRUE; piglit_UseProgram(prog); glBindBuffer(GL_ARRAY_BUFFER, 0); glVertexAttribIPointer(input_index, 1, GL_UNSIGNED_INT, sizeof(GLuint), &verts); glEnableVertexAttribArray(input_index); pass = piglit_check_gl_error(0) && pass; glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, xfb_buf); memset(buffer, 0xffffffff, sizeof(buffer)); glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, sizeof(buffer), buffer, GL_STREAM_READ); piglit_BindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, xfb_buf, additional_offset, sizeof(buffer) - additional_offset); piglit_BeginTransformFeedback(GL_POINTS); glDrawArrays(GL_POINTS, 0, 4); piglit_EndTransformFeedback(); pass = piglit_check_gl_error(0) && pass; readback = glMapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY); pass = piglit_check_gl_error(0) && pass; /* Figure out expected output */ memset(expected, 0xffffffff, sizeof(expected)); for (i = 0; i < EXPECTED_NUM_OUTPUTS; ++i) { expected[i + additional_offset / 4] = 0x00010203 + 0x04040404 * i; } /* Check output */ for (i = 0; i < BUFFER_SIZE; ++i) { if (expected[i] != readback[i]) { printf("readback[%u]: %u, expected: %u\n", i, readback[i], expected[i]); pass = GL_FALSE; } } piglit_present_results(); return pass ? PIGLIT_PASS : PIGLIT_FAIL; }
static GLboolean do_test(const struct test_desc *test) { GLuint *bufs; GLboolean pass = GL_TRUE; GLint max_separate_attribs; float initial_xfb_buffer_contents[XFB_BUFFER_SIZE]; int i; glGetIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS, &max_separate_attribs); printf("MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTIBS=%i\n", max_separate_attribs); bufs = malloc(max_separate_attribs * sizeof(GLuint)); glGenBuffers(max_separate_attribs, bufs); memset(initial_xfb_buffer_contents, 0, sizeof(initial_xfb_buffer_contents)); /* Main GL_TRANSFORM_FEEDBACK_BUFFER_BINDING should still be * set to its default value. */ CHECK_INTEGER(GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, 0); /* Set up buffers. */ for (i = 0; i < max_separate_attribs; ++i) { printf("BindBuffer(TRANSFORM_FEEDBACK_BUFFER, %u)\n", bufs[i]); glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, bufs[i]); CHECK_INTEGER(GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, bufs[i]); glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, sizeof(initial_xfb_buffer_contents), initial_xfb_buffer_contents, GL_STREAM_READ); } /* Indexed bindings should still be set to their default values. */ for (i = 0; i < max_separate_attribs; ++i) { CHECK_INDEXED(GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, i, 0); CHECK_INDEXED(GL_TRANSFORM_FEEDBACK_BUFFER_START, i, 0); CHECK_INDEXED(GL_TRANSFORM_FEEDBACK_BUFFER_SIZE, i, 0); } /* Bind buffers, setting various offsets and sizes. */ for (i = 0; i < max_separate_attribs; ++i) { int offset = 4 * (i % 4); int size = 4 * ((i % 3) + 1); printf("BindBufferRange(TRANSFORM_FEEDBACK_BUFFER, %i, %u, %i, %i)\n", i, bufs[i], offset, size); piglit_BindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, i, bufs[i], offset, size); CHECK_INTEGER(GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, bufs[i]); } /* Check indexed bindings. */ for (i = 0; i < max_separate_attribs; ++i) { int offset = 4 * (i % 4); int size = 4 * ((i % 3) + 1); CHECK_INDEXED(GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, i, bufs[i]); CHECK_INDEXED(GL_TRANSFORM_FEEDBACK_BUFFER_START, i, offset); CHECK_INDEXED(GL_TRANSFORM_FEEDBACK_BUFFER_SIZE, i, size); } return pass; }
static GLboolean test(int bind_size, int num_varyings, int num_primitives, int mode_index) { float initial_xfb_buf[XFB_BUFFER_SIZE]; float vertex_data[MAX_VERTICES]; int i, j; int vertices_per_prim = mode_vertices_per_prim[mode_index]; int expected_primitives_written = MIN2(num_primitives, bind_size / num_varyings / vertices_per_prim); int expected_vertices_written = expected_primitives_written * vertices_per_prim; GLuint query_result; GLboolean pass = GL_TRUE; float expected_xfb_results[XFB_BUFFER_SIZE]; float *readback; 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 */ piglit_UseProgram(progs[num_varyings - 1]); for (i = 0; i < MAX_VERTICES; ++i) vertex_data[i] = i; glVertexAttribPointer(0, 1, GL_FLOAT, GL_FALSE, sizeof(float), &vertex_data); glEnableVertexAttribArray(0); for (i = 0; i < XFB_BUFFER_SIZE; ++i) initial_xfb_buf[i] = 0.0; glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, xfb_buf); glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, sizeof(initial_xfb_buf), initial_xfb_buf, GL_STREAM_READ); piglit_BindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, xfb_buf, 0, sizeof(float) * bind_size); /* Start queries and XFB */ glBeginQuery(GL_PRIMITIVES_GENERATED, query_prims_generated); glBeginQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, query_prims_written); piglit_BeginTransformFeedback(modes[mode_index]); /* Draw */ glDrawArrays(modes[mode_index], 0, num_primitives * vertices_per_prim); /* Stop XFB and check queries */ piglit_EndTransformFeedback(); glEndQuery(GL_PRIMITIVES_GENERATED); glGetQueryObjectuiv(query_prims_generated, GL_QUERY_RESULT, &query_result); if (query_result != num_primitives) { printf("\n Expected %u primitives generated, got %u\n", (unsigned) num_primitives, query_result); pass = GL_FALSE; } glEndQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN); glGetQueryObjectuiv(query_prims_written, GL_QUERY_RESULT, &query_result); if (query_result != expected_primitives_written) { printf("\n Expected %u primitives written, got %u", (unsigned) expected_primitives_written, query_result); pass = GL_FALSE; } /* Check transform feedback buffer */ memcpy(expected_xfb_results, initial_xfb_buf, sizeof(initial_xfb_buf)); for (i = 0; i < expected_vertices_written; ++i) { for (j = 0; j < num_varyings; ++j) { expected_xfb_results[i * num_varyings + j] = 100.0 * (j + 1) + i; } } readback = glMapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY); for (i = 0; i < XFB_BUFFER_SIZE; ++i) { if (expected_xfb_results[i] != readback[i]) { printf("\n Expected buf[%i] = %f, got %f", i, expected_xfb_results[i], readback[i]); pass = GL_FALSE; } } if (pass) printf("PASS\n"); else printf(" FAIL\n"); return pass; }
void piglit_init(int argc, char **argv) { GLuint vs; unsigned i; float data[BUF_FLOATS]; for (i = 0; i < BUF_FLOATS; i++) { data[i] = DEFAULT_VALUE; } /* Parse params. */ for (i = 1; i < argc; i++) { if (!strcmp(argv[i], "discard")) { discard = GL_TRUE; } else if (!strcmp(argv[i], "offset")) { /* BindBufferOffset only exists in the EXT specification */ piglit_require_extension("GL_EXT_transform_feedback"); offset = OFFSET; } else if (!strcmp(argv[i], "range")) { offset = OFFSET; range = MAX_RANGE-7; } else if (!strcmp(argv[i], "render")) { test = RENDER; } else if (!strcmp(argv[i], "primgen")) { test = PRIMGEN; } else if (!strcmp(argv[i], "primwritten")) { test = PRIMWRITTEN; } } piglit_ortho_projection(piglit_width, piglit_height, GL_FALSE); /* Check the driver. */ if (piglit_get_gl_version() < 15) { fprintf(stderr, "OpenGL 1.5 required.\n"); piglit_report_result(PIGLIT_SKIP); } piglit_require_GLSL(); piglit_require_transform_feedback(); /* Create shaders. */ vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vstext); prog = piglit_CreateProgram(); piglit_AttachShader(prog, vs); piglit_TransformFeedbackVaryings(prog, 1, varyings, GL_INTERLEAVED_ATTRIBS_EXT); piglit_LinkProgram(prog); if (!piglit_link_check_status(prog)) { piglit_DeleteProgram(prog); piglit_report_result(PIGLIT_FAIL); } vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vspassthrough); prog_passthrough = piglit_CreateProgram(); piglit_AttachShader(prog_passthrough, vs); piglit_TransformFeedbackVaryings(prog_passthrough, 1, varyings, GL_INTERLEAVED_ATTRIBS_EXT); piglit_LinkProgram(prog_passthrough); if (!piglit_link_check_status(prog_passthrough)) { piglit_DeleteProgram(prog_passthrough); piglit_report_result(PIGLIT_FAIL); } /* Set up the transform feedback buffer. */ glGenBuffers(1, &buf); glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER_EXT, buf); glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER_EXT, BUF_FLOATS*sizeof(float), data, GL_STREAM_READ); assert(glGetError() == 0); if (range) { puts("Testing BindBufferRange."); piglit_BindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER_EXT, 0, buf, offset*sizeof(float), range*sizeof(float)); } else if (offset) { puts("Testing BindBufferOffset."); glBindBufferOffsetEXT(GL_TRANSFORM_FEEDBACK_BUFFER_EXT, 0, buf, offset*sizeof(float)); } else { puts("Testing BindBufferBase."); piglit_BindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER_EXT, 0, buf); } if (!range) { range = MAX_RANGE; } else { range = MAX_RANGE/2; /* just one primitive is going to be written */ } assert(glGetError() == 0); glClearColor(0.2, 0.2, 0.2, 1.0); glEnableClientState(GL_VERTEX_ARRAY); }