[Piglit] [PATCH 1/2] Add a new comprehensive test for textureSize().
Kenneth Graunke
kenneth at whitecape.org
Fri Nov 18 02:31:56 PST 2011
On 11/17/2011 10:48 PM, Kenneth Graunke wrote:
> This exhaustively tests of GLSL 1.30's textureSize variants, both in the
> vertex and fragment shaders. It covers:
> - Sampler data type (floating point, signed integer, unsigned integer)
> - Dimensionality (1D, 2D, 3D, Cube, 1DArray, 2DArray)
> - Color and shadow samplers
> - Mipmapped textures
> - Non-power-of-two textures
>
> It doesn't cover texture format variations. In fact, the test never
> actually provides any content for the textures, because it should be
> irrelevant for textureSize(), is easier to program, and also extra mean.
>
> The new "textureSize" binary takes two arguments: shader stage and
> sampler type. For example:
>
> ./bin/textureSize fs sampler1DArrayShadow
> ./bin/textureSize vs usamplerCube
>
> Signed-off-by: Kenneth Graunke <kenneth at whitecape.org>
> ---
> tests/all.tests | 5 +
> tests/spec/glsl-1.30/execution/CMakeLists.gl.txt | 1 +
> tests/spec/glsl-1.30/execution/textureSize.c | 327 ++++++++++++++++++++++
> 3 files changed, 333 insertions(+), 0 deletions(-)
> create mode 100644 tests/spec/glsl-1.30/execution/textureSize.c
>
> diff --git a/tests/all.tests b/tests/all.tests
> index 48ce2cb..ddfc42a 100644
> --- a/tests/all.tests
> +++ b/tests/all.tests
> @@ -872,6 +872,11 @@ import_glsl_parser_tests(spec['glsl-1.30'],
> os.path.join(generatedTestDir, 'spec', 'glsl-1.30'),
> ['compiler'])
> spec['glsl-1.30']['execution'] = Group()
> +sampler_types = ['sampler1D', 'sampler2D', 'samplerCube', 'sampler1DShadow', 'sampler2DShadow', 'sampler1DArray', 'sampler2DArray', 'sampler1DArrayShadow', 'sampler2DArrayShadow', 'isampler1D', 'isampler2D', 'isamplerCube', 'isampler1DArray', 'isampler2DArray', 'usampler1D', 'usampler2D', 'usamplerCube', 'usampler1DArray', 'usampler2DArray']
> +for stage in ['vs', 'fs']:
> + for sampler in sampler_types:
> + test_name = stage + '-textureSize-' + sampler
> + spec['glsl-1.30']['execution'][test_name] = PlainExecTest(['textureSize', stage, sampler, '-auto', '-fbo'])
> add_plain_test(spec['glsl-1.30']['execution'], 'fs-textureSize-2D')
> add_plain_test(spec['glsl-1.30']['execution'], 'fs-texelFetch-2D')
> add_plain_test(spec['glsl-1.30']['execution'], 'fs-texelFetchOffset-2D')
> diff --git a/tests/spec/glsl-1.30/execution/CMakeLists.gl.txt b/tests/spec/glsl-1.30/execution/CMakeLists.gl.txt
> index c9a816d..d80bebe 100644
> --- a/tests/spec/glsl-1.30/execution/CMakeLists.gl.txt
> +++ b/tests/spec/glsl-1.30/execution/CMakeLists.gl.txt
> @@ -16,6 +16,7 @@ link_libraries (
> add_executable (fs-textureSize-2D fs-textureSize-2D.c)
> add_executable (fs-texelFetch-2D fs-texelFetch-2D.c)
> add_executable (fs-texelFetchOffset-2D fs-texelFetchOffset-2D.c)
> +add_executable (textureSize textureSize.c)
> IF (NOT MSVC)
> add_executable (isinf-and-isnan isinf-and-isnan.c)
> ENDIF (NOT MSVC)
> diff --git a/tests/spec/glsl-1.30/execution/textureSize.c b/tests/spec/glsl-1.30/execution/textureSize.c
> new file mode 100644
> index 0000000..dcde354
> --- /dev/null
> +++ b/tests/spec/glsl-1.30/execution/textureSize.c
> @@ -0,0 +1,327 @@
> +/*
> + * Copyright © 2011 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.
> + */
> +
> +/**
> + * \file textureSize.c
> + *
> + * Tests the GLSL 1.30 built-in function textureSize().
> + *
> + * Creates a mipmapped 64x32 2D texture and draws a series of squares whose
> + * color contains the width (red) and height (green) of each mipmap level.
> + */
Oops. This comment is out of date...that's what the /old/ test did. :)
It basically does that now too, but for newer dimensions. I'll update
the comment.
> +#include "piglit-util.h"
> +
> +int piglit_width = 150, piglit_height = 30;
> +int piglit_window_mode = GLUT_RGBA | GLUT_DOUBLE;
> +
> +#define BS 500
> +static char vs_code[BS];
> +static char fs_code[BS];
> +
> +static int lod_location;
> +
> +/** Array containing the dimensions of the texture */
> +int tex_size[3] = { 65, 32, 0 };
> +int miplevels;
> +
> +enum shader_target {
> + UNKNOWN,
> + VS,
> + FS
> +};
> +
> +struct sampler_info {
> + const char *name;
> + int size;
> + GLenum gl_target;
> + bool shadow;
> +};
> +
> +const struct sampler_info *sampler = NULL;
> +
> +static float max2(float x, float y) { return (x > y) ? x : y; }
> +static float max3(float x, float y, float z) { return max2(x, max2(y, z)); }
> +
> +enum piglit_result
> +piglit_display()
> +{
> + bool pass = true;
> + int is_array = sampler->gl_target == GL_TEXTURE_1D_ARRAY ||
> + sampler->gl_target == GL_TEXTURE_2D_ARRAY;
> + int i, l;
> +
> + glClearColor(0.5, 0.5, 0.5, 1.0);
> + glClear(GL_COLOR_BUFFER_BIT);
> +
> + int level_size[3] = { 1, 1, 1 };
> + for (i = 0; i < sampler->size; i++)
> + level_size[i] = tex_size[i];
> +
> + /* Draw consecutive squares for each mipmap level */
> + for (l = 0; l < miplevels; l++) {
> + const int x = 10 + l * 20;
> + float expected_color[4] = { 0.0, 0.0, 0.0, 1.0 };
> + for (i = 0; i < sampler->size; i++)
> + expected_color[i] = 0.01 * level_size[i];
> +
> + piglit_Uniform1i(lod_location, l);
> + glViewport(x, 10, 10, 10);
> + piglit_draw_rect(-1, -1, 2, 2);
> +
> + pass &= piglit_probe_rect_rgba(x, 10, 10, 10, expected_color);
> +
> + /* For arrays, the # of slices never changes; don't divide */
> + for (i = 0; i < sampler->size - is_array; i++)
> + level_size[i] = max2(level_size[i] / 2, 1);
> + }
> +
> + piglit_present_results();
> +
> + return pass ? PIGLIT_PASS : PIGLIT_FAIL;
> +}
> +
> +void
> +generate_texture()
> +{
> + int i;
> + GLuint tex;
> + GLenum target = sampler->gl_target;
> + GLenum format = sampler->shadow ? GL_DEPTH_COMPONENT : GL_RGBA;
> +
> + glActiveTexture(GL_TEXTURE0);
> +
> + glGenTextures(1, &tex);
> + glBindTexture(target, tex);
> + glEnable(target);
> + glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
> + glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
> + glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
> + glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
> +
> + switch (sampler->gl_target) {
> + case GL_TEXTURE_1D:
> + glTexImage1D(GL_TEXTURE_1D, 0, format,
> + tex_size[0],
> + 0, format, GL_FLOAT, NULL);
> + break;
> + case GL_TEXTURE_2D:
> + glTexImage2D(GL_TEXTURE_2D, 0, format,
> + tex_size[0], tex_size[1],
> + 0, format, GL_FLOAT, NULL);
> + break;
> + case GL_TEXTURE_3D:
> + tex_size[2] = 64;
> + glTexImage3D(GL_TEXTURE_3D, 0, format,
> + tex_size[0], tex_size[1], tex_size[2],
> + 0, format, GL_FLOAT, NULL);
> + break;
> + case GL_TEXTURE_CUBE_MAP:
> + /* Cube face width/height must be the same */
> + tex_size[1] = tex_size[0];
> + for (i = 0; i < 6; i++) {
> + glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0,
> + format, tex_size[0], tex_size[1], 0,
> + format, GL_FLOAT, NULL);
> + }
> + break;
> + case GL_TEXTURE_1D_ARRAY:
> + tex_size[0] = 64;
> + tex_size[1] = 40;
> + glTexImage2D(GL_TEXTURE_1D_ARRAY, 0, format,
> + tex_size[0], tex_size[1],
> + 0, format, GL_FLOAT, NULL);
> + break;
> + case GL_TEXTURE_2D_ARRAY:
> + tex_size[2] = 40;
> + glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, format,
> + tex_size[0], tex_size[1], tex_size[2],
> + 0, format, GL_FLOAT, NULL);
> + break;
> + }
> + glGenerateMipmap(target);
> +
> + miplevels = (int) log2f(max3(tex_size[0], tex_size[1], tex_size[2]))+1;
> +
> + for (i = sampler->size; i < 3; i++)
> + tex_size[i] = 0;
> +}
> +
> +
> +int
> +generate_GLSL(enum shader_target test_stage)
> +{
> + int vs, fs;
> + static const char *zeros[3] = { "", "0, ", "0, 0, " };
> + assert(sampler->size >= 1 && sampler->size <= 3);
> +
> + switch (test_stage) {
> + case VS:
> + snprintf(vs_code, BS,
> + "#version 130\n"
> + "#define vec1 float\n"
> + "uniform int lod;\n"
> + "uniform %s tex;\n"
> + "out vec%d size;\n"
> + "void main()\n"
> + "{\n"
> + " size = textureSize(tex, lod);\n"
> + " gl_Position = gl_Vertex;\n"
> + "}\n",
> + sampler->name, sampler->size);
> + snprintf(fs_code, BS,
> + "#version 130\n"
> + "#define vec1 float\n"
> + "in vec%d size;\n"
> + "void main()\n"
> + "{\n"
> + " gl_FragColor = vec4(0.01 * size,%s 1);\n"
> + "}\n",
> + sampler->size, zeros[3 - sampler->size]);
> + break;
> + case FS:
> + snprintf(vs_code, BS,
> + "#version 130\n"
> + "void main()\n"
> + "{\n"
> + " gl_Position = gl_Vertex;\n"
> + "}\n");
> + snprintf(fs_code, BS,
> + "#version 130\n"
> + "#define ivec1 int\n"
> + "uniform int lod;\n"
> + "uniform %s tex;\n"
> + "void main()\n"
> + "{\n"
> + " ivec%d size = textureSize(tex, lod);\n"
> + " gl_FragColor = vec4(0.01 * size,%s 1);\n"
> + "}\n",
> + sampler->name, sampler->size, zeros[3-sampler->size]);
> + break;
> + default:
> + assert(!"Should not get here.");
> + break;
> + }
> +
> + vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vs_code);
> + fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, fs_code);
> + return piglit_link_simple_program(vs, fs);
> +}
> +
> +void
> +select_sampler(char *name)
> +{
> + int i;
> + static const struct sampler_info samplers[] =
> + {
> + { "sampler1D", 1, GL_TEXTURE_1D, false },
> + { "sampler2D", 2, GL_TEXTURE_2D, false },
> + { "sampler3D", 3, GL_TEXTURE_3D, false },
> + { "samplerCube", 2, GL_TEXTURE_CUBE_MAP, false },
> + { "sampler1DShadow", 1, GL_TEXTURE_1D, true },
> + { "sampler2DShadow", 2, GL_TEXTURE_2D, true },
> + { "samplerCubeShadow", 2, GL_TEXTURE_CUBE_MAP, true },
> + { "sampler1DArray", 2, GL_TEXTURE_1D_ARRAY, false },
> + { "sampler2DArray", 3, GL_TEXTURE_2D_ARRAY, false },
> + { "sampler1DArrayShadow", 2, GL_TEXTURE_1D_ARRAY, true},
> + { "sampler2DArrayShadow", 3, GL_TEXTURE_2D_ARRAY, true}
> + };
> +
> + for (i = 0; i < ARRAY_SIZE(samplers); i++) {
> + if (strcmp(samplers[i].name, name) == 0) {
> + sampler = &samplers[i];
> + return;
> + }
> + }
> +}
> +
> +void
> +fail_and_show_usage()
> +{
> + printf("Usage: textureSize <vs|fs> <sampler type> [piglit args...]\n");
> + piglit_report_result(PIGLIT_SKIP);
> +}
> +
> +void
> +piglit_init(int argc, char **argv)
> +{
> + int prog;
> + int tex_location;
> + int i;
> + enum shader_target test_stage = UNKNOWN;
> + bool integer_format = false;
> +
> + piglit_require_GLSL_version(130);
> +
> + for (i = 1; i < argc; i++) {
> + /* Ignore piglit arguments like -auto and -fbo */
> + if (argv[i][0] == '-')
> + continue;
> +
> + if (test_stage == UNKNOWN) {
> + /* Maybe it's the shader stage? */
> + if (strcmp(argv[i], "vs") == 0) {
> + test_stage = VS;
> + continue;
> + } else if (strcmp(argv[i], "fs") == 0) {
> + test_stage = FS;
> + continue;
> + }
> + }
> +
> + if (sampler == NULL) {
> + /* Maybe it's the sampler type? */
> + if (argv[i][0] == 'i' || argv[i][0] == 'u') {
> + integer_format = true;
> + select_sampler(argv[i] + 1);
> + } else {
> + integer_format = false;
> + select_sampler(argv[i]);
> + }
> +
> + if (sampler != NULL)
> + continue;
> + }
> +
> + fail_and_show_usage();
> + }
> +
> + if (test_stage == UNKNOWN || sampler == NULL)
> + fail_and_show_usage();
> +
> + /* Skip if the driver doesn't export VS texture units */
> + glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &i);
> + if (test_stage == VS && i <= 0)
> + piglit_report_result(PIGLIT_SKIP);
> +
> + prog = generate_GLSL(test_stage);
> +
> + tex_location = piglit_GetUniformLocation(prog, "tex");
> + lod_location = piglit_GetUniformLocation(prog, "lod");
> + piglit_UseProgram(prog);
> + piglit_Uniform1i(tex_location, 0);
> +
> + if (integer_format && sampler->shadow)
> + piglit_report_result(PIGLIT_SKIP);
> +
> + generate_texture();
> +}
More information about the Piglit
mailing list