void piglit_init(int argc, char **argv) { GLuint vs; GLint maxcomps, maxattrs; unsigned i; 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(); glGetIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_EXT, &maxattrs); if (maxattrs < 4) { fprintf(stderr, "Not enough separate attribs supported by transform feedback.\n"); piglit_report_result(PIGLIT_SKIP); } glGetIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS_EXT, &maxcomps); if (maxcomps < 4) { fprintf(stderr, "Not enough separate components supported by transform feedback.\n"); piglit_report_result(PIGLIT_SKIP); } /* Create shaders. */ vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vstext); prog = piglit_CreateProgram(); piglit_AttachShader(prog, vs); piglit_TransformFeedbackVaryings(prog, sizeof(varyings)/sizeof(varyings[0]), varyings, GL_SEPARATE_ATTRIBS_EXT); piglit_LinkProgram(prog); if (!piglit_link_check_status(prog)) { piglit_DeleteProgram(prog); piglit_report_result(PIGLIT_FAIL); } /* Set up the transform feedback buffer. */ glGenBuffers(4, buf); for (i = 0; i < 4; i++) { unsigned j; float *ptr; glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER_EXT, buf[i]); glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER_EXT, NUM_OUT_VERTICES*4*sizeof(float), NULL, GL_STREAM_READ); ptr = glMapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER_EXT, GL_WRITE_ONLY); for (j = 0; j < NUM_OUT_VERTICES*4; j++) { ptr[j] = 0.123456; } glUnmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER_EXT); piglit_BindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER_EXT, i, buf[i]); } assert(glGetError() == 0); glClearColor(0.2, 0.2, 0.2, 1.0); glEnableClientState(GL_VERTEX_ARRAY); }
static void draw() { static const GLenum bo_modes[] = { GL_STREAM_DRAW, GL_STREAM_READ, GL_STREAM_COPY, GL_STATIC_DRAW, GL_STATIC_READ, GL_STATIC_COPY, GL_DYNAMIC_DRAW, GL_DYNAMIC_READ, GL_DYNAMIC_COPY, }; int i; bool pass = true; glEnable(GL_RASTERIZER_DISCARD); for (i = 0; i < ARRAY_SIZE(bo_modes); i++) { static GLuint xfb_buf; float *readback; /* Make a new TFB output buffer with the chosen usage * mode. Note, from ARB_vertex_buffer_object: * * "The specified usage value does not constrain * the actual usage pattern of the data store." */ glGenBuffers(1, &xfb_buf); glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, xfb_buf); glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, sizeof(float), NULL, bo_modes[i]); piglit_BindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, xfb_buf); /* Do the draw call. Here's where we segfaulted before. */ piglit_BeginTransformFeedback(GL_POINTS); glDrawArrays(GL_POINTS, 0, 1); piglit_EndTransformFeedback(); /* Test the output, just to be sure. */ readback = glMapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY); if (readback[0] != 1.0) { fprintf(stderr, "Readback found %f, expected 1.0\n", readback[0]); pass = false; } glUnmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER); glDeleteBuffers(1, &xfb_buf); } piglit_report_result(pass ? PIGLIT_PASS : PIGLIT_FAIL); }
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); }