enum piglit_result piglit_display(void) { GLuint vs, fs; bool pass = true; GLuint prog; float green[] = {0.0, 1.0, 0.0, 0.0}; GLint status; /* Initial buffer clear. */ glClearColor(1.0, 0.0, 0.0, 0.0); glClear(GL_COLOR_BUFFER_BIT); vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vs_source); fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, fs_source); prog = piglit_link_simple_program(vs, fs); if (!vs || !fs || !prog) piglit_report_result(PIGLIT_FAIL); piglit_DeleteShader(vs); piglit_DeleteShader(fs); piglit_UseProgram(prog); piglit_DeleteProgram(prog); /* Try to blow out the refcount */ piglit_DeleteProgram(prog); piglit_DeleteProgram(prog); piglit_DeleteProgram(prog); /* Sanity check: deleting didn't already unbind our shader program. */ piglit_draw_rect(-1, -1, 2, 2); pass = piglit_probe_rect_rgba(0, 0, piglit_width, piglit_height, green) && pass; /* The program should still report being deleted. */ piglit_GetProgramiv(prog, GL_DELETE_STATUS, &status); if (!piglit_check_gl_error(0)) piglit_report_result(PIGLIT_FAIL); if (status != GL_TRUE) { fprintf(stderr, "GL_DELETE_STATUS after a clear reported non-true %d\n", status); pass = false; } /* Now, disable the program and it should be finally deleted. */ piglit_UseProgram(0); piglit_GetProgramiv(prog, GL_DELETE_STATUS, &status); pass = piglit_check_gl_error(GL_INVALID_VALUE) && pass; piglit_present_results(); return pass ? PIGLIT_PASS : PIGLIT_FAIL; }
void piglit_init(int argc, char **argv) { int vs, fs, prog; int tex_location; piglit_require_GLSL_version(130); glActiveTexture(GL_TEXTURE0); piglit_rgbw_texture(GL_RGBA, tex_size, tex_size / 2, true, false, GL_UNSIGNED_NORMALIZED); piglit_ortho_projection(piglit_width, piglit_height, false); vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vert); fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, frag); prog = piglit_link_simple_program(vs, fs); tex_location = piglit_GetUniformLocation(prog, "tex"); lod_location = piglit_GetUniformLocation(prog, "lod"); pos_location = piglit_GetUniformLocation(prog, "pos"); piglit_UseProgram(prog); piglit_Uniform1i(tex_location, 0); }
void setup_glsl_programs() { GLuint vs; GLuint fs; GLuint prog; char vert[4096]; char frag[4096]; char *version_directive; if (use_glsl_130) { version_directive = "#version 130"; } else { version_directive = ""; } sprintf(vert, "%s\n" "uniform float position_angle;\n" "uniform float clipVertex_angle;\n" "mat4 rotate(float angle)\n" "{\n" " angle = radians(angle);\n" " return mat4( cos(angle), sin(angle), 0.0, 0.0,\n" " -sin(angle), cos(angle), 0.0, 0.0,\n" " 0.0, 0.0, 1.0, 0.0,\n" " 0.0, 0.0, 0.0, 1.0);\n" "}\n" "void main()\n" "{\n" "%s\n" "}", version_directive, setters); sprintf(frag, "%s\n" "void main()\n" "{\n" " gl_FragColor = vec4(1.0);\n" "}", version_directive); vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vert); fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, frag); prog = piglit_CreateProgram(); piglit_AttachShader(prog, vs); piglit_AttachShader(prog, fs); piglit_LinkProgram(prog); piglit_DeleteShader(vs); piglit_DeleteShader(fs); piglit_UseProgram(prog); position_angle_loc = piglit_GetUniformLocation(prog, "position_angle"); if (use_clip_vertex) { clipVertex_angle_loc = piglit_GetUniformLocation(prog, "clipVertex_angle"); } }
void piglit_init(int argc, char **argv) { int prog; int tex_location; int i; enum shader_target test_stage = UNKNOWN; bool sampler_found = false; for (i = 1; i < argc; i++) { if (test_stage == UNKNOWN) { /* Maybe it's the shader stage? */ if (strcmp(argv[i], "vs") == 0) { test_stage = VS; continue; } else if (strcmp(argv[i], "fs") == 0) { test_stage = FS; continue; } } if (strcmp(argv[i], "140") == 0) { shader_version = 140; continue; } /* Maybe it's the sampler type? */ if (!sampler_found && (sampler_found = select_sampler(argv[i]))) continue; fail_and_show_usage(); } if (test_stage == UNKNOWN || !sampler_found) fail_and_show_usage(); /* Not implemented yet */ assert(sampler.target != GL_TEXTURE_CUBE_MAP_ARRAY); require_GL_features(test_stage); prog = generate_GLSL(test_stage); if (!prog) piglit_report_result(PIGLIT_FAIL); tex_location = piglit_GetUniformLocation(prog, "tex"); lod_location = piglit_GetUniformLocation(prog, "lod"); vertex_location = piglit_GetAttribLocation(prog, "vertex"); piglit_UseProgram(prog); piglit_Uniform1i(tex_location, 0); /* Create textures and set miplevel info */ set_base_size(); compute_miplevel_info(); generate_texture(); }
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; }
/** * Test drawing with GLSL shaders and no vertex arrays. * Use a vertex shader with a hard-coded vertex position. */ static GLboolean test_glsl_no_arrays(void) { static const char *noVertexVertShaderText = "varying vec4 colorVar; \n" "void main() \n" "{ \n" " colorVar = vec4(1.0, 1.0, 0.0, 1.0); \n" " gl_Position = vec4(0.0, 0.0, 0.0, 1.0); \n" "} \n"; static const char *fragShaderText = "varying vec4 colorVar; \n" "void main() \n" "{ \n" " gl_FragColor = colorVar; \n" "} \n"; static const GLfloat expected[4] = {1.0, 1.0, 0.0, 1.0}; GLboolean p, pass = GL_TRUE; GLuint vertShader, fragShader, program; vertShader = piglit_compile_shader_text(GL_VERTEX_SHADER, noVertexVertShaderText); fragShader = piglit_compile_shader_text(GL_FRAGMENT_SHADER, fragShaderText); program = piglit_link_simple_program(vertShader, fragShader); piglit_UseProgram(program); glClear(GL_COLOR_BUFFER_BIT); glPointSize(3.0); glDrawArrays(GL_POINTS, 0, 1); glPointSize(1.0); p = piglit_probe_pixel_rgba(piglit_width/2, piglit_height/2, expected); glutSwapBuffers(); if (!p) { printf("%s: failed when drawing with GLSL and no vertex arrays\n", TestName); pass = GL_FALSE; } piglit_DeleteShader(vertShader); piglit_DeleteProgram(program); return pass; }
void piglit_init(int argc, char **argv) { int vs, fs, prog; piglit_require_GLSL_version(130); vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vs_source); fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, fs_source); prog = piglit_link_simple_program(vs, fs); if (!vs || !fs || !prog) piglit_report_result(PIGLIT_FAIL); coord1_location = piglit_GetUniformLocation(prog, "coord1"); coord2_location = piglit_GetUniformLocation(prog, "coord2"); piglit_UseProgram(prog); }
void piglit_init(int argc, char **argv) { GLuint vs; GLuint fs; piglit_require_GLSL(); piglit_require_GLSL_version(130); vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vert); fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, frag); prog = piglit_CreateProgram(); piglit_AttachShader(prog, vs); piglit_AttachShader(prog, fs); piglit_LinkProgram(prog); piglit_DeleteShader(vs); piglit_DeleteShader(fs); piglit_UseProgram(prog); }
static void initialize_shader_and_xfb() { GLuint prog, vs; const char *varying = "tf"; piglit_require_gl_version(30); piglit_require_GLSL_version(130); piglit_require_transform_feedback(); vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vstext); prog = piglit_CreateProgram(); piglit_AttachShader(prog, vs); piglit_TransformFeedbackVaryings(prog, 1, &varying, GL_INTERLEAVED_ATTRIBS); piglit_LinkProgram(prog); if (!piglit_link_check_status(prog)) { piglit_DeleteProgram(prog); piglit_report_result(PIGLIT_FAIL); } piglit_UseProgram(prog); }
enum piglit_result piglit_display(void) { GLboolean pass = GL_TRUE; static const float verts[] = { 10, 10, 10, 20, 20, 20, 20, 10 }; static const float v3[] = {0.55, 0.66, 0.77}; static const float frontcolor[] = {1.0, 0.9, 0.8, 0.7}; static const float v2[] = {0.2, 0.7}; static const float texcoord1[] = {0.6, 0.0, 0.1, 0.6}; glClear(GL_COLOR_BUFFER_BIT); /* Render into TFBO. */ glLoadIdentity(); piglit_UseProgram(prog); glEnable(GL_RASTERIZER_DISCARD); piglit_BeginTransformFeedback(GL_TRIANGLES); glVertexPointer(2, GL_FLOAT, 0, verts); glDrawArrays(GL_QUADS, 0, 4); piglit_EndTransformFeedback(); glDisable(GL_RASTERIZER_DISCARD); assert(glGetError() == 0); pass = probe_buffer(buf[0], 0, 3, v3) && pass; pass = probe_buffer(buf[1], 1, 4, frontcolor) && pass; pass = probe_buffer(buf[2], 2, 2, v2) && pass; pass = probe_buffer(buf[3], 3, 4, texcoord1) && pass; assert(glGetError() == 0); piglit_present_results(); return pass ? PIGLIT_PASS : PIGLIT_FAIL; }
/** * Draw quad with fragment shader that compares fragment.z against the * depth texture value (draw on left side of window). * We draw on the left side of the window to easily convert gl_FragCoord * into a texture coordinate. */ static void draw_sphere_with_fragment_shader_compare(void) { glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); glViewport(0 * SIZE, 0, SIZE, SIZE); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(-1.0, 1.0, -1.0, 1.0, -1, 1.0); glBindTexture(TexTarget, DepthTex); piglit_UseProgram(ShaderProg); glEnable(GL_DEPTH_TEST); if (1) { draw_sphere(); } else { /* To test using gl_TexCoord[0].xy instead of gl_FragCoord.xy in the shader */ static const GLfloat sPlane[4] = {0.5, 0, 0, 0.5}; static const GLfloat tPlane[4] = {0, 0.5, 0, 0.5}; glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR); glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR); glTexGenfv(GL_S, GL_EYE_PLANE, sPlane); glTexGenfv(GL_T, GL_EYE_PLANE, tPlane); glEnable(GL_TEXTURE_GEN_S); glEnable(GL_TEXTURE_GEN_T); draw_sphere(); glDisable(GL_TEXTURE_GEN_S); glDisable(GL_TEXTURE_GEN_T); } glDisable(GL_DEPTH_TEST); piglit_UseProgram(0); #if DEBUG { GLfloat *z = read_float_z_image(0, 0); GLfloat min, max, center; find_float_min_max_center(z, SIZE * SIZE, &min, &max, ¢er); printf("rendered min %f max %f center %f\n", min, max, center); free(z); } { GLuint *z = read_uint_z_image(0, 0); GLuint min, max, center; find_uint_min_max_center(z, SIZE * SIZE, &min, &max, ¢er); printf("rendered min 0x%x max 0x%x center 0x%x\n", min, max, center); free(z); } #endif /* DEBUG */ }
static void create_frag_shader(void) { /* This shader samples the currently bound depth texture, then compares * that value to the current fragment Z value to produce a shade of red * indicating error/difference. * * E.g: gl_FragColor = scale * abs(texture.Z - fragment.Z); * * Note that we have to be pretty careful with converting gl_FragCoord * into a 2D texture coordinate. There's a -0.5 bias and scale factor. */ static const char *text_2d = "uniform sampler2D zTex; \n" "uniform float sizeScale; \n" "uniform float errorScale; \n" "void main() \n" "{ \n" " vec2 coord = (gl_FragCoord.xy - vec2(0.5)) / sizeScale; \n" " vec4 z = texture2D(zTex, coord); \n" " float diff = errorScale * abs(z.r - gl_FragCoord.z); \n" " //gl_FragColor = vec4(gl_FragCoord.z, 0, 0, 0); \n" " //gl_FragColor = z; \n" " gl_FragColor = vec4(diff, 0, 0, 0); \n" " gl_FragDepth = gl_FragCoord.z; \n" "} \n"; static const char *text_rect = "#extension GL_ARB_texture_rectangle: require \n" "uniform sampler2DRect zTex; \n" "uniform float sizeScale; \n" "uniform float errorScale; \n" "void main() \n" "{ \n" " vec2 coord = gl_FragCoord.xy; \n" " vec4 z = texture2DRect(zTex, coord); \n" " float diff = errorScale * abs(z.r - gl_FragCoord.z); \n" " //gl_FragColor = vec4(gl_FragCoord.z, 0, 0, 0); \n" " //gl_FragColor = z; \n" " gl_FragColor = vec4(diff, 0, 0, 0); \n" " gl_FragDepth = gl_FragCoord.z; \n" "} \n"; GLuint fs; GLint zTex, errorScale, sizeScale; if (TexTarget == GL_TEXTURE_2D) fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, text_2d); else fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, text_rect); assert(fs); ShaderProg = piglit_link_simple_program(0, fs); assert(ShaderProg); piglit_UseProgram(ShaderProg); zTex = piglit_GetUniformLocation(ShaderProg, "zTex"); piglit_Uniform1i(zTex, 0); /* unit 0 */ errorScale = piglit_GetUniformLocation(ShaderProg, "errorScale"); piglit_Uniform1f(errorScale, ErrorScale); sizeScale = piglit_GetUniformLocation(ShaderProg, "sizeScale"); piglit_Uniform1f(sizeScale, (float) (SIZE - 1)); piglit_UseProgram(0); }
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; }
/** Test drawing with GLSL shaders */ static GLboolean test_glsl_arrays(void) { static const char *vertShaderText = "attribute vec4 color, pos; \n" "varying vec4 colorVar; \n" "void main() \n" "{ \n" " colorVar = color; \n" " gl_Position = gl_ModelViewProjectionMatrix * pos; \n" "} \n"; static const char *fragShaderText = "varying vec4 colorVar; \n" "void main() \n" "{ \n" " gl_FragColor = colorVar; \n" "} \n"; static const GLfloat expected[4] = {0.5, 0.0, 0.5, 1.0}; GLuint buf; GLboolean p, pass = GL_TRUE; GLint posAttrib, colorAttrib; GLuint vertShader, fragShader, program; buf = setup_vbo(); glBindBufferARB(GL_ARRAY_BUFFER_ARB, buf); vertShader = piglit_compile_shader_text(GL_VERTEX_SHADER, vertShaderText); fragShader = piglit_compile_shader_text(GL_FRAGMENT_SHADER, fragShaderText); program = piglit_link_simple_program(vertShader, fragShader); piglit_UseProgram(program); /* * Draw with compiler-assigned attribute locations */ { posAttrib = piglit_GetAttribLocation(program, "pos"); colorAttrib = piglit_GetAttribLocation(program, "color"); if (0) printf("%s: GLSL posAttrib = %d colorAttrib = %d\n", TestName, posAttrib, colorAttrib); glVertexAttribPointerARB(posAttrib, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), (void *) 0); glVertexAttribPointerARB(colorAttrib, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (void *) (8 * sizeof(GLfloat))); glEnableVertexAttribArrayARB(posAttrib); glEnableVertexAttribArrayARB(colorAttrib); glClear(GL_COLOR_BUFFER_BIT); glDrawArrays(GL_QUADS, 0, 4); p = piglit_probe_pixel_rgba(piglit_width/2, piglit_height/2, expected); glutSwapBuffers(); if (!p) { printf("%s: failed when drawing with ", TestName); printf("compiler-assigned attribute locations\n"); pass = GL_FALSE; } glDisableVertexAttribArrayARB(posAttrib); glDisableVertexAttribArrayARB(colorAttrib); } /* * Draw with user-defined attribute bindings, not using 0. */ { posAttrib = 5; colorAttrib = 7; piglit_BindAttribLocation(program, posAttrib, "pos"); piglit_BindAttribLocation(program, colorAttrib, "color"); piglit_LinkProgram(program); glVertexAttribPointerARB(posAttrib, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), (void *) 0); glVertexAttribPointerARB(colorAttrib, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (void *) (8 * sizeof(GLfloat))); glEnableVertexAttribArrayARB(posAttrib); glEnableVertexAttribArrayARB(colorAttrib); glClear(GL_COLOR_BUFFER_BIT); glDrawArrays(GL_QUADS, 0, 4); p = piglit_probe_pixel_rgba(piglit_width/2, piglit_height/2, expected); glutSwapBuffers(); if (!p) { printf("%s: failed when drawing with ", TestName); printf("user-assigned attribute locations\n"); pass = GL_FALSE; } glDisableVertexAttribArrayARB(posAttrib); glDisableVertexAttribArrayARB(colorAttrib); } piglit_DeleteShader(vertShader); piglit_DeleteProgram(program); glDeleteBuffersARB(1, &buf); return pass; }
enum piglit_result piglit_display(void) { GLboolean pass = GL_TRUE; GLuint q; float *ptr; unsigned i, qresult; static const float verts[] = { 10, 10, 10, 20, 20, 20, 20, 10 }; static const float expected[] = { -0.687500, -0.375000, 0.000000, 1.000000, -0.687500, 0.250000, 0.000000, 1.000000, -0.375000, -0.375000, 0.000000, 1.000000, -0.687500, 0.250000, 0.000000, 1.000000, -0.375000, 0.250000, 0.000000, 1.000000, -0.375000, -0.375000, 0.000000, 1.000000, }; static const unsigned indices[] = { 0, 1, 3, 1, 2, 3 }; static const float clearcolor[] = {0.2, 0.2, 0.2}; static const float white[] = {1, 1, 1}; static const float red[] = {1, 0, 0}; glClear(GL_COLOR_BUFFER_BIT); /* Set up queries. */ switch (test) { case PRIMGEN: glGenQueries(1, &q); glBeginQuery(GL_PRIMITIVES_GENERATED_EXT, q); break; case PRIMWRITTEN: glGenQueries(1, &q); glBeginQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_EXT, q); break; } /* Render into TFBO. */ glLoadIdentity(); piglit_UseProgram(prog); if (discard) glEnable(GL_RASTERIZER_DISCARD_EXT); piglit_BeginTransformFeedback(GL_TRIANGLES); glBindBuffer(GL_ARRAY_BUFFER, 0); glVertexPointer(2, GL_FLOAT, 0, verts); glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, indices); piglit_EndTransformFeedback(); if (discard) glDisable(GL_RASTERIZER_DISCARD_EXT); assert(glGetError() == 0); switch (test) { case READBACK: puts("Testing readback."); ptr = glMapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER_EXT, GL_READ_ONLY); for (i = 0; i < BUF_FLOATS; i++) { float value = i >= offset && i < offset+range ? expected[i-offset] : DEFAULT_VALUE; //printf("%f, ", ptr[i]); if (fabs(ptr[i] - value) > 0.01) { printf("Buffer[%i]: %f, Expected: %f\n", i, ptr[i], value); pass = GL_FALSE; } } glUnmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER_EXT); break; case RENDER: puts("Testing rendering."); piglit_UseProgram(prog_passthrough); glBindBuffer(GL_ARRAY_BUFFER, buf); glVertexPointer(4, GL_FLOAT, 0, (void*)(intptr_t)(offset * sizeof(float))); glDrawArrays(GL_TRIANGLES, 0, range == MAX_RANGE ? 6 : 3); pass = piglit_probe_pixel_rgb(33, 18, range == MAX_RANGE ? red : clearcolor) && pass; pass = piglit_probe_pixel_rgb(28, 12, red) && pass; break; case PRIMGEN: puts("Testing a primitives-generated query."); glEndQuery(GL_PRIMITIVES_GENERATED_EXT); glGetQueryObjectuiv(q, GL_QUERY_RESULT, &qresult); { int expected = 2; /* RASTERIZER_DISCARD should not affect this. */ if (qresult != expected) { printf("Primitives generated: %i, Expected: %i\n", qresult, expected); pass = GL_FALSE; } } break; case PRIMWRITTEN: puts("Testing a primitives-written query."); glEndQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_EXT); glGetQueryObjectuiv(q, GL_QUERY_RESULT, &qresult); { int expected = range == MAX_RANGE ? 2 : 1; if (qresult != expected) { printf("Primitives written: %i, Expected: %i\n", qresult, expected); pass = GL_FALSE; } } break; default: piglit_report_result(PIGLIT_SKIP); } pass = piglit_probe_pixel_rgb(5, 5, clearcolor) && pass; pass = piglit_probe_pixel_rgb(15, 15, discard ? clearcolor : white) && pass; assert(glGetError() == 0); piglit_present_results(); return pass ? PIGLIT_PASS : PIGLIT_FAIL; }
void piglit_init(int argc, char **argv) { static const float uniform_data[4] = { 12.0, 0.5, 3.14169, 42.0 }; GLint vs; GLint fs; unsigned i; union data_blob buffer[16]; piglit_require_vertex_shader(); piglit_require_fragment_shader(); vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vs_text); fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, fs_text); prog = piglit_link_simple_program(vs, fs); piglit_UseProgram(prog); base_location = piglit_GetUniformLocation(prog, "c"); if (base_location < 0) { printf("Could not get location of `c'.\n"); piglit_report_result(PIGLIT_FAIL); } for (i = 0; i < 4; i++) { char name[5]; name[0] = 'c'; name[1] = '['; name[2] = '0' + i; name[3] = ']'; name[4] = '\0'; array_location[i] = piglit_GetUniformLocation(prog, name); if (array_location[i] < 0) { printf("Could not get location of `%s'.\n", name); piglit_report_result(PIGLIT_FAIL); } } /* From page 80 of the OpenGL 2.1 spec: * * The first element of a uniform array is identified using the * name of the uniform array appended with "[0]". Except if the * last part of the string name indicates a uniform array, then * the location of the first element of that array can be * retrieved by either using the name of the uniform array, or the * name of the uniform array appended with "[0]". */ if (base_location != array_location[0]) { printf("Locations of `c' = %d and `c[0]' = %d, but they " "should be the same.\n", base_location, array_location[0]); piglit_report_result(PIGLIT_FAIL); } piglit_Uniform1fv(base_location, 4, uniform_data); /* From page 264 of the OpenGL 2.1 spec: * * In order to query the values of an array of uniforms, a * GetUniform* command needs to be issued for each array element. * * This means that querying using the location of 'array' is the same * as 'array[0]'. */ printf("Getting array element 0 from base location...\n"); for (i = 0; i < ARRAY_SIZE(buffer); i++) { buffer[i].u = 0xdeadbeef; } piglit_GetUniformfv(prog, base_location, (GLfloat *) buffer); validate_buffer(buffer, ARRAY_SIZE(buffer), uniform_data[0]); printf("Getting one array element at a time...\n"); for (i = 0; i < 4; i++) { unsigned j; for (j = 0; j < ARRAY_SIZE(buffer); j++) { buffer[j].u = 0xdeadbeef; } piglit_GetUniformfv(prog, array_location[i], (GLfloat *) buffer); validate_buffer(buffer, ARRAY_SIZE(buffer), uniform_data[i]); } piglit_report_result(PIGLIT_PASS); }