[Piglit] [PATCH 1/4] Add a new comprehensive test for textureSize().
Ian Romanick
idr at freedesktop.org
Fri Dec 9 15:36:08 PST 2011
On 12/06/2011 01:23 PM, Kenneth Graunke wrote:
> This exhaustively tests all 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/texturing/CMakeLists.txt | 1 +
> tests/texturing/shaders/CMakeLists.gl.txt | 16 ++
> tests/texturing/shaders/CMakeLists.txt | 1 +
> tests/texturing/shaders/common.c | 288 +++++++++++++++++++++++++++++
> tests/texturing/shaders/common.h | 101 ++++++++++
> tests/texturing/shaders/textureSize.c | 282 ++++++++++++++++++++++++++++
> 7 files changed, 694 insertions(+), 0 deletions(-)
> create mode 100644 tests/texturing/shaders/CMakeLists.gl.txt
> create mode 100644 tests/texturing/shaders/CMakeLists.txt
> create mode 100644 tests/texturing/shaders/common.c
> create mode 100644 tests/texturing/shaders/common.h
> create mode 100644 tests/texturing/shaders/textureSize.c
>
> diff --git a/tests/all.tests b/tests/all.tests
> index 68a379c..5907174 100644
> --- a/tests/all.tests
> +++ b/tests/all.tests
> @@ -881,6 +881,11 @@ import_glsl_parser_tests(spec['glsl-1.30'],
> os.path.join(generatedTestDir, 'spec', 'glsl-1.30'),
> ['compiler'])
> spec['glsl-1.30']['execution'] = Group()
> +spec['glsl-1.30']['execution']['textureSize'] = Group()
> +for stage in ['vs', 'fs']:
> + # textureSize():
> + for sampler in ['sampler1D', 'sampler2D', 'sampler3D', 'samplerCube', 'sampler1DShadow', 'sampler2DShadow', 'samplerCubeShadow', 'sampler1DArray', 'sampler2DArray', 'sampler1DArrayShadow', 'sampler2DArrayShadow', 'isampler1D', 'isampler2D', 'isampler3D', 'isamplerCube', 'isampler1DArray', 'isampler2DArray', 'usampler1D', 'usampler2D', 'usampler3D', 'usamplerCube', 'usampler1DArray', 'usampler2DArray']:
> + spec['glsl-1.30']['execution']['textureSize'][stage + '-textureSize-' + sampler] = 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/texturing/CMakeLists.txt b/tests/texturing/CMakeLists.txt
> index 144a306..1bc9f55 100644
> --- a/tests/texturing/CMakeLists.txt
> +++ b/tests/texturing/CMakeLists.txt
> @@ -1 +1,2 @@
> +add_subdirectory (shaders)
> piglit_include_target_api()
> diff --git a/tests/texturing/shaders/CMakeLists.gl.txt b/tests/texturing/shaders/CMakeLists.gl.txt
> new file mode 100644
> index 0000000..e54760f
> --- /dev/null
> +++ b/tests/texturing/shaders/CMakeLists.gl.txt
> @@ -0,0 +1,16 @@
> +include_directories(
> + ${GLEXT_INCLUDE_DIR}
> + ${OPENGL_INCLUDE_PATH}
> + ${GLUT_INCLUDE_DIR}
> + ${piglit_SOURCE_DIR}/tests/mesa/util
> + ${piglit_SOURCE_DIR}/tests/util
> +)
> +
> +link_libraries (
> + piglitutil
> + ${OPENGL_gl_LIBRARY}
> + ${OPENGL_glu_LIBRARY}
> + ${GLUT_glut_LIBRARY}
> +)
> +
> +add_executable (textureSize textureSize.c common.c)
> diff --git a/tests/texturing/shaders/CMakeLists.txt b/tests/texturing/shaders/CMakeLists.txt
> new file mode 100644
> index 0000000..144a306
> --- /dev/null
> +++ b/tests/texturing/shaders/CMakeLists.txt
> @@ -0,0 +1 @@
> +piglit_include_target_api()
> diff --git a/tests/texturing/shaders/common.c b/tests/texturing/shaders/common.c
> new file mode 100644
> index 0000000..d5cc45d
> --- /dev/null
> +++ b/tests/texturing/shaders/common.c
> @@ -0,0 +1,288 @@
> +/*
> + * 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 common.c
> + *
> + * Helper functions for GLSL 1.30+ texturing tests.
> + */
> +#include "common.h"
> +
> +/**
> + * Load a miplevel's texel data via glTexImage.
> + *
> + * \param level The miplevel to be loaded (0<= level<= miplevels)
> + * \param level_image The data to be loaded.
> + *
> + * This function assumes that select_sampler() and compute_miplevel_info()
> + * have already been called.
> + */
> +void
> +upload_miplevel_data(GLenum target, int level, void *level_image)
> +{
> + const GLenum format = sampler.format;
> + const GLenum internal_format = sampler.internal_format;
> + const GLenum data_type = sampler.data_type;
> +
> + switch (target) {
> + case GL_TEXTURE_1D:
> + glTexImage1D(GL_TEXTURE_1D, level, internal_format,
> + level_size[level][0],
> + 0, format, data_type, level_image);
> + break;
> + case GL_TEXTURE_2D:
> + case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
> + case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
> + case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
> + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
> + case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
> + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
> + glTexImage2D(target, level, internal_format,
> + level_size[level][0], level_size[level][1],
> + 0, format, data_type, level_image);
> + break;
> + case GL_TEXTURE_3D:
> + case GL_TEXTURE_2D_ARRAY:
> + glTexImage3D(target, level, internal_format,
> + level_size[level][0],
> + level_size[level][1],
> + level_size[level][2],
> + 0, format, data_type, level_image);
> + break;
> + case GL_TEXTURE_1D_ARRAY:
> + glTexImage2D(GL_TEXTURE_1D_ARRAY, level, internal_format,
> + level_size[level][0], level_size[level][2],
> + 0, format, data_type, level_image);
> + break;
> + default:
> + assert(!"Not implemented yet.");
> + break;
> + }
> +}
> +
> +
> +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));
> +}
> +
> +/**
> + * Compute the number of miplevels, as well as the dimensions (width, height,
> + * depth/number of array slices) of each level.
> + *
> + * This function assumes base_size is already set.
> + */
> +void
> +compute_miplevel_info()
> +{
> + int i, l;
> + bool is_array = is_array_sampler();
> +
> + /* Compute the number of miplevels */
> + miplevels = (int) log2f(max3(base_size[0], base_size[1], base_size[2])) + 1;
For array textures, the number of array slices does not affect the
number of mipmap levels. If I have a 64x64x10000 2D array, it still
only has 6 mipmap levels.
> +
> + /* Compute the size of each miplevel */
> + level_size = malloc(miplevels * sizeof(int *));
> +
> + level_size[0] = malloc(3 * sizeof(int));
> + memcpy(level_size[0], base_size, 3 * sizeof(int));
> + for (l = 1; l< miplevels; l++) {
> + level_size[l] = malloc(3 * sizeof(int));
> +
> + for (i = 0; i< 3 - is_array; i++)
> + level_size[l][i] = max2(level_size[l-1][i] / 2, 1);
> +
> + if (is_array)
> + level_size[l][2] = base_size[2];
> + }
> +}
> +
> +bool
> +has_height()
> +{
> + return sampler.target == GL_TEXTURE_2D ||
> + sampler.target == GL_TEXTURE_3D ||
> + sampler.target == GL_TEXTURE_2D_ARRAY ||
> + sampler.target == GL_TEXTURE_RECTANGLE;
> +}
> +
> +bool
> +has_slices()
> +{
> + return is_array_sampler() || sampler.target == GL_TEXTURE_3D;
> +}
> +
> +bool
> +is_array_sampler()
> +{
> + return sampler.target == GL_TEXTURE_1D_ARRAY ||
> + sampler.target == GL_TEXTURE_2D_ARRAY ||
> + sampler.target == GL_TEXTURE_CUBE_MAP_ARRAY;
> +}
> +
> +bool
> +is_shadow_sampler()
> +{
> + return sampler.format == GL_DEPTH_COMPONENT;
> +}
> +
> +/**
> + * Check if a given command line argument is a valid GLSL sampler type.
> + * If so, infer dimensionality and data format based on the name.
> + *
> + * Returns \c true if \p name was a valid sampler.
> + */
> +bool
> +select_sampler(const char *name)
> +{
> + int i;
> + bool found = false;
> + struct {
> + const char *name;
> + GLenum type;
> + GLenum target;
> + } samplers[] = {
> + { "sampler1D", GL_SAMPLER_1D, GL_TEXTURE_1D, },
> + { "sampler2D", GL_SAMPLER_2D, GL_TEXTURE_2D, },
> + { "sampler3D", GL_SAMPLER_3D, GL_TEXTURE_3D, },
> + { "samplerCube", GL_SAMPLER_CUBE, GL_TEXTURE_CUBE_MAP },
> + { "sampler2DRect", GL_SAMPLER_2D_RECT, GL_TEXTURE_RECTANGLE },
> + { "sampler1DArray", GL_SAMPLER_1D_ARRAY, GL_TEXTURE_1D_ARRAY },
> + { "sampler2DArray", GL_SAMPLER_2D_ARRAY, GL_TEXTURE_2D_ARRAY },
> + { "samplerCubeArray", GL_SAMPLER_CUBE_MAP_ARRAY, GL_TEXTURE_CUBE_MAP_ARRAY },
> +
> + { "sampler1DShadow", GL_SAMPLER_1D_SHADOW, GL_TEXTURE_1D },
> + { "sampler2DShadow", GL_SAMPLER_2D_SHADOW, GL_TEXTURE_2D },
> + { "samplerCubeShadow", GL_SAMPLER_CUBE_SHADOW, GL_TEXTURE_CUBE_MAP },
> + { "sampler2DRectShadow", GL_SAMPLER_2D_RECT_SHADOW, GL_TEXTURE_RECTANGLE },
> + { "sampler1DArrayShadow", GL_SAMPLER_1D_ARRAY_SHADOW, GL_TEXTURE_1D_ARRAY },
> + { "sampler2DArrayShadow", GL_SAMPLER_1D_ARRAY_SHADOW, GL_TEXTURE_2D_ARRAY },
> + { "samplerCubeArrayShadow", GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW, GL_TEXTURE_CUBE_MAP_ARRAY },
> +
> + { "isampler1D", GL_INT_SAMPLER_1D, GL_TEXTURE_1D },
> + { "isampler2D", GL_INT_SAMPLER_2D, GL_TEXTURE_2D },
> + { "isampler3D", GL_INT_SAMPLER_3D, GL_TEXTURE_3D },
> + { "isamplerCube", GL_INT_SAMPLER_CUBE, GL_TEXTURE_CUBE_MAP },
> + { "isampler2DRect", GL_INT_SAMPLER_2D_RECT, GL_TEXTURE_RECTANGLE },
> + { "isampler1DArray", GL_INT_SAMPLER_1D_ARRAY, GL_TEXTURE_1D_ARRAY },
> + { "isampler2DArray", GL_INT_SAMPLER_2D_ARRAY, GL_TEXTURE_2D_ARRAY },
> + { "isamplerCubeArray", GL_INT_SAMPLER_CUBE_MAP_ARRAY, GL_TEXTURE_CUBE_MAP_ARRAY },
> +
> + { "usampler1D", GL_UNSIGNED_INT_SAMPLER_1D, GL_TEXTURE_1D },
> + { "usampler2D", GL_UNSIGNED_INT_SAMPLER_2D, GL_TEXTURE_2D },
> + { "usampler3D", GL_UNSIGNED_INT_SAMPLER_3D, GL_TEXTURE_3D },
> + { "usamplerCube", GL_UNSIGNED_INT_SAMPLER_CUBE, GL_TEXTURE_CUBE_MAP },
> + { "usampler2DRect", GL_UNSIGNED_INT_SAMPLER_2D_RECT, GL_TEXTURE_RECTANGLE },
> + { "usampler1DArray", GL_UNSIGNED_INT_SAMPLER_1D_ARRAY, GL_TEXTURE_1D_ARRAY },
> + { "usampler2DArray", GL_UNSIGNED_INT_SAMPLER_2D_ARRAY, GL_TEXTURE_2D_ARRAY },
> + { "usamplerCubeArray", GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY, GL_TEXTURE_CUBE_MAP_ARRAY },
> + };
> +
> + for (i = 0; i< ARRAY_SIZE(samplers); i++) {
> + if (strcmp(samplers[i].name, name) == 0) {
> + found = true;
> + break;
> + }
> + }
> +
> + if (!found)
> + return false;
> +
> + sampler.name = name;
> + sampler.type = samplers[i].type;
> + sampler.target = samplers[i].target;
> +
> + if (name[0] == 'i') {
> + sampler.data_type = GL_INT;
> + sampler.format = GL_RGBA_INTEGER;
> + sampler.internal_format = GL_RGBA32I;
> + sampler.return_type = "ivec4";
> + } else if (name[0] == 'u') {
> + sampler.data_type = GL_UNSIGNED_INT;
> + sampler.format = GL_RGBA_INTEGER;
> + sampler.internal_format = GL_RGBA32UI;
> + sampler.return_type = "uvec4";
> + } else if (strchr(name, 'w')) {
'strstr(name, "Shadow") != NULL' would make this more obvious and more
future-proof.
> + /* Shadow Sampler */
> + sampler.data_type = GL_FLOAT;
> + sampler.format = GL_DEPTH_COMPONENT;
> + sampler.internal_format = GL_DEPTH_COMPONENT;
> + sampler.return_type = "float";
> + } else {
> + sampler.data_type = GL_FLOAT;
> + sampler.format = GL_RGBA;
> + sampler.internal_format = GL_RGBA32F;
> + sampler.return_type = "vec4";
> + }
> +
> + return true;
> +}
> +
> +/**
> + * Ensures the driver supports the required extensions, GL, and GLSL versions.
> + * If it doesn't, report PIGLIT_SKIP and exit the test.
> + */
> +void
> +require_GL_features(enum shader_target test_stage)
> +{
> + int tex_units;
> +
> + piglit_require_GLSL_version(130);
> +
> + switch (sampler.internal_format) {
> + case GL_RGBA32I:
> + case GL_RGBA32UI:
> + piglit_require_extension("GL_EXT_texture_integer");
> + break;
> + case GL_RGBA32F:
> + piglit_require_extension("GL_ARB_texture_float");
> + break;
> + }
> +
> + switch (sampler.target) {
> + case GL_TEXTURE_CUBE_MAP_ARRAY:
> + piglit_require_extension("GL_ARB_texture_cube_map_array");
> + /* fallthrough */
This probably isn't necessary. Beside, an implementation could have
GL_ARB_texture_cube_map_array + OpenGL 3.0 without GL_EXT_texture_array.
> + case GL_TEXTURE_1D_ARRAY:
> + case GL_TEXTURE_2D_ARRAY:
> + piglit_require_extension("GL_EXT_texture_array");
> + break;
> + case GL_TEXTURE_CUBE_MAP:
> + if (is_shadow_sampler())
> + piglit_require_gl_version(30);
> + break;
> + case GL_TEXTURE_RECTANGLE:
> + piglit_require_extension("GL_ARB_texture_rectangle");
> + break;
> + }
> +
> + /* If testing in the VS, check for VS texture units */
> + glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS,&tex_units);
> + if (test_stage == VS&& tex_units<= 0)
> + piglit_report_result(PIGLIT_SKIP);
> +}
> diff --git a/tests/texturing/shaders/common.h b/tests/texturing/shaders/common.h
> new file mode 100644
> index 0000000..c25bf2c
> --- /dev/null
> +++ b/tests/texturing/shaders/common.h
> @@ -0,0 +1,101 @@
> +/*
> + * 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 common.h
> + *
> + * Common structures and functions used for GLSL 1.30+ texturing tests.
> + */
> +#pragma once
> +#define _GNU_SOURCE
> +#include "piglit-util.h"
> +
> +/**
> + * Texture miplevel info:
> + * @{
> + *
> + * The total number of miplevels:
> + */
> +int miplevels;
> +
> +/** Size of the base level */
> +int base_size[3];
> +
> +/**
> + * Multidimensional array containing the dimensions of each miplevel, indexed
> + * by miplevel and then x/y/z. For example, miplevel[0][1] is the height of
> + * miplevel 0, while miplevel[5][2] is the number of slices in miplevel 5.
> + */
> +int **level_size;
> +/** @} */
> +
> +struct sampler_info
> +{
> + /** GLSL sampler name (such as "usampler2DArray"). */
> + const char *name;
> +
> + /** GLSL sampler return type: vec4, ivec4, uvec4, or float. */
> + const char *return_type;
> +
> + /** GL sampler type (such as GL_UNSIGNED_INT_SAMPLER_2D_ARRAY). */
> + GLenum type;
> +
> + /** GL texture target (such as GL_TEXTURE_2D_ARRAY). */
> + GLenum target;
> +
> + /** Texture format data type: GL_FLOAT, GL_INT, or GL_UNSIGNED_INT. */
> + GLenum data_type;
> +
> + /** Texture format: GL_RGBA, GL_RGBA_INTEGER, or GL_DEPTH_COMPONENT */
> + GLenum format;
> +
> + /**
> + * Texture internal format: GL_RGBA32F, GL_RGBA32I, GL_RGBA32UI, or
> + * GL_DEPTH_COMPONENT.
> + */
> + GLenum internal_format;
> +} sampler;
> +
> +/**
> + * Which shader stage to test
> + */
> +enum shader_target {
> + UNKNOWN,
> + VS,
> + FS,
> + GS
> +};
> +
> +float max2(float x, float y);
> +
> +bool has_height();
> +bool has_slices();
> +
> +bool is_array_sampler();
> +bool is_shadow_sampler();
> +
> +void upload_miplevel_data(GLenum target, int level, void *level_image);
> +void compute_miplevel_info();
> +void require_GL_features(enum shader_target test_stage);
> +bool select_sampler(const char *name);
> +
> diff --git a/tests/texturing/shaders/textureSize.c b/tests/texturing/shaders/textureSize.c
> new file mode 100644
> index 0000000..4184458
> --- /dev/null
> +++ b/tests/texturing/shaders/textureSize.c
> @@ -0,0 +1,282 @@
> +/*
> + * 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+ textureSize() built-in function.
> + *
> + * The test covers:
> + * - All pipeline stages (VS, FS)
> + * - Sampler data types (floating point, signed integer, unsigned integer)
> + * - Sampler 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 "textureSize" binary takes two arguments: shader stage and sampler type.
> + *
> + * For example:
> + * ./bin/textureSize fs sampler1DArrayShadow
> + * ./bin/textureSize vs usamplerCube
> + */
> +#include "common.h"
> +
> +int piglit_width = 150, piglit_height = 30;
> +int piglit_window_mode = GLUT_RGBA | GLUT_DOUBLE;
> +
> +static int lod_location;
> +
> +/**
> + * Returns the number of components expected from textureSize().
> + */
> +int
> +sampler_size()
> +{
> + switch (sampler.target) {
> + case GL_TEXTURE_1D:
> + return 1;
> + case GL_TEXTURE_2D:
> + case GL_TEXTURE_1D_ARRAY:
> + case GL_TEXTURE_CUBE_MAP:
> + case GL_TEXTURE_RECTANGLE:
> + return 2;
> + case GL_TEXTURE_3D:
> + case GL_TEXTURE_2D_ARRAY:
> + return 3;
> + case GL_TEXTURE_CUBE_MAP_ARRAY:
> + assert(!"Not implemented yet.");
> + default:
> + assert(!"Should not get here.");
> + return 0;
> + }
> +}
> +
> +enum piglit_result
> +piglit_display()
> +{
> + bool pass = true;
> + int i, l;
> + const int size = sampler_size();
> +
> + glClearColor(0.5, 0.5, 0.5, 1.0);
> + glClear(GL_COLOR_BUFFER_BIT);
> +
> + /* Draw consecutive squares for each mipmap level */
> + for (l = 0; l< miplevels; l++) {
> + const int x = 10 + l * 20;
> + float expected_color[4];
> + expected_color[0] = 0.01 * level_size[l][0];
> + if (sampler.target == GL_TEXTURE_1D_ARRAY) {
> + expected_color[1] = 0.01 * level_size[l][2];
> + } else {
> + for (i = 1; i< size; i++)
> + expected_color[i] = 0.01 * level_size[l][i];
> + }
> + expected_color[3] = 1.0;
> +
> + 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);
> + }
> +
> + piglit_present_results();
> +
> + return pass ? PIGLIT_PASS : PIGLIT_FAIL;
> +}
> +
> +/**
> + * Set the size of the texture's base level.
> + */
> +void
> +set_base_size()
> +{
> + if (sampler.target == GL_TEXTURE_CUBE_MAP) {
> + /* Cube face width/height must be the same size. */
> + base_size[0] = base_size[1] = 65;
> + base_size[2] = 1;
> + } else {
> + base_size[0] = 65;
> + base_size[1] = has_height() ? 32 : 1;
> + base_size[2] = has_slices() ? 40 : 1;
> + }
> +}
> +
> +void
> +generate_texture()
> +{
> + int l, i;
> + GLuint tex;
> + const GLenum target = sampler.target;
> +
> + 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);
> +
> + for (l = 0; l< miplevels; l++) {
> + if (target == GL_TEXTURE_CUBE_MAP) {
> + for (i = 0; i< 6; i++) {
> + GLenum f = GL_TEXTURE_CUBE_MAP_POSITIVE_X + i;
> + upload_miplevel_data(f, l, NULL);
> + }
> + } else {
> + upload_miplevel_data(sampler.target, l, NULL);
> + }
> + }
> +}
> +
> +
> +int
> +generate_GLSL(enum shader_target test_stage)
> +{
> + int vs, fs;
> +
> + static char *vs_code;
> + static char *fs_code;
> +
> + static const char *zeroes[3] = { "", "0, ", "0, 0, " };
> +
> + const int size = sampler_size();
> +
> + switch (test_stage) {
> + case VS:
> + asprintf(&vs_code,
> + "#version 130\n"
> + "#define ivec1 int\n"
> + "uniform int lod;\n"
> + "uniform %s tex;\n"
> + "flat out ivec%d size;\n"
> + "void main()\n"
> + "{\n"
> + " size = textureSize(tex, lod);\n"
> + " gl_Position = gl_Vertex;\n"
> + "}\n",
> + sampler.name, size);
> + asprintf(&fs_code,
> + "#version 130\n"
> + "#define ivec1 int\n"
> + "#define vec1 float\n"
> + "flat in ivec%d size;\n"
> + "void main()\n"
> + "{\n"
> + " gl_FragColor = vec4(0.01 * size,%s 1);\n"
> + "}\n",
> + size, zeroes[3 - size]);
> + break;
> + case FS:
> + asprintf(&vs_code,
> + "#version 130\n"
> + "void main()\n"
> + "{\n"
> + " gl_Position = gl_Vertex;\n"
> + "}\n");
> + asprintf(&fs_code,
> + "#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, size, zeroes[3 - 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
> +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 sampler_found = false;
> +
> + for (i = 1; i< argc; i++) {
> + 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;
> + }
> + }
> +
> + /* Maybe it's the sampler type? */
> + if (!sampler_found&& (sampler_found = select_sampler(argv[i])))
> + continue;
> +
> + fail_and_show_usage();
> + }
> +
> + if (test_stage == UNKNOWN || !sampler_found)
> + fail_and_show_usage();
> +
> + /* Not implemented yet */
> + assert(sampler.target != GL_TEXTURE_CUBE_MAP_ARRAY&&
> + sampler.target != GL_TEXTURE_RECTANGLE);
> +
> + require_GL_features(test_stage);
> +
> + 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);
> +
> + /* Create textures and set miplevel info */
> + set_base_size();
> + compute_miplevel_info();
> + generate_texture();
> +}
More information about the Piglit
mailing list