static bool check_gl_error2_(GLenum expected_error1, GLenum expected_error2, const char *file, unsigned line) { const GLenum actual_error = glGetError(); if (actual_error == expected_error1 || actual_error == expected_error2) { return true; } /* * If the lookup of the error's name is successful, then print * Unexpected GL error: NAME 0xHEX * Else, print * Unexpected GL error: 0xHEX */ printf("Unexpected GL error: %s 0x%x\n", piglit_get_gl_error_name(actual_error), actual_error); printf("(Error at %s:%u)\n", file, line); if (expected_error2 != GL_NO_ERROR) { printf("Expected GL error: %s 0x%x or %s 0x%x\n", piglit_get_gl_error_name(expected_error1), expected_error1, piglit_get_gl_error_name(expected_error2), expected_error2); } else if (expected_error1 != GL_NO_ERROR) { printf("Expected GL error: %s 0x%x\n", piglit_get_gl_error_name(expected_error1), expected_error1); } return false; }
void ShaderAPITest::assert_error_test(const char *file, int line, GLenum expect) { GLenum err; err = glGetError(); if (err != expect) { fprintf(stderr, "%s:%d expected %s but received %s\n", file, line, piglit_get_gl_error_name(expect), piglit_get_gl_error_name(err)); error = true; } while (glGetError()) ; /* consume any following errors */ }
/** * Check for either of two expected GL errors. * XXX this could be a piglit util function */ static bool check_gl_error2_(GLenum err1, GLenum err2, int line) { GLenum err = glGetError(); if (err != err1 && err != err2) { printf("Unexpected error %s at %s:%d\n", piglit_get_gl_error_name(err), __FILE__, line); return false; } return true; }
void ShaderAPITest::assert_no_error_test(const char *file, int line) { GLenum err; err = glGetError(); if (err != GL_NO_ERROR) { error = true; fprintf(stderr, "%s:%d received error %s\n", file, line, piglit_get_gl_error_name(err)); } }
static enum piglit_result sample_and_destroy_img(unsigned w, unsigned h, EGLImageKHR img) { GLuint prog, tex; GLenum error; glGenTextures(1, &tex); glBindTexture(GL_TEXTURE_EXTERNAL_OES, tex); /* Set the image as level zero */ glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, (GLeglImageOES)img); error = glGetError(); /** * EGL may not support binding of external textures, this is not an * error. */ if (error == GL_INVALID_OPERATION) return PIGLIT_SKIP; if (error != GL_NO_ERROR) { printf("glEGLImageTargetTexture2DOES() failed: %s 0x%x\n", piglit_get_gl_error_name(error), error); return PIGLIT_FAIL; } glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_NEAREST); prog = piglit_build_simple_program(vs_src, fs_src); glUseProgram(prog); glUniform1i(glGetUniformLocation(prog, "sampler"), 0); set_vertices(prog); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glViewport(0, 0, w, h); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); glDeleteProgram(prog); glUseProgram(0); glDeleteTextures(1, &tex); eglDestroyImageKHR(eglGetCurrentDisplay(), img); return PIGLIT_PASS; }
bool PixelFormatsTest::CheckError(const char *where) const { GLint err = glGetError(); if (err) { char msg[1000]; sprintf(msg, "GL Error: %s (0x%x) in %s\n", piglit_get_gl_error_name(err), err, where); env->log << msg; return true; } return false; }
void piglit_init(int argc, char **argv) { bool pass = true; GLuint framebuffer; GLuint default_framebuffer = 0; GLenum bufs[2] = {GL_BACK_LEFT, GL_BACK}; GLenum one_buf; bool subtest_pass; int i; glCreateFramebuffers(1, &framebuffer); piglit_check_gl_error(GL_NO_ERROR); /* * "An INVALID_OPERATION error is generated by * NamedFramebufferDrawBuffers if framebuffer is not zero or * the name of an existing framebuffer" */ glNamedFramebufferDrawBuffers(5, 2, bufs); PIGLIT_SUBTEST_ERROR(GL_INVALID_OPERATION, pass, "INVALID_OPERATION if " "framebuffer is not zero or the name of an existing " "framebuffer"); /* * "An INVALID_VALUE error is generated if n is negative, or greater than the * value of MAX_DRAW_BUFFERS." */ int max_draw_buffers; glGetIntegerv(GL_MAX_DRAW_BUFFERS, &max_draw_buffers); subtest_pass = true; glNamedFramebufferDrawBuffers(0, -1, bufs); subtest_pass = subtest_pass & piglit_check_gl_error(GL_INVALID_VALUE); glNamedFramebufferDrawBuffers(0, max_draw_buffers + 1, bufs); subtest_pass = subtest_pass & piglit_check_gl_error(GL_INVALID_VALUE); PIGLIT_SUBTEST_CONDITION(subtest_pass, pass, "INVALID_VALUE error is " "generated if n is negative, or greater than " "the value of MAX_DRAW_BUFFERS."); /* * From OpenGL 4.5 spec * "An INVALID_ENUM error is generated if any value in bufs * is not one of the values in tables 17.5 or 17.6." */ subtest_pass = true; one_buf = GL_RED; glNamedFramebufferDrawBuffers(default_framebuffer, 1, &one_buf); subtest_pass = subtest_pass && piglit_check_gl_error(GL_INVALID_ENUM); glNamedFramebufferDrawBuffers(framebuffer, 1, &one_buf); subtest_pass = subtest_pass && piglit_check_gl_error(GL_INVALID_ENUM); PIGLIT_SUBTEST_CONDITION(subtest_pass, pass, "INVALID_ENUM error is " "generated if any value in bufs is not one of " "the values in tables 17.5 or 17.6."); /* * (cont on error out of 17.5 or 17.6) Specifically for the default * framebuffer: * From OpenGL 4.5 spec, page 492 (515 PDF) * "If the default framebuffer is affected, then each of the * constants must be one of the values listed in table 17.6 * or the special value BACK ."" * * And: *"An INVALID_OPERATION error is generated if the default * framebuffer is affected and any value in bufs is a * constant (other than NONE or BACK) that does not indicate * one of the color buffers allocated to the default * framebuffer." * * So for the default framebuffer, and that table, we expect * GL_NO_ERROR or GL_INVALID_OPERATION. */ subtest_pass = true; for (i = 0; i < ARRAY_SIZE(table_17_6_and_back); i++) { GLenum err = 0; glNamedFramebufferDrawBuffers(default_framebuffer, 1, &table_17_6_and_back[i]); /* We manually check glGetError instead of relying on * piglit_check_gl_error like in other subtests * because for subtests that checks several enums, we * are interested on getting which one failed. That * makes debugging easier. */ err = glGetError(); if (err != GL_NO_ERROR && err != GL_INVALID_OPERATION) { printf("Expected GL_NO_ERROR or GL_INVALID_OPERATION " "with %s but received: %s\n", piglit_get_gl_enum_name(table_17_6_and_back[i]), piglit_get_gl_error_name(err)); subtest_pass = false; } } /* For that spec paragraph, we also test enums from table * 17.5. They should return INVALID_OPERATION, as after all, * they are not allocated to the default framebuffer. */ one_buf = GL_COLOR_ATTACHMENT0; glNamedFramebufferDrawBuffers(default_framebuffer, 1, &one_buf); subtest_pass = subtest_pass && piglit_check_gl_error(GL_INVALID_OPERATION); PIGLIT_SUBTEST_CONDITION(subtest_pass, pass, "If the default framebuffer" " is affected, then each of the constants must " "be one of the values listed in table 17.6 or " "the special value BACK. INVALID_OPERATION error" " is generated if the default framebuffer is " "affected and any value in bufs is a constant " "(other than NONE or BACK ) that does not indicate " "one of the color buffers allocated to the default" " framebuffer."); /* (cont default framebuffer) * From OpenGL 4.5 spec: * "When BACK is used, n must be 1 and color values are * written into the left buffer for single-buffered * contexts, or into the back left buffer for * double-buffered contexts" * * From the error table: * "An INVALID_OPERATION error is generated if any value in * bufs is BACK , and n is not one." * */ glNamedFramebufferDrawBuffers(default_framebuffer, 2, bufs); PIGLIT_SUBTEST_ERROR(GL_INVALID_OPERATION, pass, "(default framebuffer)" " An INVALID_OPERATION error is generated if any " "value in bufs is BACK, and n is not one."); /* * Now, specifically for a framebuffer object: * "If a framebuffer object is affected, then each of the * constants must be one of the values listed in table 17.5." * * 17.5 is GL_NONE, and COLOR_ATTACHMENTi, where i < * MAX_COLOR_ATTACHMENTS - 1 */ int max_attachments; glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS, &max_attachments); subtest_pass = true; for (i = 0; i < max_attachments; i++) { one_buf = GL_COLOR_ATTACHMENT0 + i; glNamedFramebufferDrawBuffers(framebuffer, 1, &one_buf); subtest_pass = subtest_pass && piglit_check_gl_error(GL_NO_ERROR); } PIGLIT_SUBTEST_CONDITION(subtest_pass, pass, "If a framebuffer object is " "affected, then each of constants must be one of the " "values listed in table 17.5."); /* * "An INVALID_OPERATION error is generated if a framebuffer * object is affected and any value in bufs is a constant * from table 17.6, or COLOR_ATTACHMENTm where m is greater * than or equal to the value of MAX_COLOR_ATTACHMENTS." */ subtest_pass = true; /* Starting at 1, as GL_NONE is valid */ for (i = 1; i < ARRAY_SIZE(table_17_6); i++) { GLenum err = 0; glNamedFramebufferDrawBuffers(framebuffer, 1, &table_17_6[i]); err = glGetError(); if (err != GL_INVALID_OPERATION) { printf("Expected GL_INVALID_OPERATION with" " %s but received: %s\n", piglit_get_gl_enum_name(table_17_6[i]), piglit_get_gl_error_name(err)); subtest_pass = false; } } one_buf = GL_COLOR_ATTACHMENT0 + max_attachments; glNamedFramebufferDrawBuffers(framebuffer, 1, &one_buf); subtest_pass = subtest_pass && piglit_check_gl_error(GL_INVALID_OPERATION); PIGLIT_SUBTEST_CONDITION(subtest_pass, pass, "INVALID_OPERATION error is " "generated if a framebuffer object is affected and any " "value in bufs is a constant from table 17.6, or " "COLOR_ATTACHMENTm where m is greater than or equal " "to the value of MAX_COLOR_ATTACHMENTS."); /* * "An INVALID_OPERATION error is generated if a buffer other * than NONE is specified more than once in the array pointed * to by bufs" */ bufs[0] = bufs[1] = GL_FRONT_LEFT; glNamedFramebufferDrawBuffers(framebuffer, 2, bufs); PIGLIT_SUBTEST_ERROR(GL_INVALID_OPERATION, pass, "INVALID_OPERATION error " "is generated if a buffer other than NONE is specified " "more than once in the array pointed to by bufs."); /* * From OpenGL 4.5 spec: * "An INVALID_ENUM error is generated if any value in bufs is * FRONT, LEFT, RIGHT, or FRONT_AND_BACK . This restriction * applies to both the default framebuffer and framebuffer * objects, and exists because these constants may themselves * refer to multiple buffers, as shown in table 17.4." */ subtest_pass = true; for (i = 0; i < ARRAY_SIZE(multiple_buffers); i++) { GLenum err = 0; bool local_pass = true; glNamedFramebufferDrawBuffers(default_framebuffer, 1, &multiple_buffers[i]); err = glGetError(); local_pass = local_pass && (err == GL_INVALID_ENUM); glNamedFramebufferDrawBuffers(framebuffer, 1, &multiple_buffers[i]); err = glGetError(); local_pass = local_pass && (err == GL_INVALID_ENUM); if (!local_pass) printf("Expected GL_INVALID_ENUM with" " %s but received: %s\n", piglit_get_gl_enum_name(table_17_6_and_back[i]), piglit_get_gl_error_name(err)); subtest_pass = subtest_pass && local_pass; } PIGLIT_SUBTEST_CONDITION(subtest_pass, pass, "INVALID_ENUM error is " "generated if any value in bufs is FRONT, LEFT," " RIGHT, or FRONT_AND_BACK "); /* clean up */ glDeleteFramebuffers(1, &framebuffer); piglit_report_result(pass ? PIGLIT_PASS : PIGLIT_FAIL); }
void piglit_init(int argc, char **argv) { static const struct { bool color; bool stencil; bool depth; bool packed; } test_vectors[] = { { true, false, false, false }, { false, false, true, false }, { true, false, true, false }, { false, true, true, false }, { true, true, true, false }, { false, true, true, true }, { true, true, true, true }, }; static const float first[4] = { 0.5, 1.0, 1.0, 1.0 }; static const float second[4] = { 0.8, 0.0, 0.0, 0.0 }; unsigned i; bool pass = true; piglit_require_gl_version(30); for (i = 0; i < ARRAY_SIZE(test_vectors); i++) { GLenum err; GLuint fb = generate_simple_fbo(test_vectors[i].color, test_vectors[i].stencil, test_vectors[i].depth, test_vectors[i].packed); if (fb == 0) { if (!piglit_automatic) { printf("Skipping framebuffer %s color, " "%s depth, and " "%s stencil (%s).\n", test_vectors[i].color ? "with" : "without", test_vectors[i].depth ? "with" : "without", test_vectors[i].stencil ? "with" : "without", test_vectors[i].packed ? "packed" : "separate"); } continue; } if (!piglit_automatic) { printf("Trying framebuffer %s color, " "%s depth and " "%s stencil (%s)...\n", test_vectors[i].color ? "with" : "without", test_vectors[i].depth ? "with" : "without", test_vectors[i].stencil ? "with" : "without", test_vectors[i].packed ? "packed" : "separate"); } /* The GL spec says nothing about generating an error for * clearing a buffer that does not exist. Certainly glClear * does not. */ glClearBufferfv(GL_DEPTH, 0, first); err = glGetError(); if (err != GL_NO_ERROR) { fprintf(stderr, "First call to glClearBufferfv erroneously " "generated a GL error (%s, 0x%04x)\n", piglit_get_gl_error_name(err), err); pass = false; } pass = simple_probe(test_vectors[i].color, default_color, test_vectors[i].stencil, default_stencil, test_vectors[i].depth, first[0]) && pass; glClearBufferfv(GL_DEPTH, 0, second); err = glGetError(); if (err != GL_NO_ERROR) { fprintf(stderr, "Second call to glClearBufferfv erroneously " "generated a GL error (%s, 0x%04x)\n", piglit_get_gl_error_name(err), err); pass = false; } pass = simple_probe(test_vectors[i].color, default_color, test_vectors[i].stencil, default_stencil, test_vectors[i].depth, second[0]) && pass; glDeleteFramebuffers(1, &fb); pass = piglit_check_gl_error(GL_NO_ERROR) && pass; } piglit_report_result(pass ? PIGLIT_PASS : PIGLIT_FAIL); }
/////////////////////////////////////////////////////////////////////////////// // logGLErrors: Check for OpenGL errors and log any that have occurred. /////////////////////////////////////////////////////////////////////////////// void logGLErrors(Environment& env) { GLenum err; while ((err = glGetError())) env.log << "\tOpenGL error: " << piglit_get_gl_error_name(err) << '\n'; } // logGLErrors