void piglit_init(int argc, char **argv) { int i = 1; if (i < argc && strcmp(argv[i], "rect") == 0) { TexTarget = GL_TEXTURE_RECTANGLE; i++; } if (i < argc) { ErrorScale = atof(argv[i]); } piglit_require_extension("GL_EXT_framebuffer_object"); piglit_require_fragment_shader(); if (TexTarget == GL_TEXTURE_RECTANGLE) { piglit_require_extension("GL_ARB_texture_rectangle"); } create_fbo(); if (ErrorScale == 0.0) { /* A 1-bit error/difference in Z values results in a delta of 64 in * pixel intensity (where pixels are in [0,255]). */ ErrorScale = ((double) (1ull << Zbits)) * 64.0 / 255.0; } create_frag_shader(); if (!piglit_automatic) { printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER)); printf("Left: Shader showing difference pixels (black=good, red=error)\n"); printf("Middle: Depth buffer of FBO\n"); printf("Right: Quad textured with depth values\n"); printf("Z bits = %d\n", Zbits); printf("ErrorScale = %f\n", ErrorScale); printf("Texture target: %s\n", TexTarget == GL_TEXTURE_RECTANGLE ? "RECTANGLE" : "2D" ); } }
enum piglit_result piglit_display(void) { GLboolean pass = GL_TRUE; GLuint tex; int x1 = 10 + TEX_WIDTH / 4; int x2 = 10 + TEX_WIDTH * 3 / 4; int y1 = 10 + TEX_HEIGHT / 4; int y2 = 10 + TEX_HEIGHT * 3 / 4; glClearColor(0.5, 0.5, 0.5, 0.5); glClear(GL_COLOR_BUFFER_BIT); tex = create_fbo(); glViewport(0, 0, piglit_width, piglit_height); piglit_ortho_projection(piglit_width, piglit_height, GL_FALSE); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); glEnable(GL_TEXTURE_2D); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); piglit_draw_rect_tex(10, 10, TEX_WIDTH, TEX_HEIGHT, 0, 0, 1, 1); pass &= piglit_probe_pixel_rgb(x1, y1, red); pass &= piglit_probe_pixel_rgb(x2, y1, green); pass &= piglit_probe_pixel_rgb(x1, y2, blue); pass &= piglit_probe_pixel_rgb(x2, y2, white); glDeleteTextures(1, &tex); glDisable(GL_TEXTURE_2D); glutSwapBuffers(); return pass ? PIGLIT_PASS : PIGLIT_FAIL; }
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"); piglit_require_extension("GL_ARB_texture_non_power_of_two"); 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); }
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 enum piglit_result test(void) { GLenum buffers[32]; 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 }; GLfloat expected[32][4]; int i; create_fbo(); for (i = 0; i < maxBuffers; i++) { buffers[i] = GL_COLOR_ATTACHMENT0_EXT + i; } glDrawBuffersARB(maxBuffers, buffers); /* 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 (i = 0; i < maxBuffers; i++) { if (i % 2 == 0) { float a; glBlendFunciARB(i, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); a = test_color[3]; expected[i][0] = test_color[0] * a + dest_color[0] * (1.0 - a); expected[i][1] = test_color[1] * a + dest_color[1] * (1.0 - a); expected[i][2] = test_color[2] * a + dest_color[2] * (1.0 - a); expected[i][3] = test_color[3] * a + dest_color[3] * (1.0 - a); } else { glBlendFunciARB(i, GL_ONE, GL_ONE); glBlendEquationiARB(i, GL_FUNC_SUBTRACT); expected[i][0] = test_color[0] - dest_color[0]; expected[i][1] = test_color[1] - dest_color[1]; expected[i][2] = test_color[2] - dest_color[2]; expected[i][3] = test_color[3] - dest_color[3]; } expected[i][0] = CLAMP(expected[i][0], 0.0, 1.0); expected[i][1] = CLAMP(expected[i][1], 0.0, 1.0); expected[i][2] = CLAMP(expected[i][2], 0.0, 1.0); expected[i][3] = CLAMP(expected[i][3], 0.0, 1.0); glEnableIndexedEXT(GL_BLEND, i); } /* query blend modes */ for (i = 0; i < maxBuffers; i++) { GLint p0, p1, p2, p3; glGetIntegerIndexedvEXT(GL_BLEND_SRC, i, &p0); glGetIntegerIndexedvEXT(GL_BLEND_DST, i, &p1); glGetIntegerIndexedvEXT(GL_BLEND_EQUATION, i, &p2); glGetIntegerIndexedvEXT(GL_BLEND, i, &p3); if (i % 2 == 0) { MY_ASSERT(p0 == GL_SRC_ALPHA); MY_ASSERT(p1 == GL_ONE_MINUS_SRC_ALPHA); MY_ASSERT(p2 == GL_FUNC_ADD); } else { MY_ASSERT(p0 == GL_ONE); MY_ASSERT(p1 == GL_ONE); MY_ASSERT(p2 == GL_FUNC_SUBTRACT); } MY_ASSERT(p3 == GL_TRUE); } /* test drawing */ glClearColor(dest_color[0], dest_color[1], dest_color[2], dest_color[3]); glClear(GL_COLOR_BUFFER_BIT); glColor4fv(test_color); piglit_draw_rect(0, 0, piglit_width, piglit_height); for (i = 0; i < maxBuffers; i++) { glReadBuffer(GL_COLOR_ATTACHMENT0_EXT + i); check_error(__LINE__); if (!piglit_probe_pixel_rgba(5, 5, expected[i])) { printf("For color buffer %d\n", i); return PIGLIT_FAIL; } } return PIGLIT_PASS; }
static bool test_format(const struct fmt_test *test) { bool pass = true; if (piglit_is_extension_supported("GL_OES_texture_buffer") && test->can_texbuf) { bool buf_test = buffer_test(test); piglit_report_subtest_result(PIGLIT_RESULT(buf_test), "format 0x%x TBO test", test->iformat); pass &= buf_test; } glUseProgram(prog); glUniform1i(0 /* explicit loc */, 0); /* Create a texture, upload data */ const GLuint texture = create_texture(test); glBindTexture(GL_TEXTURE_2D, texture); /* Can only texture from. */ if (!test->req_render) { /* Render texture to window and verify contents. */ render_texture(texture, GL_TEXTURE_2D, 0); bool render_test = verify_contents_float(test); piglit_present_results(); piglit_report_subtest_result(PIGLIT_RESULT(render_test), "format 0x%x", test->iformat); glDeleteTextures(1, &texture); pass &= render_test; return pass; } /* Test glRenderbufferStorage. */ GLuint rbo = create_rbo(test); if (!rbo || !piglit_check_gl_error(GL_NO_ERROR)) { piglit_report_subtest_result(PIGLIT_FAIL, "format 0x%x RBO test", test->iformat); pass &= false; } else { piglit_report_subtest_result(PIGLIT_PASS, "format 0x%x RBO test", test->iformat); } glDeleteRenderbuffers(1, &rbo); /* Create framebuffer object. */ GLuint fbo_tex; const GLuint fbo = create_fbo(test, &fbo_tex); if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { piglit_report_subtest_result(PIGLIT_FAIL, "format 0x%x fbo fail", test->iformat); pass &= false; } render_texture(texture, GL_TEXTURE_2D, fbo); /* Test glCopyTexImage2D by copying current fbo content to * a texture, rendering copy back to fbo and verifying fbo contents. */ GLuint tmp_tex = create_empty_texture(); glCopyTexImage2D(GL_TEXTURE_2D, 0, test->iformat, 0, 0, piglit_width, piglit_height, 0); render_texture(tmp_tex, GL_TEXTURE_2D, fbo); /* If format can be read, verify contents. */ if (test->can_read) pass &= verify_contents(test); glDeleteTextures(1, &tmp_tex); /* If GL_EXT_copy_image is supported then create another * texture, copy contents and render result to fbo. */ GLuint texture_copy = 0; if (piglit_is_extension_supported("GL_EXT_copy_image")) { bool copy_pass = test_copy_image(test, texture, &texture_copy); pass &= copy_pass; piglit_report_subtest_result(PIGLIT_RESULT(copy_pass), "copy image format 0x%x", test->iformat); render_texture(texture_copy, GL_TEXTURE_2D, fbo); } /* If format can be read, verify contents. */ if (test->can_read) pass &= verify_contents(test); /* Render fbo contents to window. */ render_texture(fbo_tex, GL_TEXTURE_2D, 0); piglit_present_results(); glDeleteFramebuffers(1, &fbo); glDeleteTextures(1, &texture); glDeleteTextures(1, &texture_copy); return pass; }