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); }
/** 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); glUseProgram(program); /* * Draw with compiler-assigned attribute locations */ { posAttrib = glGetAttribLocation(program, "pos"); colorAttrib = glGetAttribLocation(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); piglit_present_results(); 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; glBindAttribLocation(program, posAttrib, "pos"); glBindAttribLocation(program, colorAttrib, "color"); glLinkProgram(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); piglit_present_results(); if (!p) { printf("%s: failed when drawing with ", TestName); printf("user-assigned attribute locations\n"); pass = GL_FALSE; } glDisableVertexAttribArrayARB(posAttrib); glDisableVertexAttribArrayARB(colorAttrib); } glDeleteShader(vertShader); glDeleteProgram(program); glDeleteBuffersARB(1, &buf); return pass; }
static void test_error_cases(bool *pass) { GLenum props[] = {GL_NAME_LENGTH}; GLenum props_invalid[] = {GL_NAME_LENGTH, GL_TRUE, GL_TYPE}; GLenum props_error[] = {GL_NAME_LENGTH, GL_OFFSET, GL_TYPE}; int values[10]; GLuint shader; bool prg_tst; /* test using an unexisting program ID */ glGetProgramResourceiv(1337, GL_UNIFORM, 0, 1, props, 10, NULL, values); prg_tst = piglit_check_gl_error(GL_INVALID_VALUE); *pass = *pass && prg_tst; piglit_report_subtest_result(prg_tst ? PIGLIT_PASS : PIGLIT_FAIL, "Invalid program (undefined ID)"); /* test using a shader ID */ shader = piglit_compile_shader_text(GL_VERTEX_SHADER, vs_empty); glGetProgramResourceIndex(shader, GL_UNIFORM, "resource"); prg_tst = piglit_check_gl_error(GL_INVALID_OPERATION); *pass = *pass && prg_tst; piglit_report_subtest_result(prg_tst ? PIGLIT_PASS : PIGLIT_FAIL, "Invalid program (call on shader)"); /* invalid index. This is unspecified but let's check it is consistent * with GetProgramResourceName. */ glGetProgramResourceiv(prog_std, GL_UNIFORM, 1337, 0, props, 10, NULL, values); prg_tst = piglit_check_gl_error(GL_INVALID_VALUE); *pass = *pass && prg_tst; piglit_report_subtest_result(prg_tst ? PIGLIT_PASS : PIGLIT_FAIL, "Invalid index"); /* test propcount == 0 */ glGetProgramResourceiv(prog_std, GL_UNIFORM, 0, 0, props, 10, NULL, values); prg_tst = piglit_check_gl_error(GL_INVALID_VALUE); *pass = *pass && prg_tst; piglit_report_subtest_result(prg_tst ? PIGLIT_PASS : PIGLIT_FAIL, "<propcount> == 0"); /* test propcount < 0 */ glGetProgramResourceiv(prog_std, GL_UNIFORM, 0, -1, props, 10, NULL, values); prg_tst = piglit_check_gl_error(GL_INVALID_VALUE); *pass = *pass && prg_tst; piglit_report_subtest_result(prg_tst ? PIGLIT_PASS : PIGLIT_FAIL, "<propcount> < 0"); /* one invalid property */ glGetProgramResourceiv(prog_std, GL_UNIFORM, 0, 3, props_invalid, 10, NULL, values); prg_tst = piglit_check_gl_error(GL_INVALID_ENUM); *pass = *pass && prg_tst; piglit_report_subtest_result(prg_tst ? PIGLIT_PASS : PIGLIT_FAIL, "prop == GL_TRUE"); /* property not acceptable for one program interface */ glGetProgramResourceiv(prog_std, GL_PROGRAM_INPUT, 0, 3, props_error, 10, NULL, values); prg_tst = piglit_check_gl_error(GL_INVALID_OPERATION); *pass = *pass && prg_tst; piglit_report_subtest_result(prg_tst ? PIGLIT_PASS : PIGLIT_FAIL, "GL_OFFSET on GL_PROGRAM_INPUT"); }
static GLboolean do_test(const struct test_desc *test) { GLuint vs; GLuint progs[2]; GLuint bufs[NUM_BUFFERS]; float initial_xfb_buffer_contents[XFB_BUFFER_SIZE]; GLboolean pass = GL_TRUE; int i; int num_varyings = test->mode == NO_VARYINGS ? 0 : test->num_buffers; GLint max_separate_attribs; glGetIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS, &max_separate_attribs); printf("MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTIBS=%i\n", max_separate_attribs); printf("Compile vertex shader\n"); vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vstext); if (test->mode == NOT_A_PROGRAM) { printf("Create a program and then delete it\n"); progs[0] = glCreateProgram(); glDeleteProgram(progs[0]); } else { progs[0] = glCreateProgram(); glAttachShader(progs[0], vs); } pass = piglit_check_gl_error(GL_NO_ERROR) && pass; printf("Setup transform feedback for %i varyings in %s mode\n", num_varyings, test->buffer_mode == GL_INTERLEAVED_ATTRIBS ? "interleaved" : "separate"); glTransformFeedbackVaryings(progs[0], num_varyings, varyings, test->buffer_mode); if (test->mode == NOT_A_PROGRAM) { pass = piglit_check_gl_error(GL_INVALID_VALUE) && pass; return pass; } printf("Link program\n"); glLinkProgram(progs[0]); pass = piglit_link_check_status(progs[0]) && pass; if (test->mode == USEPROG_ACTIVE || test->mode == LINK_OTHER_ACTIVE) { printf("Prepare 2nd program\n"); progs[1] = glCreateProgram(); glAttachShader(progs[1], vs); } if (test->mode == USEPROG_ACTIVE) { printf("Link 2nd program\n"); glLinkProgram(progs[1]); pass = piglit_link_check_status(progs[1]) && pass; } if (test->mode == SKIP_USE_PROGRAM) { printf("Don't use program\n"); } else { printf("Use program\n"); glUseProgram(progs[0]); } printf("Prepare %i buffers\n", test->num_buffers); glGenBuffers(test->num_buffers, bufs); memset(initial_xfb_buffer_contents, 0, sizeof(initial_xfb_buffer_contents)); for (i = 0; i < test->num_buffers; ++i) { glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, bufs[i]); glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, sizeof(initial_xfb_buffer_contents), initial_xfb_buffer_contents, GL_STREAM_READ); } switch (test->mode) { case BIND_MAX: do_bind(test, bufs[0], max_separate_attribs); pass = piglit_check_gl_error(GL_INVALID_VALUE) && pass; return pass; case BIND_BAD_SIZE: case BIND_BAD_OFFSET: do_bind(test, bufs[0], 0); pass = piglit_check_gl_error(GL_INVALID_VALUE) && pass; return pass; default: break; } for (i = 0; i < test->num_buffers; ++i) { if (test->mode == UNBOUND_BUFFER && i == test->param) { printf("Don't bind buffer %i\n", i); } else { do_bind(test, bufs[i], i); } } pass = piglit_check_gl_error(GL_NO_ERROR) && pass; if (test->mode == END_INACTIVE) { printf("EndTransformFeedback\n"); glEndTransformFeedback(); pass = piglit_check_gl_error(GL_INVALID_OPERATION) && pass; return pass; } printf("BeginTransformFeedback\n"); glBeginTransformFeedback(GL_POINTS); switch (test->mode) { case UNBOUND_BUFFER: case NO_VARYINGS: case SKIP_USE_PROGRAM: pass = piglit_check_gl_error(GL_INVALID_OPERATION) && pass; break; default: pass = piglit_check_gl_error(GL_NO_ERROR) && pass; break; } switch (test->mode) { case BEGIN_ACTIVE: printf("BeginTransformFeedback\n"); glBeginTransformFeedback(GL_POINTS); pass = piglit_check_gl_error(GL_INVALID_OPERATION) && pass; break; case USEPROG_ACTIVE: printf("Use new program\n"); glUseProgram(progs[1]); pass = piglit_check_gl_error(GL_INVALID_OPERATION) && pass; break; case LINK_CURRENT_ACTIVE: printf("Link current program\n"); glLinkProgram(progs[0]); pass = piglit_check_gl_error(GL_INVALID_OPERATION) && pass; break; case LINK_OTHER_ACTIVE: printf("Link 2nd program\n"); glLinkProgram(progs[1]); pass = piglit_check_gl_error(GL_NO_ERROR) && pass; break; case BIND_ACTIVE: do_bind(test, bufs[0], 0); pass = piglit_check_gl_error(GL_INVALID_OPERATION) && pass; break; default: break; } return pass; }
void piglit_init(int argc, char **argv) { bool pass = true; GLuint fs; GLuint save_index = 0xaaaaaaaa; const GLchar *one_uniform = "a"; const GLchar *uniform_names[] = {"a", "b", "c"}; bool found_index[3] = {false, false, false}; GLuint indices[3], index; int i; piglit_require_extension("GL_ARB_uniform_buffer_object"); fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, frag_shader_text); if (!fs) { printf("Failed to compile FS:\n%s", frag_shader_text); piglit_report_result(PIGLIT_FAIL); } prog = piglit_link_simple_program(0, fs); if (!prog) piglit_report_result(PIGLIT_FAIL); /* From the GL_ARB_uniform_buffer_object spec: * * "The error INVALID_VALUE is generated by GetUniformIndices, * GetActiveUniformsiv, GetActiveUniformName, GetUniformBlockIndex, * GetActiveUniformBlockiv, GetActiveUniformBlockName, and * UniformBlockBinding if <program> is not a value generated by GL. * * ... * * The error INVALID_VALUE is generated by GetUniformIndices and * GetActiveUniformsiv if <uniformCount> is less than zero. * * ... * * "If an error occurs, nothing is written to <uniformIndices>." */ index = save_index; glGetUniformIndices(prog, -1, &one_uniform, &index); if (!piglit_check_gl_error(GL_INVALID_VALUE)) { pass = false; } else if (index != save_index) { printf("Bad program uniform index: 0x%08x\n", index); printf(" Expected 0x%08x\n", save_index); pass = false; } index = save_index; glGetUniformIndices(0xd0d0, 1, &one_uniform, &index); if (!piglit_check_gl_error(GL_INVALID_VALUE)) { pass = false; } else if (index != save_index) { printf("Bad program uniform index: 0x%08x\n", index); printf(" Expected 0x%08x\n", save_index); pass = false; } glGetUniformIndices(prog, 3, uniform_names, indices); if (!piglit_check_gl_error(0)) piglit_report_result(PIGLIT_FAIL); for (i = 0; i < 3; i++) { printf("%s: index %d\n", uniform_names[i], indices[i]); if (indices[i] < 0 || indices[i] > 2 || found_index[indices[i]]) { printf("Expected consecutive numbers starting from 0\n"); pass = false; } found_index[indices[i]] = true; } piglit_report_result(pass ? PIGLIT_PASS : PIGLIT_FAIL); }
void piglit_init(int argc, char **argv) { bool pass = true; GLuint pipe; GLuint vs_prog; GLuint active_prog; GLuint unlinked_prog; GLuint shader; unsigned glsl_version; char *source; piglit_require_extension("GL_ARB_separate_shader_objects"); glsl_version = pick_a_glsl_version(); glGenProgramPipelines(1, &pipe); pass = piglit_check_gl_error(GL_NO_ERROR) && pass; glBindProgramPipeline(pipe); (void)!asprintf(&source, vs_code_template, glsl_version); vs_prog = glCreateShaderProgramv(GL_VERTEX_SHADER, 1, (const GLchar *const *) &source); pass = piglit_link_check_status(vs_prog) && pass; /* First, make a valid program active. */ glActiveShaderProgram(pipe, vs_prog); pass = piglit_check_gl_error(GL_NO_ERROR) && pass; /* Next, try to make an invalid program active and verify that the * correct error is generated. Also make sure the old program is * still active. * * Section 7.4 (Program Pipeline Objects) under ActiveShaderProgram of * the OpenGL 4.4 spec says: * * "An INVALID_VALUE error is generated if program is not zero and * is not the name of either a program or shader object." */ glActiveShaderProgram(pipe, ~vs_prog); pass = piglit_check_gl_error(GL_INVALID_VALUE) && pass; glGetProgramPipelineiv(pipe, GL_ACTIVE_PROGRAM, (GLint *) &active_prog); if (active_prog != vs_prog) { printf("glActiveShaderProgram with an invalid program name " "changed the active program state.\n"); pass = false; } else { glActiveShaderProgram(pipe, vs_prog); } /* Try the same thing with a valid shader object (that is not part of * a linked program). Verify that the correct error is generated, and * make sure the old program is still active. * * Section 7.4 (Program Pipeline Objects) under ActiveShaderProgram of * the OpenGL 4.4 spec says: * * "An INVALID_OPERATION error is generated if program is the name * of a shader object." */ shader = piglit_compile_shader_text(GL_VERTEX_SHADER, source); glActiveShaderProgram(pipe, shader); pass = piglit_check_gl_error(GL_INVALID_OPERATION) && pass; glGetProgramPipelineiv(pipe, GL_ACTIVE_PROGRAM, (GLint *) &active_prog); if (active_prog != vs_prog) { printf("glActiveShaderProgram with a shader object " "changed the active program state.\n"); pass = false; } else { glActiveShaderProgram(pipe, vs_prog); } /* Finally, try the same thing with a valid program that is not * linked. Verify that the correct error is generated, and make sure * the old program is still active. * * Section 7.4 (Program Pipeline Objects) under ActiveShaderProgram of * the OpenGL 4.4 spec says: * * "An INVALID_OPERATION error is generated if program is not zero * and has not been linked, or was last linked unsuccessfully." */ unlinked_prog = glCreateShaderProgramv(GL_VERTEX_SHADER, 1, (const GLchar *const *) &invalid_code); glActiveShaderProgram(pipe, unlinked_prog); pass = piglit_check_gl_error(GL_INVALID_OPERATION) && pass; glGetProgramPipelineiv(pipe, GL_ACTIVE_PROGRAM, (GLint *) &active_prog); if (active_prog != vs_prog) { printf("glActiveShaderProgram with an unlinked program " "changed the active program state.\n"); pass = false; } else { glActiveShaderProgram(pipe, vs_prog); } free(source); piglit_report_result(pass ? PIGLIT_PASS : PIGLIT_FAIL); }
int generate_GLSL(enum shader_target test_stage) { int vs, fs; static char *vs_code; static char *fs_code; char *lod_arg; static const char *zeroes[3] = { "", "0, ", "0, 0, " }; const int size = sampler_size(); /* The GLSL 1.40 sampler2DRect/samplerBuffer samplers don't * take a lod argument. */ if (sampler.target == GL_TEXTURE_RECTANGLE || sampler.target == GL_TEXTURE_BUFFER) lod_arg = ""; else lod_arg = ", lod"; switch (test_stage) { case VS: asprintf(&vs_code, "#version %d\n" "#define ivec1 int\n" "uniform int lod;\n" "uniform %s tex;\n" "in vec4 vertex;\n" "flat out ivec%d size;\n" "void main()\n" "{\n" " size = textureSize(tex%s);\n" " gl_Position = vertex;\n" "}\n", shader_version, sampler.name, size, lod_arg); asprintf(&fs_code, "#version %d\n" "#define ivec1 int\n" "#define vec1 float\n" "flat in ivec%d size;\n" "void main()\n" "{\n" " gl_FragColor = vec4(0.01 * size,%s 1);\n" "}\n", shader_version, size, zeroes[3 - size]); break; case FS: asprintf(&vs_code, "#version %d\n" "in vec4 vertex;\n" "void main()\n" "{\n" " gl_Position = vertex;\n" "}\n", shader_version); asprintf(&fs_code, "#version %d\n" "#define ivec1 int\n" "uniform int lod;\n" "uniform %s tex;\n" "void main()\n" "{\n" " ivec%d size = textureSize(tex%s);\n" " gl_FragColor = vec4(0.01 * size,%s 1);\n" "}\n", shader_version, sampler.name, size, lod_arg, zeroes[3 - size]); break; default: assert(!"Should not get here."); break; } vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vs_code); fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, fs_code); if (!vs || !fs) return 0; return piglit_link_simple_program(vs, fs); }
/** * Generate a vertex or fragment shader to test the given set of * varyings. */ static GLint get_shader(bool is_vs, unsigned glsl_version, int num_varyings, struct varying_desc *varyings, enum test_array_type array_type) { GLuint shader; char *full_text = malloc(1000 * 100 + num_varyings); char *text = full_text; unsigned i, j, k, l, m; const char *varying_keyword; unsigned offset = 0; GLenum shader_type = is_vs ? GL_VERTEX_SHADER : GL_FRAGMENT_SHADER; bool fp64 = false; if (glsl_version >= 130) { if (is_vs) varying_keyword = "out"; else varying_keyword = "in"; } else { varying_keyword = "varying"; } text += sprintf(text, "#version %u\n", glsl_version); if (array_type == ARRAYS_OF_ARRAYS) text += sprintf(text, "#extension GL_ARB_arrays_of_arrays: enable\n"); for (i = 0; i < num_varyings; ++i) { const char *opt_flat_keyword = ""; if (!fp64 && varyings[i].type->base == BASE_TYPE_DOUBLE) { text += sprintf(text, "#extension GL_ARB_gpu_shader_fp64: enable\n"); fp64 = true; } if (varyings[i].type->base != BASE_TYPE_FLOAT) opt_flat_keyword = "flat "; if (varyings[i].two_dim_array_elems != 0) { text += sprintf(text, "%s%s %s var%03u[%u][%u];\n", opt_flat_keyword, varying_keyword, varyings[i].type->name, i, outer_dim_size, varyings[i].two_dim_array_elems); } else if (varyings[i].one_dim_array_elems != 0) { text += sprintf(text, "%s%s %s var%03u[%u];\n", opt_flat_keyword, varying_keyword, varyings[i].type->name, i, varyings[i].one_dim_array_elems); } else { text += sprintf(text, "%s%s %s var%03u;\n", opt_flat_keyword, varying_keyword, varyings[i].type->name, i); } } if (glsl_version >= 150 && is_vs) { text += sprintf(text, "in vec4 piglit_vertex;\n"); text += sprintf(text, "#define gl_Vertex piglit_vertex\n"); } text += sprintf(text, "uniform int i;\n"); text += sprintf(text, "\n" "void main()\n" "{\n"); if (is_vs) text += sprintf(text, " gl_Position = gl_Vertex;\n"); else text += sprintf(text, " bool failed = false;\n"); for (i = 0; i < num_varyings; ++i) { unsigned array_loop_bound; unsigned outer_array_loop_bound = 1; const char *base_type_name = get_base_type_name(varyings[i].type->base); if (varyings[i].two_dim_array_elems != 0) { outer_array_loop_bound = outer_dim_size; array_loop_bound = varyings[i].two_dim_array_elems; } else { array_loop_bound = varyings[i].one_dim_array_elems; } if (array_loop_bound == 0) array_loop_bound = 1; for (j = 0; j < outer_array_loop_bound; ++j) { for (k = 0; k < array_loop_bound; ++k) { for (l = 0; l < varyings[i].type->num_cols; ++l) { for (m = 0; m < varyings[i].type->num_rows; ++m) { text += sprintf(text, " "); if (!is_vs) text += sprintf(text, "failed = failed || "); text += sprintf(text, "var%03u", i); if (varyings[i].two_dim_array_elems) text += sprintf(text, "[%u]", j); if (varyings[i].one_dim_array_elems || varyings[i].two_dim_array_elems) text += sprintf(text, "[%u]", k); if (varyings[i].type->num_cols > 1) text += sprintf(text, "[%u]", l); if (varyings[i].type->num_rows > 1) text += sprintf(text, "[%u]", m); if (is_vs) text += sprintf(text, " = "); else text += sprintf(text, " != "); text += sprintf(text, "%s(i + %u);\n", base_type_name, offset++); } } } } } if (!is_vs) { text += sprintf(text, " if (failed)\n" " gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n" " else\n" " gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);\n"); } text += sprintf(text, "}\n"); shader = piglit_compile_shader_text(shader_type, full_text); free(full_text); return shader; }
void piglit_init(int argc, char **argv) { enum piglit_result result = PIGLIT_PASS; GLint prog; GLint fs; GLint vs; GLenum err; if (piglit_get_gl_version() < 20) { printf("Requires OpenGL 2.0\n"); piglit_report_result(PIGLIT_SKIP); } 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); glUseProgram(prog); /* There shouldn't be any GL errors, but clear them all just to be * sure. */ while (glGetError() != 0) /* empty */ ; glBegin(GL_TRIANGLE_STRIP); glUseProgram(0); glEnd(); err = glGetError(); if (err != GL_INVALID_OPERATION) { printf("Unexpected OpenGL error state 0x%04x for " "glUseProgram(0) " "inside glBegin/glEnd pair (expected 0x%04x).\n", err, GL_INVALID_OPERATION); result = PIGLIT_FAIL; } while (glGetError() != 0) /* empty */ ; /* Try again, but re-use the same program. This should still generate * an error even though it's a no-op. */ glUseProgram(prog); glBegin(GL_TRIANGLE_STRIP); glUseProgram(prog); glEnd(); err = glGetError(); if (err != GL_INVALID_OPERATION) { printf("Unexpected OpenGL error state 0x%04x for " "glUseProgram(prog) " "inside glBegin/glEnd pair (expected 0x%04x).\n", err, GL_INVALID_OPERATION); result = PIGLIT_FAIL; } piglit_report_result(result); }
void piglit_init(int argc, char **argv) { GLuint vs; GLuint *readback; GLuint buffer[BUFFER_SIZE]; GLuint expected[BUFFER_SIZE]; int i; bool pass = true; GLint input_index; GLuint prog; GLuint xfb_buf, vbo; GLuint verts[4] = { 0, 1, 2, 3 }; const char *varying = "o"; piglit_require_GLSL_version(140); piglit_require_gl_version(30); piglit_require_transform_feedback(); vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vs_source); prog = glCreateProgram(); glAttachShader(prog, vs); glTransformFeedbackVaryings(prog, 1, &varying, GL_INTERLEAVED_ATTRIBS); glLinkProgram(prog); if (!piglit_link_check_status(prog)) piglit_report_result(PIGLIT_FAIL); glGenBuffers(1, &xfb_buf); if (!piglit_check_gl_error(0)) piglit_report_result(PIGLIT_FAIL); input_index = glGetAttribLocation(prog, "i"); glUseProgram(prog); if (piglit_get_gl_version() >= 31) { GLuint vao; glGenVertexArrays(1, &vao); glBindVertexArray(vao); } glGenBuffers(1, &vbo); glBindBuffer(GL_ARRAY_BUFFER, vbo); glBufferData(GL_ARRAY_BUFFER, 4 * sizeof(GLuint), verts, GL_STATIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, vbo); glVertexAttribIPointer(input_index, 1, GL_UNSIGNED_INT, sizeof(GLuint), 0); glEnableVertexAttribArray(input_index); pass = piglit_check_gl_error(0) && pass; glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, xfb_buf); memset(buffer, 0xd0, sizeof(buffer)); glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, sizeof(buffer), buffer, GL_STREAM_READ); glBindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, xfb_buf, 0, sizeof(buffer)); glBeginTransformFeedback(GL_POINTS); glDrawArrays(GL_POINTS, 0, ARRAY_SIZE(verts)); glEndTransformFeedback(); readback = glMapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY); /* Check output */ for (i = 0; i < BUFFER_SIZE; ++i) { if (verts[i] != readback[i]) { printf("readback[%u]: %u, expected: %u\n", i, readback[i], expected[i]); pass = false; } } /* Note that rasterization occurred, but the results were * undefined due to gl_Position not being written. We do want * to have rasterization occur (as opposed to just transform * feedback) just to make sure the GPU didn't wedge or * anything. */ piglit_report_result(pass ? PIGLIT_PASS : PIGLIT_FAIL); }
static GLboolean test_uniform_funcs(void) { static const char *signedFragText = "uniform int value1; \n" "uniform ivec2 value2; \n" "uniform ivec3 value3; \n" "uniform ivec4 value4; \n" "void main() \n" "{ \n" " vec4 t = vec4(value4); \n" " t += vec4(value3, 0.0); \n" " t += vec4(value2, 0.0, 0.0); \n" " t += vec4(value1, 0.0, 0.0, 0.0); \n" " gl_FragColor = 0.01 * t; \n" "} \n"; static const char *unsignedFragText = "#extension GL_EXT_gpu_shader4: enable \n" "uniform unsigned int value1; \n" "uniform uvec2 value2; \n" "uniform uvec3 value3; \n" "uniform uvec4 value4; \n" "void main() \n" "{ \n" " vec4 t = vec4(value4); \n" " t += vec4(value3, 0.0); \n" " t += vec4(value2, 0.0, 0.0); \n" " t += vec4(value1, 0.0, 0.0, 0.0); \n" " gl_FragColor = 0.01 * t; \n" "} \n"; GLint vals[4], loc1, loc2, loc3, loc4; GLuint shader; /* * Signed integer tests. */ shader = piglit_compile_shader_text(GL_FRAGMENT_SHADER, signedFragText); assert(shader); Program = piglit_link_simple_program(0, shader); assert(Program); glUseProgram(Program); check_error(__FILE__, __LINE__); loc1 = glGetUniformLocation(Program, "value1"); assert(loc1 >= 0); loc2 = glGetUniformLocation(Program, "value2"); assert(loc2 >= 0); loc3 = glGetUniformLocation(Program, "value3"); assert(loc3 >= 0); loc4 = glGetUniformLocation(Program, "value4"); assert(loc4 >= 0); check_error(__FILE__, __LINE__); gen_values(vals, 1, SIGNED); glUniform1iARB(loc1, vals[0]); if (!check_uniform(vals, 1, SIGNED, loc1, "glUniform1iARB")) return GL_FALSE; gen_values(vals, 2, SIGNED); glUniform2iARB(loc2, vals[0], vals[1]); if (!check_uniform(vals, 2, SIGNED, loc2, "glUniform2iARB")) return GL_FALSE; gen_values(vals, 3, SIGNED); glUniform3iARB(loc3, vals[0], vals[1], vals[2]); if (!check_uniform(vals, 3, SIGNED, loc3, "glUniform3iARB")) return GL_FALSE; gen_values(vals, 4, SIGNED); glUniform4iARB(loc4, vals[0], vals[1], vals[2], vals[3]); if (!check_uniform(vals, 4, SIGNED, loc4, "glUniform4iARB")) return GL_FALSE; /* * Unsigned integer tests. */ shader = piglit_compile_shader_text(GL_FRAGMENT_SHADER, unsignedFragText); assert(shader); Program = piglit_link_simple_program(0, shader); assert(Program); glUseProgram(Program); check_error(__FILE__, __LINE__); loc1 = glGetUniformLocation(Program, "value1"); assert(loc1 >= 0); loc2 = glGetUniformLocation(Program, "value2"); assert(loc2 >= 0); loc3 = glGetUniformLocation(Program, "value3"); assert(loc3 >= 0); loc4 = glGetUniformLocation(Program, "value4"); assert(loc4 >= 0); check_error(__FILE__, __LINE__); gen_values(vals, 1, UNSIGNED); glUniform1uiEXT(loc1, vals[0]); if (!check_uniform(vals, 1, UNSIGNED, loc1, "glUniform1uiEXT")) return GL_FALSE; gen_values(vals, 2, UNSIGNED); glUniform2uiEXT(loc2, vals[0], vals[1]); if (!check_uniform(vals, 2, UNSIGNED, loc2, "glUniform2uiEXT")) return GL_FALSE; gen_values(vals, 3, UNSIGNED); glUniform3uiEXT(loc3, vals[0], vals[1], vals[2]); if (!check_uniform(vals, 3, UNSIGNED, loc3, "glUniform3uiEXT")) return GL_FALSE; gen_values(vals, 4, UNSIGNED); glUniform4uiEXT(loc4, vals[0], vals[1], vals[2], vals[3]); if (!check_uniform(vals, 4, UNSIGNED, loc4, "glUniform4uiEXT")) return GL_FALSE; return GL_TRUE; }
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); }
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); }
static GLboolean do_test(const struct test_desc *test) { GLuint vs; GLuint progs[2] = { 0 }; GLuint pipes[2]; GLuint bufs[NUM_BUFFERS]; float initial_xfb_buffer_contents[XFB_BUFFER_SIZE]; GLboolean pass = GL_TRUE; int i; int num_varyings = test->mode == NO_VARYINGS ? 0 : test->num_buffers; GLint max_separate_attribs; char* vstext_sep; if (test->mode == USEPROGSTAGE_ACTIVE || test->mode == USEPROGSTAGE_NOACTIVE || test->mode == BIND_PIPELINE) { piglit_require_extension("GL_ARB_separate_shader_objects"); if (piglit_get_gl_version() >= 32) asprintf(&vstext_sep, vstext_sep_template, 150); else asprintf(&vstext_sep, vstext_sep_template, 110); } glGetIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS, &max_separate_attribs); printf("MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTIBS=%i\n", max_separate_attribs); printf("Compile vertex shader\n"); vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vstext); if (test->mode == USEPROGSTAGE_ACTIVE || test->mode == USEPROGSTAGE_NOACTIVE || test->mode == BIND_PIPELINE) { /* Note, we can't use glCreateShaderProgramv because the setup * of transform feedback must be done before linking */ vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vstext_sep); progs[0] = glCreateProgram(); glProgramParameteri(progs[0], GL_PROGRAM_SEPARABLE, GL_TRUE); glAttachShader(progs[0], vs); } else if (test->mode == NOT_A_PROGRAM) { printf("Create a program and then delete it\n"); progs[0] = glCreateProgram(); glDeleteProgram(progs[0]); } else { progs[0] = glCreateProgram(); glAttachShader(progs[0], vs); } pass = piglit_check_gl_error(GL_NO_ERROR) && pass; printf("Setup transform feedback for %i varyings in %s mode\n", num_varyings, test->buffer_mode == GL_INTERLEAVED_ATTRIBS ? "interleaved" : "separate"); glTransformFeedbackVaryings(progs[0], num_varyings, varyings, test->buffer_mode); if (test->mode == NOT_A_PROGRAM) { pass = piglit_check_gl_error(GL_INVALID_VALUE) && pass; return pass; } printf("Link program\n"); glLinkProgram(progs[0]); pass = piglit_link_check_status(progs[0]) && pass; if (test->mode == USEPROGSTAGE_ACTIVE || test->mode == USEPROGSTAGE_NOACTIVE || test->mode == BIND_PIPELINE) { printf("Create 2nd program for the pipeline\n"); progs[1] = glCreateShaderProgramv(GL_VERTEX_SHADER, 1, (const char **) &vstext_sep); pass = piglit_link_check_status(progs[1]) && pass; } if (test->mode == USEPROG_ACTIVE || test->mode == LINK_OTHER_ACTIVE) { printf("Prepare 2nd program\n"); progs[1] = glCreateProgram(); glAttachShader(progs[1], vs); } if (test->mode == USEPROG_ACTIVE) { printf("Link 2nd program\n"); glLinkProgram(progs[1]); pass = piglit_link_check_status(progs[1]) && pass; } if (test->mode == USEPROGSTAGE_ACTIVE || test->mode == USEPROGSTAGE_NOACTIVE || test->mode == BIND_PIPELINE) { printf("Use pipeline\n"); glGenProgramPipelines(2, pipes); glUseProgramStages(pipes[0], GL_VERTEX_SHADER_BIT, progs[0]); glUseProgramStages(pipes[1], GL_VERTEX_SHADER_BIT, progs[1]); glBindProgramPipeline(pipes[0]); } else if (test->mode == SKIP_USE_PROGRAM) { printf("Don't use program\n"); } else { printf("Use program\n"); glUseProgram(progs[0]); } printf("Prepare %i buffers\n", test->num_buffers); glGenBuffers(test->num_buffers, bufs); memset(initial_xfb_buffer_contents, 0, sizeof(initial_xfb_buffer_contents)); for (i = 0; i < test->num_buffers; ++i) { glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, bufs[i]); glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, sizeof(initial_xfb_buffer_contents), initial_xfb_buffer_contents, GL_STREAM_READ); } switch (test->mode) { case BIND_MAX: do_bind(test, bufs[0], max_separate_attribs); pass = piglit_check_gl_error(GL_INVALID_VALUE) && pass; return pass; case BIND_BAD_SIZE: case BIND_BAD_OFFSET: do_bind(test, bufs[0], 0); pass = piglit_check_gl_error(GL_INVALID_VALUE) && pass; return pass; default: break; } for (i = 0; i < test->num_buffers; ++i) { if (test->mode == UNBOUND_BUFFER && i == test->param) { printf("Don't bind buffer %i\n", i); } else { do_bind(test, bufs[i], i); } } pass = piglit_check_gl_error(GL_NO_ERROR) && pass; if (test->mode == END_INACTIVE) { printf("EndTransformFeedback\n"); glEndTransformFeedback(); pass = piglit_check_gl_error(GL_INVALID_OPERATION) && pass; return pass; } printf("BeginTransformFeedback\n"); glBeginTransformFeedback(GL_POINTS); switch (test->mode) { case UNBOUND_BUFFER: case NO_VARYINGS: case SKIP_USE_PROGRAM: pass = piglit_check_gl_error(GL_INVALID_OPERATION) && pass; break; default: pass = piglit_check_gl_error(GL_NO_ERROR) && pass; break; } switch (test->mode) { case BEGIN_ACTIVE: printf("BeginTransformFeedback\n"); glBeginTransformFeedback(GL_POINTS); pass = piglit_check_gl_error(GL_INVALID_OPERATION) && pass; break; case USEPROG_ACTIVE: printf("Use new program\n"); glUseProgram(progs[1]); pass = piglit_check_gl_error(GL_INVALID_OPERATION) && pass; break; case LINK_CURRENT_ACTIVE: printf("Link current program\n"); glLinkProgram(progs[0]); pass = piglit_check_gl_error(GL_INVALID_OPERATION) && pass; break; case LINK_OTHER_ACTIVE: printf("Link 2nd program\n"); glLinkProgram(progs[1]); pass = piglit_check_gl_error(GL_NO_ERROR) && pass; break; case BIND_ACTIVE: do_bind(test, bufs[0], 0); pass = piglit_check_gl_error(GL_INVALID_OPERATION) && pass; break; case USEPROGSTAGE_ACTIVE: printf("Use new program stage\n"); glUseProgramStages(pipes[0], GL_VERTEX_SHADER_BIT, progs[1]); pass = piglit_check_gl_error(GL_INVALID_OPERATION) && pass; break; case USEPROGSTAGE_NOACTIVE: printf("Use new program stage\n"); glUseProgramStages(pipes[1], GL_VERTEX_SHADER_BIT, progs[1]); pass = piglit_check_gl_error(GL_NO_ERROR) && pass; break; case BIND_PIPELINE: printf("Bind a new pipeline\n"); glBindProgramPipeline(pipes[1]); pass = piglit_check_gl_error(GL_INVALID_OPERATION) && pass; break; default: break; } return pass; }
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); /* Since the program is in use, it should be flagged for * deletion but not 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 when deleted reported non-true %d\n", status); pass = false; } /* 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; glClearColor(1.0, 0.0, 0.0, 0.0); glClear(GL_COLOR_BUFFER_BIT); /* The main test: Can we still draw after a clear with a * delete 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) { GLint max_draw_buffers; GLuint prog; GLuint vs; GLuint fs; GLint loc; piglit_require_gl_version(30); /* This test needs some number of draw buffers, so make sure the * implementation isn't broken. This enables the test to generate a * useful failure message. */ glGetIntegerv(GL_MAX_DRAW_BUFFERS, &max_draw_buffers); if (max_draw_buffers < 8) { fprintf(stderr, "OpenGL 3.0 requires GL_MAX_DRAW_BUFFERS >= 8. " "Only got %d!\n", max_draw_buffers); piglit_report_result(PIGLIT_FAIL); } prog = glCreateProgram(); vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vs_text); fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, fs_text); if (!piglit_check_gl_error(GL_NO_ERROR)) piglit_report_result(PIGLIT_FAIL); /* First, verify that the program will link without making any * location assignments through the API. */ printf("Basic test...\n"); glAttachShader(prog, vs); glAttachShader(prog, fs); glLinkProgram(prog); if (!piglit_check_gl_error(GL_NO_ERROR)) piglit_report_result(PIGLIT_FAIL); if (!piglit_link_check_status(prog)) { piglit_report_result(PIGLIT_FAIL); } /* Page 237 (page 253 of the PDF) of the OpenGL 3.0 spec says: * * "Assigned bindings for variables that do not exist are * ignored." */ printf("Binding `unicorn' to a non-conflicting location...\n"); glBindFragDataLocation(prog, 0, "v"); if (!piglit_check_gl_error(GL_NO_ERROR)) piglit_report_result(PIGLIT_FAIL); glBindFragDataLocation(prog, 1, "unicorn"); if (!piglit_check_gl_error(GL_NO_ERROR)) piglit_report_result(PIGLIT_FAIL); glLinkProgram(prog); if (!piglit_check_gl_error(GL_NO_ERROR)) piglit_report_result(PIGLIT_FAIL); if (!piglit_link_check_status(prog)) { fprintf(stderr, "Linking failed when it should have been " "successful.\n"); piglit_report_result(PIGLIT_FAIL); } loc = glGetFragDataLocation(prog, "unicorn"); if (!piglit_check_gl_error(GL_NO_ERROR)) piglit_report_result(PIGLIT_FAIL); if (loc != -1) { fprintf(stderr, "Expected location = -1, got %d\n", loc); piglit_report_result(PIGLIT_FAIL); } printf("Binding `unicorn' to a conflicting location...\n"); glBindFragDataLocation(prog, 0, "v"); if (!piglit_check_gl_error(GL_NO_ERROR)) piglit_report_result(PIGLIT_FAIL); glBindFragDataLocation(prog, 0, "unicorn"); if (!piglit_check_gl_error(GL_NO_ERROR)) piglit_report_result(PIGLIT_FAIL); glLinkProgram(prog); if (!piglit_check_gl_error(GL_NO_ERROR)) piglit_report_result(PIGLIT_FAIL); if (!piglit_link_check_status(prog)) { fprintf(stderr, "Linking failed when it should have been " "successful.\n"); piglit_report_result(PIGLIT_FAIL); } loc = glGetFragDataLocation(prog, "unicorn"); if (!piglit_check_gl_error(GL_NO_ERROR)) piglit_report_result(PIGLIT_FAIL); if (loc != -1) { fprintf(stderr, "Expected location = -1, got %d\n", loc); piglit_report_result(PIGLIT_FAIL); } piglit_report_result(PIGLIT_PASS); }
static void generate_and_display_drawbuffers(int count) { GLuint tex[MAX_TARGETS], fb, fs, vs, prog; GLenum attachments[MAX_TARGETS], status; char *fs_count_source; int i; int colors_uniform; glGenFramebuffersEXT(1, &fb); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb); for (i = 0; i < count; i++) { tex[i] = attach_texture(i); attachments[i] = GL_COLOR_ATTACHMENT0 + i; } status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); if (status != GL_FRAMEBUFFER_COMPLETE_EXT) { fprintf(stderr, "fbo incomplete (status = 0x%04x)\n", status); piglit_report_result(PIGLIT_SKIP); } glDrawBuffersARB(count, attachments); /* Clear all to red so we see if the shader rendering happens. */ glClearColor(1.0, 0.0, 0.0, 0.0); glClear(GL_COLOR_BUFFER_BIT); /* Build the shader that writes different color to each buffer. */ vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vs_source); fs_count_source = malloc(strlen(fs_source) + 5); sprintf(fs_count_source, fs_source, count); fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, fs_count_source); free(fs_count_source); prog = piglit_link_simple_program(vs, fs); glUseProgram(prog); if (!piglit_check_gl_error(GL_NO_ERROR)) piglit_report_result(PIGLIT_FAIL); colors_uniform = glGetUniformLocation(prog, "colors"); glUniform4fv(colors_uniform, MAX_TARGETS, (GLfloat *) colors); /* Now render to all the color buffers. */ piglit_draw_rect(-1, -1, 2, 2); /* OK, now draw each of these textures to the winsys framebuffer. */ glUseProgram(0); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, piglit_winsys_fbo); piglit_ortho_projection(piglit_width, piglit_height, GL_FALSE); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); glEnable(GL_TEXTURE_2D); /* draw row of boxes, each with the color from texture/target[i] */ for (i = 0; i < count; i++) { glBindTexture(GL_TEXTURE_2D, tex[i]); piglit_draw_rect_tex(16 * i, 16 * (count - 1), 16, 16, 0, 0, 1, 1); } glDisable(GL_TEXTURE_2D); for (i = 0; i < count; i++) { glDeleteTextures(1, &tex[i]); } glDeleteFramebuffersEXT(1, &fb); }
void piglit_init(int argc, char **argv) { enum piglit_result result = PIGLIT_PASS; GLenum err; GLint ok; GLuint prog; GLuint vs; if (piglit_get_gl_version() < 20) { printf("Requires OpenGL 2.0\n"); piglit_report_result(PIGLIT_SKIP); } piglit_require_extension("GL_EXT_separate_shader_objects"); printf("Trying shader with unresolved external symbol...\n"); vs = piglit_compile_shader_text(GL_VERTEX_SHADER, bad_vs_text); prog = glCreateProgram(); glAttachShader(prog, vs); glLinkProgram(prog); glDeleteShader(vs); ok = piglit_link_check_status_quiet(prog); if (ok) { fprintf(stderr, "Linking with unresolved symbol succeeded when it " "should have failed.\n"); piglit_report_result(PIGLIT_FAIL); } /* There shouldn't be any GL errors, but clear them all just to be * sure. */ while (glGetError() != 0) /* empty */ ; /* The specified program is not linked. This should generate * the error GL_INVALID_OPERATION. */ glActiveProgramEXT(prog); err = glGetError(); if (err != GL_INVALID_OPERATION) { printf("Unexpected OpenGL error state 0x%04x for " "glActiveProgramEXT called with\n" "an unlinked shader program (expected 0x%04x).\n", err, GL_INVALID_OPERATION); result = PIGLIT_FAIL; } glDeleteProgram(prog); glUseProgram(0); /* Try again with a shader program that could be linked but wasn't. */ printf("Trying unlinked, valid shader...\n"); vs = piglit_compile_shader_text(GL_VERTEX_SHADER, good_vs_text); prog = glCreateProgram(); glAttachShader(prog, vs); glDeleteShader(vs); /* There shouldn't be any GL errors, but clear them all just to be * sure. */ while (glGetError() != 0) /* empty */ ; /* The specified program is not linked. This should generate * the error GL_INVALID_OPERATION. */ glActiveProgramEXT(prog); err = glGetError(); if (err != GL_INVALID_OPERATION) { printf("Unexpected OpenGL error state 0x%04x for " "glActiveProgramEXT called with\n" "an unlinked shader program (expected 0x%04x).\n", err, GL_INVALID_OPERATION); result = PIGLIT_FAIL; } glDeleteProgram(prog); glUseProgram(0); piglit_report_result(result); }
bool do_test(const struct test *tests, unsigned num_tests) { bool pass = true; unsigned i; for (i = 0; i < num_tests; i++) { GLint vert = piglit_compile_shader_text(GL_VERTEX_SHADER, tests[i].code); GLint prog = piglit_link_simple_program(vert, 0); GLint num_attr; unsigned visited_count[64]; unsigned j; bool shader_dumped = false; memset(visited_count, 0, sizeof(visited_count)); /* From page 93 (page 109 of the PDF) says: * * "An attribute variable (either conventional or generic) * is considered active if it is determined by the * compiler and linker that the attribute may be accessed * when the shader is executed. Attribute variables that * are declared in a vertex shader but never used will not * count against the limit. In cases where the compiler * and linker cannot make a conclusive determination, an * attribute will be considered active." * * Compare the set of active attributes against the list of * expected active attributes. */ piglit_GetProgramiv(prog, GL_ACTIVE_ATTRIBUTES, &num_attr); for (j = 0; j < num_attr; j++) { const struct attribute *attr; char name_buf[256]; int attr_idx; GLsizei name_len; GLint size; GLenum type; glGetActiveAttrib(prog, j, sizeof(name_buf), &name_len, &size, &type, name_buf); attr_idx = find_attrib(tests[i].attributes, name_buf); /* If the named attribute is not in the list for the * test, then it must not be active. */ if (attr_idx < 0) { DUMP_SHADER(tests[i].code); fprintf(stderr, "Attribute `%s' should not be active " "but is.\n", name_buf); pass = false; continue; } attr = &tests[i].attributes[attr_idx]; if (visited_count[attr_idx] != 0) { DUMP_SHADER(tests[i].code); fprintf(stderr, "Attribute `%s' listed multiple times " "in active list.\n", name_buf); pass = false; } else if (attr->size != size) { DUMP_SHADER(tests[i].code); fprintf(stderr, "Attribute `%s' should have size %d, " "but had size %d.\n", name_buf, attr->size, size); pass = false; } else if (attr->type != type) { DUMP_SHADER(tests[i].code); fprintf(stderr, "Attribute `%s' should have type " "0x%04x, but had type 0x%04x.\n", name_buf, attr->type, type); pass = false; } visited_count[attr_idx]++; } for (j = 0; tests[i].attributes[j].name != NULL; j++) { if (tests[i].attributes[j].must_be_active && visited_count[j] == 0) { DUMP_SHADER(tests[i].code); fprintf(stderr, "Attribute `%s' should have been " "active but wasn't.\n", tests[i].attributes[j].name); pass = false; } } } return pass; }
static void generate_and_display_drawbuffers(int count) { GLuint tex[16], fb, fs, vs, prog; GLenum attachments[16], status, error; char *fs_count_source; int i; glGenFramebuffersEXT(1, &fb); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb); for (i = 0; i < count; i++) { tex[i] = attach_texture(i); attachments[i] = GL_COLOR_ATTACHMENT0 + i; } status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); if (status != GL_FRAMEBUFFER_COMPLETE_EXT) { fprintf(stderr, "fbo incomplete (status = 0x%04x)\n", status); piglit_report_result(PIGLIT_SKIP); } glDrawBuffersARB(count, attachments); /* Clear all to red so we see if the shader rendering happens. */ glClearColor(1.0, 0.0, 0.0, 0.0); glClear(GL_COLOR_BUFFER_BIT); /* Build the shader that spams green to all outputs. */ vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vs_source); fs_count_source = malloc(strlen(fs_source) + 5); sprintf(fs_count_source, fs_source, count); fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, fs_count_source); free(fs_count_source); prog = piglit_link_simple_program(vs, fs); glUseProgram(prog); error = glGetError(); if (error) { fprintf(stderr, "glUseProgram error: 0x%x\n", error); piglit_report_result(PIGLIT_FAIL); } /* Now render to all the color buffers. */ piglit_draw_rect(-1, -1, 2, 2); /* OK, now draw each of these textures to the winsys framebuffer. */ glUseProgram(0); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); piglit_ortho_projection(piglit_width, piglit_height, GL_FALSE); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); glEnable(GL_TEXTURE_2D); for (i = 0; i < count; i++) { glBindTexture(GL_TEXTURE_2D, tex[i]); piglit_draw_rect_tex(16 * i, 16 * (count - 1), 16, 16, 0, 0, 1, 1); } glDisable(GL_TEXTURE_2D); for (i = 0; i < count; i++) { glDeleteTextures(1, &tex[i]); } glDeleteFramebuffersEXT(1, &fb); }
enum piglit_result piglit_display(void) { const char *vs_ubo_template = "#extension GL_ARB_uniform_buffer_object : enable\n" "\n" "varying vec4 vary;" "\n" "layout(std140) uniform ubo {\n" " vec4 v[%d];\n" "};\n" "uniform int i;\n" "\n" "void main() {\n" " gl_Position = gl_Vertex;\n" " vary = v[i];\n" "}\n"; const char *fs_template = "#extension GL_ARB_uniform_buffer_object : enable\n" "\n" "varying vec4 vary;" "\n" "void main() {\n" " gl_FragColor = vary;\n" "}\n"; const char *vs_template = "#extension GL_ARB_uniform_buffer_object : enable\n" "\n" "void main() {\n" " gl_Position = gl_Vertex;\n" "}\n"; const char *fs_ubo_template = "#extension GL_ARB_uniform_buffer_object : enable\n" "\n" "layout(std140) uniform ubo {\n" " vec4 v[%d];\n" "};\n" "uniform int i;\n" "\n" "void main() {\n" " gl_FragColor = v[i];\n" "}\n"; char *vs_source, *fs_source; GLint max_size, vec4s, i_location; GLuint vs, fs, prog, bo; GLenum target; float *data; size_t size; bool pass = true; bool may_link_fail; const float green[4] = { 0, 1, 0, 0 }; int test_index; piglit_require_extension("GL_ARB_uniform_buffer_object"); glGetIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE, &max_size); printf("Max uniform block size: %d\n", max_size); vec4s = max_size / 4 / 4; switch (mode) { case VS: target = GL_VERTEX_SHADER; may_link_fail = false; test_index = vec4s - 1; break; case VS_EXCEED: target = GL_VERTEX_SHADER; may_link_fail = true; vec4s++; test_index = vec4s - 2; break; case FS: target = GL_FRAGMENT_SHADER; may_link_fail = false; test_index = vec4s - 1; break; case FS_EXCEED: target = GL_FRAGMENT_SHADER; may_link_fail = true; vec4s++; test_index = vec4s - 2; break; default: assert(false); target = GL_NONE; may_link_fail = false; } switch (target) { case GL_VERTEX_SHADER: (void)!asprintf(&vs_source, vs_ubo_template, vec4s); (void)!asprintf(&fs_source, "%s", fs_template); printf("Testing VS with uniform block vec4 v[%d]\n", vec4s); break; case GL_FRAGMENT_SHADER: (void)!asprintf(&vs_source, "%s", vs_template); (void)!asprintf(&fs_source, fs_ubo_template, vec4s); printf("Testing FS with uniform block vec4 v[%d]\n", vec4s); break; default: piglit_report_result(PIGLIT_FAIL); } vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vs_source); fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, fs_source); prog = glCreateProgram(); glAttachShader(prog, vs); glAttachShader(prog, fs); glLinkProgram(prog); if (may_link_fail) { if (!piglit_link_check_status_quiet(prog)) { printf("Failed to link with uniform block vec4 " "v[%d]\n", vec4s); piglit_report_result(PIGLIT_PASS); } } else { if (!piglit_link_check_status_quiet(prog)) { fprintf(stderr, "Failed to link with uniform block vec4 " "v[%d]\n", vec4s); return PIGLIT_FAIL; } } size = vec4s * 4 * sizeof(float); glGenBuffers(1, &bo); glBindBuffer(GL_UNIFORM_BUFFER, bo); glBufferData(GL_UNIFORM_BUFFER, size, NULL, GL_DYNAMIC_DRAW); data = glMapBuffer(GL_UNIFORM_BUFFER, GL_READ_WRITE); memset(data, 0, size); /* The whole uniform buffer will be zeros, except for the * entry at v[test_index] which will be green. */ data[test_index * 4 + 0] = green[0]; data[test_index * 4 + 1] = green[1]; data[test_index * 4 + 2] = green[2]; data[test_index * 4 + 3] = green[3]; glUnmapBuffer(GL_UNIFORM_BUFFER); glUseProgram(prog); i_location = glGetUniformLocation(prog, "i"); glUniform1i(i_location, test_index); glUniformBlockBinding(prog, 0, 0); glBindBufferBase(GL_UNIFORM_BUFFER, 0, bo); piglit_draw_rect(-1, -1, 2, 2); pass = piglit_probe_rect_rgba(0, 0, piglit_width, piglit_height, green); glDeleteProgram(prog); piglit_present_results(); return pass ? PIGLIT_PASS : PIGLIT_FAIL; }
/** * Generate a vertex or fragment shader to test the given set of * varyings. */ static GLint get_shader(bool is_vs, unsigned glsl_version, int num_varyings, struct varying_desc *varyings) { GLuint shader; char *full_text = malloc(1000 * 100 + num_varyings); char *text = full_text; unsigned i, j, k, l; const char *varying_keyword; unsigned offset = 0; GLenum shader_type = is_vs ? GL_VERTEX_SHADER : GL_FRAGMENT_SHADER; if (glsl_version >= 130) { if (is_vs) varying_keyword = "out"; else varying_keyword = "in"; } else { varying_keyword = "varying"; } text += sprintf(text, "#version %u\n", glsl_version); text += sprintf(text, "uniform int i;\n"); for (i = 0; i < num_varyings; ++i) { const char *opt_flat_keyword = ""; if (varyings[i].type->base != BASE_TYPE_FLOAT) opt_flat_keyword = "flat "; if (varyings[i].array_elems != 0) { text += sprintf(text, "%s%s %s var%u[%u];\n", opt_flat_keyword, varying_keyword, varyings[i].type->name, i, varyings[i].array_elems); } else { text += sprintf(text, "%s%s %s var%u;\n", opt_flat_keyword, varying_keyword, varyings[i].type->name, i); } } text += sprintf(text, "\n" "void main()\n" "{\n"); if (is_vs) text += sprintf(text, " gl_Position = gl_Vertex;\n"); else text += sprintf(text, " bool failed = false;\n"); for (i = 0; i < num_varyings; ++i) { unsigned array_loop_bound = varyings[i].array_elems; const char *base_type_name = get_base_type_name(varyings[i].type->base); if (array_loop_bound == 0) array_loop_bound = 1; for (j = 0; j < array_loop_bound; ++j) { for (k = 0; k < varyings[i].type->num_cols; ++k) { for (l = 0; l < varyings[i].type->num_rows; ++l) { text += sprintf(text, " "); if (!is_vs) text += sprintf(text, "if ("); text += sprintf(text, "var%u", i); if (varyings[i].array_elems) text += sprintf(text, "[%u]", j); if (varyings[i].type->num_cols > 1) text += sprintf(text, "[%u]", k); if (varyings[i].type->num_rows > 1) text += sprintf(text, "[%u]", l); if (is_vs) text += sprintf(text, " = "); else text += sprintf(text, " != "); text += sprintf(text, "%s(i + %u)", base_type_name, offset++); if (is_vs) { text += sprintf(text, ";\n"); } else { text += sprintf(text, ")\n" " failed = true;\n"); } } } } } if (!is_vs) { text += sprintf(text, " if (failed)\n" " gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n" " else\n" " gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);\n"); } text += sprintf(text, "}\n"); shader = piglit_compile_shader_text(shader_type, full_text); free(full_text); return shader; }
static GLboolean render_and_check_textures(GLenum internal_format) { GLuint rgba_fb; GLuint other_fb; float rgba_image[4 * 64 * 64]; float other_image[4 * 64 * 64]; GLboolean has_green; GLuint vs; GLuint fs; GLint scale_loc; GLint bias_loc; float scale; float bias; piglit_require_extension("GL_EXT_framebuffer_object"); piglit_require_extension("GL_ARB_texture_rg"); has_green = GL_FALSE; scale = 1.0; bias = 0.0; switch (internal_format) { case GL_RG: case GL_RG8: case GL_RG16: has_green = GL_TRUE; /* FALLTHROUGH */ case GL_RED: case GL_R8: case GL_R16: break; case GL_RG16F: has_green = GL_TRUE; /* FALLTHROUGH */ case GL_R16F: piglit_require_extension("GL_ARB_half_float_pixel"); /* FALLTHROUGH */ case GL_RG32F: has_green = GL_TRUE; /* FALLTHROUGH */ case GL_R32F: scale = 511.0; piglit_require_extension("GL_ARB_texture_float"); break; case GL_RG_INTEGER: case GL_RG8I: case GL_RG16I: case GL_RG32I: has_green = GL_TRUE; /* FALLTHROUGH */ case GL_R8I: case GL_R16I: case GL_R32I: bias = -100.0; scale = 511.0; piglit_require_extension("GL_EXT_texture_integer"); break; case GL_RG8UI: case GL_RG16UI: case GL_RG32UI: has_green = GL_TRUE; /* FALLTHROUGH */ case GL_R16UI: case GL_R32UI: scale = 511.0; piglit_require_extension("GL_EXT_texture_integer"); break; case GL_RG_SNORM: case GL_RG8_SNORM: case GL_RG16_SNORM: has_green = GL_TRUE; /* FALLTHROUGH */ case GL_RED_SNORM: case GL_R8_SNORM: case GL_R16_SNORM: scale = 0.5; bias = -0.5; piglit_require_extension("GL_EXT_texture_snorm"); break; default: fprintf(stderr, "invalid format 0x%04x\n", internal_format); piglit_report_result(PIGLIT_FAIL); break; } glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), positions); glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), colors); glEnableVertexAttribArray(0); glEnableVertexAttribArray(1); vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vert_code); fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, frag_code); fbo_program = piglit_link_simple_program(vs, fs); glBindAttribLocation(fbo_program, 0, "position"); glBindAttribLocation(fbo_program, 1, "color"); glLinkProgram(fbo_program); if (!piglit_link_check_status(fbo_program)) piglit_report_result(PIGLIT_FAIL); scale_loc = glGetUniformLocation(fbo_program, "scale"); if (scale_loc < 0) { fprintf(stderr, "couldn't get uniform location for \"scale\"\n"); piglit_report_result(PIGLIT_FAIL); } bias_loc = glGetUniformLocation(fbo_program, "bias"); if (bias_loc < 0) { fprintf(stderr, "couldn't get uniform location for \"bias\"\n"); piglit_report_result(PIGLIT_FAIL); } glUseProgram(fbo_program); glUniform1f(scale_loc, scale); glUniform1f(bias_loc, bias); /* Draw the reference image to the RGBA texture. */ rgba_fb = create_fbo(64, 64, GL_RGBA); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, rgba_fb); glViewport(0, 0, 64, 64); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); glGetFramebufferAttachmentParameterivEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT, (GLint *) &rgba_tex); glBindTexture(GL_TEXTURE_2D, rgba_tex); glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_FLOAT, rgba_image); /* Draw the comparison image to the other texture. */ other_fb = create_fbo(64, 64, internal_format); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, other_fb); glViewport(0, 0, 64, 64); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); glGetFramebufferAttachmentParameterivEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT, (GLint *) &other_tex); glBindTexture(GL_TEXTURE_2D, other_tex); glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_FLOAT, other_image); glUseProgram(0); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, piglit_winsys_fbo); glViewport(0, 0, piglit_width, piglit_height); return compare_texture(rgba_image, other_image, internal_format, GL_RGBA, 64 * 64, has_green); }
void piglit_init(int argc, char **argv) { GLuint vs_spiral, gs_spiral, vs_ref_main, vs_test_main, gs_test_main, gs_layout, fs_main, vao, element_buf; GLint max_gs_out_vertices, max_gs_out_components; int max_testable_vertices; char *text, *endptr; /* parse args */ if (argc != 2) print_usage_and_exit(argv[0]); endptr = NULL; num_vertices = strtol(argv[1], &endptr, 0); if (endptr != argv[1] + strlen(argv[1])) print_usage_and_exit(argv[0]); /* Figure out the maximum number of vertices we can test. */ glGetIntegerv(GL_MAX_GEOMETRY_OUTPUT_VERTICES, &max_gs_out_vertices); glGetIntegerv(GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS, &max_gs_out_components); if (!piglit_check_gl_error(GL_NO_ERROR)) piglit_report_result(PIGLIT_FAIL); max_testable_vertices = MIN2(max_gs_out_vertices, max_gs_out_components / 4); /* If num_vertices == 0, test the maximum possible number of * vertices. Otherwise ensure that the requested number is * supported by the implementation. */ if (num_vertices == 0) num_vertices = max_testable_vertices; else if (num_vertices > max_testable_vertices) { printf("Can't test more than %d vertices\n", max_testable_vertices); piglit_report_result(PIGLIT_SKIP); } /* Compile shaders */ vs_spiral = piglit_compile_shader_text(GL_VERTEX_SHADER, spiral_text); gs_spiral = piglit_compile_shader_text(GL_GEOMETRY_SHADER, spiral_text); vs_ref_main = piglit_compile_shader_text(GL_VERTEX_SHADER, vs_ref_text); vs_test_main = piglit_compile_shader_text(GL_VERTEX_SHADER, vs_test_text); gs_test_main = piglit_compile_shader_text(GL_GEOMETRY_SHADER, gs_test_text); asprintf(&text, gs_layout_template, num_vertices); gs_layout = piglit_compile_shader_text(GL_GEOMETRY_SHADER, text); free(text); fs_main = piglit_compile_shader_text(GL_FRAGMENT_SHADER, fs_text); prog_ref = glCreateProgram(); glAttachShader(prog_ref, vs_ref_main); glAttachShader(prog_ref, vs_spiral); glAttachShader(prog_ref, fs_main); glLinkProgram(prog_ref); if (!piglit_link_check_status(prog_ref)) piglit_report_result(PIGLIT_FAIL); prog_test = glCreateProgram(); glAttachShader(prog_test, vs_test_main); glAttachShader(prog_test, gs_test_main); glAttachShader(prog_test, gs_spiral); glAttachShader(prog_test, gs_layout); glAttachShader(prog_test, fs_main); glLinkProgram(prog_test); if (!piglit_link_check_status(prog_test)) piglit_report_result(PIGLIT_FAIL); glDeleteShader(vs_spiral); glDeleteShader(gs_spiral); glDeleteShader(vs_ref_main); glDeleteShader(vs_test_main); glDeleteShader(gs_test_main); glDeleteShader(gs_layout); glDeleteShader(fs_main); /* Various other GL objects needed by the test */ glGenVertexArrays(1, &vao); glBindVertexArray(vao); glGenBuffers(1, &element_buf); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, element_buf); if (!piglit_check_gl_error(GL_NO_ERROR)) piglit_report_result(PIGLIT_FAIL); }
void piglit_init(int argc, char **argv) { GLuint vs, prog; GLint numUniforms, i; GLint expectedNum = 7; GLint loc_f1, loc_f2, loc_sa, loc_sd, loc_v1; GLfloat v[4]; static const GLfloat vVals[4] = {30.0, 31.0, 32.0, 33.0}; piglit_require_vertex_shader(); piglit_require_fragment_shader(); vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vs_text); prog = piglit_link_simple_program(vs, 0); glUseProgram(prog); glGetProgramiv(prog, GL_ACTIVE_UNIFORMS, &numUniforms); if (numUniforms != expectedNum) { printf("%s: incorrect number of uniforms (found %d, expected %d)\n", TestName, numUniforms, expectedNum); piglit_report_result(PIGLIT_FAIL); } /* check types, sizes */ for (i = 0; i < numUniforms; i++) { GLcharARB name[100]; GLsizei len; GLint size, expectedSize; GLenum type, expectedType; GLint loc; glGetActiveUniform(prog, i, sizeof(name), &len, &size, &type, name); loc = glGetUniformLocation(prog, name); if (loc < 0) { printf("%s: bad uniform location for %s: %d\n", TestName, name, loc); piglit_report_result(PIGLIT_FAIL); } if (!piglit_automatic) { printf("%d: %s loc=%d size=%d type=0x%x\n", i, name, loc, size, type); } /* OpenGL ES 3.0 and OpenGL 4.2 require that the "[0]" be appended to * the name. Earlier versions of the spec are ambiguous. Accept either * name. */ if (strcmp(name, "v") == 0 || strcmp(name, "v[0]") == 0) { expectedType = GL_FLOAT_VEC4_ARB; expectedSize = 3; } else { expectedType = GL_FLOAT; expectedSize = 1; } if (type != expectedType) { printf("%s: wrong type for 'v' (found 0x%x, expected 0x%x)\n", TestName, type, expectedType); piglit_report_result(PIGLIT_FAIL); } if (size != expectedSize) { printf("%s: wrong size for 'v' (found %d, expected %d)\n", TestName, size, expectedSize); piglit_report_result(PIGLIT_FAIL); } } /* Check setting/getting values */ loc_f1 = glGetUniformLocation(prog, "f1"); loc_f2 = glGetUniformLocation(prog, "f2"); loc_sa = glGetUniformLocation(prog, "s.a"); loc_sd = glGetUniformLocation(prog, "s.d"); loc_v1 = glGetUniformLocation(prog, "v[1]"); glUniform1f(loc_f1, 5.0); glUniform1f(loc_f2, 10.0); glUniform1f(loc_sa, 15.0); glUniform1f(loc_sd, 20.0); glUniform4fv(loc_v1, 1, vVals); glGetUniformfv(prog, loc_f1, v); if (v[0] != 5.0) { printf("%s: wrong value for f1 (found %f, expected %f)\n", TestName, v[0], 5.0); piglit_report_result(PIGLIT_FAIL); } glGetUniformfv(prog, loc_f2, v); if (v[0] != 10.0) { printf("%s: wrong value for f2 (found %f, expected %f)\n", TestName, v[0], 10.0); piglit_report_result(PIGLIT_FAIL); } glGetUniformfv(prog, loc_sa, v); if (v[0] != 15.0) { printf("%s: wrong value for s.a (found %f, expected %f)\n", TestName, v[0], 15.0); piglit_report_result(PIGLIT_FAIL); } glGetUniformfv(prog, loc_sd, v); if (v[0] != 20.0) { printf("%s: wrong value for s.d (found %f, expected %f)\n", TestName, v[0], 20.0); piglit_report_result(PIGLIT_FAIL); } glGetUniformfv(prog, loc_v1, v); if (v[0] != 30.0 || v[1] != 31.0 || v[2] != 32.0 || v[3] != 33.0) { printf("%s: wrong value for v[1] (found %g,%g,%g,%g, expected %g,%g,%g,%g)\n", TestName, v[0], v[1], v[2], v[3], 30.0, 31.0, 32.0, 33.0); piglit_report_result(PIGLIT_FAIL); } piglit_report_result(PIGLIT_PASS); }
void piglit_init(int argc, char **argv) { GLint vs, fs, gs, tes, tcs; GLuint pipe; GLint prog_vs, prog_fs, prog_gs, prog_tcs, prog_tes, prog_tess; GLint prog_vs_fs, prog_vs_gs; GLint separable; int version; char *vs_source, *fs_source, *gs_source, *te_source, *tc_source; const bool has_tess = piglit_get_gl_version() >= 40 || piglit_is_extension_supported("GL_ARB_tessellation_shader"); const bool has_geo = piglit_get_gl_version() >= 32; piglit_require_extension("GL_ARB_separate_shader_objects"); if (piglit_get_gl_version() >= 40) version = 400; else if (piglit_get_gl_version() >= 32) version = 150; else version = 120; pass = true; /* create the shader program */ asprintf(&vs_source, vs_source_template, version); asprintf(&fs_source, fs_source_template, version); asprintf(&gs_source, gs_source_template, version); asprintf(&te_source, te_source_template, version); asprintf(&tc_source, tc_source_template, version); vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vs_source); fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, fs_source); pass = (fs != 0) && (vs != 0) && pass; if (has_geo) { gs = piglit_compile_shader_text(GL_GEOMETRY_SHADER, gs_source); pass = (gs != 0) && pass; } if (has_tess) { tes = piglit_compile_shader_text(GL_TESS_EVALUATION_SHADER, te_source); tcs = piglit_compile_shader_text(GL_TESS_CONTROL_SHADER, tc_source); pass = (tes != 0) && (tcs != 0) && pass; } free(vs_source); free(fs_source); free(gs_source); free(te_source); free(tc_source); prog_vs = create_prog(vs, 0); prog_fs = create_prog(fs, 0); prog_vs_fs = create_prog(vs, fs); if (has_geo) { prog_gs = create_prog(gs, 0); prog_vs_gs = create_prog(vs, gs); } if (has_tess) { prog_tcs = create_prog(tcs, 0); prog_tes = create_prog(tes, 0); prog_tess = create_prog(tcs, tes); } /* Setup or compilation failure. Stop here */ pass = piglit_check_gl_error(GL_NO_ERROR) && pass; if (!pass) { piglit_report_result(PIGLIT_FAIL); return; } if (!piglit_automatic) { if (has_tess && has_geo) { printf("INFO: ALL stages supported: running all " "test\n"); } else { if (!has_tess) printf("INFO: GL_ARB_tessellation_shader / " "OpenGL 4.0 not supported: tesselation " "test disabled\n"); if (!has_geo) printf("INFO: OpenGL 3.2 not " "supported: geometry test disabled\n"); } } /* Create the pipeline */ glGenProgramPipelines(1, &pipe); build_and_validate_pipe(pipe, true, "VS/FS program, single glUseProgramStages " "call", GL_ALL_SHADER_BITS, prog_vs_fs, 0, 0, 0, 0, 0, 0, 0, 0); build_and_validate_pipe(pipe, true, "VS/FS program, multiple glUseProgramStages " "calls", GL_FRAGMENT_SHADER_BIT, prog_vs_fs, GL_VERTEX_SHADER_BIT, prog_vs_fs, 0, 0, 0, 0, 0, 0); build_and_validate_pipe(pipe, true, "program per pipeline stage", GL_VERTEX_SHADER_BIT, prog_vs, GL_FRAGMENT_SHADER_BIT, prog_fs, (has_geo) ? GL_GEOMETRY_SHADER_BIT : 0, prog_gs, (has_tess) ? GL_TESS_CONTROL_SHADER_BIT : 0, prog_tcs, (has_tess) ? GL_TESS_EVALUATION_SHADER_BIT : 0, prog_tes); /* Section 2.11.11 (Shader Execution), subpart "Validation" of the * OpenGL 4.1 spec says: * * "If the current set of active program objects cannot be * executed, no primitives are processed and the error * INVALID_OPERATION will be generated. This error is generated * by any command that transfers vertices to the GL if: * * ... * * - One program object is active for at least two shader stages * and a second program is active for a shader stage between two * stages for which the first program was active." */ if (has_geo) build_and_validate_pipe(pipe, false, "GS splitting a VS/FS pipeline", GL_ALL_SHADER_BITS, prog_vs_fs, GL_GEOMETRY_SHADER_BIT, prog_gs, 0, 0, 0, 0, 0, 0); else piglit_report_subtest_result(PIGLIT_SKIP, "GS splitting a VS/FS pipeline"); if (has_tess) build_and_validate_pipe(pipe, false, "TCS splitting a VS/GS pipeline", GL_ALL_SHADER_BITS, prog_vs_gs, GL_TESS_CONTROL_SHADER_BIT, prog_tcs, 0, 0, 0, 0, 0, 0); else piglit_report_subtest_result(PIGLIT_SKIP, "TCS splitting a VS/GS pipeline"); if (has_tess) build_and_validate_pipe(pipe, false, "TES splitting a VS/GS program", GL_ALL_SHADER_BITS, prog_vs_gs, GL_FRAGMENT_SHADER_BIT, prog_fs, GL_TESS_EVALUATION_SHADER_BIT, prog_tes, 0, 0, 0, 0); else piglit_report_subtest_result(PIGLIT_SKIP, "TES splitting a VS/GS program"); /* Section 2.11.11 (Shader Execution), subpart "Validation" of the * OpenGL 4.1 spec says: * * "If the current set of active program objects cannot be * executed, no primitives are processed and the error * INVALID_OPERATION will be generated. This error is generated * by any command that transfers vertices to the GL if: * * ... * * - There is an active program for tessellation control, * tessellation evaluation, or geometry stages with * corresponding executable shader, but there is no active * program with executable vertex shader." */ if (has_geo) build_and_validate_pipe(pipe, false, "GS without VS", GL_FRAGMENT_SHADER_BIT, prog_fs, GL_GEOMETRY_SHADER_BIT, prog_gs, 0, 0, 0, 0, 0, 0); else piglit_report_subtest_result(PIGLIT_SKIP, "GS without VS"); if (has_tess) build_and_validate_pipe(pipe, false, "TES/TCS without VS", GL_ALL_SHADER_BITS, prog_tess, GL_FRAGMENT_SHADER_BIT, prog_fs, 0, 0, 0, 0, 0, 0); else piglit_report_subtest_result(PIGLIT_SKIP, "TES/TCS without VS"); /* Section 2.11.11 (Shader Execution), subpart "Validation" of the * OpenGL 4.1 spec says: * * "If the current set of active program objects cannot be * executed, no primitives are processed and the error * INVALID_OPERATION will be generated. This error is generated * by any command that transfers vertices to the GL if: * * - A program object is active for at least one, but not all of * the shader stages that were present when the program was * linked." */ build_and_validate_pipe(pipe, false, "Only VS from a VS/FS program", GL_FRAGMENT_SHADER_BIT, prog_fs, GL_VERTEX_SHADER_BIT, prog_vs_fs, 0, 0, 0, 0, 0, 0); if (has_geo) build_and_validate_pipe(pipe, false, "Only GS from a VS/GS program", GL_FRAGMENT_SHADER_BIT, prog_fs, GL_GEOMETRY_SHADER_BIT, prog_vs_gs, GL_VERTEX_SHADER_BIT, prog_vs, 0, 0, 0, 0); else piglit_report_subtest_result(PIGLIT_SKIP, "Only GS from a VS/GS program"); if (has_tess) build_and_validate_pipe(pipe, false, "Only TES from TES/TCS program", GL_FRAGMENT_SHADER_BIT, prog_fs, GL_TESS_EVALUATION_SHADER_BIT, prog_tess, GL_VERTEX_SHADER_BIT, prog_vs, 0, 0, 0, 0); else piglit_report_subtest_result(PIGLIT_SKIP, "Only TES from TES/TCS program"); /* Section 2.11.11 (Shader Execution), subpart "Validation" of the * OpenGL 4.1 spec says: * * "If the current set of active program objects cannot be * executed, no primitives are processed and the error * INVALID_OPERATION will be generated. This error is generated * by any command that transfers vertices to the GL if: * * ... * * - There is no current unified program object and the current * program pipeline object includes a program object that was * relinked since being applied to the pipeline object via * UseProgramStages with the PROGRAM_SEPARABLE parameter set to * FALSE." */ build_and_validate_pipe(pipe, true, "Relink attached VS without " "GL_PROGRAM_SEPARABLE (sanity pre-test)", GL_FRAGMENT_SHADER_BIT, prog_fs, GL_VERTEX_SHADER_BIT, prog_vs, 0, 0, 0, 0, 0, 0); glGetProgramiv(prog_vs, GL_PROGRAM_SEPARABLE, &separable); if (!separable) { printf("Error: %d was not a separable program\n", prog_vs); pass = false; } glProgramParameteri(prog_vs, GL_PROGRAM_SEPARABLE, GL_FALSE); glGetProgramiv(prog_vs, GL_PROGRAM_SEPARABLE, &separable); /* NOTE: This check /may/ need to be moved after the call to * glLinkProgram. There has been some discussion as to whether this * is supposed to be "latched" state. */ if (separable) { printf("Error: fail to remove separable flags of program %d\n", prog_vs); pass = false; } glLinkProgram(prog_vs); pass = piglit_link_check_status(prog_vs) && pass; validate_pipe(pipe, GL_FALSE, "Relink attached VS without GL_PROGRAM_SEPARABLE"); piglit_present_results(); piglit_report_result(pass ? PIGLIT_PASS : PIGLIT_FAIL); }
static enum piglit_result test(void) { static const GLfloat dest_color[4] = { 0.75, 0.25, 0.25, 0.5 }; static const GLfloat test_color[4] = { 1.0, 0.25, 0.75, 0.25 }; static const GLfloat test_color1[4] = { 0.5, 0.5, 0.5, 0.5 }; GLfloat expected[4]; GLuint prog; GLuint vs; GLuint fs; int i, j, k, o; if (max_ds_buffers > 1) { printf("Test only supports 1 dual source blending color buffer\n"); max_ds_buffers = 1; } prog = glCreateProgram(); vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vs_text); fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, fs_text); glAttachShader(prog, vs); glAttachShader(prog, fs); piglit_check_gl_error(GL_NO_ERROR); glBindFragDataLocationIndexed(prog, 0, 0, "col0"); glBindFragDataLocationIndexed(prog, 0, 1, "col1"); create_fbo(); glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT); glLinkProgram(prog); glUseProgram(prog); uniform_src0 = glGetUniformLocation(prog, "src0"); uniform_src1 = glGetUniformLocation(prog, "src1"); /* Setup blend modes and compute expected result color. * We only test two simple blending modes. A more elaborate * test would exercise a much wider variety of modes. */ for (o = 0; o < ARRAY_SIZE(operators); o++) { for (i = 0; i < ARRAY_SIZE(srcFactors); i++) { for (j = 0; j < ARRAY_SIZE(dstFactors); j++) { blend_expected(expected, test_color, test_color1, dest_color, srcFactors[i], dstFactors[j], operators[o]); blend(test_color, test_color1, dest_color, srcFactors[i], dstFactors[j], operators[o]); for (k = 0; k < max_ds_buffers; k++) { glReadBuffer(GL_COLOR_ATTACHMENT0_EXT + k); check_error(__LINE__); if (!piglit_probe_pixel_rgba(5, 5, expected)) { printf("For src/dst %d %d %d\n", i, j, o); return PIGLIT_FAIL; } } } } } return PIGLIT_PASS; }
static void generate_and_display_drawbuffers(int count) { GLuint tex[16], fb, fs, vs, prog; GLenum attachments[16], status; int i; char fs_output_line[256]; char fs_full_source[1024]; glGenFramebuffersEXT(1, &fb); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb); for (i = 0; i < count; i++) { tex[i] = attach_texture(i); attachments[i] = GL_COLOR_ATTACHMENT0 + i; } status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); if (status != GL_FRAMEBUFFER_COMPLETE_EXT) { fprintf(stderr, "fbo incomplete (status = 0x%04x)\n", status); piglit_report_result(PIGLIT_SKIP); } glDrawBuffersARB(count, attachments); /* Clear all to 0.25 so we see if the shader rendering happens. */ glClearColor(clear_value, clear_value, clear_value, clear_value); glClear(GL_COLOR_BUFFER_BIT); /* Build the shader that spams green to all outputs. */ vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vs_source); strcpy(fs_full_source, fs_source_start); for (i = 0; i < count; i++) { sprintf(fs_output_line, fs_source_output, i, output_values[i * 4], output_values[(i * 4) + 1], output_values[(i * 4) + 2], output_values[(i * 4) + 3]); strcat(fs_full_source, fs_output_line); } strcat(fs_full_source, fs_source_end); assert(strlen(fs_full_source) + 1 < sizeof(fs_full_source) / sizeof(fs_full_source[0])); fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, fs_full_source); prog = piglit_link_simple_program(vs, fs); glUseProgram(prog); glEnable(GL_BLEND); glBlendFunc(GL_ONE, GL_ONE); glBlendEquation(GL_FUNC_ADD); /* Now render to all the color buffers. */ piglit_draw_rect(-1, -1, 2, 2); glDisable(GL_BLEND); /* OK, now draw each of these textures to the winsys framebuffer. */ glUseProgram(0); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); piglit_ortho_projection(piglit_width, piglit_height, GL_FALSE); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); glEnable(GL_TEXTURE_2D); for (i = 0; i < count; i++) { glBindTexture(GL_TEXTURE_2D, tex[i]); piglit_draw_rect_tex(16 * i, 16 * (count - 1), 16, 16, 0, 0, 1, 1); } glDisable(GL_TEXTURE_2D); for (i = 0; i < count; i++) { glDeleteTextures(1, &tex[i]); } glDeleteFramebuffersEXT(1, &fb); }
void piglit_init(int argc, char **argv) { GLuint tex, fb; GLenum status; int i, dim; GLuint fs, prog, loc_tex; for (i = 1; i < argc; i++) { if (strcmp(argv[i], "-inplace") == 0) in_place_probing = GL_TRUE; else if (strcmp(argv[i], "-nobias") == 0) no_bias = GL_TRUE; else if (strcmp(argv[i], "-nolod") == 0) no_lod = GL_TRUE; else if (strcmp(argv[i], "-GL_ARB_shader_texture_lod") == 0) ARB_shader_texture_lod = GL_TRUE; } piglit_require_extension("GL_EXT_framebuffer_object"); if (piglit_get_gl_version() < 14) piglit_report_result(PIGLIT_SKIP); if (ARB_shader_texture_lod) { piglit_require_GLSL(); piglit_require_extension("GL_ARB_shader_texture_lod"); fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, fscode); prog = piglit_link_simple_program(0, fs); glUseProgram(prog); loc_tex = glGetUniformLocation(prog, "tex"); loc_lod = glGetUniformLocation(prog, "lod"); glUniform1i(loc_tex, 0); puts("Testing GL_ARB_shader_texture_lod."); } glGenTextures(1, &tex); glBindTexture(GL_TEXTURE_2D, tex); for (i = 0, dim = TEX_WIDTH; dim >0; i++, dim /= 2) { glTexImage2D(GL_TEXTURE_2D, i, GL_RGBA, dim, dim, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); } assert(glGetError() == 0); glBindTexture(GL_TEXTURE_2D, 0); glDisable(GL_TEXTURE_2D); glGenFramebuffersEXT(1, &fb); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb); for (i = 0, dim = TEX_WIDTH; dim >0; i++, dim /= 2) { glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, tex, i); status = glCheckFramebufferStatusEXT (GL_FRAMEBUFFER_EXT); if (status != GL_FRAMEBUFFER_COMPLETE_EXT) { fprintf(stderr, "FBO incomplete\n"); piglit_report_result(PIGLIT_SKIP); } glClearColor(colors[i][0], colors[i][1], colors[i][2], 0.0); glClear(GL_COLOR_BUFFER_BIT); assert(glGetError() == 0); } glDeleteFramebuffersEXT(1, &fb); glBindTexture(GL_TEXTURE_2D, tex); glViewport(0, 0, piglit_width, piglit_height); piglit_ortho_projection(piglit_width, piglit_height, GL_FALSE); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, piglit_winsys_fbo); glEnable(GL_TEXTURE_2D); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); }
void piglit_init(int argc, char **argv) { bool pass = true; GLuint vs = 0, gs = 0; int i; prog = glCreateProgram(); vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vstext); gs = piglit_compile_shader_text(GL_GEOMETRY_SHADER, gstext); glAttachShader(prog, vs); glAttachShader(prog, gs); /* check that invalid_varying_names fail to link */ for (i = 0; i < ARRAY_SIZE(invalid_varying_names); i++) { glTransformFeedbackVaryings(prog, 1, &invalid_varying_names[i], GL_INTERLEAVED_ATTRIBS); glLinkProgram(prog); if (piglit_link_check_status_quiet(prog)) { printf("%s is not valid but it was allowed.\n", invalid_varying_names[i]); pass = false; } } /* check that valid_varying_names link properly */ glTransformFeedbackVaryings(prog, ARRAY_SIZE(valid_varying_names), valid_varying_names, GL_INTERLEAVED_ATTRIBS); glLinkProgram(prog); if (!piglit_link_check_status(prog)) { glDeleteProgram(prog); printf("Transform feedback varyings failed to link properly" " with valid names.\n"); piglit_report_result(PIGLIT_FAIL); } glUseProgram(prog); for (i = 0; i < ARRAY_SIZE(valid_varying_names); i++) { char varName[50]; GLsizei nameLength = 0, varSize = 0; GLenum varType = GL_NONE; glGetTransformFeedbackVarying( prog, i, sizeof(varName), &nameLength, &varSize, &varType, varName); printf("Name: %s\t\tType: %s\n", varName, piglit_get_gl_enum_name(varType)); } pass = piglit_check_gl_error(GL_NO_ERROR) && pass; piglit_report_result(pass ? PIGLIT_PASS : PIGLIT_FAIL); }