[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