[Piglit] [RFC PATCH 2/5] add API-related tests for ARB_bindless_texture
Samuel Pitoiset
samuel.pitoiset at gmail.com
Mon Mar 27 22:05:10 UTC 2017
Signed-off-by: Samuel Pitoiset <samuel.pitoiset at gmail.com>
---
tests/all.py | 14 +
tests/spec/CMakeLists.txt | 1 +
tests/spec/arb_bindless_texture/CMakeLists.gl.txt | 21 +
tests/spec/arb_bindless_texture/CMakeLists.txt | 1 +
tests/spec/arb_bindless_texture/border-color.c | 209 ++++++++
tests/spec/arb_bindless_texture/conversions.c | 280 +++++++++++
tests/spec/arb_bindless_texture/errors.c | 514 +++++++++++++++++++
tests/spec/arb_bindless_texture/handles.c | 576 ++++++++++++++++++++++
tests/spec/arb_bindless_texture/illegal.c | 331 +++++++++++++
tests/spec/arb_bindless_texture/legal.c | 259 ++++++++++
tests/spec/arb_bindless_texture/limit.c | 302 ++++++++++++
tests/spec/arb_bindless_texture/uint64_attribs.c | 96 ++++
tests/spec/arb_bindless_texture/uniform.c | 371 ++++++++++++++
13 files changed, 2975 insertions(+)
create mode 100644 tests/spec/arb_bindless_texture/CMakeLists.gl.txt
create mode 100644 tests/spec/arb_bindless_texture/CMakeLists.txt
create mode 100644 tests/spec/arb_bindless_texture/border-color.c
create mode 100644 tests/spec/arb_bindless_texture/conversions.c
create mode 100644 tests/spec/arb_bindless_texture/errors.c
create mode 100644 tests/spec/arb_bindless_texture/handles.c
create mode 100644 tests/spec/arb_bindless_texture/illegal.c
create mode 100644 tests/spec/arb_bindless_texture/legal.c
create mode 100644 tests/spec/arb_bindless_texture/limit.c
create mode 100644 tests/spec/arb_bindless_texture/uint64_attribs.c
create mode 100644 tests/spec/arb_bindless_texture/uniform.c
diff --git a/tests/all.py b/tests/all.py
index ee7043118..58e9fc88c 100644
--- a/tests/all.py
+++ b/tests/all.py
@@ -4940,5 +4940,19 @@ with profile.test_list.group_manager(
g(['intel_conservative_rasterization-innercoverage_gles3'])
g(['intel_conservative_rasterization-tri_gles3'])
+# Group ARB_bindless_texture
+with profile.test_list.group_manager(
+ PiglitGLTest,
+ grouptools.join('spec', 'ARB_bindless_texture')) as g:
+ g(['arb_bindless_texture-border-color'], 'border-color')
+ g(['arb_bindless_texture-conversions'], 'conversions')
+ g(['arb_bindless_texture-errors'], 'errors')
+ g(['arb_bindless_texture-handles'], 'handles')
+ g(['arb_bindless_texture-illegal'], 'illegal')
+ g(['arb_bindless_texture-legal'], 'legal')
+ g(['arb_bindless_texture-limit'], 'limit')
+ g(['arb_bindless_texture-uint64_attribs'], 'uint64_attribs')
+ g(['arb_bindless_texture-uniform'], 'uniform')
+
if platform.system() is 'Windows':
profile.filters.append(lambda p, _: not p.startswith('glx'))
diff --git a/tests/spec/CMakeLists.txt b/tests/spec/CMakeLists.txt
index 01a7935c7..b3adcdcfd 100644
--- a/tests/spec/CMakeLists.txt
+++ b/tests/spec/CMakeLists.txt
@@ -2,6 +2,7 @@ add_subdirectory (amd_performance_monitor)
add_subdirectory (amd_pinned_memory)
add_subdirectory (arb_arrays_of_arrays)
add_subdirectory (arb_base_instance)
+add_subdirectory (arb_bindless_texture)
add_subdirectory (arb_buffer_storage)
add_subdirectory (arb_clear_buffer_object)
add_subdirectory (arb_clear_texture)
diff --git a/tests/spec/arb_bindless_texture/CMakeLists.gl.txt b/tests/spec/arb_bindless_texture/CMakeLists.gl.txt
new file mode 100644
index 000000000..2c83a296e
--- /dev/null
+++ b/tests/spec/arb_bindless_texture/CMakeLists.gl.txt
@@ -0,0 +1,21 @@
+include_directories(
+ ${GLEXT_INCLUDE_DIR}
+ ${OPENGL_INCLUDE_PATH}
+)
+
+link_libraries (
+ piglitutil_${piglit_target_api}
+ ${OPENGL_gl_LIBRARY}
+)
+
+piglit_add_executable (arb_bindless_texture-border-color border-color.c)
+piglit_add_executable (arb_bindless_texture-conversions conversions.c)
+piglit_add_executable (arb_bindless_texture-errors errors.c)
+piglit_add_executable (arb_bindless_texture-handles handles.c)
+piglit_add_executable (arb_bindless_texture-illegal illegal.c)
+piglit_add_executable (arb_bindless_texture-legal legal.c)
+piglit_add_executable (arb_bindless_texture-limit limit.c)
+piglit_add_executable (arb_bindless_texture-uint64_attribs uint64_attribs.c)
+piglit_add_executable (arb_bindless_texture-uniform uniform.c)
+
+# vim: ft=cmake:
diff --git a/tests/spec/arb_bindless_texture/CMakeLists.txt b/tests/spec/arb_bindless_texture/CMakeLists.txt
new file mode 100644
index 000000000..144a306f4
--- /dev/null
+++ b/tests/spec/arb_bindless_texture/CMakeLists.txt
@@ -0,0 +1 @@
+piglit_include_target_api()
diff --git a/tests/spec/arb_bindless_texture/border-color.c b/tests/spec/arb_bindless_texture/border-color.c
new file mode 100644
index 000000000..76f3f9292
--- /dev/null
+++ b/tests/spec/arb_bindless_texture/border-color.c
@@ -0,0 +1,209 @@
+/*
+ * 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 exercise different border color values with
+ * glGetTextureHandleARB() and glGetTextureSamplerARB().
+ */
+
+/* The ARB_bindless_texture spec says:
+ *
+ * "The error INVALID_OPERATION is generated if the border color (taken from
+ * the embedded sampler for GetTextureHandleARB or from the <sampler> for
+ * GetTextureSamplerHandleARB) is not one of the following allowed values.
+ * If the texture's base internal format is signed or unsigned integer,
+ * allowed values are (0,0,0,0), (0,0,0,1), (1,1,1,0), and (1,1,1,1). If the
+ * base internal format is not integer, allowed values are
+ * (0.0,0.0,0.0,0.0), (0.0,0.0,0.0,1.0), (1.0,1.0,1.0,0.0), and
+ * (1.0,1.0,1.0,1.0)."
+ */
+
+#include "piglit-util-gl.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;
+
+PIGLIT_GL_TEST_CONFIG_END
+
+static enum piglit_result
+check_valid_integer_border_colors(void *data)
+{
+ GLint border_colors[4][4] = {
+ { 0, 0, 0, 0 },
+ { 0, 0, 0, 1 },
+ { 1, 1, 1, 0 },
+ { 1, 1, 1, 1 },
+ };
+ GLuint tex, i;
+
+ for (i = 0; i < 4; i++) {
+ tex = piglit_integer_texture(GL_RGBA32I, 16, 16, 0, 0);
+ glTextureParameterIiv(tex, GL_TEXTURE_BORDER_COLOR,
+ border_colors[i]);
+ glBindTexture(GL_TEXTURE_2D, 0);
+
+ glGetTextureHandleARB(tex);
+ if (!piglit_check_gl_error(GL_NO_ERROR))
+ return PIGLIT_FAIL;
+ }
+
+ return PIGLIT_PASS;
+}
+
+static enum piglit_result
+check_invalid_integer_border_colors(void *data)
+{
+ GLint border_color[4] = { 42, 2, 7, 9 };
+ GLuint sampler, texture;
+
+ texture = piglit_integer_texture(GL_RGBA32I, 16, 16, 0, 0);
+ glBindTexture(GL_TEXTURE_2D, 0);
+
+ /* Texture and sampler have to be consistent. */
+ glGenSamplers(1, &sampler);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
+ GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
+ GL_NEAREST);
+
+ glSamplerParameterIiv(sampler, GL_TEXTURE_BORDER_COLOR, border_color);
+
+ glGetTextureSamplerHandleARB(texture, sampler);
+ if (!piglit_check_gl_error(GL_INVALID_OPERATION))
+ return PIGLIT_FAIL;
+
+ return PIGLIT_PASS;
+}
+
+static enum piglit_result
+check_valid_float_border_colors(void *data)
+{
+ GLfloat border_colors[4][4] = {
+ { 0.0, 0.0, 0.0, 0.0 },
+ { 0.0, 0.0, 0.0, 1.0 },
+ { 1.0, 1.0, 1.0, 0.0 },
+ { 1.0, 1.0, 1.0, 1.0 },
+ };
+ GLuint tex, i;
+
+ for (i = 0; i < 4; i++) {
+ tex = piglit_rgbw_texture(GL_RGBA32F, 16, 16, GL_FALSE,
+ GL_FALSE, GL_UNSIGNED_NORMALIZED);
+ glTextureParameterfv(tex, GL_TEXTURE_BORDER_COLOR,
+ border_colors[i]);
+ glBindTexture(GL_TEXTURE_2D, 0);
+
+ glGetTextureHandleARB(tex);
+ if (!piglit_check_gl_error(GL_NO_ERROR))
+ return PIGLIT_FAIL;
+ }
+
+ return PIGLIT_PASS;
+}
+
+static enum piglit_result
+check_invalid_float_border_colors(void *data)
+{
+ GLfloat border_color[4] = { 0.3, 0.9, 0.7, 0.5 };
+ GLuint sampler, texture;
+
+ texture = piglit_rgbw_texture(GL_RGBA, 16, 16, GL_FALSE, GL_FALSE,
+ GL_UNSIGNED_NORMALIZED);
+ glBindTexture(GL_TEXTURE_2D, 0);
+
+ /* Texture and sampler have to be consistent. */
+ glGenSamplers(1, &sampler);
+ glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+
+ /* Set an invalid border color */
+ glSamplerParameterfv(sampler, GL_TEXTURE_BORDER_COLOR, border_color);
+
+ glGetTextureSamplerHandleARB(texture, sampler);
+ if (!piglit_check_gl_error(GL_INVALID_OPERATION))
+ return PIGLIT_FAIL;
+
+ return PIGLIT_PASS;
+}
+
+static const struct piglit_subtest subtests[] = {
+ {
+ "Check valid integer border color values",
+ "check_valid_integer_border_colors",
+ check_valid_integer_border_colors,
+ NULL
+ },
+ {
+ "Check invalid integer border color values",
+ "check_invalid_integer_border_colors",
+ check_invalid_integer_border_colors,
+ NULL
+ },
+ {
+ "Check valid float border color values",
+ "check_valid_float_border_colors",
+ check_valid_float_border_colors,
+ NULL
+ },
+ {
+ "Check invalid float border color values",
+ "check_invalid_float_border_colors",
+ check_invalid_float_border_colors,
+ 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);
+}
diff --git a/tests/spec/arb_bindless_texture/conversions.c b/tests/spec/arb_bindless_texture/conversions.c
new file mode 100644
index 000000000..809f908cb
--- /dev/null
+++ b/tests/spec/arb_bindless_texture/conversions.c
@@ -0,0 +1,280 @@
+/*
+ * 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
+ * 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
+ *
+ * Test cases for conversions and explicit constructors.
+ */
+
+#include "piglit-util-gl.h"
+
+static struct piglit_gl_test_config *piglit_config;
+
+PIGLIT_GL_TEST_CONFIG_BEGIN
+
+ piglit_config = &config;
+ config.supports_gl_core_version = 33;
+ config.supports_gl_compat_version = 33;
+
+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";
+
+GLuint vs;
+
+static enum piglit_result
+convert_sampler_to_uvec2(void *data)
+{
+ static const char *fs_src =
+ "#version 330\n"
+ "#extension GL_ARB_bindless_texture: require\n"
+ "\n"
+ "layout (bindless_sampler) uniform;\n"
+ "\n"
+ "uniform sampler2D given_tex;\n"
+ "uniform uvec2 expected_uval;\n"
+ "out vec4 color;\n"
+ "\n"
+ "void main()\n"
+ "{\n"
+ " color = vec4(0.0, 1.0, 0.0, 1.0);\n"
+ " uvec2 packval = uvec2(given_tex);\n"
+ " if (packval != expected_uval)\n"
+ " color.r = 1.0;\n"
+ "}\n";
+ float expected[4] = { 0.0, 1.0, 0.0, 1.0 };
+ GLuint expected_uval[2] = { 0x0040020, 0x1 };
+ GLuint64 handle = 0x100040020;
+ GLuint prog, fs;
+ GLint loc;
+ bool pass;
+
+ fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, fs_src);
+ prog = piglit_link_simple_program(vs, fs);
+ glUseProgram(prog);
+
+ loc = glGetUniformLocation(prog, "expected_uval");
+ glUniform2uiv(loc, 1, expected_uval);
+
+ loc = glGetUniformLocation(prog, "given_tex");
+ glUniformHandleui64vARB(loc, 1, &handle);
+
+ piglit_draw_rect(-1, -1, 1, 1);
+ pass = piglit_probe_pixel_rgba(0, 0, expected);
+
+ piglit_present_results();
+
+ return pass ? PIGLIT_PASS : PIGLIT_FAIL;
+}
+
+static enum piglit_result
+convert_uvec2_to_sampler(void *data)
+{
+ static const char *fs_src =
+ "#version 330\n"
+ "#extension GL_ARB_bindless_texture: require\n"
+ "\n"
+ "uniform uvec2 given_uval;\n"
+ "out vec4 color;\n"
+ "\n"
+ "void main()\n"
+ "{\n"
+ " color = vec4(0.0, 1.0, 0.0, 1.0);\n"
+ " sampler2D tex = sampler2D(given_uval);\n"
+ " uvec2 pair = uvec2(tex);\n"
+ " if (pair != given_uval)\n"
+ " color.r = 1.0;\n"
+ "}\n";
+ float expected[4] = { 0.0, 1.0, 0.0, 1.0 };
+ GLuint given_uval[2] = { 0x0040020, 0x1 };
+ GLuint prog, fs;
+ GLint loc;
+ bool pass;
+
+ fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, fs_src);
+ prog = piglit_link_simple_program(vs, fs);
+ glUseProgram(prog);
+
+ loc = glGetUniformLocation(prog, "given_uval");
+ glUniform2uiv(loc, 1, given_uval);
+
+ piglit_draw_rect(-1, -1, 1, 1);
+ pass = piglit_probe_pixel_rgba(0, 0, expected);
+
+ piglit_present_results();
+
+ return pass ? PIGLIT_PASS : PIGLIT_FAIL;
+}
+
+static enum piglit_result
+convert_image_to_uvec2(void *data)
+{
+ static const char *fs_src =
+ "#version 330\n"
+ "#extension GL_ARB_bindless_texture: require\n"
+ "#extension GL_ARB_shader_image_load_store: enable\n"
+ "\n"
+ "layout (bindless_image) uniform;\n"
+ "\n"
+ "uniform writeonly image2D given_img;\n"
+ "uniform uvec2 expected_uval;\n"
+ "out vec4 color;\n"
+ "\n"
+ "void main()\n"
+ "{\n"
+ " color = vec4(0.0, 1.0, 0.0, 1.0);\n"
+ " uvec2 packval = uvec2(given_img);\n"
+ " if (packval != expected_uval)\n"
+ " color.r = 1.0;\n"
+ "}\n";
+ float expected[4] = { 0.0, 1.0, 0.0, 1.0 };
+ GLuint expected_val[2] = { 0x0040020, 0x1 };
+ GLuint64 handle = 0x100040020;
+ GLuint prog, fs;
+ GLint loc;
+ bool pass;
+
+ if (!piglit_is_extension_supported("GL_ARB_shader_image_load_store"))
+ return PIGLIT_SKIP;
+
+ fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, fs_src);
+ prog = piglit_link_simple_program(vs, fs);
+ glUseProgram(prog);
+
+ loc = glGetUniformLocation(prog, "expected_uval");
+ glUniform2uiv(loc, 1, expected_val);
+
+ loc = glGetUniformLocation(prog, "given_img");
+ glUniformHandleui64vARB(loc, 1, &handle);
+
+ piglit_draw_rect(-1, -1, 1, 1);
+ pass = piglit_probe_pixel_rgba(0, 0, expected);
+
+ piglit_present_results();
+
+ return pass ? PIGLIT_PASS : PIGLIT_FAIL;
+}
+
+static enum piglit_result
+convert_uvec2_to_image(void *data)
+{
+ static const char *fs_src =
+ "#version 330\n"
+ "#extension GL_ARB_bindless_texture: require\n"
+ "#extension GL_ARB_shader_image_load_store: enable\n"
+ "\n"
+ "uniform uvec2 given_uval;\n"
+ "out vec4 color;\n"
+ "\n"
+ "void main()\n"
+ "{\n"
+ " color = vec4(0.0, 1.0, 0.0, 1.0);\n"
+ " writeonly image2D img = sampler2D(given_uval);\n"
+ " uvec2 pair = uvec2(img);\n"
+ " if (pair != given_uval)\n"
+ " color.r = 1.0;\n"
+ "}\n";
+ float expected[4] = { 0.0, 1.0, 0.0, 1.0 };
+ GLuint given_uval[2] = { 0x0040020, 0x1 };
+ GLuint prog, fs;
+ GLint loc;
+ bool pass;
+
+ if (!piglit_is_extension_supported("GL_ARB_shader_image_load_store"))
+ return PIGLIT_SKIP;
+
+ fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, fs_src);
+ prog = piglit_link_simple_program(vs, fs);
+ glUseProgram(prog);
+
+ loc = glGetUniformLocation(prog, "given_uval");
+ glUniform2uiv(loc, 1, given_uval);
+
+ piglit_draw_rect(-1, -1, 1, 1);
+ pass = piglit_probe_pixel_rgba(0, 0, expected);
+
+ piglit_present_results();
+
+ return pass ? PIGLIT_PASS : PIGLIT_FAIL;
+}
+
+static const struct piglit_subtest subtests[] = {
+ {
+ "Convert sampler to uvec2",
+ "convert_sampler_to_uvec2",
+ convert_sampler_to_uvec2,
+ NULL
+ },
+ {
+ "Convert uvec2 to sampler",
+ "convert_uvec2_to_sampler",
+ convert_uvec2_to_sampler,
+ },
+ {
+ "Convert image to uvec2",
+ "convert_image_to_uvec2",
+ convert_image_to_uvec2,
+ NULL
+ },
+ {
+ "Convert uvec2 to image",
+ "convert_uvec2_to_image",
+ convert_uvec2_to_image,
+ },
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ }
+};
+
+enum piglit_result
+piglit_display(void)
+{
+ return PIGLIT_FAIL;
+}
+
+void
+piglit_init(int argc, char **argv)
+{
+ enum piglit_result result;
+
+ vs = piglit_compile_shader_text(GL_VERTEX_SHADER, passthrough_vs_src);
+
+ 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);
+}
diff --git a/tests/spec/arb_bindless_texture/errors.c b/tests/spec/arb_bindless_texture/errors.c
new file mode 100644
index 000000000..2f6607671
--- /dev/null
+++ b/tests/spec/arb_bindless_texture/errors.c
@@ -0,0 +1,514 @@
+/*
+ * 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 new bindless API.
+ */
+
+#include "piglit-util-gl.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;
+
+PIGLIT_GL_TEST_CONFIG_END
+
+static enum piglit_result
+check_GetTextureHandle_invalid_values(void *data)
+{
+ GLuint sampler, texture;
+
+ /* The ARB_bindless_texture spec says:
+ *
+ * "The error INVALID_VALUE is generated by GetTextureHandleARB or
+ * GetTextureSamplerHandleARB if <texture> is zero or not the name of
+ * an existing texture object."
+ */
+
+ /* Invalid texture */
+ glGetTextureHandleARB(42);
+ if (!piglit_check_gl_error(GL_INVALID_VALUE))
+ return PIGLIT_FAIL;
+
+ /* Invalid texture */
+ glGenSamplers(1, &sampler);
+ glGetTextureSamplerHandleARB(42, sampler);
+ if (!piglit_check_gl_error(GL_INVALID_VALUE))
+ return PIGLIT_FAIL;
+
+ /* The ARB_bindless_texture spec says:
+ *
+ * "The error INVALID_VALUE is generated by GetTextureSamplerHandleARB
+ * if <sampler> is zero or is not the name of an existing sampler
+ * object."
+ */
+
+ /* Invalid sampler */
+ glGenTextures(1, &texture);
+ glGetTextureSamplerHandleARB(texture, 42);
+ if (!piglit_check_gl_error(GL_INVALID_VALUE))
+ return PIGLIT_FAIL;
+
+ return PIGLIT_PASS;
+}
+
+static enum piglit_result
+check_GetTextureHandle_invalid_operations(void *data)
+{
+ GLuint sampler, texture;
+
+ glGenTextures(1, &texture);
+ glBindTexture(GL_TEXTURE_2D, texture);
+
+ /* The ARB_bindless_texture spec says:
+ *
+ * "The error INVALID_OPERATION is generated by GetTextureHandleARB or
+ * GetTextureSamplerHandleARB if the texture object specified by
+ * <texture> is not complete."
+ */
+
+ /* Incomplete texture */
+ glGetTextureHandleARB(texture);
+ if (!piglit_check_gl_error(GL_INVALID_OPERATION))
+ return PIGLIT_FAIL;
+
+ /* Incomplete texture */
+ glGenSamplers(1, &sampler);
+ glBindSampler(0, sampler);
+ glGetTextureSamplerHandleARB(texture, sampler);
+ if (!piglit_check_gl_error(GL_INVALID_OPERATION))
+ return PIGLIT_FAIL;
+
+ return PIGLIT_PASS;
+}
+
+static enum piglit_result
+check_MakeTextureHandleResident_invalid_operations(void *data)
+{
+ GLuint64 handle;
+ GLuint texture;
+
+ /* The ARB_bindless_texture spec says:
+ *
+ * "The error INVALID_OPERATION is generated by
+ * MakeTextureHandleResidentARB if <handle> is not a valid texture
+ * handle, or if <handle> is already resident in the current GL
+ * context."
+ */
+
+ /* Invalid handle */
+ glMakeTextureHandleResidentARB(42);
+ if (!piglit_check_gl_error(GL_INVALID_OPERATION))
+ return PIGLIT_FAIL;
+
+ texture = piglit_rgbw_texture(GL_RGBA, 16, 16, GL_FALSE, GL_FALSE,
+ GL_UNSIGNED_NORMALIZED);
+ glBindTexture(GL_TEXTURE_2D, 0);
+
+ handle = glGetTextureHandleARB(texture);
+ if (!piglit_check_gl_error(GL_NO_ERROR))
+ return PIGLIT_FAIL;
+
+ glMakeTextureHandleResidentARB(handle);
+ if (!piglit_check_gl_error(GL_NO_ERROR))
+ return PIGLIT_FAIL;
+
+ /* Already resident */
+ glMakeTextureHandleResidentARB(handle);
+ if (!piglit_check_gl_error(GL_INVALID_OPERATION))
+ return PIGLIT_FAIL;
+
+ return PIGLIT_PASS;
+}
+
+static enum piglit_result
+check_MakeTextureHandleNonResident_invalid_operations(void *data)
+{
+ GLuint64 handle;
+ GLuint texture;
+
+ /* The ARB_bindless_texture spec says:
+ *
+ * "The error INVALID_OPERATION is generated by
+ * MakeTextureHandleNonResidentARB if <handle> is not a valid texture
+ * handle, or if <handle> is not resident in the current GL context."
+ */
+
+ /* Invalid handle */
+ glMakeTextureHandleNonResidentARB(42);
+ if (!piglit_check_gl_error(GL_INVALID_OPERATION))
+ return PIGLIT_FAIL;
+
+ texture = piglit_rgbw_texture(GL_RGBA, 16, 16, GL_FALSE, GL_FALSE,
+ GL_UNSIGNED_NORMALIZED);
+ glBindTexture(GL_TEXTURE_2D, 0);
+
+ handle = glGetTextureHandleARB(texture);
+ if (!piglit_check_gl_error(GL_NO_ERROR))
+ return PIGLIT_FAIL;
+
+ /* Not resident */
+ glMakeTextureHandleNonResidentARB(handle);
+ if (!piglit_check_gl_error(GL_INVALID_OPERATION))
+ return PIGLIT_FAIL;
+
+ return PIGLIT_PASS;
+}
+
+static enum piglit_result
+check_IsTextureHandleResident_invalid_operations(void *data)
+{
+ GLboolean ret;
+
+ /* The ARB_bindless_texture spec says:
+ *
+ * "The error INVALID_OPERATION will be generated by
+ * IsTextureHandleResidentARB and IsImageHandleResidentARB if <handle>
+ * is not a valid texture or image handle, respectively."
+ */
+ ret = glIsTextureHandleResidentARB(42);
+ if (!piglit_check_gl_error(GL_INVALID_OPERATION))
+ return PIGLIT_FAIL;
+
+ return ret == false ? PIGLIT_PASS : PIGLIT_FAIL;
+}
+
+static enum piglit_result
+check_GetImageHandle_invalid_values(void *data)
+{
+ GLuint tex;
+
+ if (!piglit_is_extension_supported("GL_ARB_shader_image_load_store"))
+ return PIGLIT_SKIP;
+
+ /* The ARB_bindless_texture spec says:
+ *
+ * "The error INVALID_VALUE is generated by GetImageHandleARB if
+ * <texture> is zero or not the name of an existing texture object, if
+ * the image for <level> does not existing in <texture>, or if
+ * <layered> is FALSE and <layer> is greater than or equal to the
+ * number of layers in the image at <level>."
+ *
+ * NOTE: The spec says nothing about invalid formats, but I think it
+ * makes sense to return INVALID_VALUE like BindImageTexture().
+ */
+
+ /* Invalid texture */
+ glGetImageHandleARB(42, 0, GL_FALSE, 0, GL_RGBA32F);
+ if (!piglit_check_gl_error(GL_INVALID_VALUE))
+ return PIGLIT_FAIL;
+
+ tex = piglit_rgbw_texture(GL_RGBA32F, 16, 16, GL_TRUE, GL_FALSE,
+ GL_UNSIGNED_NORMALIZED);
+ glBindTexture(GL_TEXTURE_2D, 0);
+
+ /* Invalid level */
+ glGetImageHandleARB(tex, 42, GL_FALSE, 0, GL_RGBA32F);
+ if (!piglit_check_gl_error(GL_INVALID_VALUE))
+ return PIGLIT_FAIL;
+
+ /* Invalid layer */
+ glGetImageHandleARB(tex, 0, GL_FALSE, 42, GL_RGBA32F);
+ if (!piglit_check_gl_error(GL_INVALID_VALUE))
+ return PIGLIT_FAIL;
+
+ /* Invalid format */
+ glGetImageHandleARB(tex, 0, GL_FALSE, 0, GL_RGBA);
+ if (!piglit_check_gl_error(GL_INVALID_VALUE))
+ return PIGLIT_FAIL;
+
+ return PIGLIT_PASS;
+}
+
+static enum piglit_result
+check_GetImageHandle_invalid_operations(void *data)
+{
+ GLuint tex;
+
+ if (!piglit_is_extension_supported("GL_ARB_shader_image_load_store"))
+ return PIGLIT_SKIP;
+
+ glGenTextures(1, &tex);
+ glBindTexture(GL_TEXTURE_2D, tex);
+
+ /* The ARB_bindless_texture spec says:
+ *
+ * "The error INVALID_OPERATION is generated by GetImageHandleARB if
+ * the texture object <texture> is not complete or if <layered> is
+ * TRUE and <texture> is not a three-dimensional, one-dimensional
+ * array, two dimensional array, cube map, or cube map array texture."
+ */
+
+ /* Incomplete texture */
+ glGetImageHandleARB(tex, 0, GL_FALSE, 0, GL_RGBA32F);
+ if (!piglit_check_gl_error(GL_INVALID_OPERATION))
+ return PIGLIT_FAIL;
+
+ tex = piglit_rgbw_texture(GL_RGBA32F, 16, 16, GL_FALSE, GL_FALSE,
+ GL_UNSIGNED_NORMALIZED);
+ glBindTexture(GL_TEXTURE_2D, 0);
+
+ /* Not layered texture */
+ glGetImageHandleARB(tex, 0, GL_TRUE, 0, GL_RGBA32F);
+ if (!piglit_check_gl_error(GL_INVALID_OPERATION))
+ return PIGLIT_FAIL;
+
+ return PIGLIT_PASS;
+}
+
+static enum piglit_result
+check_MakeImageHandleResident_invalid_enum(void *data)
+{
+ GLuint64 handle;
+ GLuint tex;
+
+ if (!piglit_is_extension_supported("GL_ARB_shader_image_load_store"))
+ return PIGLIT_SKIP;
+
+ /* The ARB_bindless_texture spec says:
+ *
+ * "To make an image handle accessible to shaders for image loads,
+ * stores, and atomic operations, the handle must be made resident by
+ * calling:
+ *
+ * void MakeImageHandleResidentARB(uint64 handle, enum access);
+ *
+ * <access> specifies whether the texture bound to the image handle
+ * will be treated as READ_ONLY, WRITE_ONLY, or READ_WRITE."
+ *
+ * NOTE: The spec doesn't explicitely say that INVALID_ENUM should
+ * be returned, but I think it makes sense (like NVIDIA).
+ */
+ tex = piglit_rgbw_texture(GL_RGBA32F, 16, 16, GL_FALSE, GL_FALSE,
+ GL_UNSIGNED_NORMALIZED);
+ glBindTexture(GL_TEXTURE_2D, 0);
+
+ handle = glGetImageHandleARB(tex, 0, GL_FALSE, 0, GL_RGBA32F);
+ if (!piglit_check_gl_error(GL_NO_ERROR))
+ return PIGLIT_FAIL;
+
+ /* Invalid access */
+ glMakeImageHandleResidentARB(handle, GL_DEPTH);
+ if (!piglit_check_gl_error(GL_INVALID_ENUM))
+ return PIGLIT_FAIL;
+
+ return PIGLIT_PASS;
+}
+
+static enum piglit_result
+check_MakeImageHandleResident_invalid_operations(void *data)
+{
+ GLuint64 handle;
+ GLuint tex;
+
+ if (!piglit_is_extension_supported("GL_ARB_shader_image_load_store"))
+ return PIGLIT_SKIP;
+
+ /* The ARB_bindless_texture spec says:
+ *
+ * "The error INVALID_OPERATION is generated by
+ * MakeImageHandleResidentARB if <handle> is not a valid image handle,
+ * or if <handle> is already resident in the current GL context."
+ */
+
+ /* Invalid handle */
+ glMakeImageHandleResidentARB(42, GL_READ_WRITE);
+ if (!piglit_check_gl_error(GL_INVALID_OPERATION))
+ return PIGLIT_FAIL;
+
+ tex = piglit_rgbw_texture(GL_RGBA32F, 16, 16, GL_FALSE, GL_FALSE,
+ GL_UNSIGNED_NORMALIZED);
+ glBindTexture(GL_TEXTURE_2D, 0);
+
+ handle = glGetImageHandleARB(tex, 0, GL_FALSE, 0, GL_RGBA32F);
+ if (!piglit_check_gl_error(GL_NO_ERROR))
+ return PIGLIT_FAIL;
+
+ glMakeImageHandleResidentARB(handle, GL_READ_WRITE);
+ if (!piglit_check_gl_error(GL_NO_ERROR))
+ return PIGLIT_FAIL;
+
+ /* Handle already resident. */
+ glMakeImageHandleResidentARB(handle, GL_READ_WRITE);
+ if (!piglit_check_gl_error(GL_INVALID_OPERATION))
+ return PIGLIT_FAIL;
+
+ return PIGLIT_PASS;
+}
+
+static enum piglit_result
+check_MakeImageHandleNonResident_invalid_operations(void *data)
+{
+ GLuint64 handle;
+ GLuint tex;
+
+ if (!piglit_is_extension_supported("GL_ARB_shader_image_load_store"))
+ return PIGLIT_SKIP;
+
+ /* The ARB_bindless_texture spec says:
+ *
+ * "The error INVALID_OPERATION is generated by
+ * MakeImageHandleNonResidentARB if <handle> is not a valid image
+ * handle, or if <handle> is not resident in the current GL context."
+ */
+
+ /* Invalid handle */
+ glMakeImageHandleNonResidentARB(42);
+ if (!piglit_check_gl_error(GL_INVALID_OPERATION))
+ return PIGLIT_FAIL;
+
+ tex = piglit_rgbw_texture(GL_RGBA32F, 16, 16, GL_FALSE, GL_FALSE,
+ GL_UNSIGNED_NORMALIZED);
+ glBindTexture(GL_TEXTURE_2D, 0);
+
+ handle = glGetImageHandleARB(tex, 0, GL_FALSE, 0, GL_RGBA32F);
+ if (!piglit_check_gl_error(GL_NO_ERROR))
+ return PIGLIT_FAIL;
+
+ /* Handle not resident. */
+ glMakeImageHandleNonResidentARB(handle);
+ if (!piglit_check_gl_error(GL_INVALID_OPERATION))
+ return PIGLIT_FAIL;
+
+ return PIGLIT_PASS;
+}
+
+static enum piglit_result
+check_IsImageHandleResident_invalid_operations(void *data)
+{
+ GLboolean ret;
+
+ if (!piglit_is_extension_supported("GL_ARB_shader_image_load_store"))
+ return PIGLIT_SKIP;
+
+ /* The ARB_bindless_texture spec says:
+ *
+ * "The error INVALID_OPERATION will be generated by
+ * IsTextureHandleResidentARB and IsImageHandleResidentARB if <handle>
+ * is not a valid texture or image handle, respectively."
+ */
+ ret = glIsImageHandleResidentARB(42);
+ if (!piglit_check_gl_error(GL_INVALID_OPERATION))
+ return PIGLIT_FAIL;
+
+ return ret == false ? PIGLIT_PASS : PIGLIT_FAIL;
+}
+
+static const struct piglit_subtest subtests[] = {
+ {
+ "Check glGetTexture*HandleARB() invalid values",
+ "check_GetTextureHandle_invalid_values",
+ check_GetTextureHandle_invalid_values,
+ NULL
+ },
+ {
+ "Check glGetTexture*HandleARB() invalid operations",
+ "check_GetTextureHandle_invalid_operations",
+ check_GetTextureHandle_invalid_operations,
+ NULL
+ },
+ {
+ "Check glMakeTextureHandleResidentARB() invalid operations",
+ "check_MakeTextureHandleResident_invalid_operations",
+ check_MakeTextureHandleResident_invalid_operations,
+ NULL
+ },
+ {
+ "Check glMakeTextureHandleNonResidentARB() invalid operations",
+ "check_MakeTextureHandleNonResident_invalid_operations",
+ check_MakeTextureHandleNonResident_invalid_operations,
+ NULL
+ },
+ {
+ "Check glIsTextureHandleResidentARB() invalid operations",
+ "check_IsTextureHandleResident_invalid_operations",
+ check_IsTextureHandleResident_invalid_operations,
+ NULL
+ },
+ {
+ "Check glGetImageHandleARB() invalid values",
+ "check_GetImageHandle_invalid_values",
+ check_GetImageHandle_invalid_values,
+ NULL
+ },
+ {
+ "Check glGetImageHandleARB() invalid operations",
+ "check_GetImageHandle_invalid_operations",
+ check_GetImageHandle_invalid_operations,
+ NULL
+ },
+ {
+ "Check glMakeImageHandleResidentARB() invalid enum",
+ "check_MakeImageHandleResident_invalid_enum",
+ check_MakeImageHandleResident_invalid_enum,
+ NULL
+ },
+ {
+ "Check glMakeImageHandleResidentARB() invalid operations",
+ "check_MakeImageHandleResident_invalid_operations",
+ check_MakeImageHandleResident_invalid_operations,
+ NULL
+ },
+ {
+ "Check glMakeImageHandleNonResidentARB() invalid operations",
+ "check_MakeImageHandleNonResident_invalid_operations",
+ check_MakeImageHandleNonResident_invalid_operations,
+ NULL
+ },
+ {
+ "Check glIsImageHandleResidentARB() invalid operations",
+ "check_IsImageHandleResident_invalid_operations",
+ check_IsImageHandleResident_invalid_operations,
+ 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);
+}
diff --git a/tests/spec/arb_bindless_texture/handles.c b/tests/spec/arb_bindless_texture/handles.c
new file mode 100644
index 000000000..902a1c392
--- /dev/null
+++ b/tests/spec/arb_bindless_texture/handles.c
@@ -0,0 +1,576 @@
+/*
+ * 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 texture handle API with
+ * glGetTextureHandleARB(), glMakeTextureHandleResidentARB(), etc.
+ */
+
+#include "piglit-util-gl.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;
+
+PIGLIT_GL_TEST_CONFIG_END
+
+static enum piglit_result
+check_GetTextureHandle_zero_handle(void *data)
+{
+ bool pass = true;
+ GLuint64 handle;
+
+ /* The ARB_bindless_texture spec says:
+ *
+ * "If an error occurs, a handle of zero is returned."
+ */
+ handle = glGetTextureHandleARB(42);
+ if (!piglit_check_gl_error(GL_INVALID_VALUE))
+ return PIGLIT_FAIL;
+
+ pass &= handle == 0;
+
+ handle = glGetTextureSamplerHandleARB(42, 42);
+ if (!piglit_check_gl_error(GL_INVALID_VALUE))
+ return PIGLIT_FAIL;
+
+ pass &= handle == 0;
+
+ return pass ? PIGLIT_PASS : PIGLIT_FAIL;
+}
+
+static enum piglit_result
+check_GetTextureHandle_reserved_zero_handle(void *data)
+{
+ GLuint texture, sampler;
+ bool pass = true;
+ GLuint64 handle;
+
+ texture = piglit_rgbw_texture(GL_RGBA32F, 16, 16, GL_FALSE, GL_FALSE,
+ GL_UNSIGNED_NORMALIZED);
+ glBindTexture(GL_TEXTURE_2D, 0);
+
+ /* The ARB_bindless_texture spec says:
+ *
+ * "The handle zero is reserved and will never be assigned to a valid
+ * texture handle."
+ */
+ handle = glGetTextureHandleARB(texture);
+ if (!piglit_check_gl_error(GL_NO_ERROR))
+ return PIGLIT_FAIL;
+
+ pass &= handle > 0;
+
+ /* Texture and sampler have to be consistent. */
+ glGenSamplers(1, &sampler);
+ glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+
+ handle = glGetTextureSamplerHandleARB(texture, sampler);
+ if (!piglit_check_gl_error(GL_NO_ERROR))
+ return PIGLIT_FAIL;
+
+ pass &= handle > 0;
+
+ return pass ? PIGLIT_PASS : PIGLIT_FAIL;
+}
+
+static enum piglit_result
+check_GetTextureHandle_uniqueness(void *data)
+{
+ GLuint sampler, texture;
+ GLuint64 handles[4];
+ bool pass = true;
+
+ texture = piglit_rgbw_texture(GL_RGBA32F, 16, 16, GL_FALSE, GL_FALSE,
+ GL_UNSIGNED_NORMALIZED);
+ glBindTexture(GL_TEXTURE_2D, 0);
+
+ /* The ARB_bindless_texture spec says:
+ *
+ * "The handle for each texture or texture/sampler pair is unique; the
+ * same handle will be returned if GetTextureHandleARB is called
+ * multiple times for the same texture or if GetTextureSamplerHandleARB
+ * is called multiple times for the same texture/sampler pair."
+ */
+ handles[0] = glGetTextureHandleARB(texture);
+ handles[1] = glGetTextureHandleARB(texture);
+ if (!piglit_check_gl_error(GL_NO_ERROR))
+ return PIGLIT_FAIL;
+
+ pass &= handles[0] == handles[1];
+
+ /* Texture and sampler have to be consistent. */
+ glGenSamplers(1, &sampler);
+ glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+
+ handles[2] = glGetTextureSamplerHandleARB(texture, sampler);
+ handles[3] = glGetTextureSamplerHandleARB(texture, sampler);
+ if (!piglit_check_gl_error(GL_NO_ERROR))
+ return PIGLIT_FAIL;
+
+ pass &= handles[2] == handles[3];
+ pass &= handles[0] != handles[2];
+
+ return pass ? PIGLIT_PASS : PIGLIT_FAIL;
+}
+
+static enum piglit_result
+check_IsTextureHandleResident_valid(void *data)
+{
+ bool pass = true;
+ GLuint64 handle;
+ GLboolean ret;
+ GLuint tex;
+
+ tex = piglit_rgbw_texture(GL_RGBA32F, 16, 16, GL_FALSE, GL_FALSE,
+ GL_UNSIGNED_NORMALIZED);
+ glBindTexture(GL_TEXTURE_2D, 0);
+
+ handle = glGetTextureHandleARB(tex);
+ if (!piglit_check_gl_error(GL_NO_ERROR))
+ return PIGLIT_FAIL;
+
+ /* Resident */
+ glMakeTextureHandleResidentARB(handle);
+ if (!piglit_check_gl_error(GL_NO_ERROR))
+ return PIGLIT_FAIL;
+
+ ret = glIsTextureHandleResidentARB(handle);
+ if (!piglit_check_gl_error(GL_NO_ERROR))
+ return PIGLIT_FAIL;
+
+ pass &= ret;
+
+ /* Non resident */
+ glMakeTextureHandleNonResidentARB(handle);
+ if (!piglit_check_gl_error(GL_NO_ERROR))
+ return PIGLIT_FAIL;
+
+ ret = glIsTextureHandleResidentARB(handle);
+ if (!piglit_check_gl_error(GL_NO_ERROR))
+ return PIGLIT_FAIL;
+
+ pass &= !ret;
+
+ return pass ? PIGLIT_PASS : PIGLIT_FAIL;
+}
+
+static enum piglit_result
+delete_texture_sampler_while_handle_is_allocated(void *data)
+{
+ GLuint texture, sampler;
+ GLuint64 handle;
+
+ /* The ARB_bindless_texture spec says:
+ *
+ * "(5) Is there a way to release a texture or image handle after it
+ * is created?"
+ *
+ * "RESOLVED: No API is provided to release or delete handles once
+ * they are created. Texture and image handles are automatically
+ * reclaimed when the underlying texture or sampler objects are finally
+ * deleted. This deletion will happen only when no handle using the
+ * texture or sampler object is resident on any context."
+ */
+
+ /* Test #1: Create a texture handle and remove it. */
+ texture = piglit_rgbw_texture(GL_RGBA32F, 16, 16, GL_FALSE, GL_FALSE,
+ GL_UNSIGNED_NORMALIZED);
+ glBindTexture(GL_TEXTURE_2D, 0);
+
+ handle = glGetTextureHandleARB(texture);
+ if (!piglit_check_gl_error(GL_NO_ERROR))
+ return PIGLIT_FAIL;
+
+ glDeleteTextures(1, &texture);
+
+ /* Texture handle should have been removed. */
+ glMakeTextureHandleResidentARB(handle);
+ if (!piglit_check_gl_error(GL_INVALID_OPERATION))
+ return PIGLIT_FAIL;
+
+ /* Test #2: Create a texture/sampler handle and remove the sampler. */
+ texture = piglit_rgbw_texture(GL_RGBA32F, 16, 16, GL_FALSE, GL_FALSE,
+ GL_UNSIGNED_NORMALIZED);
+ glBindTexture(GL_TEXTURE_2D, 0);
+
+ /* Texture and sampler have to be consistent. */
+ glGenSamplers(1, &sampler);
+ glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+
+ handle = glGetTextureSamplerHandleARB(texture, sampler);
+ if (!piglit_check_gl_error(GL_NO_ERROR))
+ return PIGLIT_FAIL;
+
+ glDeleteSamplers(1, &sampler);
+
+ /* Texture handle should have been removed. */
+ glMakeTextureHandleResidentARB(handle);
+ if (!piglit_check_gl_error(GL_INVALID_OPERATION))
+ return PIGLIT_FAIL;
+
+ return PIGLIT_PASS;
+}
+
+static enum piglit_result
+delete_texture_sampler_while_handle_is_resident(void *data)
+{
+ GLuint texture, sampler;
+ GLuint64 handle;
+ GLboolean ret;
+
+ /* The ARB_bindless_texture_spec says:
+ *
+ * "(7) What happens if you try to delete a texture or sampler object
+ * with a handle that is resident in another context?"
+ *
+ * "RESOLVED: Deleting the texture will remove the texture from the
+ * name space and make all handles using the texture non-resident in
+ * the current context. However, texture or image handles for a
+ * deleted texture are not deleted until the underlying texture or
+ * sampler object itself is deleted. That deletion won't happen
+ * until the object is not bound anywhere and there are no handles
+ * using the object that are resident in any context."
+ */
+
+ /* Test #1: Create a texture handle, make it resident and remove the
+ * texture. */
+ texture = piglit_rgbw_texture(GL_RGBA, 16, 16, GL_FALSE, GL_FALSE,
+ GL_UNSIGNED_NORMALIZED);
+ glBindTexture(GL_TEXTURE_2D, 0);
+
+ handle = glGetTextureHandleARB(texture);
+ if (!piglit_check_gl_error(GL_NO_ERROR))
+ return PIGLIT_FAIL;
+
+ glMakeTextureHandleResidentARB(handle);
+ if (!piglit_check_gl_error(GL_NO_ERROR))
+ return PIGLIT_FAIL;
+
+ glDeleteTextures(1, &texture);
+
+ /* Texture handle should have been removed. */
+ glIsTextureHandleResidentARB(handle);
+ if (!piglit_check_gl_error(GL_INVALID_OPERATION))
+ return PIGLIT_FAIL;
+
+ /* Test #2: Create a texture/sampler handle, make it resident and
+ * remove the sampler. */
+ texture = piglit_rgbw_texture(GL_RGBA32F, 16, 16, GL_FALSE, GL_FALSE,
+ GL_UNSIGNED_NORMALIZED);
+ glBindTexture(GL_TEXTURE_2D, 0);
+
+ /* Texture and sampler have to be consistent. */
+ glGenSamplers(1, &sampler);
+ glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+
+ handle = glGetTextureSamplerHandleARB(texture, sampler);
+ if (!piglit_check_gl_error(GL_NO_ERROR))
+ return PIGLIT_FAIL;
+
+ glMakeTextureHandleResidentARB(handle);
+ if (!piglit_check_gl_error(GL_NO_ERROR))
+ return PIGLIT_FAIL;
+
+ glDeleteSamplers(1, &sampler);
+
+ /* Texture handle should still be resident. */
+ ret = glIsTextureHandleResidentARB(handle);
+ if (!piglit_check_gl_error(GL_NO_ERROR))
+ return PIGLIT_FAIL;
+
+ if (!ret)
+ return PIGLIT_FAIL;
+
+ return PIGLIT_PASS;
+}
+
+static enum piglit_result
+check_GetImageHandle_zero_handle(void *data)
+{
+ GLuint64 handle;
+
+ if (!piglit_is_extension_supported("GL_ARB_shader_image_load_store"))
+ return PIGLIT_SKIP;
+
+ /* The ARB_bindless_texture spec says:
+ *
+ * "A 64-bit unsigned integer handle is returned if the command
+ * succeeds; otherwise, zero is returned."
+ */
+ handle = glGetImageHandleARB(42, 0, GL_FALSE, 0, GL_RGBA32F);
+ if (!piglit_check_gl_error(GL_INVALID_VALUE))
+ return PIGLIT_FAIL;
+
+ return handle == 0 ? PIGLIT_PASS : PIGLIT_FAIL;
+}
+
+static enum piglit_result
+check_GetImageHandle_reserved_zero_handle(void *data)
+{
+ GLuint64 handle;
+ GLuint tex;
+
+ if (!piglit_is_extension_supported("GL_ARB_shader_image_load_store"))
+ return PIGLIT_SKIP;
+
+ tex = piglit_rgbw_texture(GL_RGBA32F, 16, 16, GL_FALSE, GL_FALSE,
+ GL_UNSIGNED_NORMALIZED);
+ glBindTexture(GL_TEXTURE_2D, 0);
+
+ /* The ARB_bindless_texture spec says:
+ *
+ * "The handle zero is reserved and will never be assigned to a valid
+ * image handle."
+ */
+ handle = glGetImageHandleARB(tex, 0, GL_FALSE, 0, GL_RGBA32F);
+ if (!piglit_check_gl_error(GL_NO_ERROR))
+ return PIGLIT_FAIL;
+
+ return handle > 0 ? PIGLIT_PASS : PIGLIT_FAIL;
+}
+
+static enum piglit_result
+check_GetImageHandle_uniqueness(void *data)
+{
+ GLuint64 handles[4];
+ bool pass = true;
+ GLuint tex;
+
+ if (!piglit_is_extension_supported("GL_ARB_shader_image_load_store"))
+ return PIGLIT_SKIP;
+
+ tex = piglit_rgbw_texture(GL_RGBA32F, 16, 16, GL_TRUE, GL_FALSE,
+ GL_UNSIGNED_NORMALIZED);
+ glBindTexture(GL_TEXTURE_2D, 0);
+
+ /* The ARB_bindless_texture spec says:
+ *
+ * "The handle returned for each combination of <texture>, <level>,
+ * <layered>, <layer>, and <format> is unique; the same handle will
+ * be returned if GetImageHandleARB is called multiple times with
+ * the same parameters."
+ */
+ handles[0] = glGetImageHandleARB(tex, 0, GL_FALSE, 0, GL_RGBA32F);
+ handles[1] = glGetImageHandleARB(tex, 0, GL_FALSE, 0, GL_RGBA32F);
+ if (!piglit_check_gl_error(GL_NO_ERROR))
+ return PIGLIT_FAIL;
+
+ pass &= handles[0] == handles[1];
+
+ /* Use a different format. */
+ handles[2] = glGetImageHandleARB(tex, 0, GL_FALSE, 0, GL_RGBA32I);
+ handles[3] = glGetImageHandleARB(tex, 0, GL_FALSE, 0, GL_RGBA32I);
+ if (!piglit_check_gl_error(GL_NO_ERROR))
+ return PIGLIT_FAIL;
+
+ pass &= handles[2] == handles[3];
+ pass &= handles[0] != handles[2];
+
+ return pass ? PIGLIT_PASS : PIGLIT_FAIL;
+}
+
+static enum piglit_result
+check_IsImageHandleResident_valid(void *data)
+{
+ bool pass = true;
+ GLuint64 handle;
+ GLboolean ret;
+ GLuint tex;
+
+ if (!piglit_is_extension_supported("GL_ARB_shader_image_load_store"))
+ return PIGLIT_SKIP;
+
+ tex = piglit_rgbw_texture(GL_RGBA32F, 16, 16, GL_TRUE, GL_FALSE,
+ GL_UNSIGNED_NORMALIZED);
+ glBindTexture(GL_TEXTURE_2D, 0);
+
+ handle = glGetImageHandleARB(tex, 0, GL_FALSE, 0, GL_RGBA32F);
+ if (!piglit_check_gl_error(GL_NO_ERROR))
+ return PIGLIT_FAIL;
+
+ /* Resident */
+ glMakeImageHandleResidentARB(handle, GL_READ_WRITE);
+ if (!piglit_check_gl_error(GL_NO_ERROR))
+ return PIGLIT_FAIL;
+
+ ret = glIsImageHandleResidentARB(handle);
+ if (!piglit_check_gl_error(GL_NO_ERROR))
+ return PIGLIT_FAIL;
+
+ pass &= ret;
+
+ /* Non resident */
+ glMakeImageHandleNonResidentARB(handle);
+ if (!piglit_check_gl_error(GL_NO_ERROR))
+ return PIGLIT_FAIL;
+
+ ret = glIsImageHandleResidentARB(handle);
+ if (!piglit_check_gl_error(GL_NO_ERROR))
+ return PIGLIT_FAIL;
+
+ pass &= !ret;
+
+ return pass ? PIGLIT_PASS : PIGLIT_FAIL;
+}
+
+static enum piglit_result
+delete_texture_while_image_handle_resident(void *data)
+{
+ GLuint64 handle;
+ GLuint tex;
+
+ if (!piglit_is_extension_supported("GL_ARB_shader_image_load_store"))
+ return PIGLIT_SKIP;
+
+ tex = piglit_rgbw_texture(GL_RGBA32F, 16, 16, GL_TRUE, GL_FALSE,
+ GL_UNSIGNED_NORMALIZED);
+ glBindTexture(GL_TEXTURE_2D, 0);
+
+ handle = glGetImageHandleARB(tex, 0, GL_FALSE, 0, GL_RGBA32F);
+ if (!piglit_check_gl_error(GL_NO_ERROR))
+ return PIGLIT_FAIL;
+
+ glMakeImageHandleResidentARB(handle, GL_READ_WRITE);
+ if (!piglit_check_gl_error(GL_NO_ERROR))
+ return PIGLIT_FAIL;
+
+ glDeleteTextures(1, &tex);
+
+ /* Image handle should have been removed. */
+ glMakeImageHandleResidentARB(handle, GL_READ_WRITE);
+ if (!piglit_check_gl_error(GL_INVALID_OPERATION))
+ return PIGLIT_FAIL;
+
+ return PIGLIT_PASS;
+}
+
+static const struct piglit_subtest subtests[] = {
+ {
+ "Check glGetTexture*HandleARB() zero handle",
+ "check_GetTextureHandle_zero_handle",
+ check_GetTextureHandle_zero_handle,
+ NULL
+ },
+ {
+ "Check glGetTexture*HandleARB() reserved zero handle",
+ "check_GetTextureHandle_reserved_zero_handle",
+ check_GetTextureHandle_reserved_zero_handle,
+ NULL
+ },
+ {
+ "Check glGetTexture*HandleARB() uniqueness",
+ "check_GetTextureHandle_uniqueness",
+ check_GetTextureHandle_uniqueness,
+ NULL
+ },
+ {
+ "Check glIsTextureHandleResidentARB() valid",
+ "check_IsTextureHandleResident_valid",
+ check_IsTextureHandleResident_valid,
+ NULL
+ },
+ {
+ "Delete the texture/sampler while a handle is allocated",
+ "delete_texture_sampler_while_handle_is_allocated",
+ delete_texture_sampler_while_handle_is_allocated,
+ NULL
+ },
+ {
+ "Delete the texture/sampler while the handle is resident",
+ "delete_texture_sampler_while_handle_is_resident",
+ delete_texture_sampler_while_handle_is_resident,
+ },
+ {
+ "Check glGetImageHandleARB() zero handle",
+ "check_GetImageHandle_zero_handle",
+ check_GetImageHandle_zero_handle,
+ NULL
+ },
+ {
+ "Check glGetImageHandleARB() reserved zero handle",
+ "check_GetImageHandle_reserved_zero_handle",
+ check_GetImageHandle_reserved_zero_handle,
+ NULL
+ },
+ {
+ "Check glGetImageHandleARB() uniqueness",
+ "check_GetImageHandle_uniqueness",
+ check_GetImageHandle_uniqueness,
+ NULL
+ },
+ {
+ "Check glIsImageHandleResidentARB() valid",
+ "check_IsImageHandleResident_valid",
+ check_IsImageHandleResident_valid,
+ NULL
+ },
+ {
+ "Delete the texture while the image handle is resident",
+ "delete_texture_while_image_handle_resident",
+ delete_texture_while_image_handle_resident,
+ 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);
+}
diff --git a/tests/spec/arb_bindless_texture/illegal.c b/tests/spec/arb_bindless_texture/illegal.c
new file mode 100644
index 000000000..c2c713452
--- /dev/null
+++ b/tests/spec/arb_bindless_texture/illegal.c
@@ -0,0 +1,331 @@
+/*
+ * 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 exercise illegal operations when a texture/sampler object
+ * has been referenced by one or more texture handles.
+ */
+
+#include "piglit-util-gl.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;
+
+PIGLIT_GL_TEST_CONFIG_END
+
+static enum piglit_result
+call_TextureParameter_when_texture_is_referenced(void *data)
+{
+ GLuint tex;
+
+ tex = piglit_integer_texture(GL_RGBA32I, 16, 16, 0, 0);
+
+ glGetTextureHandleARB(tex);
+ if (!piglit_check_gl_error(GL_NO_ERROR))
+ return PIGLIT_FAIL;
+
+ /* The ARB_bindless_texture_spec says:
+ *
+ * "The error INVALID_OPERATION is generated by TexImage*,
+ * CopyTexImage*, CompressedTexImage*, TexBuffer*, TexParameter*, as
+ * well as other functions defined in terms of these, if the texture
+ * object to be modified is referenced by one or more texture or image
+ * handles."
+ */
+ glTextureParameteri(tex, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ if (!piglit_check_gl_error(GL_INVALID_OPERATION))
+ return PIGLIT_FAIL;
+
+ return PIGLIT_PASS;
+}
+
+static enum piglit_result
+call_TexImage_when_texture_is_referenced(void *data)
+{
+ GLuint tex;
+
+ tex = piglit_integer_texture(GL_RGBA32I, 16, 16, 0, 0);
+
+ glGetTextureHandleARB(tex);
+ if (!piglit_check_gl_error(GL_NO_ERROR))
+ return PIGLIT_FAIL;
+
+ /* The ARB_bindless_texture_spec says:
+ *
+ * "The error INVALID_OPERATION is generated by TexImage*,
+ * CopyTexImage*, CompressedTexImage*, TexBuffer*, TexParameter*, as
+ * well as other functions defined in terms of these, if the texture
+ * object to be modified is referenced by one or more texture or image
+ * handles."
+ */
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32I, 16, 16, 0, GL_RGBA_INTEGER,
+ GL_INT, NULL);
+ if (!piglit_check_gl_error(GL_INVALID_OPERATION))
+ return PIGLIT_FAIL;
+
+ return PIGLIT_PASS;
+}
+
+static enum piglit_result
+call_CopyTexImage_when_texture_is_referenced(void *data)
+{
+ GLuint tex;
+
+ tex = piglit_integer_texture(GL_RGBA32I, 16, 16, 0, 0);
+
+ glGetTextureHandleARB(tex);
+ if (!piglit_check_gl_error(GL_NO_ERROR))
+ return PIGLIT_FAIL;
+
+ /* The ARB_bindless_texture_spec says:
+ *
+ * "The error INVALID_OPERATION is generated by TexImage*,
+ * CopyTexImage*, CompressedTexImage*, TexBuffer*, TexParameter*, as
+ * well as other functions defined in terms of these, if the texture
+ * object to be modified is referenced by one or more texture or image
+ * handles."
+ */
+ glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, 16, 16, 0);
+ if (!piglit_check_gl_error(GL_INVALID_OPERATION))
+ return PIGLIT_FAIL;
+
+ return PIGLIT_PASS;
+}
+
+static enum piglit_result
+call_CompressedTexImage_when_texture_is_referenced(void *data)
+{
+ void *compressed;
+ GLuint tex;
+ GLint size;
+
+ tex = piglit_rgbw_texture(GL_COMPRESSED_RGBA_BPTC_UNORM, 16, 16,
+ GL_FALSE, GL_FALSE, GL_UNSIGNED_NORMALIZED);
+
+ glGetTextureHandleARB(tex);
+ if (!piglit_check_gl_error(GL_NO_ERROR))
+ return PIGLIT_FAIL;
+
+ glGetTexLevelParameteriv(GL_TEXTURE_2D, 0,
+ GL_TEXTURE_COMPRESSED_IMAGE_SIZE, &size);
+
+ compressed = malloc(size);
+ glGetCompressedTexImage(GL_TEXTURE_2D, 0, compressed);
+
+ /* The ARB_bindless_texture_spec says:
+ *
+ * "The error INVALID_OPERATION is generated by TexImage*,
+ * CopyTexImage*, CompressedTexImage*, TexBuffer*, TexParameter*, as
+ * well as other functions defined in terms of these, if the texture
+ * object to be modified is referenced by one or more texture or
+ * image handles."
+ */
+ glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_BPTC_UNORM,
+ 16, 16, 0, size, compressed);
+ if (!piglit_check_gl_error(GL_INVALID_OPERATION))
+ return PIGLIT_FAIL;
+
+ free(compressed);
+ return PIGLIT_PASS;
+}
+
+static enum piglit_result
+call_TexBuffer_when_texture_is_referenced(void *data)
+{
+ static const float red[4] = {1, 0, 0, 0};
+ GLuint tex, tbo;
+
+ glGenBuffers(1, &tbo);
+ glBindBuffer(GL_TEXTURE_BUFFER, tbo);
+ glBufferData(GL_TEXTURE_BUFFER, sizeof(red), red, GL_STATIC_DRAW);
+ if (!piglit_check_gl_error(GL_NO_ERROR))
+ return PIGLIT_FAIL;
+
+ glGenTextures(1, &tex);
+ glBindTexture(GL_TEXTURE_BUFFER, tex);
+ glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32F, tbo);
+ if (!piglit_check_gl_error(GL_NO_ERROR))
+ return PIGLIT_FAIL;
+
+ glGetTextureHandleARB(tex);
+ if (!piglit_check_gl_error(GL_NO_ERROR))
+ return PIGLIT_FAIL;
+
+ /* The ARB_bindless_texture_spec says:
+ *
+ * "The error INVALID_OPERATION is generated by TexImage*,
+ * CopyTexImage*, CompressedTexImage*, TexBuffer*, TexParameter*, as
+ * well as other functions defined in terms of these, if the texture
+ * object to be modified is referenced by one or more texture or
+ * image handles."
+ */
+ glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32F, tbo);
+ if (!piglit_check_gl_error(GL_INVALID_OPERATION))
+ return PIGLIT_FAIL;
+
+ return PIGLIT_PASS;
+}
+
+static enum piglit_result
+call_BufferData_when_texture_is_referenced(void *data)
+{
+ static const float red[4] = {1, 0, 0, 0};
+ GLuint tex, tbo;
+
+ glGenBuffers(1, &tbo);
+ glBindBuffer(GL_TEXTURE_BUFFER, tbo);
+ glBufferData(GL_TEXTURE_BUFFER, sizeof(red), red, GL_STATIC_DRAW);
+ if (!piglit_check_gl_error(GL_NO_ERROR))
+ return PIGLIT_FAIL;
+
+ glGenTextures(1, &tex);
+ glBindTexture(GL_TEXTURE_BUFFER, tex);
+ glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32F, tbo);
+ if (!piglit_check_gl_error(GL_NO_ERROR))
+ return PIGLIT_FAIL;
+
+ glGetTextureHandleARB(tex);
+ if (!piglit_check_gl_error(GL_NO_ERROR))
+ return PIGLIT_FAIL;
+
+ /* The ARB_bindless_texture spec says:
+ *
+ * "The error INVALID_OPERATION is generated by BufferData if it is
+ * called to modify a buffer object bound to a buffer texture while
+ * that texture object is referenced by one or more texture handles."
+ */
+ glBufferData(GL_TEXTURE_BUFFER, sizeof(red), red, GL_STATIC_DRAW);
+ if (!piglit_check_gl_error(GL_INVALID_OPERATION))
+ return PIGLIT_FAIL;
+
+ return PIGLIT_PASS;
+}
+
+static enum piglit_result
+call_SamplerParameter_when_texture_is_referenced(void *data)
+{
+ GLuint sampler, texture;
+
+ texture = piglit_integer_texture(GL_RGBA32I, 16, 16, 0, 0);
+
+ /* Texture and sampler have to be consistent. */
+ glGenSamplers(1, &sampler);
+ glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+
+ glGetTextureSamplerHandleARB(texture, sampler);
+ if (!piglit_check_gl_error(GL_NO_ERROR))
+ return PIGLIT_FAIL;
+
+ /* The ARB_bindless_texture spec says:
+ *
+ * "When a sampler object is referenced by one or more texture
+ * handles, the sampler parameters of the object may not be changed.
+ * The error INVALID_OPERATION is generated when calling
+ * SamplerParameter* functions to modify a sampler object referenced
+ * by one or more texture handles."
+ */
+ glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ if (!piglit_check_gl_error(GL_INVALID_OPERATION))
+ return PIGLIT_FAIL;
+
+ return PIGLIT_PASS;
+}
+
+static const struct piglit_subtest subtests[] = {
+ {
+ "Call glTextureParameter* when a texture handle is referenced",
+ "call_TextureParameter_when_texture_referenced",
+ call_TextureParameter_when_texture_is_referenced,
+ NULL
+ },
+ {
+ "Call glTexImage* when a texture handle is referenced",
+ "call_TexImage_when_texture_referenced",
+ call_TexImage_when_texture_is_referenced,
+ NULL
+ },
+ {
+ "Call glCopyTexImage* when a texture handle is referenced",
+ "call_CopyTexImage_when_texture_referenced",
+ call_CopyTexImage_when_texture_is_referenced,
+ NULL
+ },
+ {
+ "Call glCompressedTexImage* when a texture handle is referenced",
+ "call_CompressedTexImage_when_texture_referenced",
+ call_CompressedTexImage_when_texture_is_referenced,
+ NULL
+ },
+ {
+ "Call glTexBuffer* when a texture handle is referenced",
+ "call_TexBuffer_when_texture_referenced",
+ call_TexBuffer_when_texture_is_referenced,
+ NULL
+ },
+ {
+ "Call glBufferData when a texture handle is referenced",
+ "call_BufferData_when_texture_referenced",
+ call_BufferData_when_texture_is_referenced,
+ NULL
+ },
+ {
+ "Call glSamplerParameter* when a texture handle is referenced",
+ "call_SamplerParameter_when_texture_referenced",
+ call_SamplerParameter_when_texture_is_referenced,
+ 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);
+}
diff --git a/tests/spec/arb_bindless_texture/legal.c b/tests/spec/arb_bindless_texture/legal.c
new file mode 100644
index 000000000..0626eef0e
--- /dev/null
+++ b/tests/spec/arb_bindless_texture/legal.c
@@ -0,0 +1,259 @@
+/*
+ * 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 exercise legal operations when a texture/sampler object
+ * has been referenced by one or more texture handles.
+ */
+
+#include "piglit-util-gl.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;
+
+PIGLIT_GL_TEST_CONFIG_END
+
+static enum piglit_result
+call_TexSubImage_when_texture_is_referenced(void *data)
+{
+ int *img = malloc(16 * 16 * 4 * sizeof(unsigned));
+ GLuint tex;
+
+ tex = piglit_integer_texture(GL_RGBA32I, 16, 16, 0, 0);
+
+ glGetTextureHandleARB(tex);
+ if (!piglit_check_gl_error(GL_NO_ERROR))
+ return PIGLIT_FAIL;
+
+ /* The ARB_bindless_texture spec says:
+ *
+ * "The contents of the images in a texture object may still be
+ * updated via commands such as TexSubImage*, CopyTexSubImage*, and
+ * CompressedTexSubImage*, and by rendering to a framebuffer object,
+ * even if the texture object is referenced by one or more texture
+ * handles."
+ */
+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 16, 16, GL_RGBA_INTEGER,
+ GL_INT, img);
+ if (!piglit_check_gl_error(GL_NO_ERROR))
+ return PIGLIT_FAIL;
+
+ free(img);
+ return PIGLIT_PASS;
+}
+
+static enum piglit_result
+call_CopyTexSubImage_when_texture_is_referenced(void *data)
+{
+ GLuint tex;
+
+ tex = piglit_rgbw_texture(GL_RGBA8, 16, 16, GL_FALSE, GL_FALSE,
+ GL_UNSIGNED_BYTE);
+
+ glGetTextureHandleARB(tex);
+ if (!piglit_check_gl_error(GL_NO_ERROR))
+ return PIGLIT_FAIL;
+
+ /* The ARB_bindless_texture spec says:
+ *
+ * "The contents of the images in a texture object may still be
+ * updated via commands such as TexSubImage*, CopyTexSubImage*, and
+ * CompressedTexSubImage*, and by rendering to a framebuffer object,
+ * even if the texture object is referenced by one or more texture
+ * handles."
+ */
+ glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 16, 16);
+ if (!piglit_check_gl_error(GL_NO_ERROR))
+ return PIGLIT_FAIL;
+
+ return PIGLIT_PASS;
+}
+
+static enum piglit_result
+call_CompressedTexSubImage_when_texture_is_referenced(void *data)
+{
+ void *compressed;
+ GLuint tex;
+ GLint size;
+
+ tex = piglit_rgbw_texture(GL_COMPRESSED_RGBA_BPTC_UNORM, 16, 16,
+ GL_FALSE, GL_FALSE, GL_UNSIGNED_NORMALIZED);
+
+ glGetTextureHandleARB(tex);
+ if (!piglit_check_gl_error(GL_NO_ERROR))
+ return PIGLIT_FAIL;
+
+ glGetTexLevelParameteriv(GL_TEXTURE_2D, 0,
+ GL_TEXTURE_COMPRESSED_IMAGE_SIZE, &size);
+
+ compressed = malloc(size);
+ glGetCompressedTexImage(GL_TEXTURE_2D, 0, compressed);
+
+ /* The ARB_bindless_texture spec says:
+ *
+ * "The contents of the images in a texture object may still be
+ * updated via commands such as TexSubImage*, CopyTexSubImage*, and
+ * CompressedTexSubImage*, and by rendering to a framebuffer object,
+ * even if the texture object is referenced by one or more texture
+ * handles."
+ */
+ glCompressedTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 16, 16,
+ GL_COMPRESSED_RGBA_BPTC_UNORM, size,
+ compressed);
+ if (!piglit_check_gl_error(GL_NO_ERROR))
+ return PIGLIT_FAIL;
+
+ free(compressed);
+ return PIGLIT_PASS;
+}
+
+static enum piglit_result
+call_BufferSubData_when_texture_is_referenced(void *data)
+{
+ static const float red[4] = {1, 0, 0, 0};
+ GLuint tex, tbo;
+
+ glGenBuffers(1, &tbo);
+ glBindBuffer(GL_TEXTURE_BUFFER, tbo);
+ glBufferData(GL_TEXTURE_BUFFER, sizeof(red), red, GL_STATIC_DRAW);
+
+ glGenTextures(1, &tex);
+ glBindTexture(GL_TEXTURE_BUFFER, tex);
+ glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32F, tbo);
+
+ glGetTextureHandleARB(tex);
+ if (!piglit_check_gl_error(GL_NO_ERROR))
+ return PIGLIT_FAIL;
+
+ /* The ARB_bindless_texture spec says:
+ *
+ * "The contents of the buffer object may still be updated via buffer
+ * update commands such as BufferSubData and MapBuffer*, or via the
+ * texture update commands, even if the buffer is bound to a texture
+ * while that buffer texture object is referenced by one or more
+ * texture handles."
+ */
+ glBufferSubData(GL_TEXTURE_BUFFER, 0, sizeof(red), red);
+ if (!piglit_check_gl_error(GL_NO_ERROR))
+ return PIGLIT_FAIL;
+
+ return PIGLIT_PASS;
+}
+
+static enum piglit_result
+call_MapBuffer_when_texture_is_referenced(void *data)
+{
+ static const float red[4] = {1, 0, 0, 0};
+ GLuint tex, tbo;
+
+ glGenBuffers(1, &tbo);
+ glBindBuffer(GL_TEXTURE_BUFFER, tbo);
+ glBufferData(GL_TEXTURE_BUFFER, sizeof(red), red, GL_STATIC_DRAW);
+
+ glGenTextures(1, &tex);
+ glBindTexture(GL_TEXTURE_BUFFER, tex);
+ glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32F, tbo);
+
+ glGetTextureHandleARB(tex);
+ if (!piglit_check_gl_error(GL_NO_ERROR))
+ return PIGLIT_FAIL;
+
+ /* The ARB_bindless_texture spec says:
+ *
+ * "The contents of the buffer object may still be updated via buffer
+ * update commands such as BufferSubData and MapBuffer*, or via the
+ * texture update commands, even if the buffer is bound to a texture
+ * while that buffer texture object is referenced by one or more
+ * texture handles."
+ */
+ glMapBuffer(GL_TEXTURE_BUFFER, GL_READ_ONLY);
+ if (!piglit_check_gl_error(GL_NO_ERROR))
+ return PIGLIT_FAIL;
+ glUnmapBuffer(GL_TEXTURE_BUFFER);
+
+ return PIGLIT_PASS;
+}
+
+static const struct piglit_subtest subtests[] = {
+ {
+ "Call glTexSubImage* when a texture handle is referenced",
+ "call_TexSubImage_when_texture_referenced",
+ call_TexSubImage_when_texture_is_referenced,
+ NULL
+ },
+ {
+ "Call glCopyTexSubImage* when a texture handle is referenced",
+ "call_CopyTexSubImage_when_texture_referenced",
+ call_CopyTexSubImage_when_texture_is_referenced,
+ NULL
+ },
+ {
+ "Call glCompressedTexSubImage* when a texture handle is referenced",
+ "call_CompressedTexSubImage_when_texture_referenced",
+ call_CompressedTexSubImage_when_texture_is_referenced,
+ NULL
+ },
+ {
+ "Call glBufferSubData when a texture handle is referenced",
+ "call_BufferSubData_when_texture_referenced",
+ call_BufferSubData_when_texture_is_referenced,
+ NULL
+ },
+ {
+ "Call glMapBuffer when a texture handle is referenced",
+ "call_MapBuffer_when_texture_referenced",
+ call_MapBuffer_when_texture_is_referenced,
+ 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);
+}
diff --git a/tests/spec/arb_bindless_texture/limit.c b/tests/spec/arb_bindless_texture/limit.c
new file mode 100644
index 000000000..960027597
--- /dev/null
+++ b/tests/spec/arb_bindless_texture/limit.c
@@ -0,0 +1,302 @@
+/*
+ * 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.
+ *
+ * Authors:
+ * Marek Olšák <maraeo at gmail.com>
+ * Samuel Pitoiset <samuel.pitoiset at gmail.com>
+ */
+
+/**
+ * Test that samplers accessed using texture handles are not counted against
+ * the texture limits.
+ * Derived from Marek's max-samplers test.
+ */
+
+#include "piglit-util-gl.h"
+
+PIGLIT_GL_TEST_CONFIG_BEGIN
+
+ config.supports_gl_compat_version = 33;
+ config.supports_gl_core_version = 33;
+
+ config.window_width = 300;
+ config.window_height = 300;
+ config.window_visual = PIGLIT_GL_VISUAL_RGB | PIGLIT_GL_VISUAL_DOUBLE;
+
+PIGLIT_GL_TEST_CONFIG_END
+
+static const char *vs_source =
+ "#version 330\n"
+ "#extension GL_ARB_bindless_texture: require\n"
+ "\n"
+ "#define NUM %i \n"
+ "layout (bindless_sampler) uniform;\n"
+ "\n"
+ "uniform sampler2D vertex_tex[NUM]; \n"
+ "uniform int vertex_index;"
+ "in vec4 piglit_vertex;\n"
+ "out vec3 vertex_tex_color; \n"
+ "\n"
+ "void main() \n"
+ "{ \n"
+ " int i; \n"
+ " gl_Position = piglit_vertex;\n"
+ " vertex_tex_color = vec3(0.0); \n"
+ " for (i = 0; i < NUM; i++) \n"
+ " if (i == vertex_index) \n"
+ " vertex_tex_color = textureLod(vertex_tex[i], vec2(%f), 0.0).xyz; \n"
+ "} \n";
+
+static const char *fs_source =
+ "#version 330\n"
+ "#extension GL_ARB_bindless_texture: require\n"
+ "\n"
+ "#define NUM %i \n"
+ "layout (bindless_sampler) uniform;\n"
+ "\n"
+ "uniform sampler2D fragment_tex[NUM]; \n"
+ "uniform int fragment_index;"
+ "in vec3 vertex_tex_color; \n"
+ "void main() \n"
+ "{ \n"
+ " int i; \n"
+ " vec3 fragment_tex_color = vec3(0.0); \n"
+ " for (i = 0; i < NUM; i++) \n"
+ " if (i == fragment_index) \n"
+ " fragment_tex_color = texture2D(fragment_tex[i], vec2(%f), 0.0).xyz; \n"
+ " gl_FragColor = vec4(fragment_tex_color + vertex_tex_color, 1.0); \n"
+ "} \n";
+
+GLuint prog;
+static int max_vs_textures, max_fs_textures;
+
+static void
+get_texture_color(int unit, float out[4])
+{
+ out[0] = (unit % 16) / 15.0;
+ out[1] = (unit / 16) / 15.0;
+ out[2] = 0;
+ out[3] = 1;
+}
+
+static void
+set_uniform(GLuint prog, const char *name, int value)
+{
+ GLuint loc = glGetUniformLocation(prog, name);
+ if (loc != -1)
+ glUniform1i(loc, value);
+}
+
+static GLvoid
+draw_rect_core(int ix, int iy, int iw, int ih)
+{
+ float x = -1 + 2.0*ix/piglit_width;
+ float y = -1 + 2.0*iy/piglit_height;
+ float w = 2.0*iw/piglit_width;
+ float h = 2.0*ih/piglit_height;
+ float verts[4][4];
+ GLuint vbo;
+
+ verts[0][0] = x;
+ verts[0][1] = y;
+ verts[0][2] = 0.0;
+ verts[0][3] = 1.0;
+ verts[1][0] = x + w;
+ verts[1][1] = y;
+ verts[1][2] = 0.0;
+ verts[1][3] = 1.0;
+ verts[2][0] = x + w;
+ verts[2][1] = y + h;
+ verts[2][2] = 0.0;
+ verts[2][3] = 1.0;
+ verts[3][0] = x;
+ verts[3][1] = y + h;
+ verts[3][2] = 0.0;
+ verts[3][3] = 1.0;
+
+ glGenBuffers(1, &vbo);
+ glBindBuffer(GL_ARRAY_BUFFER, vbo);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_STATIC_DRAW);
+
+ glEnableVertexAttribArray(0);
+ glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, NULL);
+
+ glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+
+ glDisableVertexAttribArray(0);
+ glDeleteBuffers(1, &vbo);
+}
+
+static GLboolean
+probe_pixel(int num, int x, int y)
+{
+ float expected[4];
+
+ get_texture_color(num, expected);
+
+ if (piglit_probe_pixel_rgb(x, y, expected))
+ return GL_TRUE;
+
+ printf(" When testing texture num %i\n", num);
+ return GL_FALSE;
+}
+
+enum piglit_result
+piglit_display(void)
+{
+ GLboolean pass = GL_TRUE;
+ int i, num, x, y;
+
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ x = 0;
+ y = 0;
+ num = 0;
+
+ set_uniform(prog, "fragment_index", max_fs_textures);
+ for (i = 0; i < max_vs_textures; i++) {
+ set_uniform(prog, "vertex_index", i);
+ draw_rect_core(x, y, 20, 20);
+ pass = probe_pixel(num, x+10, y+10) && pass;
+
+ num++;
+ x += 20;
+ if (x+20 > piglit_width) {
+ x = 0;
+ y += 20;
+ }
+ }
+
+ set_uniform(prog, "vertex_index", max_vs_textures);
+ for (i = 0; i < max_fs_textures; i++) {
+ set_uniform(prog, "fragment_index", i);
+ draw_rect_core(x, y, 20, 20);
+ pass = probe_pixel(num, x+10, y+10) && pass;
+
+ num++;
+ x += 20;
+ if (x+20 > piglit_width) {
+ x = 0;
+ y += 20;
+ }
+ }
+
+ piglit_check_gl_error(GL_NO_ERROR);
+ piglit_present_results();
+
+ return pass ? PIGLIT_PASS : PIGLIT_FAIL;
+}
+
+static void
+set_texture_handle(GLuint prog, const char *name, GLuint64 handle)
+{
+ GLint loc;
+
+ loc = glGetUniformLocation(prog, name);
+ if (loc != -1)
+ glUniformHandleui64vARB(loc, 1, &handle);
+}
+
+static GLuint64
+new_bindless_texture(int idx)
+{
+ GLuint64 handle;
+ float color[4];
+ GLuint tex;
+
+ get_texture_color(idx, color);
+
+ glGenTextures(1, &tex);
+ glBindTexture(GL_TEXTURE_2D, tex);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 1, 1, 0,
+ GL_RGBA, GL_FLOAT, color);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
+ glBindTexture(GL_TEXTURE_2D, 0);
+
+ handle = glGetTextureHandleARB(tex);
+ glMakeTextureHandleResidentARB(handle);
+
+ return handle;
+}
+
+void
+piglit_init(int argc, char **argv)
+{
+ GLuint vs, fs, vao;
+ int max_combined_textures, i, num;
+ char str[2048];
+ float texcoord = 0.5;
+ GLuint64 handle;
+
+ piglit_require_extension("GL_ARB_bindless_texture");
+
+ /* get limits */
+ glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &max_fs_textures);
+ glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &max_vs_textures);
+ glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &max_combined_textures);
+ printf("GL_MAX_TEXTURE_IMAGE_UNITS = %d\n", max_fs_textures);
+ printf("GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS = %d\n", max_vs_textures);
+ printf("GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS = %d\n", max_combined_textures);
+
+ assert(max_fs_textures <= max_combined_textures);
+
+ /* use max_combined_textures + max_vs_textures */
+ max_vs_textures = MIN2(max_vs_textures, max_combined_textures - max_fs_textures);
+ max_fs_textures = max_combined_textures;
+
+ /* compile shaders */
+ sprintf(str, vs_source, max_vs_textures, texcoord);
+ vs = piglit_compile_shader_text(GL_VERTEX_SHADER, str);
+ sprintf(str, fs_source, max_fs_textures, texcoord);
+ fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, str);
+
+ prog = piglit_link_simple_program(vs, fs);
+ glUseProgram(prog);
+
+ /* initialize resident textures */
+ num = 0;
+ for (i = 0; i < max_vs_textures; i++) {
+ char name[64];
+ sprintf(name, "vertex_tex[%i]", i);
+ handle = new_bindless_texture(num);
+ set_texture_handle(prog, name, handle);
+ num++;
+ }
+
+ for (i = 0; i < max_fs_textures; i++) {
+ char name[64];
+ sprintf(name, "fragment_tex[%i]", i);
+ handle = new_bindless_texture(num);
+ set_texture_handle(prog, name, handle);
+ num++;
+ }
+
+ piglit_check_gl_error(GL_NO_ERROR);
+
+ glClearColor(0.0, 0.0, 1.0, 1.0);
+
+ glGenVertexArrays(1, &vao);
+ glBindVertexArray(vao);
+
+ piglit_check_gl_error(GL_NO_ERROR);
+}
diff --git a/tests/spec/arb_bindless_texture/uint64_attribs.c b/tests/spec/arb_bindless_texture/uint64_attribs.c
new file mode 100644
index 000000000..b6d085b6d
--- /dev/null
+++ b/tests/spec/arb_bindless_texture/uint64_attribs.c
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2010 VMware, Inc.
+ * Copyright (c) 2015 Red Hat Inc.
+ * 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 inherited vertex attributes from NV_vertex_attrib_integer_64bit.
+ * Derived from Brian's gpu_shader4 tests and Dave's vertex_attrib_64bit tests.
+ */
+
+#include <inttypes.h>
+
+#include "piglit-util-gl.h"
+
+PIGLIT_GL_TEST_CONFIG_BEGIN
+
+ config.supports_gl_core_version = 33;
+
+ config.window_visual = PIGLIT_GL_VISUAL_RGBA | PIGLIT_GL_VISUAL_DOUBLE;
+
+PIGLIT_GL_TEST_CONFIG_END
+
+static const char *TestName = "uint64_attribs";
+static const GLuint Index = 3;
+
+static GLboolean
+check_uint64_attrib(const GLuint64EXT expected, const char *func)
+{
+ GLuint64EXT vals[4];
+
+ glGetVertexAttribLui64vARB(Index, GL_CURRENT_VERTEX_ATTRIB_ARB, vals);
+
+ if (expected != vals[0]) {
+ fprintf(stderr, "%s: %s failed\n", TestName, func);
+ fprintf(stderr, " Expected: %"PRIu64" Found: %"PRIu64"\n",
+ expected, vals[0]);
+ return GL_FALSE;
+ }
+ return GL_TRUE;
+}
+
+enum piglit_result
+piglit_display(void)
+{
+ return PIGLIT_FAIL;
+}
+
+void
+piglit_init(int argc, char **argv)
+{
+ GLuint64EXT val = 1844674407370955165;
+
+ piglit_require_extension("GL_ARB_bindless_texture");
+
+ /* The ARB_bindless_texture spec says:
+ *
+ * "Interactions with NV_vertex_attrib_integer_64bit"
+ *
+ * "If NV_vertex_attrib_integer_64bit is not supported, this
+ * extension inherits the {Get}VertexAttribL1ui64{v}ARB entry points
+ * and UNSIGNED_INT64_ARB enum, as well as the functional edits
+ * describing them. However, references to the uint64_t type in the
+ * shader and providing 64-bit unsigned integer data to the shader
+ * are removed."
+ */
+ glVertexAttribL1ui64ARB(Index, val);
+ if (!check_uint64_attrib(val, "glVertexAttribL1ui64ARB"))
+ piglit_report_result(PIGLIT_FAIL);
+
+ glVertexAttribL1ui64vARB(Index, &val);
+ if (!check_uint64_attrib(val, "glVertexAttribL1ui64vARB"))
+ piglit_report_result(PIGLIT_FAIL);
+
+ piglit_report_result(PIGLIT_PASS);
+}
diff --git a/tests/spec/arb_bindless_texture/uniform.c b/tests/spec/arb_bindless_texture/uniform.c
new file mode 100644
index 000000000..5e4c6ba84
--- /dev/null
+++ b/tests/spec/arb_bindless_texture/uniform.c
@@ -0,0 +1,371 @@
+/*
+ * 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 "piglit-util-gl.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;
+
+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_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_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;
+
+ 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_UniformHandleui64_with_implicit_bound_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_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:
+ *
+ * "When used as uniforms in the default block, the value of sampler
+ * variables may be specified with either Uniform1i{v} or
+ * UniformHandleui64{v}ARB."
+ */
+ glUniformHandleui64ARB(loc, handle);
+ if (!piglit_check_gl_error(GL_NO_ERROR))
+ return PIGLIT_FAIL;
+
+ glProgramUniformHandleui64vARB(prog, loc, 1, &handle);
+ if (!piglit_check_gl_error(GL_NO_ERROR))
+ 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;
+
+ 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_UniformHandleui64_with_implicit_bound_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_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:
+ *
+ * "When used as uniforms in the default block, the value of sampler
+ * variables may be specified with either Uniform1i{v} or
+ * UniformHandleui64{v}ARB."
+ */
+ glUniformHandleui64ARB(loc, handle);
+ if (!piglit_check_gl_error(GL_NO_ERROR))
+ return PIGLIT_FAIL;
+
+ glProgramUniformHandleui64vARB(prog, loc, 1, &handle);
+ if (!piglit_check_gl_error(GL_NO_ERROR))
+ return PIGLIT_FAIL;
+
+ return PIGLIT_PASS;
+}
+
+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 glUniformHandleui64*ARB() with implicit bound_sampler",
+ "check_UniformHandleui64_with_implicit_bound_sampler",
+ check_UniformHandleui64_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 glUniformHandleui64*ARB() with implicit bound_image",
+ "check_UniformHandleui64_with_implicit_bound_image",
+ check_UniformHandleui64_with_implicit_bound_image,
+ 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);
+}
--
2.12.1
More information about the Piglit
mailing list