--- tests/all.py | 1 + .../spec/arb_direct_state_access/CMakeLists.gl.txt | 1 + .../spec/arb_direct_state_access/texturesubimage.c | 415 +++++++++++++++++++++ 3 files changed, 417 insertions(+) create mode 100644 tests/spec/arb_direct_state_access/texturesubimage.c
diff --git a/tests/all.py b/tests/all.py index 84639c2..5ed0444 100644 --- a/tests/all.py +++ b/tests/all.py @@ -4308,6 +4308,7 @@ import_glsl_parser_tests(arb_derivative_control, spec['ARB_direct_state_access'] = {} spec['ARB_direct_state_access']['dsa-textures'] = PiglitGLTest('arb_direct_state_access-dsa-textures', run_concurrent=True) +spec['ARB_direct_state_access']['texturesubimage'] = PiglitGLTest('arb_direct_state_access-texturesubimage', run_concurrent=True) profile.tests['hiz'] = hiz profile.tests['fast_color_clear'] = fast_color_clear diff --git a/tests/spec/arb_direct_state_access/CMakeLists.gl.txt b/tests/spec/arb_direct_state_access/CMakeLists.gl.txt index cb0f7da..102579c 100644 --- a/tests/spec/arb_direct_state_access/CMakeLists.gl.txt +++ b/tests/spec/arb_direct_state_access/CMakeLists.gl.txt @@ -10,4 +10,5 @@ link_libraries ( ) piglit_add_executable (arb_direct_state_access-dsa-textures dsa-textures.c dsa-utils.c) +piglit_add_executable (arb_direct_state_access-dsa-texturesubimage texturesubimage.c) # vim: ft=cmake: diff --git a/tests/spec/arb_direct_state_access/texturesubimage.c b/tests/spec/arb_direct_state_access/texturesubimage.c new file mode 100644 index 0000000..b3a09e6 --- /dev/null +++ b/tests/spec/arb_direct_state_access/texturesubimage.c @@ -0,0 +1,415 @@ +/* + * Copyright © 2011 VMware, Inc. + * Copyright © 2014 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + + +/** + * This should expose any errors in texel addressing within a texture image + * when calling glTextureSubImage1D/2D/3D(). + * + * Brian Paul + * October 2011 + * + * Adapted for testing ARB_direct_state_access by + * Laura Ekstrand + * October 2014 + */ + + +#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 + +/** + * This is a subset of the formats in fbo-formats.h + * We don't test non-color, float, or int/uint textures at this time. + */ +static const struct test_desc texsubimage_test_sets[] = { + { + core, + ARRAY_SIZE(core), + "Core formats", + GL_UNSIGNED_NORMALIZED, + }, + { + tdfx_texture_compression_fxt1, + ARRAY_SIZE(tdfx_texture_compression_fxt1), + "GL_3DFX_texture_compression_FXT1", + GL_UNSIGNED_NORMALIZED, + {"GL_ARB_texture_compression", + "GL_3DFX_texture_compression_FXT1"}, + }, + { + ext_texture_compression_s3tc, + ARRAY_SIZE(ext_texture_compression_s3tc), + "GL_EXT_texture_compression_s3tc", + GL_UNSIGNED_NORMALIZED, + {"GL_ARB_texture_compression", + "GL_EXT_texture_compression_s3tc"}, + }, + { + ext_texture_compression_rgtc, + ARRAY_SIZE(ext_texture_compression_rgtc), + "GL_EXT_texture_compression_rgtc", + GL_UNSIGNED_NORMALIZED, + {"GL_EXT_texture_compression_rgtc"} + }, + { + ext_texture_compression_latc, + ARRAY_SIZE(ext_texture_compression_latc), + "GL_EXT_texture_compression_latc", + GL_UNSIGNED_NORMALIZED, + {"GL_EXT_texture_compression_latc"} + } +}; + + +/** + * XXX add this to piglit-util if useful elsewhere. + */ +static GLvoid +piglit_draw_rect_tex3d(float x, float y, float w, float h, + float tx, float ty, float tw, float th, + float tz0, float tz1) +{ + float verts[4][4]; + float tex[4][3]; + + verts[0][0] = x; + verts[0][1] = y; + verts[0][2] = 0.0; + verts[0][3] = 1.0; + tex[0][0] = tx; + tex[0][1] = ty; + tex[0][2] = tz0; + verts[1][0] = x + w; + verts[1][1] = y; + verts[1][2] = 0.0; + verts[1][3] = 1.0; + tex[1][0] = tx + tw; + tex[1][1] = ty; + tex[1][2] = tz1; + verts[2][0] = x + w; + verts[2][1] = y + h; + verts[2][2] = 0.0; + verts[2][3] = 1.0; + tex[2][0] = tx + tw; + tex[2][1] = ty + th; + tex[2][2] = tz1; + verts[3][0] = x; + verts[3][1] = y + h; + verts[3][2] = 0.0; + verts[3][3] = 1.0; + tex[3][0] = tx; + tex[3][1] = ty + th; + tex[3][2] = tz0; + + glVertexPointer(4, GL_FLOAT, 0, verts); + glTexCoordPointer(3, GL_FLOAT, 0, tex); + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + + glDrawArrays(GL_QUADS, 0, 4); + + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); +} + + +static GLboolean +equal_images(const GLubyte *img1, const GLubyte *img2, + GLuint w, GLuint h) +{ + return memcmp(img1, img2, w*h*4) == 0; +} + + +/** + * Get block size for compressed format. + * \return GL_TRUE if format is compressed, GL_FALSE otherwise + * XXX this could be a piglit util function if useful elsewhere. + */ +static GLboolean +get_format_block_size(GLenum format, GLuint *bw, GLuint *bh) +{ + switch (format) { + case GL_COMPRESSED_RGB_FXT1_3DFX: + case GL_COMPRESSED_RGBA_FXT1_3DFX: + *bw = 8; + *bh = 4; + return GL_TRUE; + case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: + case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: + case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: + case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: + case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT: + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT: + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: + *bw = 4; + *bh = 4; + return GL_TRUE; + case GL_COMPRESSED_RED: + case GL_COMPRESSED_RED_RGTC1_EXT: + case GL_COMPRESSED_RG: + case GL_COMPRESSED_RED_GREEN_RGTC2_EXT: + *bw = 4; + *bh = 4; + return GL_TRUE; + case GL_COMPRESSED_LUMINANCE_LATC1_EXT: + case GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT: + *bw = 4; + *bh = 4; + return GL_TRUE; + default: + *bw = *bh = 1; + return GL_FALSE; + } +} + + +/** + * Create a texture image with reference values. Draw a textured quad. + * Save reference image with glReadPixels(). + * Loop: + * replace a sub-region of the texture image with same values + * draw test textured quad + * read test image with glReadPixels + * compare reference image to test image + * \param target GL_TEXTURE_1D/2D/3D + * \param intFormat the internal texture format + */ +static GLboolean +test_format(GLenum target, GLenum intFormat) +{ + const GLenum srcFormat = GL_RGBA; + GLuint w = 128, h = 64, d = 8; + GLuint tex, i, j, k, n, t; + GLubyte *img, *ref, *testImg; + GLboolean pass = GL_TRUE; + GLuint bw, bh, wMask, hMask, dMask; + get_format_block_size(intFormat, &bw, &bh); + wMask = ~(bw-1); + hMask = ~(bh-1); + dMask = ~0; + + if (target != GL_TEXTURE_3D) + d = 1; + if (target == GL_TEXTURE_1D) + h = 1; + + img = (GLubyte *) malloc(w * h * d * 4); + ref = (GLubyte *) malloc(w * h * d * 4); + testImg = (GLubyte *) malloc(w * h * d * 4); + + /* fill source tex image */ + n = 0; + for (i = 0; i < d; i++) { + for (j = 0; j < h; j++) { + for (k = 0; k < w; k++) { + img[n++] = j * 4; + img[n++] = k * 2; + img[n++] = i * 16; + img[n++] = 255; + } + } + } + + glPixelStorei(GL_UNPACK_ROW_LENGTH, w); + glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, h); + + glCreateTextures(target, 1, &tex); + glBindTextureUnit(0, tex); + glTextureParameteri(tex, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTextureParameteri(tex, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); + glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); + glPixelStorei(GL_UNPACK_SKIP_IMAGES, 0); + if (target == GL_TEXTURE_1D) { + glTextureStorage1D(tex, 1, intFormat, w); + glTextureSubImage1D(tex, 0, 0, w, srcFormat, + GL_UNSIGNED_BYTE, img); + } + else if (target == GL_TEXTURE_2D) { + glTextureStorage2D(tex, 1, intFormat, w, h); + glTextureSubImage2D(tex, 0, 0, 0, w, h, srcFormat, + GL_UNSIGNED_BYTE, img); + } + else if (target == GL_TEXTURE_3D) { + glTextureStorage3D(tex, 1, intFormat, w, h, d); + glTextureSubImage3D(tex, 0, 0, 0, 0, w, h, d, srcFormat, + GL_UNSIGNED_BYTE, img); + } + + glEnable(target); + + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + + /* draw reference image */ + glClear(GL_COLOR_BUFFER_BIT); + piglit_draw_rect_tex3d(0, 0, w, h, 0.0, 0.0, 1.0, 1.0, 0.0, 1.0); + glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, ref); + + for (t = 0; t < 10; t++) { + /* Choose random region of texture to update. + * Use sizes and positions that are multiples of + * the compressed block size. + */ + GLint tw = (rand() % w) & wMask; + GLint th = (rand() % h) & hMask; + GLint td = (rand() % d) & dMask; + GLint tx = (rand() % (w - tw)) & wMask; + GLint ty = (rand() % (h - th)) & hMask; + GLint tz = (rand() % (d - td)) & dMask; + + assert(tx + tw <= w); + assert(ty + th <= h); + assert(tz + td <= d); + + /* replace texture region (with same data) */ + glPixelStorei(GL_UNPACK_SKIP_PIXELS, tx); + glPixelStorei(GL_UNPACK_SKIP_ROWS, ty); + glPixelStorei(GL_UNPACK_SKIP_IMAGES, tz); + if (target == GL_TEXTURE_1D) { + glTextureSubImage1D(tex, 0, tx, tw, + srcFormat, GL_UNSIGNED_BYTE, img); + } + else if (target == GL_TEXTURE_2D) { + glTextureSubImage2D(tex, 0, tx, ty, tw, th, + srcFormat, GL_UNSIGNED_BYTE, img); + } + else if (target == GL_TEXTURE_2D) { + glTextureSubImage3D(tex, 0, tx, ty, tz, tw, th, td, + srcFormat, GL_UNSIGNED_BYTE, img); + } + + /* draw test image */ + glClear(GL_COLOR_BUFFER_BIT); + piglit_draw_rect_tex3d(0, 0, w, h, 0.0, 0.0, 1.0, 1.0, 0.0, 1.0); + glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, testImg); + + piglit_present_results(); + + if (!equal_images(ref, testImg, w, h)) { + printf("texsubimage failed\n"); + printf(" target: %s\n", piglit_get_gl_enum_name(target)); + printf(" internal format: %s\n", piglit_get_gl_enum_name(intFormat)); + printf(" region: %d, %d %d x %d\n", tx, ty, tw, th); + pass = GL_FALSE; + break; + } + } + + glDisable(target); + + free(img); + free(ref); + free(testImg); + + glDeleteTextures(1, &tex); + return pass; +} + + +/** + * Test all formats in texsubimage_test_sets[] for the given + * texture target. + */ +static GLboolean +test_formats(GLenum target) +{ + GLboolean pass = GL_TRUE; + int i, j; + + /* loop over the format groups */ + for (i = 0; i < ARRAY_SIZE(texsubimage_test_sets); i++) { + const struct test_desc *set = &texsubimage_test_sets[i]; + GLboolean skip = GL_FALSE; + + /* only test compressed formats with 2D textures */ + if (i > 0 && target != GL_TEXTURE_2D) + continue; + + /* skip formats for unsupported extensions */ + for (j = 0; j < ARRAY_SIZE(set->ext); j++) { + if (set->ext[j] && + !piglit_is_extension_supported(set->ext[j])) { + /* req'd extension not supported */ + skip = GL_TRUE; + break; + } + } + if (skip) + continue; + + /* loop over formats in the set */ + for (j = 0; j < set->num_formats; j++) { + if (!test_format(target, + set->format[j].internalformat)) { + pass = GL_FALSE; + } + } + } + + return pass; +} + + +enum piglit_result +piglit_display(void) +{ + static const GLenum targets[] = { + GL_TEXTURE_1D, + GL_TEXTURE_2D, + GL_TEXTURE_3D + }; + GLboolean pass = GL_TRUE; + int i; + + /* Loop over 1/2/3D texture targets */ + for (i = 0; i < ARRAY_SIZE(targets); i++) { + pass = test_formats(targets[i]) && pass; + } + + return pass ? PIGLIT_PASS : PIGLIT_FAIL; +} + + +void +piglit_init(int argc, char **argv) +{ + piglit_require_extension("GL_ARB_direct_state_access"); + + fbo_formats_init(argc, argv, 0); + (void) fbo_formats_display; + + piglit_ortho_projection(piglit_width, piglit_height, GL_FALSE); +} -- 2.1.0 _______________________________________________ Piglit mailing list Piglit@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/piglit