[Piglit] [PATCH] ARB_texture_view: Add test suite
Jon Ashburn
jon at lunarg.com
Mon Oct 14 23:31:39 CEST 2013
---
tests/all.tests | 6 +
tests/spec/arb_texture_view/CMakeLists.gl.txt | 4 +-
tests/spec/arb_texture_view/params.c | 643 ++++++++++++++++++++++
tests/spec/arb_texture_view/queries.c | 198 +++++++
tests/spec/arb_texture_view/rendering.c | 758 ++++++++++++++++++++++++++
5 files changed, 1608 insertions(+), 1 deletion(-)
create mode 100644 tests/spec/arb_texture_view/params.c
create mode 100644 tests/spec/arb_texture_view/queries.c
create mode 100644 tests/spec/arb_texture_view/rendering.c
diff --git a/tests/all.tests b/tests/all.tests
index f38d3d8..2204b09 100644
--- a/tests/all.tests
+++ b/tests/all.tests
@@ -1404,6 +1404,12 @@ spec['ARB_texture_storage_multisample'] = arb_texture_storage_multisample
arb_texture_storage_multisample['tex-storage'] = concurrent_test('arb_texture_storage_multisample-tex-storage')
arb_texture_storage_multisample['tex-param'] = concurrent_test('arb_texture_storage_multisample-tex-param')
+arb_texture_view = Group()
+spec['ARB_texture_view'] = arb_texture_view
+arb_texture_view['rendering'] = plain_test('arb_texture_view-rendering')
+arb_texture_view['params'] = plain_test('arb_texture_view-params')
+arb_texture_view['queries'] = plain_test('arb_texture_view-queries')
+
tdfx_texture_compression_fxt1 = Group()
spec['3DFX_texture_compression_FXT1'] = tdfx_texture_compression_fxt1
add_concurrent_test(tdfx_texture_compression_fxt1, 'compressedteximage GL_COMPRESSED_RGB_FXT1_3DFX')
diff --git a/tests/spec/arb_texture_view/CMakeLists.gl.txt b/tests/spec/arb_texture_view/CMakeLists.gl.txt
index c400759..293ef72 100644
--- a/tests/spec/arb_texture_view/CMakeLists.gl.txt
+++ b/tests/spec/arb_texture_view/CMakeLists.gl.txt
@@ -9,6 +9,8 @@ link_libraries(
${OPENGL_glu_LIBRARY}
)
-piglit_add_executable(arb_texture_view-texture-immutable-levels texture-immutable-levels.c)
+piglit_add_executable(arb_texture_view-rendering rendering.c)
+piglit_add_executable(arb_texture_view-params params.c)
+piglit_add_executable(arb_texture_view-queries queries.c)
# vim: ft=cmake:
diff --git a/tests/spec/arb_texture_view/params.c b/tests/spec/arb_texture_view/params.c
new file mode 100644
index 0000000..2714dd4
--- /dev/null
+++ b/tests/spec/arb_texture_view/params.c
@@ -0,0 +1,643 @@
+/*
+ * Copyright © 2013 LunarG, Inc.
+ *
+ * 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.
+ *
+ * Author: Jon Ashburn <jon at lunarg.com>
+ */
+
+/**
+ * Tests GL_ARB_texture_view and validity of input parameters.
+ * Use both valid and invalid parameters.
+ *
+ */
+
+#include "piglit-util-gl-common.h"
+#include <stdarg.h>
+
+PIGLIT_GL_TEST_CONFIG_BEGIN
+
+ config.supports_gl_compat_version = 10;
+
+ config.window_visual = PIGLIT_GL_VISUAL_RGBA | PIGLIT_GL_VISUAL_DOUBLE;
+
+PIGLIT_GL_TEST_CONFIG_END
+
+static const char *TestName = "arb_texture_view-params";
+
+
+void update_valid_arrays(GLenum *valid, GLenum *invalid, unsigned int num_invalid,
+ unsigned int num_valid, ... )
+{
+ va_list args;
+ GLenum val;
+ unsigned int i,j;
+
+ va_start(args, num_valid);
+ for (i = 0; i < num_valid; i++) {
+ val = va_arg(args, GLenum);
+ valid[i] = val;
+ // remove the valid enum from the invalid array
+ for (j= 0; j < num_invalid; j++) {
+ if (invalid[j] == val)
+ invalid[j] = 0;
+ }
+ }
+ va_end(args);
+}
+
+/**
+ * Do error-check tests for texture targets
+ */
+static enum piglit_result
+test_target_errors(GLenum target)
+{
+ GLint width = 64, height = 14, depth = 8;
+ const GLsizei levels = 1;
+ GLuint tex;
+ GLenum legal_targets[4];
+ unsigned int num_targets, i;
+ GLenum illegal_targets[] = {
+ // skip multisample
+ GL_TEXTURE_1D,
+ GL_TEXTURE_2D,
+ GL_TEXTURE_3D,
+ GL_TEXTURE_CUBE_MAP,
+ GL_TEXTURE_RECTANGLE,
+ GL_TEXTURE_1D_ARRAY,
+ GL_TEXTURE_2D_ARRAY,
+ GL_TEXTURE_CUBE_MAP_ARRAY,
+ };
+
+ // skip 2d_multisample targets for now
+ assert(target == GL_TEXTURE_1D ||
+ target == GL_TEXTURE_2D ||
+ target == GL_TEXTURE_3D ||
+ target == GL_TEXTURE_CUBE_MAP ||
+ target == GL_TEXTURE_RECTANGLE ||
+ target == GL_TEXTURE_1D_ARRAY ||
+ target == GL_TEXTURE_2D_ARRAY ||
+ target == GL_TEXTURE_CUBE_MAP_ARRAY);
+
+ glGenTextures(1, &tex); // orig tex
+ glBindTexture(target, tex);
+
+ switch (target) {
+ case GL_TEXTURE_1D:
+ glTexStorage1D(target, levels, GL_RGBA8, width);
+ num_targets = 2;
+ update_valid_arrays(legal_targets, illegal_targets,
+ ARRAY_SIZE(illegal_targets), num_targets,
+ GL_TEXTURE_1D, GL_TEXTURE_1D_ARRAY);
+ break;
+ case GL_TEXTURE_1D_ARRAY:
+ glTexStorage2D(target, levels*2, GL_RGBA8, width, height);
+ num_targets = 2;
+ update_valid_arrays(legal_targets, illegal_targets,
+ ARRAY_SIZE(illegal_targets), num_targets,
+ GL_TEXTURE_1D, GL_TEXTURE_1D_ARRAY);
+ break;
+ case GL_TEXTURE_2D:
+ glTexStorage2D(target, levels, GL_RGBA8, width, height);
+ num_targets = 2;
+ update_valid_arrays(legal_targets, illegal_targets,
+ ARRAY_SIZE(illegal_targets), num_targets,
+ GL_TEXTURE_2D, GL_TEXTURE_2D_ARRAY);
+ break;
+ case GL_TEXTURE_RECTANGLE:
+ glTexStorage2D(target, levels, GL_RGBA8, width, height);
+ num_targets = 1;
+ update_valid_arrays(legal_targets, illegal_targets,
+ ARRAY_SIZE(illegal_targets), num_targets,
+ GL_TEXTURE_RECTANGLE);
+ break;
+ case GL_TEXTURE_CUBE_MAP:
+ width = height;
+ glTexStorage2D(target, levels, GL_RGBA8, width, height);
+ num_targets = 4;
+ update_valid_arrays(legal_targets, illegal_targets,
+ ARRAY_SIZE(illegal_targets), num_targets,
+ GL_TEXTURE_CUBE_MAP, GL_TEXTURE_2D,
+ GL_TEXTURE_2D_ARRAY, GL_TEXTURE_CUBE_MAP_ARRAY);
+ break;
+ case GL_TEXTURE_3D:
+ glTexStorage3D(target, levels, GL_RGBA8, width, height, depth);
+ num_targets = 1;
+ update_valid_arrays(legal_targets, illegal_targets,
+ ARRAY_SIZE(illegal_targets), num_targets, GL_TEXTURE_3D);
+ break;
+ case GL_TEXTURE_CUBE_MAP_ARRAY:
+ case GL_TEXTURE_2D_ARRAY:
+ height = width;
+ glTexStorage3D(target, levels, GL_RGBA8, width, height, depth*6);
+ num_targets = 4;
+ update_valid_arrays(legal_targets, illegal_targets,
+ ARRAY_SIZE(illegal_targets), num_targets,
+ GL_TEXTURE_CUBE_MAP, GL_TEXTURE_2D,
+ GL_TEXTURE_2D_ARRAY, GL_TEXTURE_CUBE_MAP_ARRAY);
+ break;
+ }
+
+
+ if (piglit_check_gl_error(GL_NO_ERROR) == GL_FALSE) {
+ printf("%s:%s Found gl errors prior to testing glTextureView\n",
+ TestName, __func__);
+ glDeleteTextures(1, &tex);
+
+ return PIGLIT_SKIP;
+ }
+
+ // ensure TextureView of legal targets works
+ for (i = 0; i < num_targets; i++) {
+ GLenum tar = legal_targets[i];
+ GLuint new_tex, layers=1;
+ glGenTextures(1, &new_tex);
+ if (tar == GL_TEXTURE_CUBE_MAP)
+ layers = 6;
+ else if (tar == GL_TEXTURE_CUBE_MAP_ARRAY)
+ layers = 12;
+ glTextureView(new_tex, tar, tex, GL_RG16, 0, levels, 0, layers);
+ glDeleteTextures(1, &new_tex);
+ if (piglit_check_gl_error(GL_NO_ERROR) == GL_FALSE) {
+ glDeleteTextures(1, &tex);
+ return PIGLIT_FAIL;
+ }
+ }
+
+ // ensure TextureView of illegal targets returns an error
+ for (i = 0; i < ARRAY_SIZE(illegal_targets); i++) {
+ GLenum tar = illegal_targets[i];
+ GLuint new_tex, layers=1;
+ if (illegal_targets[i] == 0)
+ continue;
+ glGenTextures(1, &new_tex);
+ if (tar == GL_TEXTURE_CUBE_MAP)
+ layers = 6;
+ else if (tar == GL_TEXTURE_CUBE_MAP_ARRAY)
+ layers = 12;
+ glTextureView(new_tex, tar, tex, GL_RG16, 0, levels, 0, layers);
+ if (piglit_check_gl_error(GL_INVALID_OPERATION) == GL_FALSE) {
+ glDeleteTextures(1, &new_tex);
+ glDeleteTextures(1, &tex);
+ return PIGLIT_FAIL;
+ }
+ glDeleteTextures(1, &new_tex);
+ }
+ glDeleteTextures(1, &tex);
+
+ return PIGLIT_PASS;
+}
+
+
+/**
+ * Do error-check tests for misc glTextureView parameters
+ */
+static enum piglit_result test_param_errors()
+{
+ GLuint tex[2] = {0, 0};
+ GLint level, layer, i;
+ unsigned char * ptr;
+
+ // invalid original texture param (origtexture)
+ glGenTextures(2, tex);
+ glBindTexture(GL_TEXTURE_3D, tex[0]);
+ if (piglit_check_gl_error(GL_NO_ERROR) == GL_FALSE) {
+ printf("%s:%s Found gl errors prior to testing glTextureView\n",
+ TestName, __func__);
+ glDeleteTextures(2, tex);
+ return PIGLIT_SKIP;
+ }
+ glTextureView(tex[1], GL_TEXTURE_3D, tex[0], GL_R8, 0, 1, 0, 1);
+ if (piglit_check_gl_error(GL_INVALID_OPERATION) == GL_FALSE) {
+ glDeleteTextures(2, tex);
+ return PIGLIT_FAIL;
+ }
+ glDeleteTextures(1, &tex[1]);
+ glTexStorage3D(GL_TEXTURE_3D,2, GL_RGBA32F, 16, 16, 8);
+ if (piglit_check_gl_error(GL_NO_ERROR) == GL_FALSE) {
+ glDeleteTextures(1, tex);
+ return PIGLIT_SKIP;
+ }
+ glGenTextures(1, &tex[1]);
+ glTextureView(tex[1], GL_TEXTURE_3D, 0, GL_RGBA32UI, 0, 1, 0, 1);
+ if (piglit_check_gl_error(GL_INVALID_VALUE) == GL_FALSE) {
+ glDeleteTextures(2, tex);
+ return PIGLIT_FAIL;
+ }
+ glDeleteTextures(1, &tex[1]);
+
+ // invalid texture param
+ glTextureView(0, GL_TEXTURE_3D, tex[0], GL_RGBA32I, 0, 1, 0 ,1);
+ if (piglit_check_gl_error(GL_INVALID_VALUE) == GL_FALSE) {
+ glDeleteTextures(1, tex);
+ return PIGLIT_FAIL;
+ }
+ glGenTextures(1, &tex[1]);
+ glBindTexture(GL_TEXTURE_3D, tex[1]);
+ glTextureView(tex[1], GL_TEXTURE_3D, tex[0],GL_RGBA32F, 0, 1, 0, 1);
+ if (piglit_check_gl_error(GL_INVALID_OPERATION) == GL_FALSE) {
+ glDeleteTextures(2, tex);
+ return PIGLIT_FAIL;
+ }
+ glDeleteTextures(2, tex);
+
+ glGenTextures(1, tex);
+ glBindTexture(GL_TEXTURE_3D, tex[0]);
+ glTexStorage3D(GL_TEXTURE_3D, 3, GL_RG16F, 16, 16, 8);
+ glTextureView(~tex[0],GL_TEXTURE_3D, tex[0], GL_RGBA8, 0,1,0,1);
+ if (piglit_check_gl_error(GL_INVALID_OPERATION) == GL_FALSE) {
+ glDeleteTextures(1, &tex[0]);
+ return PIGLIT_FAIL;
+ }
+ glDeleteTextures(1, tex);
+
+ // orig texture not immutable
+ ptr = (unsigned char *) malloc(32 * 32 * 4 * 6);
+ if (ptr == NULL)
+ return PIGLIT_SKIP;
+ glGenTextures(2, tex);
+ glBindTexture(GL_TEXTURE_3D, tex[0]);
+ glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB16, 32, 32, 4, 0, GL_RGB,
+ GL_SHORT, ptr);
+ glTexImage3D(GL_TEXTURE_3D, 1, GL_RGB16, 16, 16, 2, 0, GL_RGB,
+ GL_SHORT, ptr);
+ free(ptr);
+ glTextureView(tex[1], GL_TEXTURE_3D, tex[0], GL_RGBA32F, 0,1,0,1);
+ if (piglit_check_gl_error(GL_INVALID_OPERATION) == GL_FALSE) {
+ glDeleteTextures(2, tex);
+ return PIGLIT_FAIL;
+ }
+ glDeleteTextures(2, tex);
+
+ // invalid layer param
+ glGenTextures(2, tex);
+ glBindTexture(GL_TEXTURE_1D_ARRAY, tex[0]);
+ glTexStorage2D(GL_TEXTURE_1D_ARRAY, 7, GL_RGB16I, 64, 4);
+ glTextureView(tex[1],GL_TEXTURE_1D_ARRAY, tex[0], GL_RGB16UI, 0, 7, 4,
+ 2);
+ if (piglit_check_gl_error(GL_INVALID_VALUE) == GL_FALSE) {
+ glDeleteTextures(2, tex);
+ return PIGLIT_FAIL;
+ }
+ glDeleteTextures(1, &tex[1]);
+ glGenTextures(1, &tex[1]);
+ glTextureView(tex[1],GL_TEXTURE_1D, tex[0], GL_RGB16I, 1, 5, 0, 4);
+ if (piglit_check_gl_error(GL_INVALID_OPERATION) == GL_FALSE) {
+ glDeleteTextures(2, tex);
+ return PIGLIT_FAIL;
+ }
+ glDeleteTextures(1, &tex[1]);
+
+ // invalid level param
+ glGenTextures(1, &tex[1]);
+ glTextureView(tex[1],GL_TEXTURE_1D, tex[0], GL_RGB16UI, 7, 5, 1, 1);
+ if (piglit_check_gl_error(GL_INVALID_VALUE) == GL_FALSE) {
+ glDeleteTextures(2, tex);
+ return PIGLIT_FAIL;
+ }
+ glDeleteTextures(1, &tex[1]);
+
+ // numlevels clamping, minlevel range over legal values
+ for (i = 0; i < 7; i++) {
+ glGenTextures(1, &tex[1]);
+ glTextureView(tex[1],GL_TEXTURE_1D_ARRAY, tex[0], GL_RGB16F,
+ i, 8-i, 0, 5);
+ if (piglit_check_gl_error(GL_NO_ERROR) == GL_FALSE) {
+ glDeleteTextures(2, tex);
+ return PIGLIT_FAIL;
+ }
+ glBindTexture(GL_TEXTURE_1D_ARRAY, tex[1]);
+ glGetTexParameteriv(GL_TEXTURE_1D_ARRAY, GL_TEXTURE_VIEW_MIN_LEVEL,
+ &level);
+ if (level != i) {
+ printf("failed at min_level=%d, queried view_min_level=%d\n",
+ i, level);
+ glDeleteTextures(2, tex);
+ return PIGLIT_FAIL;
+ }
+ glGetTexParameteriv(GL_TEXTURE_1D_ARRAY, GL_TEXTURE_VIEW_NUM_LEVELS,
+ &level);
+ if (level != (7-i)) {
+ printf("failed at min_level=%d, queried view_num_level=%d\n",
+ i, level);
+ glDeleteTextures(2, tex);
+ return PIGLIT_FAIL;
+ }
+ glDeleteTextures(1, &tex[1]);
+ glBindTexture(GL_TEXTURE_1D_ARRAY, tex[0]);
+ }
+
+ // numlayers clamping, minlayers range over legal values
+ for (i = 0; i < 4; i++) {
+ glGenTextures(1, &tex[1]);
+ glTextureView(tex[1],GL_TEXTURE_1D_ARRAY, tex[0], GL_RGB16I,
+ 0, 7, i, 5-i);
+ if (piglit_check_gl_error(GL_NO_ERROR) == GL_FALSE) {
+ glDeleteTextures(2, tex);
+ return PIGLIT_FAIL;
+ }
+ glBindTexture(GL_TEXTURE_1D_ARRAY, tex[1]);
+ glGetTexParameteriv(GL_TEXTURE_1D_ARRAY, GL_TEXTURE_VIEW_MIN_LAYER,
+ &layer);
+ if (layer != i) {
+ printf("failed at min_layer=%d, queried view_min_layer=%d\n",
+ i, layer);
+ glDeleteTextures(2, tex);
+ return PIGLIT_FAIL;
+ }
+ glGetTexParameteriv(GL_TEXTURE_1D_ARRAY, GL_TEXTURE_VIEW_NUM_LAYERS,
+ &layer);
+ if (layer != (4-i)) {
+ printf("failed at min_layer=%d, queried view_num_layer=%d\n",
+ i, layer);
+ glDeleteTextures(2, tex);
+ return PIGLIT_FAIL;
+ }
+ glDeleteTextures(1, &tex[1]);
+ glBindTexture(GL_TEXTURE_1D_ARRAY, tex[0]);
+ }
+
+ glDeleteTextures(2, tex);
+ return PIGLIT_PASS;
+
+}
+
+/**
+ * Do error-check tests for texture targets
+ */
+static enum piglit_result
+test_format_errors(GLenum format_class)
+{
+ GLint width = 16, height = 16;
+ const GLsizei levels = 5;
+ GLenum target = GL_TEXTURE_CUBE_MAP;
+ GLuint tex;
+ GLenum legal_formats[17];
+ unsigned int num_formats, i;
+ GLenum illegal_formats[] = {
+ //skip compressed sized formats
+ //128 bit
+ GL_RGBA32F,
+ GL_RGBA32UI,
+ GL_RGBA32I,
+ // 96 bit
+ GL_RGB32F,
+ GL_RGB32UI,
+ GL_RGB32I,
+ // 64 bit
+ GL_RGBA16F,
+ GL_RG32F,
+ GL_RGBA16UI,
+ GL_RG32UI,
+ GL_RGBA16I,
+ GL_RG32I,
+ GL_RGBA16,
+ GL_RGBA16_SNORM,
+ //48 bit
+ GL_RGB16,
+ GL_RGB16_SNORM,
+ GL_RGB16F,
+ GL_RGB16UI,
+ GL_RGB16I,
+ //32 bits
+ GL_RG16F,
+ GL_R11F_G11F_B10F,
+ GL_R32F,
+ GL_RGB10_A2UI,
+ GL_RGBA8UI,
+ GL_RG16UI,
+ GL_R32UI,
+ GL_RGBA8I,
+ GL_RG16I,
+ GL_R32I,
+ GL_RGB10_A2,
+ GL_RGBA8,
+ GL_RG16,
+ GL_RGBA8_SNORM,
+ GL_RG16_SNORM,
+ GL_SRGB8_ALPHA8,
+ GL_RGB9_E5,
+ //24 bits
+ GL_RGB8,
+ GL_RGB8_SNORM,
+ GL_SRGB8,
+ GL_RGB8UI,
+ GL_RGB8I,
+ //16 bits
+ GL_R16F,
+ GL_RG8UI,
+ GL_R16UI,
+ GL_RG8I,
+ GL_R16I,
+ GL_RG8,
+ GL_R16,
+ GL_RG8_SNORM,
+ GL_R16_SNORM,
+ //8 bits
+ GL_R8UI,
+ GL_R8I,
+ GL_R8,
+ GL_R8_SNORM,
+ // a sampling of unsized formats
+ GL_ALPHA,
+ GL_LUMINANCE,
+ GL_LUMINANCE_ALPHA,
+ GL_INTENSITY,
+ GL_RGB,
+ GL_RGBA,
+ GL_DEPTH_COMPONENT,
+ GL_COMPRESSED_ALPHA,
+ GL_COMPRESSED_LUMINANCE_ALPHA,
+ GL_COMPRESSED_LUMINANCE,
+ GL_COMPRESSED_INTENSITY,
+ GL_COMPRESSED_RGB,
+ GL_COMPRESSED_RGBA,
+ GL_COMPRESSED_RGBA,
+ GL_COMPRESSED_SRGB,
+ GL_COMPRESSED_SRGB_ALPHA,
+ GL_COMPRESSED_SLUMINANCE,
+ GL_COMPRESSED_SLUMINANCE_ALPHA,
+ };
+
+ // skip compressed internal formats for now including extensions
+ assert(format_class == GL_VIEW_CLASS_128_BITS ||
+ format_class == GL_VIEW_CLASS_96_BITS ||
+ format_class == GL_VIEW_CLASS_64_BITS ||
+ format_class == GL_VIEW_CLASS_48_BITS ||
+ format_class == GL_VIEW_CLASS_32_BITS ||
+ format_class == GL_VIEW_CLASS_24_BITS ||
+ format_class == GL_VIEW_CLASS_16_BITS ||
+ format_class == GL_VIEW_CLASS_8_BITS);
+
+ glGenTextures(1, &tex); // orig tex
+ glBindTexture(target, tex);
+
+ switch (format_class) {
+ case GL_VIEW_CLASS_128_BITS:
+ glTexStorage2D(target, levels, GL_RGBA32F, width, height);
+ num_formats = 3;
+ update_valid_arrays(legal_formats, illegal_formats,
+ ARRAY_SIZE(illegal_formats), num_formats,
+ GL_RGBA32F, GL_RGBA32UI, GL_RGBA32I);
+ break;
+ case GL_VIEW_CLASS_96_BITS:
+ glTexStorage2D(target, levels, GL_RGB32F, width, height);
+ num_formats = 3;
+ update_valid_arrays(legal_formats, illegal_formats,
+ ARRAY_SIZE(illegal_formats), num_formats,
+ GL_RGB32F, GL_RGB32UI, GL_RGB32I);
+ break;
+ case GL_VIEW_CLASS_64_BITS:
+ glTexStorage2D(target, levels, GL_RGBA16F, width, height);
+ num_formats = 8;
+ update_valid_arrays(legal_formats, illegal_formats,
+ ARRAY_SIZE(illegal_formats), num_formats,
+ GL_RGBA16F, GL_RG32F, GL_RGBA16UI, GL_RG32UI,
+ GL_RGBA16I, GL_RG32I, GL_RGBA16, GL_RGBA16_SNORM);
+ break;
+ case GL_VIEW_CLASS_48_BITS:
+ glTexStorage2D(target, levels, GL_RGB16, width, height);
+ num_formats = 5;
+ update_valid_arrays(legal_formats, illegal_formats,
+ ARRAY_SIZE(illegal_formats), num_formats,
+ GL_RGB16, GL_RGB16_SNORM, GL_RGB16F, GL_RGB16UI, GL_RGB16I);
+ break;
+ case GL_VIEW_CLASS_32_BITS:
+ glTexStorage2D(target, levels, GL_RG16F, width, height);
+ num_formats = 17;
+ update_valid_arrays(legal_formats, illegal_formats,
+ ARRAY_SIZE(illegal_formats), num_formats,
+ GL_RG16F, GL_R11F_G11F_B10F, GL_R32F, GL_RGB10_A2UI,
+ GL_RGBA8UI, GL_RG16UI, GL_R32UI, GL_RGBA8I, GL_RG16I,
+ GL_R32I, GL_RGB10_A2, GL_RGBA8, GL_RG16, GL_RGBA8_SNORM,
+ GL_RG16_SNORM, GL_SRGB8_ALPHA8, GL_RGB9_E5);
+ break;
+ case GL_VIEW_CLASS_24_BITS:
+ glTexStorage2D(target, levels, GL_RGB8, width, height);
+ num_formats = 5;
+ update_valid_arrays(legal_formats, illegal_formats,
+ ARRAY_SIZE(illegal_formats), num_formats,
+ GL_RGB8, GL_RGB8_SNORM, GL_SRGB8, GL_RGB8UI, GL_RGB8I);
+ break;
+ case GL_VIEW_CLASS_16_BITS:
+ glTexStorage2D(target, levels, GL_R16F, width, height);
+ num_formats = 9;
+ update_valid_arrays(legal_formats, illegal_formats,
+ ARRAY_SIZE(illegal_formats), num_formats,
+ GL_R16F, GL_RG8UI, GL_R16UI, GL_RG8I, GL_R16I, GL_RG8,
+ GL_R16, GL_RG8_SNORM, GL_R16_SNORM);
+ break;
+ case GL_VIEW_CLASS_8_BITS:
+ glTexStorage2D(target, levels, GL_R8I, width, height);
+ num_formats = 4;
+ update_valid_arrays(legal_formats, illegal_formats,
+ ARRAY_SIZE(illegal_formats), num_formats,
+ GL_R8UI, GL_R8I, GL_R8, GL_R8_SNORM);
+ break;
+ }
+
+ if (piglit_check_gl_error(GL_NO_ERROR) == GL_FALSE) {
+ printf("%s:%s Found gl errors prior to testing glTextureView\n",
+ TestName, __func__);
+ glDeleteTextures(1, &tex);
+ return PIGLIT_SKIP;
+ }
+
+ // ensure TextureView of legal formats works
+ for (i = 0; i < num_formats; i++) {
+ GLenum format;
+ GLuint new_tex, layers=6;
+ format = legal_formats[i];
+ glGenTextures(1, &new_tex);
+ glTextureView(new_tex, target, tex, format, 0, levels, 0, layers);
+ glDeleteTextures(1, &new_tex);
+ if (piglit_check_gl_error(GL_NO_ERROR) == GL_FALSE) {
+ glDeleteTextures(1, &tex);
+ return PIGLIT_FAIL;
+ }
+ }
+
+ // ensure TextureView of illegal formats returns an error
+ for (i = 0; i < ARRAY_SIZE(illegal_formats); i++) {
+ GLenum format;
+ GLuint new_tex, layers=6;
+ format = illegal_formats[i];
+ if (format == 0)
+ continue;
+ glGenTextures(1, &new_tex);
+ glTextureView(new_tex, target, tex, format, 0, levels, 0, layers);
+ if (piglit_check_gl_error(GL_INVALID_OPERATION) == GL_FALSE) {
+ glDeleteTextures(1, &new_tex);
+ glDeleteTextures(1, &tex);
+ return PIGLIT_FAIL;
+ }
+ glDeleteTextures(1, &new_tex);
+ }
+
+ glDeleteTextures(1, &tex);
+
+ return PIGLIT_PASS;
+}
+
+
+enum piglit_result
+piglit_display(void)
+{
+ enum piglit_result pass = PIGLIT_PASS;
+ enum piglit_result tmp;
+#define X(f, n) tmp = (f); pass = tmp != PIGLIT_PASS ? PIGLIT_FAIL : pass; piglit_report_subtest_result(tmp, (n))
+ X(test_target_errors(GL_TEXTURE_1D), "1D tex target validity");
+ X(test_target_errors(GL_TEXTURE_2D), "2D tex target validity");
+ X(test_target_errors(GL_TEXTURE_3D), "3D tex target validity");
+ X(test_target_errors(GL_TEXTURE_CUBE_MAP), "Cubemap tex target validity");
+ X(test_target_errors(GL_TEXTURE_RECTANGLE), "Rectangle tex target validity");
+ X(test_target_errors(GL_TEXTURE_1D_ARRAY), "1D Array tex target validity");
+ X(test_target_errors(GL_TEXTURE_2D_ARRAY), "2D Array tex target validity");
+ X(test_target_errors(GL_TEXTURE_CUBE_MAP_ARRAY),
+ "Cubemap Array tex target validity");
+ X(test_param_errors(), "Param texture/level/layer validity");
+ X(test_format_errors(GL_VIEW_CLASS_128_BITS), "Format 128 bits validity");
+ X(test_format_errors(GL_VIEW_CLASS_96_BITS), "Format 96 bits validity");
+ X(test_format_errors(GL_VIEW_CLASS_64_BITS), "Format 64 bits validity");
+ X(test_format_errors(GL_VIEW_CLASS_48_BITS), "Format 48 bits validity");
+ X(test_format_errors(GL_VIEW_CLASS_32_BITS), "Format 32 bits validity");
+ X(test_format_errors(GL_VIEW_CLASS_24_BITS), "Format 24 bits validity");
+ X(test_format_errors(GL_VIEW_CLASS_16_BITS), "Format 16 bits validity");
+ X(test_format_errors(GL_VIEW_CLASS_8_BITS), "Format 8 bits validity");
+#undef X
+ if (piglit_check_gl_error(GL_NO_ERROR) == GL_FALSE)
+ return PIGLIT_FAIL;
+ return pass;
+}
+
+
+void
+piglit_init(int argc, char **argv)
+{
+ piglit_require_extension("GL_ARB_texture_storage");
+ piglit_require_extension("GL_ARB_texture_view");
+ piglit_require_extension("GL_EXT_texture_integer");
+ piglit_require_extension("GL_ARB_texture_float");
+ piglit_require_extension("GL_ARB_texture_cube_map_array");
+ piglit_require_extension("GL_EXT_texture_array");
+ piglit_require_extension("GL_ARB_texture_rectangle");
+ piglit_require_extension("GL_EXT_texture3D");
+ piglit_reset_gl_error();
+}
diff --git a/tests/spec/arb_texture_view/queries.c b/tests/spec/arb_texture_view/queries.c
new file mode 100644
index 0000000..e4bb084
--- /dev/null
+++ b/tests/spec/arb_texture_view/queries.c
@@ -0,0 +1,198 @@
+/*
+ * Copyright © 2013 LunarG, Inc.
+ *
+ * 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.
+ *
+ * Author: Jon Ashburn <jon at lunarg.com>
+ */
+
+/**
+ * Tests GL_ARB_texture_view queries of new state added by this extension
+ *
+ */
+
+#include "piglit-util-gl-common.h"
+
+PIGLIT_GL_TEST_CONFIG_BEGIN
+
+ config.supports_gl_compat_version = 10;
+
+ config.window_visual = PIGLIT_GL_VISUAL_RGBA | PIGLIT_GL_VISUAL_DOUBLE;
+
+PIGLIT_GL_TEST_CONFIG_END
+
+
+enum piglit_result
+piglit_display(void)
+{
+ GLuint tex[2], view_tex, l;
+ GLint param;
+
+ glGenTextures(2, tex);
+
+ // test the view causes immutable_format to be set
+ glBindTexture(GL_TEXTURE_2D, tex[0]);
+ glTexStorage2D(GL_TEXTURE_2D, 6, GL_R32F, 16, 32);
+ glTextureView(tex[1], GL_TEXTURE_2D, tex[0], GL_RG16F, 0, 1, 0, 1);
+ if (piglit_check_gl_error(GL_NO_ERROR) == GL_FALSE) {
+ glDeleteTextures(2, tex);
+ return PIGLIT_FAIL;
+ }
+ glBindTexture(GL_TEXTURE_2D, tex[1]);
+ glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_IMMUTABLE_FORMAT, ¶m);
+ if (piglit_check_gl_error(GL_NO_ERROR) == GL_FALSE) {
+ glDeleteTextures(2, tex);
+ return PIGLIT_FAIL;
+ }
+
+ if (param != GL_TRUE) {
+ printf("bad query of immutable_format\n");
+ glDeleteTextures(2, tex);
+ return PIGLIT_FAIL;
+ }
+ glDeleteTextures(2,tex);
+
+ // test min_levels are additive
+ // test immutable_levels get set correctly
+ // note: see params test for more min/num level/layer query testing
+ glGenTextures(2,tex);
+ glBindTexture(GL_TEXTURE_CUBE_MAP, tex[0]);
+ glTexStorage2D(GL_TEXTURE_CUBE_MAP, 7, GL_R32F, 64, 64);
+ glTextureView(tex[1], GL_TEXTURE_CUBE_MAP, tex[0], GL_RG16I, 2, 4, 0, 6);
+ if (piglit_check_gl_error(GL_NO_ERROR) == GL_FALSE) {
+ glDeleteTextures(2,tex);
+ return PIGLIT_FAIL;
+ }
+ glBindTexture(GL_TEXTURE_CUBE_MAP, tex[1]);
+ glGetTexParameteriv(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_IMMUTABLE_LEVELS,
+ ¶m);
+ if (param != 7) {
+ glDeleteTextures(2, tex);
+ printf("bad query of immutable_levels, expected 7 got %u\n", param);
+ return PIGLIT_FAIL;
+ }
+ for (l = 0; l < 3; l++) {
+ glGenTextures(1, &view_tex);
+ glTextureView(view_tex, GL_TEXTURE_CUBE_MAP, tex[1], GL_RG16F, l, 4,
+ 0, 6);
+ glBindTexture(GL_TEXTURE_CUBE_MAP, view_tex);
+ glGetTexParameteriv(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_VIEW_MIN_LEVEL,
+ ¶m);
+ if (param != (2 + l)) {
+ glDeleteTextures(2, tex);
+ glDeleteTextures(1, &view_tex);
+ printf("bad query of view_min_level expected %u got %u\n", 2+l,
+ param);
+ return PIGLIT_FAIL;
+ }
+ glGetTexParameteriv(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_IMMUTABLE_LEVELS,
+ ¶m);
+ glDeleteTextures(1, &view_tex);
+ if (param != 7) {
+ glDeleteTextures(2, tex);
+ printf("query of immutable_levels not tracking orig, expected 7 got %u\n", param);
+ return PIGLIT_FAIL;
+ }
+ }
+ glDeleteTextures(2, tex);
+
+ // make sure default intial state is correct
+ // view_tex which is bound to GL_TEXTURE_CUBE_MAP is deleted
+ glGetTexParameteriv(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_VIEW_MIN_LEVEL,
+ ¶m);
+ if (param != 0) {
+ printf("bad default of min_level, expected 0 got %u\n", param);
+ return PIGLIT_FAIL;
+ }
+ glGetTexParameteriv(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_VIEW_NUM_LEVELS,
+ ¶m);
+ if (param != 0) {
+ printf("bad default of num_levels, expected 0 got %u\n", param);
+ return PIGLIT_FAIL;
+ }
+ glGetTexParameteriv(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_VIEW_MIN_LAYER,
+ ¶m);
+ if (param != 0) {
+ printf("bad default of min_layer, expected 0 got %u\n", param);
+ return PIGLIT_FAIL;
+ }
+ glGetTexParameteriv(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_VIEW_NUM_LAYERS,
+ ¶m);
+ if (param != 0) {
+ printf("bad default of num_layers, expected 0 got %u\n", param);
+ return PIGLIT_FAIL;
+ }
+ glGetTexParameteriv(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_IMMUTABLE_FORMAT,
+ ¶m);
+ if (param != 0) {
+ printf("bad default of immutable_format, expected 0 got %u\n", param);
+ return PIGLIT_FAIL;
+ }
+ glGetTexParameteriv(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_IMMUTABLE_LEVELS,
+ ¶m);
+ if (param != 0) {
+ printf("bad default of immutable_levels, expected 0 got %u\n", param);
+ return PIGLIT_FAIL;
+ }
+
+ // test min_layers are additive
+ glGenTextures(2, tex);
+ glBindTexture(GL_TEXTURE_2D_ARRAY, tex[0]);
+ glTexStorage3D(GL_TEXTURE_2D_ARRAY, 7, GL_RG16F, 64, 64, 8);
+ glTextureView(tex[1], GL_TEXTURE_2D_ARRAY, tex[0], GL_RG16I, 0, 3, 1, 8);
+ if (piglit_check_gl_error(GL_NO_ERROR) == GL_FALSE) {
+ glDeleteTextures(2,tex);
+ return PIGLIT_FAIL;
+ }
+ for (l = 0; l < 4; l++) {
+ glGenTextures(1, &view_tex);
+ glTextureView(view_tex, GL_TEXTURE_2D_ARRAY, tex[1], GL_RG16UI, 0, 4,
+ l, 7);
+ glBindTexture(GL_TEXTURE_2D_ARRAY, view_tex);
+ glGetTexParameteriv(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_VIEW_MIN_LAYER,
+ ¶m);
+ if (param != (1 + l)) {
+ glDeleteTextures(2, tex);
+ glDeleteTextures(1, &view_tex);
+ printf("bad query of view_min_layer expected %u got %u\n", 1+l,
+ param);
+ return PIGLIT_FAIL;
+ }
+ glDeleteTextures(1, &view_tex);
+ }
+ glDeleteTextures(2, tex);
+
+
+ if (piglit_check_gl_error(GL_NO_ERROR) == GL_FALSE)
+ return PIGLIT_FAIL;
+
+ return PIGLIT_PASS;
+
+}
+
+
+void
+piglit_init(int argc, char **argv)
+{
+
+ piglit_require_extension("GL_ARB_texture_storage");
+ piglit_require_extension("GL_ARB_texture_view");
+ piglit_reset_gl_error();
+}
diff --git a/tests/spec/arb_texture_view/rendering.c b/tests/spec/arb_texture_view/rendering.c
new file mode 100644
index 0000000..2674c67
--- /dev/null
+++ b/tests/spec/arb_texture_view/rendering.c
@@ -0,0 +1,758 @@
+/*
+ * Copyright © 2013 LunarG, Inc.
+ *
+ * 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.
+ *
+ * Author: Jon Ashburn <jon at lunarg.com>
+ */
+
+/**
+ * Tests GL_ARB_texture_view rendering and lifetime of views
+ * Rendering includes with various targets, layers and levels.
+ * Lifetime tests are combined with various formats and tex image data reads.
+ */
+#include <unistd.h>
+
+#include "piglit-util-gl-common.h"
+
+PIGLIT_GL_TEST_CONFIG_BEGIN
+
+ config.supports_gl_compat_version = 10;
+ config.window_width = 128;
+ config.window_height = 128;
+
+ config.window_visual = PIGLIT_GL_VISUAL_RGBA | PIGLIT_GL_VISUAL_DOUBLE;
+
+PIGLIT_GL_TEST_CONFIG_END
+
+static const char *TestName = "arb_texture_view-rendering";
+static int tex_loc_2Darray, tex_loc_1D;
+static int prog2Darray, prog1D;
+
+/* Formats. */
+
+struct format_desc {
+ const char *name;
+ GLenum internalfmt;
+ GLenum storagefmt;
+ GLenum imagefmt;
+ GLenum imagetype;
+ GLenum getfmt;
+ GLenum gettype;
+ int red, green, blue, alpha;
+};
+
+#define FORMAT(f) #f, f
+static const struct format_desc format_list[] = {
+ {FORMAT(GL_RGBA8UI), GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, 8, 8, 8, 8},
+ {FORMAT(GL_RGBA8I), GL_RGBA8I, GL_RGBA, GL_UNSIGNED_BYTE, GL_RGBA_INTEGER, GL_BYTE, 8, 8, 8, 8},
+ {FORMAT(GL_RGB16I), GL_RGB16, GL_RGB, GL_UNSIGNED_BYTE, GL_RGB_INTEGER, GL_SHORT, 16, 16, 16, 0},
+ {FORMAT(GL_RGB16F), GL_RGB16, GL_RGB, GL_UNSIGNED_BYTE, GL_RGB, GL_HALF_FLOAT, 16, 16, 16, 0},
+ {FORMAT(GL_R16UI), GL_R16, GL_RED, GL_UNSIGNED_BYTE, GL_RED_INTEGER, GL_SHORT, 16, 0, 0, 0},
+ {FORMAT(GL_R16F), GL_R16, GL_RED, GL_UNSIGNED_BYTE, GL_RED, GL_HALF_FLOAT, 16, 0, 0, 0},
+};
+#undef FORMAT
+
+
+static GLubyte Colors[][8] = {
+ {127, 0, 0, 255, 0, 10, 20, 0},
+ { 0, 127, 0, 255, 0, 0, 80, 90},
+ { 0, 0, 127, 255, 25, 0, 0, 60},
+ { 0, 127, 127, 255, 15, 15, 0, 0},
+ {127, 0, 127, 255, 0, 2, 50, 0},
+ {127, 127, 0, 255, 80, 10, 70, 20},
+ {255, 0, 0, 255, 60, 0, 40, 30},
+ { 0, 255, 0, 255, 50, 20, 2, 40},
+ { 0, 0, 255, 255, 40, 0, 1, 0},
+ { 0, 255, 255, 255, 30, 5, 3, 8},
+ {255, 0, 255, 255, 20, 18, 4, 7},
+ {255, 255, 0, 255, 10, 24, 77, 67},
+ {255, 255, 255, 255, 5, 33, 88, 44}
+};
+
+/**
+ * Create a single-color image. Up to 64 bits per color depending upon bytes
+ */
+static GLubyte *
+create_solid_image(GLint w, GLint h, GLint d, const uint bytes, const uint idx)
+{
+ GLubyte *buf = (GLubyte *) malloc(w * h * d * bytes);
+ int i,j;
+
+ if (buf == NULL || idx > (sizeof(Colors) / bytes - 1)) {
+ free(buf);
+ return NULL;
+ }
+ for (i = 0; i < w * h * d; i++) {
+ for (j = 0; j < bytes; j++) {
+ buf[i*bytes+j] = Colors[idx][j];
+ }
+ }
+ return buf;
+}
+
+static void
+draw_line(float x, float y, float w, float h)
+{
+ GLfloat vertices[6] = {x, y, 0.0,
+ x+w, y+h, 0.0};
+ GLuint elements[4] = {0, 1};
+
+ GLfloat texcoords[2] = {0.0, 1.0};
+
+
+ glVertexPointer(3, GL_FLOAT, 0, vertices);
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ glTexCoordPointer(1, GL_FLOAT, 0, texcoords);
+ glDrawElements(GL_LINES, 2, GL_UNSIGNED_INT, elements);
+}
+
+/**
+ * Draw a textured quad, sampling only the given depth of the 3D texture.
+ * Use fixed function pipeline.
+ */
+static void
+draw_3d_depth_fixed(float x, float y, float w, float h, int depth)
+{
+ float depth_coord = (float)depth;
+
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+
+ glBegin(GL_QUADS);
+
+ glTexCoord3f(0, 0, depth_coord);
+ glVertex2f(x, y);
+
+ glTexCoord3f(1, 0, depth_coord);
+ glVertex2f(x + w, y);
+
+ glTexCoord3f(1, 1, depth_coord);
+ glVertex2f(x + w, y + h);
+
+ glTexCoord3f(0, 1, depth_coord);
+ glVertex2f(x, y + h);
+
+ glEnd();
+}
+
+static void
+draw_3d_depth(float x, float y, float w, float h, int depth)
+{
+ GLfloat d = (GLfloat) depth;
+ GLfloat vertices[12] = {x, y, 0.0,
+ x+w, y, 0.0,
+ x+w, y+h, 0.0,
+ x, y+h, 0.0};
+ GLuint elements[4] = {0, 1, 2, 3};
+
+ GLfloat texcoords[12] = {0.0, 0.0, d,
+ 1.0, 0.0, d,
+ 1.0, 1.0, d,
+ 0.0, 1.0, d};
+
+ glVertexPointer(3, GL_FLOAT, 0, vertices);
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ glTexCoordPointer(3, GL_FLOAT, 0, texcoords);
+ glDrawElements(GL_TRIANGLE_FAN, 4, GL_UNSIGNED_INT, elements);
+}
+
+/**
+ * Simple views of textures; test rendering with various texture view targets
+ */
+static enum piglit_result
+test_render_with_targets(GLenum target)
+{
+ GLuint tex, new_tex;
+ GLint width = 128, height = 64, depth = 4, levels = 8;
+ GLint l;
+
+ //only handle subset of legal targets
+ assert(target == GL_TEXTURE_1D ||
+ target == GL_TEXTURE_2D ||
+ target == GL_TEXTURE_2D_ARRAY ||
+ target == GL_TEXTURE_3D);
+
+ glUseProgram(0);
+ glGenTextures(1, &tex);
+ glBindTexture(target, tex);
+
+ if (target == GL_TEXTURE_1D) {
+ glTexStorage1D(target, levels, GL_RGBA8, width);
+ height = 1;
+ depth = 1;
+ }
+ else if (target == GL_TEXTURE_2D) {
+ glTexStorage2D(target, levels, GL_RGBA8, width, height);
+ depth = 1;
+ }
+ else if (target == GL_TEXTURE_3D || target == GL_TEXTURE_2D_ARRAY) {
+ glTexStorage3D(target, levels, GL_RGBA8, width, height, depth);
+ }
+
+ /* load each mipmap with a different color texture */
+ for (l = 0; l < levels; l++) {
+ GLubyte *buf = create_solid_image(width, height, depth, 4, l);
+
+ if (buf != NULL) {
+ if (target == GL_TEXTURE_1D) {
+ glTexSubImage1D(GL_TEXTURE_1D, l, 0, width, GL_RGBA,
+ GL_UNSIGNED_BYTE, buf);
+ }
+ else if (target == GL_TEXTURE_2D) {
+ glTexSubImage2D(GL_TEXTURE_2D, l, 0, 0, width, height,
+ GL_RGBA, GL_UNSIGNED_BYTE, buf);
+ }
+ else if (target == GL_TEXTURE_3D || target == GL_TEXTURE_2D_ARRAY) {
+ glTexSubImage3D(target, l, 0, 0, 0, width, height, depth,
+ GL_RGBA, GL_UNSIGNED_BYTE, buf);
+ }
+ free(buf);
+ }
+
+ if (width > 1)
+ width /= 2;
+ if (height > 1)
+ height /= 2;
+ if (depth > 1)
+ depth /= 2;
+ }
+
+ if (piglit_check_gl_error(GL_NO_ERROR) == GL_FALSE) {
+ printf("%s:%s Found gl errors prior to testing glTextureView\n",
+ TestName, __func__);
+ glDeleteTextures(1, &tex);
+
+ return PIGLIT_SKIP;
+ }
+
+ // create view of texture and bind it to target
+ glGenTextures(1, &new_tex);
+ glTextureView(new_tex, target, tex, GL_RGBA8, 0, levels, 0, 1);
+ glDeleteTextures(1, &tex);
+ if (piglit_check_gl_error(GL_NO_ERROR) == GL_FALSE) {
+ glDeleteTextures(1, &new_tex);
+ return PIGLIT_FAIL;
+ }
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(target, new_tex);
+
+
+ /* draw a quad/line using each texture mipmap level */
+ glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
+ glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ for (l = 0; l < levels; l++) {
+ GLfloat expected[3];
+ int p;
+
+ glTexParameteri(target, GL_TEXTURE_BASE_LEVEL, l);
+ glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, l);
+
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ if (target == GL_TEXTURE_1D) {
+ glUseProgram(prog1D);
+ glUniform1i(tex_loc_1D, 0);
+ draw_line(-1.0, -1.0, 2.0, 2.0);
+ }
+ else if (target == GL_TEXTURE_2D) {
+ glEnable(target);
+ piglit_draw_rect_tex(-1.0, -1.0, 2.0, 2.0, 0.0, 0.0, 1.0, 1.0);
+ glDisable(target);
+ } else if (target == GL_TEXTURE_2D_ARRAY) {
+ glUseProgram(prog2Darray);
+ glUniform1i(tex_loc_2Darray, 0);
+ draw_3d_depth(-1.0, -1.0, 2.0, 2.0, l);
+
+ } else if (target == GL_TEXTURE_3D) {
+ glEnable(target);
+ draw_3d_depth_fixed(-1.0, -1.0, 2.0, 2.0, l);
+ glDisable(target);
+ }
+
+ expected[0] = Colors[l][0] / 255.0;
+ expected[1] = Colors[l][1] / 255.0;
+ expected[2] = Colors[l][2] / 255.0;
+
+ p = piglit_probe_pixel_rgb(piglit_width/2, piglit_height/2, expected);
+
+ piglit_present_results();
+
+ if (0) { //debug
+ printf("%s for level=%d, target=%s, expected color=%f %f %f\n",
+ __func__, l, piglit_get_gl_enum_name(target), expected[0],
+ expected[1], expected[2]);
+ sleep(1);
+ }
+
+ if (!p) {
+ printf("%s: wrong color for mipmap level %d\n", TestName, l);
+ glDeleteTextures(1, &new_tex);
+
+ return PIGLIT_FAIL;
+ }
+ }
+ glDeleteTextures(1, &new_tex);
+
+ return PIGLIT_PASS;
+}
+
+
+/**
+ * Views with varying minimum and number of levels, 2D only
+ */
+static enum piglit_result
+test_render_levels()
+{
+ GLuint tex, new_tex;
+ GLint width = 4096, height = 4096, levels =13;
+ GLuint num_levels[] = {3,2,2,1};
+ GLint l;
+ int expected_level;
+ GLfloat expected[3];
+ int p;
+
+ glUseProgram(0);
+
+ glGenTextures(1, &tex);
+ glBindTexture(GL_TEXTURE_2D, tex);
+
+ glTexStorage2D(GL_TEXTURE_2D, levels, GL_RGBA8, width, height);
+ glEnable(GL_TEXTURE_2D);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+
+ /* load each mipmap with a different color texture */
+ for (l = 0; l < levels; l++) {
+ GLubyte *buf = create_solid_image(width, height, 1, 4, l);
+
+ if (buf != NULL) {
+ glTexSubImage2D(GL_TEXTURE_2D, l, 0, 0, width, height,
+ GL_RGBA, GL_UNSIGNED_BYTE, buf);
+ free(buf);
+ }
+
+ if (width > 1)
+ width /= 2;
+ if (height > 1)
+ height /= 2;
+ }
+
+ if (piglit_check_gl_error(GL_NO_ERROR) == GL_FALSE) {
+ printf("%s:%s Found gl errors prior to testing glTextureView\n",
+ TestName, __func__);
+ glDisable(GL_TEXTURE_2D);
+ glDeleteTextures(1, &tex);
+
+ return PIGLIT_SKIP;
+ }
+
+ // create view of texture with restricted levels and draw quad
+ // using smallest mip level in the view range which varies every loop
+ for (l = 0; l < ARRAY_SIZE(num_levels); l++) {
+ glGenTextures(1, &new_tex);
+ glTextureView(new_tex, GL_TEXTURE_2D, tex, GL_RGBA8, l, num_levels[l], 0, 1);
+ glBindTexture(GL_TEXTURE_2D, new_tex);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, levels-1);
+
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ piglit_draw_rect_tex(-1.0, -1.0, 2.0/(float) (l+2), 2.0/ (float) (l+2),
+ 0.0, 0.0, 1.0, 1.0);
+
+ expected_level = l + num_levels[l] - 1;
+ expected[0] = Colors[expected_level][0] / 255.0;
+ expected[1] = Colors[expected_level][1] / 255.0;
+ expected[2] = Colors[expected_level][2] / 255.0;
+
+ p = piglit_probe_pixel_rgb(piglit_width/(2*(l+3)), piglit_height/(2*(l+3)), expected);
+
+ piglit_present_results();
+
+ if (0) { //debug
+ GLint param;
+ glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, ¶m);
+ printf("%s for view min level=%d base_level=%d expected color=%f %f %f\n",
+ __func__, l, param, expected[0], expected[1], expected[2]);
+ glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, ¶m);
+ printf("max_level=%d\n", param);
+ glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_VIEW_MIN_LEVEL, ¶m);
+ printf("view min_level=%d\n", param);
+ glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_VIEW_NUM_LEVELS, ¶m);
+ printf("view num_level=%d\n", param);
+ glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_IMMUTABLE_LEVELS, ¶m);
+ printf("immutable levels=%d\n", param);
+ glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, ¶m);
+ printf("view max_lod=%d\n", param);
+ sleep(1);
+ }
+
+ if (!p) {
+ printf("%s: wrong color for view min level %d, expected_level %d\n",
+ TestName, l, expected_level);
+ glDisable(GL_TEXTURE_2D);
+ glDeleteTextures(1, &new_tex);
+ glDeleteTextures(1, &tex);
+
+ return PIGLIT_FAIL;
+ }
+ glDeleteTextures(1, &new_tex);
+ }
+
+ glDisable(GL_TEXTURE_2D);
+ glDeleteTextures(1, &tex);
+ return PIGLIT_PASS;
+}
+
+/**
+ * Views with varying minimum and number of layers 2D_ARRAY only
+ */
+
+static enum piglit_result
+test_render_layers()
+{
+ GLuint tex, new_tex;
+ GLint width = 16, height = 16, layers = 8;
+ GLint l;
+ GLint num_layers[] = {7, 1, 2, 2};
+ int expected_layer;
+ GLfloat expected[3];
+ int p;
+
+ glUseProgram(prog2Darray);
+ glUniform1i(tex_loc_2Darray, 0);
+
+ glGenTextures(1, &tex);
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D_ARRAY, tex);
+
+ glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BASE_LEVEL, 0);
+ glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, 0);
+ glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_RGBA8, width, height, layers);
+
+ /* load each array layer with a different color texture */
+ for (l = 0; l < layers; l++) {
+ GLubyte *buf = create_solid_image(width, height, 1, 4, l);
+
+ if (buf != NULL) {
+ glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, l, width, height, 1,
+ GL_RGBA, GL_UNSIGNED_BYTE, buf);
+ free(buf);
+ }
+
+ }
+
+ if (piglit_check_gl_error(GL_NO_ERROR) == GL_FALSE) {
+ printf("%s:%s Found gl errors prior to testing glTextureView\n",
+ TestName, __func__);
+ glDeleteTextures(1, &tex);
+ return PIGLIT_SKIP;
+ }
+
+ // create view of texture with restricted layers and draw quad
+ // using a single layer in the view range which varies every loop
+ for (l = 0; l < ARRAY_SIZE(num_layers); l++) {
+ glGenTextures(1, &new_tex);
+ glTextureView(new_tex, GL_TEXTURE_2D_ARRAY, tex, GL_RGBA8, 0, 1, l, num_layers[l]);
+
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D_ARRAY, new_tex);
+
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ expected_layer = l + num_layers[l] - 1;
+ draw_3d_depth(-1.0, -1.0, 2.0, 2.0, expected_layer);
+
+ expected[0] = Colors[expected_layer][0] / 255.0;
+ expected[1] = Colors[expected_layer][1] / 255.0;
+ expected[2] = Colors[expected_layer][2] / 255.0;
+
+ p = piglit_probe_pixel_rgb(piglit_width/2, piglit_height/2, expected);
+
+ piglit_present_results();
+
+ if (0) { //debug
+ printf("%s for view min layer=%d expected_layer=%d expected color=%f %f %f\n",
+ __func__, l, expected_layer, expected[0], expected[1], expected[2]);
+ sleep(1);
+ }
+
+ if (!p) {
+ printf("%s: wrong color for view min layer %d, expected_layer %d\n",
+ TestName, l, expected_layer);
+ glDeleteTextures(1, &new_tex);
+ glDeleteTextures(1, &tex);
+
+ return PIGLIT_FAIL;
+ }
+ glDeleteTextures(1, &new_tex);
+ }
+
+ glDeleteTextures(1, &tex);
+ return PIGLIT_PASS;
+}
+
+/**
+ * Views with data format changes. 1D textures only.
+ * Also uses multiple simultaneous views with different lifetimes and check results
+ * via glGetTexImage().
+ */
+
+static int
+compare_buffers(unsigned char * buf0, unsigned char *buf1, GLint w)
+{
+ int i;
+ for (i = 0; i < w; i++) {
+ if (buf0[i] != buf1[i]) {
+ printf("mismatched texels at index (%d)\n", i);
+ printf(" Buffer0: %u\n", buf0[i]);
+ printf(" Buffer1: %u\n", buf1[i]);
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+static enum piglit_result
+test_format_lifetime(struct format_desc desc0, struct format_desc desc1)
+{
+ GLuint tex, view_tex[3];
+ GLint width = 32, w, levels = 6;
+ GLint l;
+ int bytes;
+ unsigned char *buffer0, *buffer1;
+
+ glGenTextures(1, &tex);
+ glBindTexture(GL_TEXTURE_1D, tex);
+ glTexStorage1D(GL_TEXTURE_1D, levels, desc0.storagefmt, width);
+ glGenTextures(3, view_tex);
+ glTextureView(view_tex[0], GL_TEXTURE_1D, tex, desc0.internalfmt, 0,
+ levels, 0, 1);
+ glTextureView(view_tex[1], GL_TEXTURE_1D, view_tex[0], desc1.internalfmt, 0,
+ levels, 0, 1);
+
+ if (piglit_check_gl_error(GL_NO_ERROR) == GL_FALSE) {
+ glDeleteTextures(1, &tex);
+ glDeleteTextures(3, view_tex);
+ return PIGLIT_FAIL;
+ }
+
+ /* load each mipmap with a different color texture */
+ w = width;
+ bytes = (desc0.red + desc0.green + desc0.blue + desc0.alpha) / 8;
+ for (l = 0; l < levels; l++) {
+ GLubyte *buf = create_solid_image(width, 1, 1, bytes, l);
+
+ if (buf != NULL) {
+ glTexSubImage1D(GL_TEXTURE_1D, l, 0, w, desc0.imagefmt,
+ desc0.imagetype, buf);
+ free(buf);
+ }
+
+ if (w > 1)
+ w /= 2;
+ }
+
+ if (0) { // debug
+ printf("%s:fmt0=%s, fmt1=%s, strgfmt0=%s, gettype0=%s\n",__func__,
+ piglit_get_gl_enum_name(desc0.internalfmt),
+ piglit_get_gl_enum_name(desc1.internalfmt),
+ piglit_get_gl_enum_name(desc0.storagefmt),
+ piglit_get_gl_enum_name(desc0.gettype));
+ printf("bytes=%d, width=%d, view_tex[0]=%d, [1]=%d, [2]=%d\n",bytes,width,
+ view_tex[0], view_tex[1], view_tex[2]);
+
+ }
+
+ glDeleteTextures(1, &tex);
+
+ if (piglit_check_gl_error(GL_NO_ERROR) == GL_FALSE) {
+ glDeleteTextures(3, view_tex);
+ return PIGLIT_FAIL;
+ }
+
+ /* compare view0 all level texels bytes to view1 texels bytes */
+ buffer0 = malloc(width * bytes);
+ buffer1 = malloc(width * bytes);
+ w = width;
+ for (l = 0; l < levels; l++) {
+ glBindTexture(GL_TEXTURE_1D, view_tex[0]);
+ glGetTexImage(GL_TEXTURE_1D, l, desc0.getfmt, desc0.gettype, buffer0);
+
+ glBindTexture(GL_TEXTURE_1D, view_tex[1]);
+ glGetTexImage(GL_TEXTURE_1D, l, desc1.getfmt, desc1.gettype, buffer1);
+ if (compare_buffers(buffer0, buffer1, w)) {
+ piglit_check_gl_error(GL_NO_ERROR);
+ printf("level %d texel mismatch view 0 and view1, width=%d\n", l, w);
+ free(buffer0);
+ free(buffer1);
+ glDeleteTextures(3, view_tex);
+
+ return PIGLIT_FAIL;
+
+ }
+
+ if (w > 1)
+ w /= 2;
+ }
+
+ if (piglit_check_gl_error(GL_NO_ERROR) == GL_FALSE) {
+ glDeleteTextures(3, view_tex);
+ return PIGLIT_FAIL;
+ }
+
+ /* compare view1 base level texels to view2 after view0 and view1 deleted */
+ glBindTexture(GL_TEXTURE_1D, view_tex[1]);
+ glGetTexImage(GL_TEXTURE_1D, 0, desc1.getfmt, desc1.gettype, buffer1);
+
+ if (piglit_check_gl_error(GL_NO_ERROR) == GL_FALSE) {
+ printf("gl error after glGetTexImage\n");
+ }
+
+ glTextureView(view_tex[2], GL_TEXTURE_1D, view_tex[0], desc0.internalfmt,
+ 0, 1, 0, 1);
+ if (piglit_check_gl_error(GL_NO_ERROR) == GL_FALSE) {
+ printf("gl error after glTextureView[2]n");
+ }
+ glDeleteTextures(2, view_tex);
+ glBindTexture(GL_TEXTURE_1D, view_tex[2]);
+ glGetTexImage(GL_TEXTURE_1D, 0, desc0.getfmt, desc0.gettype, buffer0);
+ if (piglit_check_gl_error(GL_NO_ERROR) == GL_FALSE) {
+ printf("gl error after glGetTexI\n");
+ }
+
+ if (compare_buffers(buffer0, buffer1, width)) {
+ free(buffer0);
+ free(buffer1);
+ glDeleteTextures(1, &view_tex[2]);
+
+ return PIGLIT_FAIL;
+ }
+
+ free(buffer0);
+ free(buffer1);
+ glDeleteTextures(1, &view_tex[2]);
+
+ return PIGLIT_PASS;
+
+}
+
+enum piglit_result
+piglit_display(void)
+{
+ enum piglit_result pass = PIGLIT_PASS;
+ enum piglit_result tmp;
+#define X(f, n) tmp = (f); pass = tmp != PIGLIT_PASS ? PIGLIT_FAIL : pass; piglit_report_subtest_result(tmp, (n))
+ X(test_format_lifetime(format_list[0], format_list[1]), "view compare 32 bit formats");
+ X(test_format_lifetime(format_list[2], format_list[3]), "view compare 48 bit formats");
+ X(test_format_lifetime(format_list[4], format_list[5]), "view compare 16 bit formats");
+ X(test_render_layers(), "2D layers rendering");
+ X(test_render_levels(), "2D levels rendering");
+ X(test_render_with_targets(GL_TEXTURE_1D), "1D view rendering");
+ X(test_render_with_targets(GL_TEXTURE_2D), "2D view rendering");
+ X(test_render_with_targets(GL_TEXTURE_3D), "3D view rendering");
+ X(test_render_with_targets(GL_TEXTURE_2D_ARRAY), "2D Array view rendering");
+#undef X
+ if (piglit_check_gl_error(GL_NO_ERROR) == GL_FALSE)
+ return PIGLIT_FAIL;
+ return pass;
+}
+
+
+void
+piglit_init(int argc, char **argv)
+{
+ int vs, fs;
+ static char *vs_code;
+ static char *fs_code;
+ char *shader_version = "";
+ char *extension_fs = "#extension GL_EXT_texture_array : enable";
+ char *extension_vs = "";
+
+ piglit_require_extension("GL_ARB_texture_storage");
+ piglit_require_extension("GL_ARB_texture_view");
+ piglit_require_extension("GL_EXT_texture_integer");
+ piglit_require_extension("GL_EXT_texture_array");
+ piglit_require_extension("GL_EXT_texture3D");
+ piglit_reset_gl_error();
+
+ // setup shaders and program object for 2DArray rendering
+ asprintf(&vs_code,
+ "%s\n%s\n"
+ "void main()\n"
+ "{\n"
+ " gl_Position = gl_Vertex;\n"
+ " gl_TexCoord[0] = gl_MultiTexCoord0;\n"
+ "}\n",
+ shader_version, extension_vs);
+ asprintf(&fs_code,
+ "%s\n%s\n"
+ "uniform sampler2DArray tex;\n"
+ "void main()\n"
+ "{\n"
+ " vec4 color = texture2DArray(tex, gl_TexCoord[0].xyz);\n"
+ " gl_FragColor = vec4(color.xyz, 1.0);\n"
+ "}\n",
+ shader_version, extension_fs);
+
+ vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vs_code);
+ fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, fs_code);
+
+ free(fs_code);
+ free(vs_code);
+ if (!vs || !fs)
+ piglit_report_result(PIGLIT_FAIL);
+
+ prog2Darray = glCreateProgram();
+ glAttachShader(prog2Darray, vs);
+ glAttachShader(prog2Darray, fs);
+ glLinkProgram(prog2Darray);
+ if (!piglit_link_check_status(prog2Darray))
+ piglit_report_result(PIGLIT_FAIL);
+
+ tex_loc_2Darray = glGetUniformLocation(prog2Darray, "tex");
+
+ // setup shaders and program object for 1D rendering
+ asprintf(&fs_code,
+ "%s\n%s\n"
+ "uniform sampler1D tex;\n"
+ "void main()\n"
+ "{\n"
+ " vec4 color = texture1D(tex, gl_TexCoord[0].x);\n"
+ " gl_FragColor = vec4(color.xyz, 1.0);\n"
+ "}\n",
+ shader_version, extension_fs);
+
+ fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, fs_code);
+ free(fs_code);
+
+ prog1D = glCreateProgram();
+ glAttachShader(prog1D, vs);
+ glAttachShader(prog1D, fs);
+ glLinkProgram(prog1D);
+ if (!piglit_link_check_status(prog1D))
+ piglit_report_result(PIGLIT_FAIL);
+
+ tex_loc_1D = glGetUniformLocation(prog1D, "tex");
+}
--
1.8.1.2
More information about the Piglit
mailing list