static void do_bind(const struct test_desc *test, GLuint buf, int i) { int size = test->mode == BIND_BAD_SIZE ? test->param : sizeof(float[XFB_BUFFER_SIZE]); int offset = test->mode == BIND_BAD_OFFSET ? test->param : 0; switch (test->bind_mode) { case BASE: printf("BindBufferBase(buffer %i)\n", i); glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, i, buf); break; case RANGE: printf("BindBufferRange(buffer %i, offset=%i, size=%i)\n", i, offset, size); glBindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, i, buf, offset, size); break; case OFFSET: printf("BindBufferOffsetEXT(buffer %i, offset=%i)\n", i, offset); glBindBufferOffsetEXT(GL_TRANSFORM_FEEDBACK_BUFFER, i, buf, offset); break; } }
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_EXTTransformFeedback_glBindBufferOffsetEXT(JNIEnv *__env, jclass clazz, jint target, jint index, jint buffer, jlong offset) { glBindBufferOffsetEXTPROC glBindBufferOffsetEXT = (glBindBufferOffsetEXTPROC)tlsGetFunction(1826); UNUSED_PARAM(clazz) glBindBufferOffsetEXT(target, index, buffer, (intptr_t)offset); }
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_EXTTransformFeedback_nglBindBufferOffsetEXT(JNIEnv *env, jclass clazz, jint target, jint index, jint buffer, jlong offset, jlong function_pointer) { glBindBufferOffsetEXTPROC glBindBufferOffsetEXT = (glBindBufferOffsetEXTPROC)((intptr_t)function_pointer); glBindBufferOffsetEXT(target, index, buffer, offset); }
enum piglit_result piglit_display(void) { GLint input_index = glGetAttribLocation(prog, "input_value"); GLfloat canary_data[MAX_BUFFER_SIZE_FLOATS]; GLfloat input_data[MAX_BUFFER_SIZE_FLOATS]; GLfloat expected_data[MAX_BUFFER_SIZE_FLOATS]; GLfloat *output_data; GLuint query_result; GLboolean pass = GL_TRUE; unsigned i; glUseProgram(prog); /* Create a transform feedback buffer. */ glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, xfb_buf); glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, selected_test->initial_size * sizeof(GLfloat), NULL, GL_STREAM_READ); /* Bind the buffer for transform feedback. */ if (selected_test->bind_size != 0) { glBindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, xfb_buf, selected_test->bind_offset * sizeof(GLfloat), selected_test->bind_size * sizeof(GLfloat)); } else if (selected_test->bind_offset != 0) { glBindBufferOffsetEXT(GL_TRANSFORM_FEEDBACK_BUFFER, 0, xfb_buf, selected_test->bind_offset * sizeof(GLfloat)); } else { glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, xfb_buf); } /* Change the size of the bound buffer. */ for (i = 0; i < MAX_BUFFER_SIZE_FLOATS; i++) canary_data[i] = -1; glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, selected_test->new_size * sizeof(GLfloat), canary_data, GL_STREAM_READ); /* Draw some triangles. */ for (i = 0; i < MAX_BUFFER_SIZE_FLOATS; i++) input_data[i] = i + 1; glBindBuffer(GL_ARRAY_BUFFER, 0); glVertexAttribPointer(input_index, 1, GL_FLOAT, GL_FALSE, sizeof(GLfloat), input_data); glEnableVertexAttribArray(input_index); glBeginTransformFeedback(GL_TRIANGLES); glBeginQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, query); glDrawArrays(GL_TRIANGLES, 0, selected_test->num_draw_triangles * 3); glEndQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN); glEndTransformFeedback(); /* Verify that the expected number of primitives were * written. */ glGetQueryObjectuiv(query, GL_QUERY_RESULT, &query_result); printf("PRIMITIVES_WRITTEN: expected=%u, actual=%u\n", selected_test->num_feedback_triangles, query_result); if (query_result != selected_test->num_feedback_triangles) pass = GL_FALSE; /* Verify that the expected data was written. */ for (i = 0; i < selected_test->new_size; i++) { if (i >= selected_test->bind_offset && i < (3 * selected_test->num_feedback_triangles + selected_test->bind_offset)) { expected_data[i] = 100.0 + input_data[i - selected_test->bind_offset]; } else { expected_data[i] = canary_data[i]; } } output_data = glMapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY); for (i = 0; i < selected_test->new_size; ++i) { printf("data[%u]: expected=%f, actual=%f\n", i, expected_data[i], output_data[i]); if (expected_data[i] != output_data[i]) pass = GL_FALSE; } glUnmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER); piglit_present_results(); return 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); }