From: Dave Airlie <[email protected]>

for every supported target for all the depth/stencil formats
this creates a texture, and then uses glGetTexImage
to read it back.

v2: fix Brian's review comments.
add to all.py
---
 tests/all.py                        |   1 +
 tests/texturing/CMakeLists.gl.txt   |   1 +
 tests/texturing/getteximage-depth.c | 629 ++++++++++++++++++++++++++++++++++++
 3 files changed, 631 insertions(+)
 create mode 100644 tests/texturing/getteximage-depth.c

diff --git a/tests/all.py b/tests/all.py
index 82e6311..faf0447 100644
--- a/tests/all.py
+++ b/tests/all.py
@@ -917,6 +917,7 @@ with profile.group_manager(
     g(['getteximage-formats'], run_concurrent=False)
     g(['getteximage-luminance'], run_concurrent=False)
     g(['getteximage-simple'], run_concurrent=False)
+    g(['getteximage-depth'], run_concurrent=True)
     g(['incomplete-texture', 'fixed'], 'incomplete-texture-fixed')
     g(['max-texture-size'], run_concurrent=False)
     g(['max-texture-size-level'])
diff --git a/tests/texturing/CMakeLists.gl.txt 
b/tests/texturing/CMakeLists.gl.txt
index 68afa16..704ea6d 100644
--- a/tests/texturing/CMakeLists.gl.txt
+++ b/tests/texturing/CMakeLists.gl.txt
@@ -34,6 +34,7 @@ piglit_add_executable (getteximage-formats 
getteximage-formats.c)
 piglit_add_executable (getteximage-simple getteximage-simple.c)
 piglit_add_executable (getteximage-luminance getteximage-luminance.c)
 piglit_add_executable (getteximage-targets getteximage-targets.c)
+piglit_add_executable (getteximage-depth getteximage-depth.c)
 piglit_add_executable (incomplete-texture incomplete-texture.c)
 piglit_add_executable (generatemipmap-cubemap generatemipmap-cubemap.c)
 piglit_add_executable (fragment-and-vertex-texturing 
fragment-and-vertex-texturing.c)
diff --git a/tests/texturing/getteximage-depth.c 
b/tests/texturing/getteximage-depth.c
new file mode 100644
index 0000000..9797713
--- /dev/null
+++ b/tests/texturing/getteximage-depth.c
@@ -0,0 +1,629 @@
+/*
+ * Copyright (c) 2015 Red Hat
+ *
+ * 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 getteximage-depth
+ *
+ * Test glGetTexImage for depth/stencil format/target combinations in a 
roundtrip.
+ * i.e. don't draw the textures, just create and readback.
+ * this was due to a bug in mesa's handling of 1D array depth textures.
+ */
+
+#include "piglit-util-gl.h"
+#include "../fbo/fbo-formats.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)
+{
+       /* UNREACHABLE */
+       return PIGLIT_FAIL;
+}
+
+#define IMAGE_WIDTH 32
+#define IMAGE_HEIGHT 32
+
+static const GLenum target_list[] = { GL_TEXTURE_1D,
+                                     GL_TEXTURE_2D,
+                                     GL_TEXTURE_3D,
+                                     GL_TEXTURE_RECTANGLE,
+                                     GL_TEXTURE_CUBE_MAP,
+                                     GL_TEXTURE_1D_ARRAY,
+                                     GL_TEXTURE_2D_ARRAY,
+                                     GL_TEXTURE_CUBE_MAP_ARRAY };
+
+static int get_test_height(GLenum target)
+{
+       switch (target) {
+       case GL_TEXTURE_1D:
+       case GL_TEXTURE_1D_ARRAY:
+               return 1;
+       default:
+               return IMAGE_HEIGHT;
+       }
+}
+
+static int get_test_depth(GLenum target)
+{
+       switch (target) {
+       case GL_TEXTURE_3D:
+               return 16;
+       case GL_TEXTURE_1D_ARRAY:
+       case GL_TEXTURE_2D_ARRAY:
+               return 7;
+       case GL_TEXTURE_CUBE_MAP_ARRAY:
+               return 12;
+       case GL_TEXTURE_CUBE_MAP:
+               return 6;
+       default:
+               return 1;
+       }
+}
+
+static float get_depth_value(int w, int x)
+{
+       if (w == 1)
+               return 1.0;
+       else
+               return (float)(x) / (w - 1);
+}
+
+static int get_stencil_value(int w, int x)
+{
+       if (w == 1)
+               return 255;
+       else
+               return (x * 255) / (w - 1);
+}
+
+static GLuint
+create_depth_texture(const struct format_desc *format, GLenum target,
+                    int w, int h, int d, bool mip)
+{
+       void *data;
+       float *f = NULL;
+       unsigned int  *i = NULL;
+       int size, x, y, level, layer;
+       GLuint tex;
+       GLuint extra = 0;
+       GLenum datatype, dataformat;
+       int mul = 1;
+
+       glGenTextures(1, &tex);
+       glBindTexture(target, tex);
+
+       if (format->internalformat == GL_DEPTH32F_STENCIL8) {
+               mul = 2;
+       }
+       extra = d * sizeof(GLfloat) * mul;
+
+       data = calloc(1, w * h * sizeof(GLfloat) * mul + extra);
+
+       if (format->internalformat == GL_DEPTH_STENCIL_EXT ||
+           format->internalformat == GL_DEPTH24_STENCIL8_EXT) {
+               dataformat = GL_DEPTH_STENCIL_EXT;
+               datatype = GL_UNSIGNED_INT_24_8_EXT;
+               i = data;
+       } else if (format->internalformat == GL_DEPTH32F_STENCIL8) {
+               dataformat = GL_DEPTH_STENCIL;
+               datatype = GL_FLOAT_32_UNSIGNED_INT_24_8_REV;
+               f = data;
+       } else {
+               dataformat = GL_DEPTH_COMPONENT;
+               datatype = GL_FLOAT;
+               f = data;
+       }
+
+       for (level = 0, size = w > h ? w : h; size > 0; level++, size >>= 1) {
+               for (y = 0; y < h; y++) {
+                       for (x = 0; x < w; x++) {
+                               float val = get_depth_value(w, x);
+
+                               if (f)
+                                       f[(y * w + x)*mul] = val;
+                               else
+                                       i[y * w + x] = 0xffffff00 * val;
+                       }
+               }
+
+               for (x = 0; x < d; x++) {
+                       float val = get_depth_value(w, x % w);
+
+                       if (f)
+                               f[(h * w + x)*mul] = val;
+                       else
+                               i[h * w + x] = 0xffffff00 * val;
+               }
+
+               switch (target) {
+               case GL_TEXTURE_1D:
+                       glTexImage1D(target, level,
+                                    format->internalformat,
+                                    w, 0,
+                                    dataformat, datatype, data);
+                       break;
+               case GL_TEXTURE_2D:
+               case GL_TEXTURE_RECTANGLE:
+                       glTexImage2D(target, level,
+                                    format->internalformat,
+                                    w, h, 0,
+                                    dataformat, datatype, data);
+                       break;
+               case GL_TEXTURE_CUBE_MAP:
+                       assert(d == 6);
+                       for (layer = 0; layer < d; layer++) {
+                               char *ptr = data;
+                               ptr += layer * 4 * mul;
+                               glTexImage2D(cube_face_targets[layer],
+                                            level, format->internalformat,
+                                            w, h, 0,
+                                            dataformat, datatype, ptr);
+                       }
+                       break;
+               case GL_TEXTURE_1D_ARRAY:
+                       glTexImage2D(target, level,
+                                    format->internalformat,
+                                    w, d, 0,
+                                    dataformat, datatype, NULL);
+                       for (layer = 0; layer < d; layer++) {
+                               char *ptr = data;
+                               ptr += layer * (4 * mul);
+                               glTexSubImage2D(target, level,
+                                               0, layer, w, 1,
+                                               dataformat, datatype, ptr);
+                       }
+                       break;
+               case GL_TEXTURE_2D_ARRAY:
+               case GL_TEXTURE_CUBE_MAP_ARRAY:
+                       glTexImage3D(target, level,
+                                    format->internalformat,
+                                    w, h, d, 0,
+                                    dataformat, datatype, NULL);
+                       for (layer = 0; layer < d; layer++) {
+                               char *ptr = data;
+                               ptr += layer * (4 * mul);
+                               glTexSubImage3D(target, level,
+                                               0, 0, layer, w, h, 1,
+                                               dataformat, datatype, ptr);
+                       }
+                       break;
+
+               default:
+                       assert(0);
+               }
+
+               if (!mip)
+                       break;
+
+               if (w > 1)
+                       w >>= 1;
+               if (target != GL_TEXTURE_1D &&
+                   target != GL_TEXTURE_1D_ARRAY &&
+                   h > 1)
+                       h >>= 1;
+       }
+       free(data);
+       return tex;
+}
+
+static GLuint
+create_stencil_texture(const struct format_desc *format, GLenum target,
+                      int w, int h, int d, bool mip)
+{
+       void *data;
+       unsigned char *u;
+       int size, x, y, level, layer;
+       GLuint tex;
+       GLenum datatype, dataformat;
+
+       glGenTextures(1, &tex);
+       glBindTexture(target, tex);
+
+       data = malloc(w * h * sizeof(GLubyte) + d * sizeof(GLubyte));
+
+       dataformat = GL_STENCIL_INDEX;
+       datatype = GL_UNSIGNED_BYTE;
+       u = data;
+       glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+       for (level = 0, size = w > h ? w : h; size > 0; level++, size >>= 1) {
+               for (y = 0; y < h; y++) {
+                       for (x = 0; x < w; x++) {
+                               GLuint val = get_stencil_value(w, x);
+
+                               u[y * w + x] = val;
+                       }
+               }
+
+               for (x = 0; x < d; x++) {
+                       GLuint val = get_stencil_value(w, x % w);
+                       u[h * w + x] = val;
+               }
+
+               switch (target) {
+               case GL_TEXTURE_1D:
+                       glTexImage1D(target, level,
+                                    format->internalformat,
+                                    w, 0,
+                                    dataformat, datatype, data);
+                       break;
+
+               case GL_TEXTURE_2D:
+               case GL_TEXTURE_RECTANGLE:
+                       glTexImage2D(target, level,
+                                    format->internalformat,
+                                    w, h, 0,
+                                    dataformat, datatype, data);
+                       break;
+               case GL_TEXTURE_CUBE_MAP:
+                       assert(d == 6);
+                       for (layer = 0; layer < d; layer++) {
+                               char *ptr = data;
+                               ptr += layer;
+                               glTexImage2D(cube_face_targets[layer],
+                                            level, format->internalformat,
+                                            w, h, 0,
+                                            dataformat, datatype, ptr);
+                       }
+                       break;
+               case GL_TEXTURE_1D_ARRAY:
+                       glTexImage2D(target, level,
+                                    format->internalformat,
+                                    w, d, 0,
+                                    dataformat, datatype, NULL);
+                       for (layer = 0; layer < d; layer++) {
+                               char *ptr = data;
+                               ptr += layer;
+                               glTexSubImage2D(target, level,
+                                               0, layer, w, 1,
+                                               dataformat, datatype, ptr);
+                       }
+                       break;
+               case GL_TEXTURE_CUBE_MAP_ARRAY:
+               case GL_TEXTURE_2D_ARRAY:
+                       glTexImage3D(target, level,
+                                    format->internalformat,
+                                    w, h, d, 0,
+                                    dataformat, datatype, NULL);
+                       for (layer = 0; layer < d; layer++) {
+                               char *ptr = data;
+                               ptr += layer;
+                               glTexSubImage3D(target, level,
+                                               0, 0, layer, w, h, 1,
+                                               dataformat, datatype, ptr);
+                       }
+                       break;
+
+               default:
+                       assert(0);
+               }
+
+               if (!mip)
+                       break;
+
+               if (w > 1)
+                       w >>= 1;
+               if (target != GL_TEXTURE_1D &&
+                   target != GL_TEXTURE_1D_ARRAY &&
+                   h > 1)
+                       h >>= 1;
+       }
+       glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
+       free(data);
+       return tex;
+}
+
+static bool
+verify_depth_data(const struct format_desc *format, GLenum target,
+                 int w, int h, int d, bool mip)
+{
+       int x, y, layer, level;
+       GLfloat *f;
+       unsigned *i = NULL;
+       int size;
+       GLenum datatype = format->base_internal_format;
+       GLenum dataformat;
+       int layer_size;
+       int mul = 1;
+       void *data, *ptr;
+       if (format->internalformat == GL_DEPTH32F_STENCIL8) {
+               dataformat = GL_FLOAT_32_UNSIGNED_INT_24_8_REV;
+               mul = 2;
+       }
+       else if (format->base_internal_format == GL_DEPTH_STENCIL)
+               dataformat = GL_UNSIGNED_INT_24_8_EXT;
+       else
+               dataformat = GL_FLOAT;
+
+       ptr = calloc(mul * 4, w * h * d);
+       if (!ptr)
+               return false;
+
+       for (level = 0, size = w > h ? w : h; size > 0; level++, size >>= 1) {
+               data = ptr;
+               layer_size = w * h * 4 * mul;
+
+               if (target == GL_TEXTURE_CUBE_MAP) {
+                       int idx;
+                       for (idx = 0; idx < 6; idx++)
+                               glGetTexImage(cube_face_targets[idx], level, 
datatype, dataformat,
+                                             (char *)data + layer_size * idx);
+               } else
+                       glGetTexImage(target, level, datatype, dataformat,
+                                     data);
+
+               for (layer = 0; layer < d; layer++) {
+                       f = data;
+                       if (format->internalformat == GL_DEPTH_STENCIL_EXT ||
+                           format->internalformat == GL_DEPTH24_STENCIL8_EXT)
+                               i = data;
+
+                       for (y = 0; y < h; y++) {
+                               for (x = 0; x < w; x++) {
+                                       int offset = (x + layer) % w;
+                                       float exp_val = get_depth_value(w, 
offset);
+                                       float got_val;
+
+                                       if (i)
+                                               got_val = (float)(i[y * w + x] 
>> 8) / (float)0xffffff;
+                                       else
+                                               got_val = f[(y * w + x) * mul];
+                                       if (fabs(got_val - exp_val) >= 1e-4) {
+                                               fprintf(stderr, "mismatch at %d 
%d %d %d %g vs %g: %d %dx%d\n", level, x, y, layer, got_val, exp_val, 
layer_size, w, h);
+                                               if (0){
+                                                       uint32_t *myptr = data;
+                                                       int myx;
+                                                       for (myx = 0; myx < w * 
h; myx++){
+                                                               fprintf(stderr, 
"%08x ", myptr[myx]);
+                                                       }
+                                                       fprintf(stderr, "\n");
+                                               }
+                                               free(ptr);
+                                               return false;
+                                       }
+                               }
+                       }
+                       data = (char *)data + layer_size;
+               }
+
+               if (!mip)
+                       break;
+               if (w > 1)
+                       w >>= 1;
+               if (target != GL_TEXTURE_1D &&
+                   target != GL_TEXTURE_1D_ARRAY &&
+                   h > 1)
+                       h >>= 1;
+       }
+       free(ptr);
+       return true;
+}
+
+static bool
+verify_stencil_data(const struct format_desc *format,
+                   GLenum target, int w, int h, int d, bool mip)
+{
+       int x, y, layer, level, size;
+       GLubyte *ub;
+       GLenum datatype = format->base_internal_format;
+       GLenum dataformat = GL_UNSIGNED_BYTE;
+       void *data, *ptr;
+       int layer_size;
+
+       ptr = calloc(1, w * h * d);
+       if (!ptr)
+               return false;
+
+       for (level = 0, size = w > h ? w : h; size > 0; level++, size >>= 1) {
+               data = ptr;
+               layer_size = w * h;
+               glPixelStorei(GL_PACK_ALIGNMENT, 1);
+               if (target == GL_TEXTURE_CUBE_MAP) {
+                       int idx;
+                       for (idx = 0; idx < 6; idx++)
+                               glGetTexImage(cube_face_targets[idx], level, 
datatype, dataformat,
+                                             (char *)data + layer_size * idx);
+               } else
+                       glGetTexImage(target, level, datatype, dataformat,
+                                     data);
+               glPixelStorei(GL_PACK_ALIGNMENT, 4);
+               for (layer = 0; layer < d; layer++) {
+                       ub = data;
+
+                       for (y = 0; y < h; y++) {
+                               for (x = 0; x < w; x++) {
+                                       int offset = (x + layer) % w;
+                                       GLubyte got_val;
+                                       GLubyte exp_val = get_stencil_value(w, 
offset);
+
+                                       got_val = ub[y * w + x];
+                                       if (exp_val != got_val) {
+                                               fprintf(stderr, "mismatch at %d 
%d %d %d %d vs %d: %d %dx%d\n", level, x, y, layer, got_val, exp_val, 
layer_size, w, h);
+                                               free(ptr);
+                                               return false;
+                                       }
+                               }
+                       }
+                       data = (char *)data + layer_size;
+               }
+
+               if (!mip)
+                       break;
+               if (w > 1)
+                       w >>= 1;
+               if (target != GL_TEXTURE_1D &&
+                   target != GL_TEXTURE_1D_ARRAY &&
+                   h > 1)
+                       h >>= 1;
+       }
+       free(ptr);
+       return true;
+}
+
+static bool
+test_depth_format(GLenum target, const struct format_desc *format)
+{
+       GLuint tex;
+       int height, num_layers;
+       bool ret;
+
+       /* 3D depth textures don't occur */
+       if (target == GL_TEXTURE_3D)
+               return true;
+
+       height = get_test_height(target);
+       num_layers = get_test_depth(target);
+
+       tex = create_depth_texture(format, target, IMAGE_WIDTH, height,
+                                  num_layers,
+                                  target == GL_TEXTURE_RECTANGLE ? false : 
true);
+
+       ret = verify_depth_data(format, target, IMAGE_WIDTH, height, num_layers,
+                               target == GL_TEXTURE_RECTANGLE ? false : true);
+
+       piglit_report_subtest_result(ret ? PIGLIT_PASS : PIGLIT_FAIL,
+                                    "%s-%s",
+                                    piglit_get_gl_enum_name(target),
+                                    
piglit_get_gl_enum_name(format->internalformat));
+       glDeleteTextures(1, &tex);
+       return ret;
+}
+
+static bool
+test_stencil_format(GLenum target, const struct format_desc *format)
+{
+       GLuint tex;
+       int height, num_layers;
+       bool ret;
+       /* 3D depth textures don't occur */
+       if (target == GL_TEXTURE_3D)
+               return true;
+
+       height = get_test_height(target);
+       num_layers = get_test_depth(target);
+
+       tex = create_stencil_texture(format, target, IMAGE_WIDTH, height,
+                                    num_layers,
+                                    target == GL_TEXTURE_RECTANGLE ? false : 
true);
+
+       ret = verify_stencil_data(format, target, IMAGE_WIDTH, height, 
num_layers,
+                                 target == GL_TEXTURE_RECTANGLE ? false : 
true);
+       piglit_report_subtest_result(ret ? PIGLIT_PASS : PIGLIT_FAIL,
+                                    "%s-%s",
+                                    piglit_get_gl_enum_name(target),
+                                    
piglit_get_gl_enum_name(format->internalformat));
+       glDeleteTextures(1, &tex);
+       return ret;
+}
+
+static bool
+test_target_format(GLenum target, const struct format_desc *format)
+{
+       if (format->base_internal_format == GL_DEPTH_COMPONENT ||
+           format->base_internal_format == GL_DEPTH_STENCIL) {
+               return test_depth_format(target, format);
+       } else if (format->base_internal_format == GL_STENCIL_INDEX) {
+               return test_stencil_format(target, format);
+       }
+       return true;
+}
+
+static bool
+test_target(GLenum target)
+{
+       int fmt_idx;
+       int set_idx;
+       int ext_idx;
+       bool do_test_set;
+       bool result = true, ret;
+
+       for (set_idx = 0; set_idx < ARRAY_SIZE(test_sets); set_idx++) {
+               do_test_set = true;
+               for (ext_idx = 0; ext_idx < 3; ext_idx++) {
+                       if (test_sets[set_idx].ext[ext_idx])
+                               if 
(!piglit_is_extension_supported(test_sets[set_idx].ext[ext_idx])) {
+                                       do_test_set = false;
+                                       break;
+                               }
+               }
+               if (!do_test_set)
+                       continue;
+
+               for (fmt_idx = 0; fmt_idx < test_sets[set_idx].num_formats; 
fmt_idx++) {
+                       ret = test_target_format(target, 
&test_sets[set_idx].format[fmt_idx]);
+                       if (ret == false)
+                               result = false;
+               }
+       }
+       return result;
+}
+
+void
+piglit_init(int argc, char **argv)
+{
+       int i;
+       enum piglit_result status = PIGLIT_PASS;
+       bool ret;
+
+       for (i = 0; i < ARRAY_SIZE(target_list); i++) {
+
+               switch (target_list[i]) {
+               case GL_TEXTURE_1D:
+               case GL_TEXTURE_2D:
+               case GL_TEXTURE_3D:
+               default:
+                       break;
+               case GL_TEXTURE_RECTANGLE:
+                       if 
(!piglit_is_extension_supported("GL_ARB_texture_rectangle"))
+                               continue;
+                       break;
+               case GL_TEXTURE_CUBE_MAP:
+                       if 
(!piglit_is_extension_supported("GL_ARB_texture_cube_map"))
+                               continue;
+                       break;
+               case GL_TEXTURE_1D_ARRAY:
+               case GL_TEXTURE_2D_ARRAY:
+                       if 
(!piglit_is_extension_supported("GL_EXT_texture_array"))
+                               continue;
+                       break;
+               case GL_TEXTURE_CUBE_MAP_ARRAY:
+                       if 
(!piglit_is_extension_supported("GL_ARB_texture_cube_map_array"))
+                               continue;
+                       break;
+               }
+
+               ret = test_target(target_list[i]);
+               if (ret == false)
+                       status = PIGLIT_FAIL;
+       }
+
+       piglit_report_result(status);
+       (void)fbo_formats_display;
+}
-- 
2.4.3

_______________________________________________
Piglit mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/piglit

Reply via email to