/* * Copyright (c) 2010 VMware, Inc. * Copyright (c) 2014 Intel Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * on the rights to use, copy, modify, merge, publish, distribute, sub * license, and/or sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NON-INFRINGEMENT. IN NO EVENT SHALL VMWARE AND/OR THEIR SUPPLIERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ /** * @file * Adapted from teximage-errors.c to test ARB_direct_state_access by * Laura Ekstrand . * Tests gl*Texture* functions for error reporting. */ #include "piglit-util-gl.h" PIGLIT_GL_TEST_CONFIG_BEGIN config.supports_gl_compat_version = 20; config.supports_gl_core_version = 31; config.window_visual = PIGLIT_GL_VISUAL_RGB; config.khr_no_error_support = PIGLIT_HAS_ERRORS; PIGLIT_GL_TEST_CONFIG_END /** Test texture size errors and subtexture position errors */ static bool test_pos_and_sizes(void) { bool pass = true; GLuint name; /* all of these should generate GL_INVALID_VALUE */ glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA, -16, 0, GL_RGBA, GL_FLOAT, NULL); pass = piglit_check_gl_error(GL_INVALID_VALUE) && pass; glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, -6, -5, 0, GL_RGBA, GL_FLOAT, NULL); pass = piglit_check_gl_error(GL_INVALID_VALUE) && pass; glTexImage2D(GL_TEXTURE_2D, -2, GL_RGBA, 16, 16, 0, GL_RGBA, GL_FLOAT, NULL); pass = piglit_check_gl_error(GL_INVALID_VALUE) && pass; glTexImage2D(GL_TEXTURE_2D, 2000, GL_RGBA, 16, 16, 0, GL_RGBA, GL_FLOAT, NULL); pass = piglit_check_gl_error(GL_INVALID_VALUE) && pass; /* Setup dsa. */ glCreateTextures(GL_TEXTURE_2D, 1, &name); glBindTextureUnit(0, name); /* Since next command isn't bindless. */ /* setup valid 2D texture for subsequent TexSubImage calls */ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_FLOAT, NULL); glTextureSubImage2D(name, 0, 6, 6, 100, 100, GL_RGBA, GL_FLOAT, NULL); pass = piglit_check_gl_error(GL_INVALID_VALUE) && pass; glTextureSubImage2D(name, 0, -6, -6, 10, 10, GL_RGBA, GL_FLOAT, NULL); pass = piglit_check_gl_error(GL_INVALID_VALUE) && pass; glCopyTextureSubImage2D(name, 0, -6, -6, 2, 2, 10, 10); pass = piglit_check_gl_error(GL_INVALID_VALUE) && pass; glCopyTextureSubImage2D(name, 0, 6, 6, 2, 2, 200, 200); pass = piglit_check_gl_error(GL_INVALID_VALUE) && pass; /* mipmap level 1 doesn't exist */ glTextureSubImage2D(name, 1, 0, 0, 8, 8, GL_RGBA, GL_FLOAT, NULL); pass = piglit_check_gl_error(GL_INVALID_OPERATION) && pass; /* mipmap level 2 doesn't exist */ glCopyTextureSubImage2D(name, 2, 0, 0, 0, 0, 4, 4); pass = piglit_check_gl_error(GL_INVALID_OPERATION) && pass; /* To test 1D and 3D entry points, let's try using the wrong functions. */ glTextureSubImage1D(name, 0, 0, 4, GL_RGBA, GL_FLOAT, NULL); pass = piglit_check_gl_error(GL_INVALID_ENUM) && pass; glTextureSubImage3D(name, 0, 0, 0, 0, 4, 4, 4, GL_RGBA, GL_FLOAT, NULL); pass = piglit_check_gl_error(GL_INVALID_ENUM) && pass; glCopyTextureSubImage1D(name, 0, 0, 0, 0, 4); pass = piglit_check_gl_error(GL_INVALID_ENUM) && pass; glCopyTextureSubImage3D(name, 0, 0, 0, 0, 0, 0, 4, 4); pass = piglit_check_gl_error(GL_INVALID_ENUM) && pass; return pass; } /* * The texture parameter must be an existing texture object as returned * by glCreateTextures */ static bool test_target_name(void) { static const GLuint badname = 250; static const GLfloat fvec[2] = { 1.0, 1.0 }; static const GLint ivec[2] = { -1, 1 }; static const GLuint uvec[2] = { 1, 1 }; bool pass = true; glTextureParameteri(badname, GL_TEXTURE_MAX_LEVEL, 4); pass = piglit_check_gl_error(GL_INVALID_OPERATION) && pass; glTextureParameterf(badname, GL_TEXTURE_MAX_LEVEL, 4.0); pass = piglit_check_gl_error(GL_INVALID_OPERATION) && pass; glTextureParameterfv(badname, GL_TEXTURE_MAX_LEVEL, fvec); pass = piglit_check_gl_error(GL_INVALID_OPERATION) && pass; glTextureParameteriv(badname, GL_TEXTURE_MAX_LEVEL, ivec); pass = piglit_check_gl_error(GL_INVALID_OPERATION) && pass; glTextureParameterIiv(badname, GL_TEXTURE_MAX_LEVEL, ivec); pass = piglit_check_gl_error(GL_INVALID_OPERATION) && pass; glTextureParameterIuiv(badname, GL_TEXTURE_MAX_LEVEL, uvec); pass = piglit_check_gl_error(GL_INVALID_OPERATION) && pass; piglit_report_subtest_result(pass ? PIGLIT_PASS : PIGLIT_FAIL, "glTextureParameter: GL_INVALID_OPERATION " "on bad texture"); return pass; } /* same as test_target_name, but for the getter functions */ static bool test_getter_target_name(void) { static const GLuint badname = 250; GLfloat f; GLuint u; GLint i; bool pass = true; glGetTextureParameterfv(badname, GL_TEXTURE_MAX_LEVEL, &f); pass = piglit_check_gl_error(GL_INVALID_OPERATION) && pass; glGetTextureParameteriv(badname, GL_TEXTURE_MAX_LEVEL, &i); pass = piglit_check_gl_error(GL_INVALID_OPERATION) && pass; glGetTextureParameterIiv(badname, GL_TEXTURE_MAX_LEVEL, &i); pass = piglit_check_gl_error(GL_INVALID_OPERATION) && pass; glGetTextureParameterIuiv(badname, GL_TEXTURE_MAX_LEVEL, &u); pass = piglit_check_gl_error(GL_INVALID_OPERATION) && pass; piglit_report_subtest_result(pass ? PIGLIT_PASS : PIGLIT_FAIL, "glGetTextureParameter: " "GL_INVALID_OPERATION on bad texture"); return pass; } static bool test_getter_pname(void) { GLuint name; GLfloat f; GLuint u; GLint i; bool pass = true; /* Setup dsa. */ glCreateTextures(GL_TEXTURE_2D, 1, &name); glBindTextureUnit(0, name); /* Since next command isn't bindless. */ glGetTextureParameterfv(name, GL_TEXTURE_1D, &f); pass = piglit_check_gl_error(GL_INVALID_ENUM) && pass; glGetTextureParameteriv(name, GL_TEXTURE_1D, &i); pass = piglit_check_gl_error(GL_INVALID_ENUM) && pass; glGetTextureParameterIiv(name, GL_TEXTURE_1D, &i); pass = piglit_check_gl_error(GL_INVALID_ENUM) && pass; glGetTextureParameterIuiv(name, GL_TEXTURE_1D, &u); pass = piglit_check_gl_error(GL_INVALID_ENUM) && pass; piglit_report_subtest_result(pass ? PIGLIT_PASS : PIGLIT_FAIL, "glGetTextureParameter: GL_INVALID_ENUM " "on bad pname"); return pass; } static bool test_pname(void) { GLuint name; const static GLfloat f = 1.0; const static GLuint u = 1; const static GLint i = -5; bool pass = true; /* Setup dsa. */ glCreateTextures(GL_TEXTURE_2D, 1, &name); glBindTextureUnit(0, name); /* Since next command isn't bindless. */ glTextureParameterfv(name, GL_TEXTURE_1D, &f); pass = piglit_check_gl_error(GL_INVALID_ENUM) && pass; glTextureParameteriv(name, GL_TEXTURE_1D, &i); pass = piglit_check_gl_error(GL_INVALID_ENUM) && pass; glTextureParameterIiv(name, GL_TEXTURE_1D, &i); pass = piglit_check_gl_error(GL_INVALID_ENUM) && pass; glTextureParameterIuiv(name, GL_TEXTURE_1D, &u); pass = piglit_check_gl_error(GL_INVALID_ENUM) && pass; piglit_report_subtest_result(pass ? PIGLIT_PASS : PIGLIT_FAIL, "glTextureParameter: GL_INVALID_ENUM on " "bad pname"); return pass; } /* GL_INVALID_ENUM is generated if glTextureParamter{if} is called for a * non-scalar parameter */ static bool test_scalar_vector(void) { bool pass = true; const static GLfloat f = 1.0; const static GLint i = -1; GLuint name; /* Setup dsa. */ glCreateTextures(GL_TEXTURE_2D, 1, &name); glBindTextureUnit(0, name); /* Since next command isn't bindless. */ glTextureParameteri(name, GL_TEXTURE_BORDER_COLOR, i); pass = piglit_check_gl_error(GL_INVALID_ENUM) && pass; glTextureParameterf(name, GL_TEXTURE_BORDER_COLOR, f); pass = piglit_check_gl_error(GL_INVALID_ENUM) && pass; piglit_report_subtest_result(pass ? PIGLIT_PASS : PIGLIT_FAIL, "glTextureParameter{if}: GL_INVALID_ENUM " "for non-scalars"); return pass; } /* GL_INVALID_ENUM is generated if the effective target is either * GL_TEXTURE_2D_MULTISAMPLE or GL_TEXTURE_2D_MULTISAMPLE_ARRAY, and pname is * any of the sampler states. */ /* XXX: Is this actually a valid implementation? */ static bool test_multisample(void) { bool pass = true; static const GLfloat f = 1.0; static const GLint i = -1; static const GLfloat fvec[2] = { 1.0, -1.0 }; static const GLint ivec[2] = { 1, -1 }; static const GLuint uvec[2] = { 1, 4 }; GLuint name; /* GL_TEXTURE_2D_MULTISAMPLE_ARRAY */ glCreateTextures(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, 1, &name); glBindTextureUnit(0, name); /* Since next command isn't bindless. */ glTextureParameteri(name, GL_TEXTURE_WRAP_R, i); pass = piglit_check_gl_error(GL_INVALID_ENUM) && pass; glTextureParameterf(name, GL_TEXTURE_WRAP_R, f); pass = piglit_check_gl_error(GL_INVALID_ENUM) && pass; glTextureParameterfv(name, GL_TEXTURE_WRAP_R, fvec); pass = piglit_check_gl_error(GL_INVALID_ENUM) && pass; glTextureParameteriv(name, GL_TEXTURE_WRAP_R, ivec); pass = piglit_check_gl_error(GL_INVALID_ENUM) && pass; glTextureParameterIiv(name, GL_TEXTURE_WRAP_R, ivec); pass = piglit_check_gl_error(GL_INVALID_ENUM) && pass; glTextureParameterIuiv(name, GL_TEXTURE_WRAP_R, uvec); pass = piglit_check_gl_error(GL_INVALID_ENUM) && pass; /* GL_TEXTURE_2D_MULTISAMPLE */ glDeleteTextures(1, &name); glCreateTextures(GL_TEXTURE_2D_MULTISAMPLE, 1, &name); glBindTextureUnit(0, name); /* Since next command isn't bindless. */ glTextureParameteri(name, GL_TEXTURE_WRAP_R, i); pass = piglit_check_gl_error(GL_INVALID_ENUM) && pass; glTextureParameterf(name, GL_TEXTURE_WRAP_R, f); pass = piglit_check_gl_error(GL_INVALID_ENUM) && pass; glTextureParameterfv(name, GL_TEXTURE_WRAP_R, fvec); pass = piglit_check_gl_error(GL_INVALID_ENUM) && pass; glTextureParameteriv(name, GL_TEXTURE_WRAP_R, ivec); pass = piglit_check_gl_error(GL_INVALID_ENUM) && pass; glTextureParameterIiv(name, GL_TEXTURE_WRAP_R, ivec); pass = piglit_check_gl_error(GL_INVALID_ENUM) && pass; glTextureParameterIuiv(name, GL_TEXTURE_WRAP_R, uvec); pass = piglit_check_gl_error(GL_INVALID_ENUM) && pass; piglit_report_subtest_result(pass ? PIGLIT_PASS : PIGLIT_FAIL, "glTextureParameter: GL_INVALID_ENUM if " "multisample+sampler state"); return pass; } /* GL_INVALID_ENUM is generated if the effective target is GL_TEXTURE_RECTANGLE * and either of pnames GL_TEXTURE_WRAP_S or GL_TEXTURE_WRAP_T is set to either * GL_MIRROR_CLAMP_TO_EDGE, GL_MIRRORED_REPEAT or GL_REPEAT. */ static bool test_texture_rec(void) { bool pass = true; GLuint name; /* GL_TEXTURE_2D_MULTISAMPLE_ARRAY */ glCreateTextures(GL_TEXTURE_RECTANGLE, 1, &name); glBindTextureUnit(0, name); /* Since next command isn't bindless. */ glTextureParameteri(name, GL_TEXTURE_WRAP_S, GL_MIRROR_CLAMP_TO_EDGE); pass = piglit_check_gl_error(GL_INVALID_ENUM) && pass; glTextureParameteri(name, GL_TEXTURE_WRAP_T, GL_MIRROR_CLAMP_TO_EDGE); pass = piglit_check_gl_error(GL_INVALID_ENUM) && pass; glTextureParameteri(name, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT); pass = piglit_check_gl_error(GL_INVALID_ENUM) && pass; glTextureParameteri(name, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT); pass = piglit_check_gl_error(GL_INVALID_ENUM) && pass; glTextureParameteri(name, GL_TEXTURE_WRAP_S, GL_REPEAT); pass = piglit_check_gl_error(GL_INVALID_ENUM) && pass; glTextureParameteri(name, GL_TEXTURE_WRAP_T, GL_REPEAT); pass = piglit_check_gl_error(GL_INVALID_ENUM) && pass; piglit_report_subtest_result(pass ? PIGLIT_PASS : PIGLIT_FAIL, "glTextureParameter: GL_INVALID_ENUM in " "texture_rectangle case"); return pass; } /* GL_INVALID_ENUM is generated if the effective target is GL_TEXTURE_RECTANGLE * and pname GL_TEXTURE_MIN_FILTER is set to a value other than GL_NEAREST or * GL_LINEAR (no mipmap filtering is permitted). */ static bool test_texture_rec_min_filter(void) { bool pass = true; GLuint name; glCreateTextures(GL_TEXTURE_RECTANGLE, 1, &name); glBindTextureUnit(0, name); /* Since next command isn't bindless. */ glTextureParameteri(name, GL_TEXTURE_MIN_FILTER, 0); pass = piglit_check_gl_error(GL_INVALID_ENUM) && pass; piglit_report_subtest_result(pass ? PIGLIT_PASS : PIGLIT_FAIL, "glTextureParameter: GL_INVALID_ENUM for " "texture_rectangle+min_filter"); return pass; } /* GL_INVALID_OPERATION is generated if the effective target is either * GL_TEXTURE_2D_MULTISAMPLE or GL_TEXTURE_2D_MULTISAMPLE_ARRAY, and pname * GL_TEXTURE_BASE_LEVEL is set to a value other than zero. */ static bool test_multisample_texture_base(void) { bool pass = true; GLuint name; glCreateTextures(GL_TEXTURE_2D_MULTISAMPLE, 1, &name); glBindTextureUnit(0, name); /* Since next command isn't bindless. */ glTextureParameteri(name, GL_TEXTURE_BASE_LEVEL, 1); pass = piglit_check_gl_error(GL_INVALID_OPERATION) && pass; glCreateTextures(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, 1, &name); glBindTextureUnit(0, name); /* Since next command isn't bindless. */ glTextureParameteri(name, GL_TEXTURE_BASE_LEVEL, 1); pass = piglit_check_gl_error(GL_INVALID_OPERATION) && pass; piglit_report_subtest_result(pass ? PIGLIT_PASS : PIGLIT_FAIL, "glTextureParameter: GL_INVALID_OPERATION " "for multisample+texture_base"); return pass; } /* GL_INVALID_OPERATION is generated if the effective target is * GL_TEXTURE_RECTANGLE and pname GL_TEXTURE_BASE_LEVEL is set to any value * other than zero. */ static bool test_texture_rec_texture_base(void) { bool pass = true; GLuint name; glCreateTextures(GL_TEXTURE_RECTANGLE, 1, &name); glBindTextureUnit(0, name); /* Since next command isn't bindless. */ glTextureParameteri(name, GL_TEXTURE_BASE_LEVEL, 1); pass = piglit_check_gl_error(GL_INVALID_OPERATION) && pass; piglit_report_subtest_result(pass ? PIGLIT_PASS : PIGLIT_FAIL, "glTextureParameter: GL_INVALID_OPERATION " "for texture_rectangle+min_filter"); return pass; } /* GL_INVALID_VALUE is generated if pname is GL_TEXTURE_BASE_LEVEL or * GL_TEXTURE_MAX_LEVEL, and param or params is negative. */ static bool test_texture_level_negative(void) { bool pass = true; GLuint name; glCreateTextures(GL_TEXTURE_2D, 1, &name); glBindTextureUnit(0, name); /* Since next command isn't bindless. */ glTextureParameteri(name, GL_TEXTURE_BASE_LEVEL, -1); pass = piglit_check_gl_error(GL_INVALID_VALUE) && pass; glTextureParameteri(name, GL_TEXTURE_MAX_LEVEL, -1); pass = piglit_check_gl_error(GL_INVALID_VALUE) && pass; piglit_report_subtest_result(pass ? PIGLIT_PASS : PIGLIT_FAIL, "glTextureParameter: GL_INVALID_VALUE for " "negative tex_*_level"); return pass; } enum piglit_result piglit_display(void) { bool pass = true; pass = test_pos_and_sizes() && pass; pass = test_target_name() && pass; pass = test_getter_target_name() && pass; pass = test_pname() && pass; pass = test_getter_pname() && pass; pass = test_scalar_vector() && pass; pass = test_texture_level_negative() && pass; if (piglit_is_extension_supported("GL_ARB_texture_multisample")){ pass = test_multisample() && pass; pass = test_multisample_texture_base() && pass; } if (piglit_is_extension_supported("GL_ARB_texture_rectangle")) { pass = test_texture_rec() && pass; pass = test_texture_rec_min_filter() && pass; pass = test_texture_rec_texture_base() && pass; } return pass ? PIGLIT_PASS : PIGLIT_FAIL; } void piglit_init(int argc, char **argv) { piglit_require_extension("GL_ARB_direct_state_access"); }