[Piglit] [PATCH] GL_ARB_get_texture_sub_image: add new tests for this extension

Brian Paul brianp at vmware.com
Thu Dec 18 07:56:08 PST 2014


On 12/18/2014 06:44 AM, Jose Fonseca wrote:
> Reviewed-by: Jose Fonseca <jfonseca at vmware.com>
>
> A few comments inline.
>
> On 13/12/14 14:43, Brian Paul wrote:
>> ---
>>   tests/all.py                                       |   6 +
>>   tests/spec/CMakeLists.txt                          |   1 +
>>   .../arb_get_texture_sub_image/CMakeLists.gl.txt    |  16 +
>>   .../spec/arb_get_texture_sub_image/CMakeLists.txt  |   1 +
>>   tests/spec/arb_get_texture_sub_image/errors.c      | 179 +++++++++
>>   tests/spec/arb_get_texture_sub_image/get.c         | 424
>> +++++++++++++++++++++
>>   .../spec/arb_get_texture_sub_image/getcompressed.c | 220 +++++++++++
>>   7 files changed, 847 insertions(+)
>>   create mode 100644
>> tests/spec/arb_get_texture_sub_image/CMakeLists.gl.txt
>>   create mode 100644 tests/spec/arb_get_texture_sub_image/CMakeLists.txt
>>   create mode 100644 tests/spec/arb_get_texture_sub_image/errors.c
>>   create mode 100644 tests/spec/arb_get_texture_sub_image/get.c
>>   create mode 100644 tests/spec/arb_get_texture_sub_image/getcompressed.c
>>
>> diff --git a/tests/all.py b/tests/all.py
>> index cfbe529..45cdaf5 100644
>> --- a/tests/all.py
>> +++ b/tests/all.py
>> @@ -1698,6 +1698,12 @@ arb_get_program_binary['misc. API error
>> checks'] = PiglitGLTest('arb_get_program
>>   arb_get_program_binary['NUM_PROGRAM_BINARY_FORMATS over-run check']
>> = PiglitGLTest('arb_get_program_binary-overrun program',
>> run_concurrent=True)
>>   arb_get_program_binary['PROGRAM_BINARY_RETRIEVABLE_HINT'] =
>> PiglitGLTest('arb_get_program_binary-retrievable_hint',
>> run_concurrent=True)
>>
>> +arb_get_texture_sub_image = {}
>> +spec['ARB_get_texture_sub_image'] = arb_get_texture_sub_image
>> +arb_get_texture_sub_image['errors'] =
>> PiglitGLTest('arb_get_texture_sub_image-errors', run_concurrent=True)
>> +arb_get_texture_sub_image['get'] =
>> PiglitGLTest('arb_get_texture_sub_image-get', run_concurrent=True)
>> +arb_get_texture_sub_image['getcompressed'] =
>> PiglitGLTest('arb_get_texture_sub_image-getcompressed',
>> run_concurrent=True)
>> +
>>   arb_depth_clamp = {}
>>   spec['ARB_depth_clamp'] = arb_depth_clamp
>>   add_plain_test(arb_depth_clamp, 'depth_clamp')
>> diff --git a/tests/spec/CMakeLists.txt b/tests/spec/CMakeLists.txt
>> index dfd822b..d308e4b 100644
>> --- a/tests/spec/CMakeLists.txt
>> +++ b/tests/spec/CMakeLists.txt
>> @@ -18,6 +18,7 @@ add_subdirectory (arb_framebuffer_object)
>>   add_subdirectory (arb_framebuffer_srgb)
>>   add_subdirectory (arb_geometry_shader4)
>>   add_subdirectory (arb_get_program_binary)
>> +add_subdirectory (arb_get_texture_sub_image)
>>   add_subdirectory (arb_gpu_shader5)
>>   add_subdirectory (arb_gpu_shader_fp64)
>>   add_subdirectory (arb_instanced_arrays)
>> diff --git a/tests/spec/arb_get_texture_sub_image/CMakeLists.gl.txt
>> b/tests/spec/arb_get_texture_sub_image/CMakeLists.gl.txt
>> new file mode 100644
>> index 0000000..6f62a2f
>> --- /dev/null
>> +++ b/tests/spec/arb_get_texture_sub_image/CMakeLists.gl.txt
>> @@ -0,0 +1,16 @@
>> +include_directories(
>> +    ${GLEXT_INCLUDE_DIR}
>> +    ${OPENGL_INCLUDE_PATH}
>> +)
>> +
>> +link_libraries (
>> +    piglitutil_${piglit_target_api}
>> +    ${OPENGL_gl_LIBRARY}
>> +    ${OPENGL_glu_LIBRARY}
>> +)
>> +
>> +piglit_add_executable (arb_get_texture_sub_image-errors errors.c)
>> +piglit_add_executable (arb_get_texture_sub_image-get get.c)
>> +piglit_add_executable (arb_get_texture_sub_image-getcompressed
>> getcompressed.c)
>> +
>> +# vim: ft=cmake:
>> diff --git a/tests/spec/arb_get_texture_sub_image/CMakeLists.txt
>> b/tests/spec/arb_get_texture_sub_image/CMakeLists.txt
>> new file mode 100644
>> index 0000000..144a306
>> --- /dev/null
>> +++ b/tests/spec/arb_get_texture_sub_image/CMakeLists.txt
>> @@ -0,0 +1 @@
>> +piglit_include_target_api()
>> diff --git a/tests/spec/arb_get_texture_sub_image/errors.c
>> b/tests/spec/arb_get_texture_sub_image/errors.c
>> new file mode 100644
>> index 0000000..1ca3e90
>> --- /dev/null
>> +++ b/tests/spec/arb_get_texture_sub_image/errors.c
>> @@ -0,0 +1,179 @@
>> +/*
>> + * Copyright 2014 VMware, 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.
>> + */
>> +
>> +#include "piglit-util-gl.h"
>> +
>> +PIGLIT_GL_TEST_CONFIG_BEGIN
>> +    config.supports_gl_compat_version = 20;
>> +    config.window_visual = PIGLIT_GL_VISUAL_RGBA |
>> +                   PIGLIT_GL_VISUAL_DOUBLE;
>> +PIGLIT_GL_TEST_CONFIG_END
>> +
>> +
>> +static bool
>> +test_texture_id(void)
>> +{
>> +    GLubyte buffer[8*8*4];
>> +    GLuint tex = 42;
>> +    bool pass = true;
>> +
>> +    /* Test get with bad texture ID */
>> +    glGetTextureSubImage(tex, 0,
>> +                 0, 0, 0, /* offset */
>> +                 8, 8, 1, /* size */
>> +                 GL_RGBA, GL_UNSIGNED_BYTE,
>> +                 sizeof(buffer), buffer);
>> +    if (!piglit_check_gl_error(GL_INVALID_OPERATION))
>> +        pass = false;
>> +
>> +    /* Test compressed get with bad texture ID */
>> +    glGetCompressedTextureSubImage(tex, 0,
>> +                       0, 0, 0, /* offset */
>> +                       8, 8, 1, /* size */
>> +                       sizeof(buffer), buffer);
>> +    if (!piglit_check_gl_error(GL_INVALID_OPERATION))
>> +        pass = false;
>> +
>> +    /* Test get with undefined texture */
>> +    glGenTextures(1, &tex);
>> +    glGetTextureSubImage(tex, 0,
>> +                 0, 0, 0, /* offset */
>> +                 8, 8, 1, /* size */
>> +                 GL_RGBA, GL_UNSIGNED_BYTE,
>> +                 sizeof(buffer), buffer);
>> +    if (!piglit_check_gl_error(GL_INVALID_OPERATION))
>> +        pass = false;
>> +
>> +    /* Test compressed get with undefined texture */
>> +    glGetCompressedTextureSubImage(tex, 0,
>> +                       0, 0, 0, /* offset */
>> +                       8, 8, 1, /* size */
>> +                       sizeof(buffer), buffer);
>> +    if (!piglit_check_gl_error(GL_INVALID_OPERATION))
>> +        pass = false;
>> +
>> +    glDeleteTextures(1, &tex);
>> +
>> +    return pass;
>> +}
>> +
>> +
>> +static bool
>> +test_buffer_size(void)
>> +{
>> +    GLubyte buffer[8*8*4];
>> +    GLubyte quadrant_buffer[4*4*4];
>> +    GLuint tex = 42;
>> +    bool pass = true;
>> +
>> +    /* setup 8x8 texture */
>> +    glGenTextures(1, &tex);
>> +    glBindTexture(GL_TEXTURE_2D, tex);
>> +    glTexStorage2D(GL_TEXTURE_2D, 4, GL_RGBA8, 8, 8);
>> +
>> +    /* Test too small of dest buffer */
>> +    glGetTextureSubImage(tex, 0,
>> +                 0, 0, 0, /* offset */
>> +                 8, 8, 1, /* size */
>> +                 GL_RGBA, GL_UNSIGNED_BYTE,
>> +                 sizeof(buffer) - 1, buffer);
>> +    if (!piglit_check_gl_error(GL_INVALID_OPERATION))
>> +        pass = false;
>> +
>> +    /* Test with pixel unpack params, sufficient buffer size */
>> +    glPixelStorei(GL_PACK_SKIP_ROWS, 4);
>> +    glPixelStorei(GL_PACK_SKIP_PIXELS, 4);
>> +    glPixelStorei(GL_PACK_ROW_LENGTH, 8);
>> +    glGetTextureSubImage(tex, 0,
>> +                 4, 4, 0, /* offset */
>> +                 4, 4, 1, /* size */
>> +                 GL_RGBA, GL_UNSIGNED_BYTE,
>> +                 sizeof(buffer), buffer);
>> +    if (!piglit_check_gl_error(GL_NO_ERROR))
>> +        pass = false;
>> +
>> +    /* Test with pixel unpack params, insufficient buffer size */
>> +    glGetTextureSubImage(tex, 0,
>> +                 4, 4, 0, /* offset */
>> +                 4, 4, 1, /* size */
>> +                 GL_RGBA, GL_UNSIGNED_BYTE,
>> +                 sizeof(buffer) - 1, buffer);
>> +    if (!piglit_check_gl_error(GL_INVALID_OPERATION))
>> +        pass = false;
>> +
>> +    /* Test getting a quadrant, sufficent buffer size */
>> +    glPixelStorei(GL_PACK_SKIP_ROWS, 0);
>> +    glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
>> +    glPixelStorei(GL_PACK_ROW_LENGTH, 0);
>> +    glGetTextureSubImage(tex, 0,
>> +                 4, 4, 0, /* offset */
>> +                 4, 4, 1, /* size */
>> +                 GL_RGBA, GL_UNSIGNED_BYTE,
>> +                 sizeof(quadrant_buffer), quadrant_buffer);
>> +    if (!piglit_check_gl_error(GL_NO_ERROR))
>> +        pass = false;
>> +
>> +    /* Test getting a quadrant, insufficent buffer size */
>> +    glPixelStorei(GL_PACK_SKIP_ROWS, 0);
>> +    glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
>> +    glPixelStorei(GL_PACK_ROW_LENGTH, 0);
>> +    glGetTextureSubImage(tex, 0,
>> +                 4, 4, 0, /* offset */
>> +                 4, 4, 1, /* size */
>> +                 GL_RGBA, GL_UNSIGNED_BYTE,
>> +                 sizeof(quadrant_buffer) - 1, quadrant_buffer);
>> +    if (!piglit_check_gl_error(GL_INVALID_OPERATION))
>> +        pass = false;
>> +
>> +    /* Test getting invalid level */
>> +    glGetTextureSubImage(tex, 99,
>> +                 0, 0, 0, /* offset */
>> +                 1, 1, 1, /* size */
>> +                 GL_RGBA, GL_UNSIGNED_BYTE,
>> +                 sizeof(buffer), buffer);
>> +    if (!piglit_check_gl_error(GL_INVALID_VALUE))
>> +        pass = false;
>> +
>> +    glDeleteTextures(1, &tex);
>> +
>> +    return pass;
>> +}
>> +
>> +
>> +enum piglit_result
>> +piglit_display(void)
>> +{
>> +    bool pass;
>> +
>> +    pass = test_texture_id();
>> +    pass = test_buffer_size() && pass;
>> +
>> +    return pass ? PIGLIT_PASS : PIGLIT_FAIL;
>> +}
>> +
>> +
>> +void
>> +piglit_init(int argc, char **argv)
>> +{
>> +    piglit_require_extension("GL_ARB_get_texture_sub_image");
>> +}
>> diff --git a/tests/spec/arb_get_texture_sub_image/get.c
>> b/tests/spec/arb_get_texture_sub_image/get.c
>> new file mode 100644
>> index 0000000..ef25d18
>> --- /dev/null
>> +++ b/tests/spec/arb_get_texture_sub_image/get.c
>> @@ -0,0 +1,424 @@
>> +/*
>> + * Copyright 2014 VMware, 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.
>> + */
>> +
>> +#include "piglit-util-gl.h"
>> +
>> +PIGLIT_GL_TEST_CONFIG_BEGIN
>> +    config.supports_gl_compat_version = 20;
>> +    config.window_visual = PIGLIT_GL_VISUAL_RGBA |
>> +                   PIGLIT_GL_VISUAL_DOUBLE;
>> +PIGLIT_GL_TEST_CONFIG_END
>> +
>> +
>> +/* XXX this could potentially be a piglit utility function */
>> +static bool
>> +minify(GLenum target, int level, int width, int height, int depth,
>> +       int *mip_width, int *mip_height, int *mip_depth)
>> +{
>> +    switch (target) {
>> +    case GL_TEXTURE_1D:
>> +        assert(height == 1);
>> +        assert(depth == 1);
>> +        if (width >> level == 0)
>> +            return false;
>> +        *mip_width = width >> level;
>> +        *mip_height = 1;
>> +        *mip_depth = 1;
>> +        return true;
>> +    case GL_TEXTURE_1D_ARRAY:
>> +        assert(depth == 1);
>> +        if (width >> level == 0)
>> +            return false;
>> +        *mip_width = width >> level;
>> +        *mip_height = height;
>> +        *mip_depth = 1;
>> +        return true;
>> +    case GL_TEXTURE_2D:
>> +        assert(depth == 1);
>> +        if (width >> level == 0 && height >> level == 0)
>> +            return false;
>> +        *mip_width = MAX2(1, width >> level);
>> +        *mip_height = MAX2(1, height >> level);
>> +        *mip_depth = 1;
>> +        return true;
>> +    case GL_TEXTURE_2D_ARRAY:
>> +        if (width >> level == 0 && height >> level == 0)
>> +            return false;
>> +        *mip_width = MAX2(1, width >> level);
>> +        *mip_height = MAX2(1, height >> level);
>> +        *mip_depth = depth;
>> +        return true;
>> +    case GL_TEXTURE_3D:
>> +        if (width >> level == 0 &&
>> +            height >> level == 0 &&
>> +            depth >> level == 0)
>> +            return false;
>> +        *mip_width = MAX2(1, width >> level);
>> +        *mip_height = MAX2(1, height >> level);
>> +        *mip_depth = MAX2(1, depth >> level);
>> +        return true;
>> +    case GL_TEXTURE_RECTANGLE:
>> +        assert(depth == 1);
>> +        if (level > 0)
>> +            return false;
>> +        *mip_width = width;
>> +        *mip_height = height;
>> +        *mip_depth = 1;
>> +        return true;
>> +    default:
>> +        return false;
>> +    }
>> +}
>> +
>> +
>> +static bool
>> +test_getsubimage(GLenum target,
>> +         GLsizei width, GLsizei height, GLsizei depth,
>> +         GLenum intFormat)
>> +{
>> +    const GLint bufSize = width * height * depth * 4 * sizeof(GLubyte);
>> +    GLubyte *texData = malloc(bufSize);
>> +    GLubyte *refData = malloc(bufSize);
>> +    GLubyte *testData = malloc(bufSize);
>> +    GLuint tex;
>> +    int i, level, bytes;
>> +    bool pass = true;
>> +    GLsizei mip_width, mip_height, mip_depth;
>> +
>> +    printf("Testing %s %s %d x %d x %d\n",
>> +           piglit_get_gl_enum_name(target),
>> +           piglit_get_gl_enum_name(intFormat),
>> +           width, height, depth);
>> +
>> +    /* initial texture data */
>> +    for (i = 0; i < width * height * depth * 4; i++) {
>> +        texData[i] = i & 0xff;
>> +    }
>> +
>> +    glGenTextures(1, &tex);
>> +    glBindTexture(target, tex);
>> +
>> +    mip_width = width;
>> +    mip_height = height;
>> +    mip_depth = depth;
>> +
>> +    /* make mipmapped texture */
>> +    for (level = 0; ; level++) {
>> +        if (!minify(target, level, width, height, depth,
>> +                &mip_width, &mip_height, &mip_depth)) {
>> +            break;
>> +        }
>> +
>> +        switch (target) {
>> +        case GL_TEXTURE_1D:
>> +            glTexImage1D(GL_TEXTURE_1D, level, intFormat,
>> +                     mip_width, 0,
>> +                     GL_RGBA, GL_UNSIGNED_BYTE, texData);
>> +            break;
>> +        case GL_TEXTURE_2D:
>> +        case GL_TEXTURE_RECTANGLE:
>> +        case GL_TEXTURE_1D_ARRAY:
>> +            glTexImage2D(target, level, intFormat,
>> +                     mip_width, mip_height, 0,
>> +                     GL_RGBA, GL_UNSIGNED_BYTE, texData);
>> +            break;
>> +        case GL_TEXTURE_3D:
>> +        case GL_TEXTURE_2D_ARRAY:
>> +            glTexImage3D(target, level, intFormat,
>> +                     mip_width, mip_height, mip_depth, 0,
>> +                     GL_RGBA, GL_UNSIGNED_BYTE, texData);
>> +            break;
>> +        case GL_TEXTURE_CUBE_MAP:
>> +            /* only tests positive Y face */
>> +            glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, level,
>> intFormat,
>> +                     mip_width, mip_height, 0,
>> +                     GL_RGBA, GL_UNSIGNED_BYTE, texData);
>> +            break;
>> +        }
>> +    }
>> +
>> +    /* compare glGetTexImage() vs. glGetTextureSubImage() */
>> +    glPixelStorei(GL_PACK_ALIGNMENT, 1);
>> +
>> +    mip_width = width;
>> +    mip_height = height;
>> +    mip_depth = depth;
>> +
>> +    for (level = 0; ; level++) {
>> +        GLint x0, y0, z0, x1, y1, z1, w0, h0, w1, h1, d0, d1;
>> +
>> +        if (!minify(target, level, width, height, depth,
>> +                &mip_width, &mip_height, &mip_depth)) {
>> +            break;
>> +        }
>> +
>> +        /* compute pos/size of sub-regions */
>> +        x0 = 0;
>> +        y0 = 0;
>> +        z0 = 0;
>> +        x1 = MAX2(1, mip_width / 3);
>> +        y1 = MAX2(1, mip_height / 3);
>> +        z1 = MAX2(1, mip_depth / 3);
>
>> +        if (intFormat == GL_COMPRESSED_RGBA_S3TC_DXT5_EXT) {
>> +            /* x1, y1 must be a multipe of 4 */
>
>
>> +            x1 &= ~0x3;
>> +            y1 &= ~0x3;
>> +        }
>> +
>> +        w0 = x1 - x0;
>> +        w1 = mip_width - x1;
>> +        h0 = y1 - y0;
>> +        h1 = mip_height - y1;
>> +        d0 = z1 - z0;
>> +        d1 = mip_depth - z1;
>
> Won't w0 and h0 be zero for small mipmaps.

Yes, but that's OK.  Passing width or height or depth=0 is legal and 
effectively becomes a no-op.

I can add a comment about that.


>
>
>> +
>> +        memset(refData, 0, bufSize);
>> +        memset(testData, 0, bufSize);
>> +
>> +        switch (target) {
>> +        case GL_TEXTURE_1D:
>> +            /*
>> +             * Get whole image (the reference)
>> +             */
>> +            glGetTexImage(GL_TEXTURE_1D, level,
>> +                      GL_RGBA, GL_UNSIGNED_BYTE, refData);
>> +
>> +            /*
>> +             * Now get two sub-regions which should be equivalent
>> +             * to the whole reference image.
>> +             */
>> +
>> +            /* left part */
>> +            glPixelStorei(GL_PACK_SKIP_PIXELS, x0);
>> +            glGetTextureSubImage(tex, level,
>> +                         x0, y0, 0, w0, h0, 1,
>
> I'd replace y0 with 0 and h0 with 1 to ensure.  As it's actually not
> obvious the is always the case.

will do.



>
>> +                         GL_RGBA, GL_UNSIGNED_BYTE,
>> +                         bufSize, testData);
>> +            /* right part */
>> +            glPixelStorei(GL_PACK_SKIP_PIXELS, x1);
>> +            glGetTextureSubImage(tex, level,
>> +                         x1, y0, 0, w1, h0, 1,
>> +                         GL_RGBA, GL_UNSIGNED_BYTE,
>> +                         bufSize, testData);
>> +
>> +            /* defaults */
>> +            glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
>> +
>> +            /* now compare the images */
>> +            bytes = mip_width * 4;
>> +            if (memcmp(refData, testData, bytes)) {
>> +                printf("Failure for GL_TEXTURE_1D:\n");
>> +                pass = false;
>> +            }
>> +            break;
>> +
>
> GL_TEXTURE_1D_ARRAY is missing here, but tested below.

I'll fix that too.

BTW, we seem to have some unresolved issued with cube map textures but 
the test for cube maps here should be OK as-is.  A more extensive cube 
map case might be added later.

-Brian



More information about the Piglit mailing list