/* * Copyright (C) 2017 Valve 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 * the rights to use, copy, modify, merge, publish, distribute, sublicense, * 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 NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS 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 * * Test cases which exercice the uniform handle API with * glUniformHandleui*64ARB(), glGetActiveUniform(), etc. */ #include #include "common.h" static struct piglit_gl_test_config *piglit_config; PIGLIT_GL_TEST_CONFIG_BEGIN piglit_config = &config; config.supports_gl_compat_version = 33; config.supports_gl_core_version = 33; config.khr_no_error_support = PIGLIT_NO_ERRORS; PIGLIT_GL_TEST_CONFIG_END static const char *passthrough_vs_src = "#version 330\n" "\n" "in vec4 piglit_vertex;\n" "\n" "void main()\n" "{\n" " gl_Position = piglit_vertex;\n" "}\n"; static const char *fs_explicit_bound_sampler = "#version 330\n" "#extension GL_ARB_bindless_texture: require\n" "\n" "layout (bound_sampler) uniform sampler2D tex;\n" "out vec4 color;\n" "\n" "void main()\n" "{\n" " color = texture(tex, vec2(0, 0));\n" "}\n"; static const char *fs_explicit_bindless_sampler = "#version 330\n" "#extension GL_ARB_bindless_texture: require\n" "\n" "layout (bindless_sampler) uniform sampler2D tex;\n" "out vec4 color;\n" "\n" "void main()\n" "{\n" " color = texture(tex, vec2(0, 0));\n" "}\n"; static const char *fs_implicit_bound_sampler = "#version 330\n" "#extension GL_ARB_bindless_texture: require\n" "\n" "uniform sampler2D tex;\n" "out vec4 color;\n" "\n" "void main()\n" "{\n" " color = texture(tex, vec2(0, 0));\n" "}\n"; static const char *fs_explicit_bound_image = "#version 330\n" "#extension GL_ARB_bindless_texture: require\n" "#extension GL_ARB_shader_image_load_store: enable\n" "\n" "layout (bound_image) writeonly uniform image2D img;\n" "out vec4 color;\n" "\n" "void main()\n" "{\n" " imageStore(img, ivec2(0, 0), color);\n" "}\n"; static const char *fs_explicit_bindless_image = "#version 330\n" "#extension GL_ARB_bindless_texture: require\n" "#extension GL_ARB_shader_image_load_store: enable\n" "\n" "layout (bindless_image) writeonly uniform image2D img;\n" "out vec4 color;\n" "\n" "void main()\n" "{\n" " imageStore(img, ivec2(0, 0), color);\n" "}\n"; static const char *fs_implicit_bound_image = "#version 330\n" "#extension GL_ARB_bindless_texture: require\n" "#extension GL_ARB_shader_image_load_store: enable\n" "\n" "writeonly uniform image2D img;\n" "out vec4 color;\n" "\n" "void main()\n" "{\n" " imageStore(img, ivec2(0, 0), color);\n" "}\n"; static enum piglit_result check_UniformHandleui64_with_explicit_bound_sampler(void *data) { GLuint vs, fs, prog; GLuint64 handle = 0; GLint loc; if (piglit_khr_no_error) return PIGLIT_SKIP; vs = piglit_compile_shader_text(GL_VERTEX_SHADER, passthrough_vs_src); fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, fs_explicit_bound_sampler); prog = piglit_link_simple_program(vs, fs); glUseProgram(prog); loc = glGetUniformLocation(prog, "tex"); if (loc == -1) return PIGLIT_FAIL; /* The ARB_bindless_texture spec says: * * "The error INVALID_OPERATION is generated by UniformHandleui64{v}ARB * if the sampler or image uniform being updated has the * "bound_sampler" or "bound_image" layout qualifier." */ glUniformHandleui64ARB(loc, handle); if (!piglit_check_gl_error(GL_INVALID_OPERATION)) return PIGLIT_FAIL; glProgramUniformHandleui64vARB(prog, loc, 1, &handle); if (!piglit_check_gl_error(GL_INVALID_OPERATION)) return PIGLIT_FAIL; return PIGLIT_PASS; } static enum piglit_result check_Uniform_with_explicit_bindless_sampler(void *data) { GLuint vs, fs, prog; GLuint64 handle = 0; GLint loc; vs = piglit_compile_shader_text(GL_VERTEX_SHADER, passthrough_vs_src); fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, fs_explicit_bindless_sampler); prog = piglit_link_simple_program(vs, fs); glUseProgram(prog); loc = glGetUniformLocation(prog, "tex"); if (loc == -1) return PIGLIT_FAIL; /* The ARB_bindless_texture spec says: * * "These modifiers control whether default-block uniforms of the * corresponding types may have their values set via both * UniformHandle* and Uniform1i (bindless_sampler and bindless_image) * or only via Uniform1i (bound_sampler and bound_image)." */ glUniform1i(loc, 5); glUniformHandleui64ARB(loc, handle); glProgramUniformHandleui64vARB(prog, loc, 1, &handle); if (!piglit_check_gl_error(GL_NO_ERROR)) return PIGLIT_FAIL; return PIGLIT_PASS; } static enum piglit_result check_Uniform_with_implicit_bound_sampler(void *data) { GLuint vs, fs, prog; GLuint64 handle = 0; GLint loc; if (piglit_khr_no_error) return PIGLIT_SKIP; vs = piglit_compile_shader_text(GL_VERTEX_SHADER, passthrough_vs_src); fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, fs_implicit_bound_sampler); prog = piglit_link_simple_program(vs, fs); glUseProgram(prog); loc = glGetUniformLocation(prog, "tex"); if (loc == -1) return PIGLIT_FAIL; /* The ARB_bindless_texture spec says: * * "These modifiers control whether default-block uniforms of the * corresponding types may have their values set via both * UniformHandle* and Uniform1i (bindless_sampler and bindless_image) * or only via Uniform1i (bound_sampler and bound_image)." * * "In the absence of these qualifiers, sampler and image uniforms are * considered "bound"." */ glUniform1i(loc, 5); if (!piglit_check_gl_error(GL_NO_ERROR)) return PIGLIT_FAIL; glUniformHandleui64ARB(loc, handle); if (!piglit_check_gl_error(GL_INVALID_OPERATION)) return PIGLIT_FAIL; glProgramUniformHandleui64vARB(prog, loc, 1, &handle); if (!piglit_check_gl_error(GL_INVALID_OPERATION)) return PIGLIT_FAIL; return PIGLIT_PASS; } static enum piglit_result check_UniformHandleui64_with_explicit_bound_image(void *data) { GLuint vs, fs, prog; GLuint64 handle = 0; GLint loc; if (piglit_khr_no_error) return PIGLIT_SKIP; vs = piglit_compile_shader_text(GL_VERTEX_SHADER, passthrough_vs_src); fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, fs_explicit_bound_image); prog = piglit_link_simple_program(vs, fs); glUseProgram(prog); loc = glGetUniformLocation(prog, "img"); if (loc == -1) return PIGLIT_FAIL; /* The ARB_bindless_texture spec says: * * "The error INVALID_OPERATION is generated by UniformHandleui64{v}ARB * if the sampler or image uniform being updated has the * "bound_sampler" or "bound_image" layout qualifier." */ glUniformHandleui64ARB(loc, handle); if (!piglit_check_gl_error(GL_INVALID_OPERATION)) return PIGLIT_FAIL; glProgramUniformHandleui64vARB(prog, loc, 1, &handle); if (!piglit_check_gl_error(GL_INVALID_OPERATION)) return PIGLIT_FAIL; return PIGLIT_PASS; } static enum piglit_result check_Uniform_with_explicit_bindless_image(void *data) { GLuint vs, fs, prog; GLuint64 handle = 0; GLint loc; vs = piglit_compile_shader_text(GL_VERTEX_SHADER, passthrough_vs_src); fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, fs_explicit_bindless_image); prog = piglit_link_simple_program(vs, fs); glUseProgram(prog); loc = glGetUniformLocation(prog, "img"); if (loc == -1) return PIGLIT_FAIL; /* The ARB_bindless_texture spec says: * * "These modifiers control whether default-block uniforms of the * corresponding types may have their values set via both * UniformHandle* and Uniform1i (bindless_sampler and bindless_image) * or only via Uniform1i (bound_sampler and bound_image)." */ glUniform1i(loc, 5); glUniformHandleui64ARB(loc, handle); glProgramUniformHandleui64vARB(prog, loc, 1, &handle); if (!piglit_check_gl_error(GL_NO_ERROR)) return PIGLIT_FAIL; return PIGLIT_PASS; } static enum piglit_result check_Uniform_with_implicit_bound_image(void *data) { GLuint vs, fs, prog; GLuint64 handle = 0; GLint loc; if (piglit_khr_no_error) return PIGLIT_SKIP; vs = piglit_compile_shader_text(GL_VERTEX_SHADER, passthrough_vs_src); fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, fs_implicit_bound_image); prog = piglit_link_simple_program(vs, fs); glUseProgram(prog); loc = glGetUniformLocation(prog, "img"); if (loc == -1) return PIGLIT_FAIL; /* The ARB_bindless_texture spec says: * * "These modifiers control whether default-block uniforms of the * corresponding types may have their values set via both * UniformHandle* and Uniform1i (bindless_sampler and bindless_image) * or only via Uniform1i (bound_sampler and bound_image)." * * "In the absence of these qualifiers, sampler and image uniforms are * considered "bound"." */ glUniform1i(loc, 5); if (!piglit_check_gl_error(GL_NO_ERROR)) return PIGLIT_FAIL; glUniformHandleui64ARB(loc, handle); if (!piglit_check_gl_error(GL_INVALID_OPERATION)) return PIGLIT_FAIL; glProgramUniformHandleui64vARB(prog, loc, 1, &handle); if (!piglit_check_gl_error(GL_INVALID_OPERATION)) return PIGLIT_FAIL; return PIGLIT_PASS; } static bool check_uniform_int(GLuint prog, int loc, int expect) { int v = 0xdeadcafe; glGetUniformiv(prog, loc, &v); if (v != expect) { fprintf(stderr, "Invalid value for uniform %d\n" " Expected: %d\n" " Observed: %d\n", loc, expect, v); return false; } return piglit_check_gl_error(GL_NO_ERROR); } static bool check_uniform_handle(GLuint prog, int loc, GLuint64 expect) { GLuint64 v = 0xdeadcafedeadcafe; glGetUniformui64vARB(prog, loc, &v); if (v != expect) { fprintf(stderr, "Invalid value for uniform %d\n" " Expected: %"PRIx64"\n" " Observed: %"PRIx64"\n", loc, expect, v); return false; } return piglit_check_gl_error(GL_NO_ERROR); } static enum piglit_result check_Uniform_with_texture_units_and_handles(void *data) { const char *fs_src = "#version 330\n" "#extension GL_ARB_bindless_texture: require\n" "\n" "layout (bindless_sampler) uniform sampler2D texs[5];\n" "uniform int i;\n" "out vec4 color;\n" "\n" "void main()\n" "{\n" " color = texture(texs[i], vec2(0, 0));\n" "}\n"; int units[5] = { 4, 7, 8, 1, 5 }; GLuint64 handle = 0x1004002010040020; GLuint vs, fs, prog; bool pass = true; GLint loc; vs = piglit_compile_shader_text(GL_VERTEX_SHADER, passthrough_vs_src); fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, fs_src); prog = piglit_link_simple_program(vs, fs); glUseProgram(prog); loc = glGetUniformLocation(prog, "texs"); if (loc == -1) return PIGLIT_FAIL; /* Check setting an array of texture units. */ glUniform1iv(loc, 5, units); for (int i = 0; i < 5; i++) { pass &= check_uniform_int(prog, loc + i, units[i]); } /* Check setting a texture handle. */ glUniformHandleui64ARB(loc, handle); pass &= check_uniform_handle(prog, loc, handle); /* Make sure setting the handle didn't overwrite other values. */ for (int i = 1; i < 5; i++) { pass &= check_uniform_int(prog, loc + i, units[i]); } return pass ? PIGLIT_PASS : PIGLIT_FAIL; } static enum piglit_result use_glGetActiveUniform_with_sampler(void *data) { GLuint vs, fs, prog; GLint num_uniforms, size; char name[128]; GLsizei len; GLenum type; vs = piglit_compile_shader_text(GL_VERTEX_SHADER, passthrough_vs_src); fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, fs_explicit_bound_sampler); prog = piglit_link_simple_program(vs, fs); glUseProgram(prog); glGetProgramiv(prog, GL_ACTIVE_UNIFORMS, &num_uniforms); if (num_uniforms != 1) return PIGLIT_FAIL; /* The ARB_bindless_texture spec says: * * "Modify Section 2.14.4, Uniform Variables, p. 97" * * "(Edit Table 2.15, "OpenGL Shading Language type tokens returned * by GetActiveUniform and GetActiveUniformsiv...", pp. 104-106. In * particular, add dots to the "Attrib" and "Xfb" columns for all * SAMPLER and IMAGE types.)" */ glGetActiveUniform(prog, 0, sizeof(name), &len, &size, &type, name); /* Minimal test which only checks one sampler type. */ return type == GL_SAMPLER_2D ? PIGLIT_PASS : PIGLIT_FAIL; } static enum piglit_result use_glGetActiveUniform_with_image(void *data) { GLuint vs, fs, prog; GLint num_uniforms, size; char name[128]; GLsizei len; GLenum type; if (!piglit_is_extension_supported("GL_ARB_shader_image_load_store")) return PIGLIT_SKIP; vs = piglit_compile_shader_text(GL_VERTEX_SHADER, passthrough_vs_src); fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, fs_explicit_bound_image); prog = piglit_link_simple_program(vs, fs); glUseProgram(prog); glGetProgramiv(prog, GL_ACTIVE_UNIFORMS, &num_uniforms); if (num_uniforms != 1) return PIGLIT_FAIL; /* The ARB_bindless_texture spec says: * * "Modify Section 2.14.4, Uniform Variables, p. 97" * * "(Edit Table 2.15, "OpenGL Shading Language type tokens returned * by GetActiveUniform and GetActiveUniformsiv...", pp. 104-106. In * particular, add dots to the "Attrib" and "Xfb" columns for all * SAMPLER and IMAGE types.)" */ glGetActiveUniform(prog, 0, sizeof(name), &len, &size, &type, name); /* Minimal test which only checks one image type. */ return type == GL_IMAGE_2D ? PIGLIT_PASS : PIGLIT_FAIL; } static const struct piglit_subtest subtests[] = { { "Check glUniformHandleui64*ARB() with explicit bound_sampler", "check_UniformHandleui64_with_explicit_bound_sampler", check_UniformHandleui64_with_explicit_bound_sampler, NULL }, { "Check glUniform*() with explicit bindless_sampler", "check_Uniform_with_explicit_bindless_sampler", check_Uniform_with_explicit_bindless_sampler, NULL }, { "Check glUniform*() with implicit bound_sampler", "check_Uniform_with_implicit_bound_sampler", check_Uniform_with_implicit_bound_sampler, NULL }, { "Check glUniformHandleui64*ARB() with explicit bound_image", "check_UniformHandleui64_with_explicit_bound_image", check_UniformHandleui64_with_explicit_bound_image, NULL }, { "Check glUniform*() with explicit bindless_image", "check_Uniform_with_explicit_bindless_image", check_Uniform_with_explicit_bindless_image, NULL }, { "Check glUniform*() with implicit bound_image", "check_Uniform_with_implicit_bound_image", check_Uniform_with_implicit_bound_image, NULL }, { "Check glUniform*() with mixed texture units/handles", "check_Uniform_with_texture_units_and_handles", check_Uniform_with_texture_units_and_handles, NULL }, { "Use glGetActiveUniform with a sampler type", "use_glGetActiveUniform_with_sampler", use_glGetActiveUniform_with_sampler, NULL }, { "Use glGetActiveUniform with an image type", "use_glGetActiveUniform_with_image", use_glGetActiveUniform_with_image, NULL }, { NULL, NULL, NULL, NULL } }; enum piglit_result piglit_display(void) { return PIGLIT_FAIL; } void piglit_init(int argc, char **argv) { enum piglit_result result; piglit_require_extension("GL_ARB_bindless_texture"); result = piglit_run_selected_subtests(subtests, piglit_config->selected_subtests, piglit_config->num_selected_subtests, PIGLIT_SKIP); piglit_report_result(result); }