[Piglit] [PATCH] ARB_texture_gather: add initial execution test

Ian Romanick idr at freedesktop.org
Tue Aug 13 13:09:31 PDT 2013


On 08/10/2013 03:10 AM, Chris Forbes wrote:
> This test exercises combinations of:
> - Shader stage vs/fs
> - Offsetting
> - Component count, up to implementation-defined limit
> - Swizzling
> - Unsigned normalized vs float type
>
> The test works by numbering the texels, and ensuring that the four
> texels sampled by textureGather*() are those we expect.
>
> Not exercised yet:
> - Integer textures
> - Samplers other than sampler2D
> - Other interesting internalformats [DEPTH_COMPONENT, etc]
> - Addressing modes other than WRAP.
>
> Signed-off-by: Chris Forbes <chrisf at ijw.co.nz>
> ---
>   tests/all.tests                           |  19 ++
>   tests/texturing/shaders/CMakeLists.gl.txt |   1 +
>   tests/texturing/shaders/textureGather.c   | 309 ++++++++++++++++++++++++++++++
>   3 files changed, 329 insertions(+)
>   create mode 100644 tests/texturing/shaders/textureGather.c
>
> diff --git a/tests/all.tests b/tests/all.tests
> index a914a2a..68e89e2 100644
> --- a/tests/all.tests
> +++ b/tests/all.tests
> @@ -969,6 +969,25 @@ for stage in ['vs', 'gs', 'fs']:
>   	for sampler in samplers_atm:
>   		spec['ARB_texture_multisample/textureSize/' + stage + '-textureSize-' + sampler] = concurrent_test('textureSize ' + stage + ' ' + sampler)
>
> +# Group ARB_texture_gather
> +arb_texture_gather = Group()
> +spec['ARB_texture_gather'] = arb_texture_gather
> +for stage in ['vs', 'fs']:

Since ARB_texture_gather will land in Mesa around the same time geometry 
shaders land, should this also test gs?  I see you also have that 
question in the test code...

> +    for comps in ['r', 'rg', 'rgb', 'rgba']:
> +        for swiz in ['red', 'green', 'blue', 'alpha'][:len(comps)] + ['', 'zero', 'one']:
> +            for type in ['', 'float']:
> +                for func in ['textureGather', 'textureGatherOffset']:
> +                    testname = '%s/%s-%s-%s-%s' % (
> +                        func, stage, comps,
> +                        swiz if len(swiz) else 'none',
> +                        type if len(type) else 'unorm')
> +                    cmd = 'textureGather %s %s %s %s %s' % (
> +                        stage,
> +                        'offset' if func == 'textureGatherOffset' else '',
> +                        comps, swiz, type
> +                        )
> +                    arb_texture_gather[testname] = concurrent_test(cmd)
> +
>   # Group AMD_shader_stencil_export
>   spec['AMD_shader_stencil_export'] = Group()
>   import_glsl_parser_tests(spec['AMD_shader_stencil_export'],
> diff --git a/tests/texturing/shaders/CMakeLists.gl.txt b/tests/texturing/shaders/CMakeLists.gl.txt
> index 7210c1c..6e4e9a7 100644
> --- a/tests/texturing/shaders/CMakeLists.gl.txt
> +++ b/tests/texturing/shaders/CMakeLists.gl.txt
> @@ -12,3 +12,4 @@ link_libraries (
>
>   piglit_add_executable (textureSize textureSize.c common.c)
>   piglit_add_executable (texelFetch texelFetch.c common.c)
> +piglit_add_executable (textureGather textureGather.c)
> diff --git a/tests/texturing/shaders/textureGather.c b/tests/texturing/shaders/textureGather.c
> new file mode 100644
> index 0000000..9a92fd9
> --- /dev/null
> +++ b/tests/texturing/shaders/textureGather.c
> @@ -0,0 +1,309 @@
> +#include "piglit-util-gl-common.h"
> +
> +PIGLIT_GL_TEST_CONFIG_BEGIN
> +
> +	config.supports_gl_compat_version = 11;
> +	config.supports_gl_core_version = 31;
> +
> +	config.window_visual = PIGLIT_GL_VISUAL_RGBA | PIGLIT_GL_VISUAL_DOUBLE;
> +
> +PIGLIT_GL_TEST_CONFIG_END
> +
> +#define TEXTURE_WIDTH 32
> +#define TEXTURE_HEIGHT 32
> +
> +enum { NONE, VS, FS } stage = NONE;
> +bool use_offset = false;
> +int components = 0;
> +int swizzle = -1;
> +bool use_float = false;
> +
> +GLenum internalformat_for_components[] = { GL_R16, GL_RG16, GL_RGB16, GL_RGBA16 };
> +GLenum internalformat_for_components_f[] = { GL_R32F, GL_RG32F, GL_RGB32F, GL_RGBA32F };
> +GLenum format_for_components[] = { GL_RED, GL_RG, GL_RGB, GL_RGBA };
> +GLenum swizzles[] = { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA, GL_ZERO, GL_ONE };
> +
> +unsigned char *pixels;
> +float *expected;
> +
> +enum piglit_result
> +piglit_display(void)
> +{
> +	int i, j;
> +	bool pass = true;
> +
> +	glViewport(0, 0, TEXTURE_WIDTH, TEXTURE_HEIGHT);
> +
> +	if (swizzle >= 0) {
> +		GLint sw[] = { swizzles[swizzle], GL_ZERO, GL_ZERO, GL_ZERO };
> +		glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, sw);
> +	}
> +
> +	if (stage == FS)
> +		glDrawArrays(GL_TRIANGLES, 0, 6);
> +	else
> +		glDrawArrays(GL_POINTS, 0, TEXTURE_WIDTH * TEXTURE_HEIGHT);
> +
> +	for (j = 0; j < TEXTURE_HEIGHT; j++)
> +		for (i = 0; i < TEXTURE_WIDTH; i++) {
> +			float *pe = &expected[4 * (j * TEXTURE_WIDTH + i)];
> +			pass = piglit_probe_pixel_rgba(i, j, pe) && pass;
> +		}
> +
> +	piglit_present_results();
> +
> +	return pass ? PIGLIT_PASS : PIGLIT_FAIL;
> +}
> +
> +/* TODO:
> + * Test mipmap selection (always selects base level)
> + * Test invariance under sampler weirdness

These two would probably be separate tests.

> + * Test other sampler types: gsampler2D|gsampler2DArray|gsamplerCube|gsamplerCubeArray

yeah. :(

> + * Test GS texturing too -- Paul?
> + */
> +
> +static unsigned char
> +pixel_value(int i, int j)
> +{
> +	if (swizzle == 4)
> +		return 0;
> +	if (swizzle == 5)
> +		return 255;
> +
> +	if (use_offset) {
> +		/* apply texel offset */
> +		i += TEXTURE_WIDTH + -8;
> +		j += TEXTURE_HEIGHT + 7;
> +	}
> +
> +	/* WRAP at border */
> +	i %= TEXTURE_WIDTH;
> +	j %= TEXTURE_HEIGHT;
> +
> +	return i + j * TEXTURE_WIDTH;
> +}
> +
> +static float
> +norm_value(int x)
> +{
> +	return (float)x / 255.0f;
> +}
> +
> +static void
> +make_image(int num_channels, int use_channel)
> +{
> +	unsigned char *pp = pixels;
> +	int i, j, ch;
> +
> +	for (j = 0; j < TEXTURE_HEIGHT; j++)
> +		for (i = 0; i < TEXTURE_WIDTH; i++)
> +			for (ch = 0; ch < num_channels; ch++)
> +				*pp++ = (ch == use_channel) ? (i+j*TEXTURE_WIDTH) : 128;
> +}
> +
> +static void
> +make_expected(void)
> +{
> +	float *pe = expected;
> +	int i, j;
> +
> +	for (j = 0; j < TEXTURE_HEIGHT; j++)
> +		for (i = 0; i < TEXTURE_WIDTH; i++) {
> +			*pe++ = norm_value(pixel_value(i, j + 1));
> +			*pe++ = norm_value(pixel_value(i + 1, j + 1));
> +			*pe++ = norm_value(pixel_value(i + 1, j));
> +			*pe++ = norm_value(pixel_value(i, j));
> +		}
> +}
> +
> +static void
> +upload_verts(void)
> +{
> +	if (stage == VS) {
> +		float v[4 * TEXTURE_WIDTH * TEXTURE_HEIGHT], *pv = v;
> +		int i, j;
> +		for (j = 0; j < TEXTURE_HEIGHT; j++)
> +			for (i = 0; i < TEXTURE_WIDTH; i++) {
> +				*pv++ = (i + 0.5f) * 2 / TEXTURE_WIDTH - 1;
> +				*pv++ = (j + 0.5f) * 2 / TEXTURE_HEIGHT - 1;
> +				*pv++ = 0;
> +				*pv++ = 1;
> +			}
> +		glBufferData(GL_ARRAY_BUFFER, sizeof(v), v, GL_STATIC_DRAW);
> +	}
> +	else {
> +		static const float verts[] = {
> +			-1, -1, 0, 1,		-1, 1, 0, 1,	1, 1, 0, 1,
> +			-1, -1, 0, 1,		1, 1, 0, 1,		1, -1, 0, 1,
> +		};
> +		glBufferData(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_STATIC_DRAW);
> +	}
> +}
> +
> +void
> +do_requires(void)
> +{
> +	int max_components;
> +	piglit_require_GLSL_version(130);
> +	piglit_require_extension("GL_ARB_texture_gather");
> +
> +	/* check whether component count will actually work */
> +	glGetIntegerv(GL_MAX_PROGRAM_TEXTURE_GATHER_COMPONENTS_ARB, &max_components);
> +	if (components > max_components) {
> +		printf("Test requires gather from texture with %d components;"
> +		       "This implementation only supports %d\n",
> +			   components, max_components);
> +		piglit_report_result(PIGLIT_SKIP);
> +	}
> +
> +	/* if we are trying to swizzle, check that we can! */
> +	if (swizzle != -1)
> +		piglit_require_extension("GL_EXT_texture_swizzle");
> +}
> +
> +void
> +do_setup(void)
> +{
> +	GLuint tex;
> +	GLint vs, fs, prog;
> +	GLint sampler_loc;
> +	GLuint vbo;
> +	char *vs_code, *fs_code;
> +
> +	pixels = malloc(components * sizeof(unsigned char) * TEXTURE_WIDTH * TEXTURE_HEIGHT);
> +	expected = malloc(4 * sizeof(float) * TEXTURE_WIDTH * TEXTURE_HEIGHT);
> +
> +	glGenTextures(1, &tex);
> +	glBindTexture(GL_TEXTURE_2D, tex);
> +
> +	make_image(components, swizzle >= 0 ? swizzle : 0);
> +	make_expected();
> +
> +	glTexImage2D(GL_TEXTURE_2D, 0,
> +	             use_float
> +				     ? internalformat_for_components_f[components-1]
> +					 : internalformat_for_components[components-1],
> +	             TEXTURE_WIDTH, TEXTURE_HEIGHT,
> +	             0, format_for_components[components-1],
> +				 GL_UNSIGNED_BYTE, pixels);
> +	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
> +	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
> +
> +	if (stage == VS) {
> +		asprintf(&vs_code, "#version 130\n"
> +				"#extension GL_ARB_explicit_attrib_location: require\n"
> +				"#extension GL_ARB_texture_gather: require\n"
> +				"\n"
> +				"layout(location=0) in vec4 pos;\n"
> +				"uniform sampler2D s;\n"
> +				"out vec4 c;\n"
> +				"\n"
> +				"void main() {\n"
> +				"	gl_Position = pos;\n"
> +				"	c = textureGather%s(s, 0.5 * pos.xy + vec2(0.5) %s);\n"
> +				"}\n",
> +				use_offset ? "Offset" : "",
> +				use_offset ? ", ivec2(-8,7)" : "");
> +		asprintf(&fs_code,
> +				"#version 130\n"
> +				"\n"
> +				"in vec4 c;\n"
> +				"\n"
> +				"void main() {\n"
> +				"	gl_FragColor = c;\n"
> +				"}\n");
> +	}
> +	else {
> +		asprintf(&vs_code,
> +				"#version 130\n"
> +				"#extension GL_ARB_explicit_attrib_location: require\n"
> +				"layout(location=0) in vec4 pos;\n"
> +				"\n"
> +				"void main() {\n"
> +				"	gl_Position = pos;\n"
> +				"}\n");
> +		asprintf(&fs_code,
> +				"#version 130\n"
> +				"#extension GL_ARB_texture_gather: require\n"
> +				"\n"
> +				"uniform sampler2D s;\n"
> +				"\n"
> +				"void main() {\n"
> +				"	gl_FragColor = textureGather%s(s, gl_FragCoord.xy / vec2(32, 32) %s);\n"

Use textureSize() instead of hardcoded vec(32,32).

> +				"}\n",
> +				use_offset ? "Offset" : "",
> +				use_offset ? ", ivec2(-8,7)" : "");
> +	}
> +
> +	vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vs_code);
> +	fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, fs_code);
> +
> +	if (!vs || !fs) {
> +		printf("Failed compiling shader.\n");
> +		piglit_report_result(PIGLIT_FAIL);
> +	}
> +
> +	prog = piglit_link_simple_program(vs, fs);
> +
> +	if (!prog) {
> +		printf("Failed linking shader.\n");
> +		piglit_report_result(PIGLIT_FAIL);
> +	}

piglit_build_simple_program

> +
> +	glUseProgram(prog);
> +    sampler_loc = glGetUniformLocation(prog, "s");
> +	glUniform1i(sampler_loc, 0);
> +
> +	if (!piglit_check_gl_error(GL_NO_ERROR)) {
> +		printf("Error in init\n");
> +		piglit_report_result(PIGLIT_FAIL);
> +	}
> +
> +	if (piglit_get_gl_version() >= 31) {
> +		GLuint vao;
> +		glGenVertexArrays(1, &vao);
> +		glBindVertexArray(vao);
> +	}
> +
> +	glGenBuffers(1, &vbo);
> +	glBindBuffer(GL_ARRAY_BUFFER, vbo);
> +	upload_verts();
> +	glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);
> +	glEnableVertexAttribArray(0);
> +}
> +
> +void
> +fail_with_usage(void)
> +{
> +	printf("Usage: textureGather vs|fs [offset] r|rg|rgb|rgba [red|green|blue|alpha|zero|one] [float]\n");
> +	piglit_report_result(PIGLIT_SKIP);
> +}
> +
> +void
> +piglit_init(int argc, char **argv)
> +{
> +	int i;
> +	for (i = 1; i < argc; i++) {
> +		char *opt = argv[i];
> +		if (!strcmp(opt, "vs")) stage = VS;
> +		else if (!strcmp(opt, "fs")) stage = FS;
> +		else if (!strcmp(opt, "offset")) use_offset = true;
> +		else if (!strcmp(opt, "r")) components = 1;
> +		else if (!strcmp(opt, "rg")) components = 2;
> +		else if (!strcmp(opt, "rgb")) components = 3;
> +		else if (!strcmp(opt, "rgba")) components = 4;
> +		else if (!strcmp(opt, "red")) swizzle = 0;
> +		else if (!strcmp(opt, "green")) swizzle = 1;
> +		else if (!strcmp(opt, "blue")) swizzle = 2;
> +		else if (!strcmp(opt, "alpha")) swizzle = 3;
> +		else if (!strcmp(opt, "zero")) swizzle = 4;
> +		else if (!strcmp(opt, "one")) swizzle = 5;
> +		else if (!strcmp(opt, "float")) use_float = true;
> +	}
> +
> +	if (stage == NONE) fail_with_usage();
> +	if (components == 0) fail_with_usage();
> +
> +	do_requires();
> +	do_setup();
> +}
>



More information about the Piglit mailing list