[Piglit] [PATCH] fbo: add a test for blending with float special values

Brian Paul brianp at vmware.com
Sun Nov 5 17:31:55 UTC 2017


On 11/04/2017 02:44 PM, Ilia Mirkin wrote:
> See what happens when doing 0 * Inf and NaN.
>
> Signed-off-by: Ilia Mirkin <imirkin at alum.mit.edu>
> ---
>
> Not sure if this is worth checking in. I was just wondering what various
> hardware did, and this covers many of the permutations. This test can be
> run both in core profile, or with the -compat flag to force a compat profile.
> Perhaps different drivers do things differently for the two.
>
> On nouveau/nvc0, it assumes 0*inf = 0, on nouveau/nv50 it assumes 0*inf = nan.
> On i965/skl, it assumes 0*inf = nan. (I have patches to change nv50 to match
> the nvc0 behavior - it's configurable on both.)
>
> I'd be curious to hear what (a) radeonsi and r600 do and (b) how this works
> on the various blob drivers. For the blob drivers, you should run it with
> both -compat and without, to see if the behavior is different. If it prints
> lots of stuff, that means the hw does 0*inf = nan. If it prints nothing out,
> then it think sthat 0*inf = 0. Either way, I'd be interested in hearing
> what the full output is.
>
> Note that the piglit always passes, since there is no right or wrong here.
>
>   tests/fbo/CMakeLists.gl.txt |   2 +
>   tests/fbo/fbo-float-nan.c   | 159 ++++++++++++++++++++++++++++++++++++++++++++
>   2 files changed, 161 insertions(+)
>   create mode 100644 tests/fbo/fbo-float-nan.c
>
> diff --git a/tests/fbo/CMakeLists.gl.txt b/tests/fbo/CMakeLists.gl.txt
> index 2e2cac9d9..2db8bf700 100644
> --- a/tests/fbo/CMakeLists.gl.txt
> +++ b/tests/fbo/CMakeLists.gl.txt
> @@ -97,4 +97,6 @@ piglit_add_executable (fbo-cubemap fbo-cubemap.c)
>   piglit_add_executable (fbo-scissor-bitmap fbo-scissor-bitmap.c)
>   piglit_add_executable (fbo-viewport fbo-viewport.c)
>
> +piglit_add_executable (fbo-float-nan fbo-float-nan.c)
> +
>   # vim: ft=cmake:
> diff --git a/tests/fbo/fbo-float-nan.c b/tests/fbo/fbo-float-nan.c
> new file mode 100644
> index 000000000..ccbf53ae5
> --- /dev/null
> +++ b/tests/fbo/fbo-float-nan.c
> @@ -0,0 +1,159 @@
> +/*
> + * Copyright © 2017 Ilia Mirkin <imirkin at alum.mit.edu>
> + *
> + * 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.
> + */
> +
> +/*
> + * The purpose of this test is to find out what happens when the
> + * shader produces a NaN value with a floating point RT. This is all
> + * undefined as far as the GL spec goes, but it's useful to be able to
> + * compare implementations.
> + */
> +
> +#include "piglit-util-gl.h"
> +
> +PIGLIT_GL_TEST_CONFIG_BEGIN
> +	config.supports_gl_core_version = 31;
> +	config.window_visual = PIGLIT_GL_VISUAL_RGBA | PIGLIT_GL_VISUAL_DOUBLE;
> +	config.khr_no_error_support = PIGLIT_NO_ERRORS;
> +PIGLIT_GL_TEST_CONFIG_END
> +
> +static const char *vs_text =
> +	"#version 130 \n"
> +	"in vec4 piglit_vertex; \n"
> +	"void main() { \n"
> +	"  gl_Position = piglit_vertex; \n"
> +	"}\n";
> +
> +static const char *fs_text =
> +	"#version 130 \n"
> +	"#extension GL_ARB_shader_bit_encoding: require \n"
> +	"out vec4 color; \n"
> +	"uniform uint c; \n"
> +	"uniform uint a; \n"
> +	"void main() { \n"
> +	"  color = vec4(vec3(uintBitsToFloat(c)), uintBitsToFloat(a)); \n"
> +	"}\n";
> +
> +GLuint program, fb, rb;
> +
> +static const unsigned uINF = 0x7f800000;
> +static const unsigned uNAN = 0x7fc00000;
> +
> +bool is_nan(unsigned arg) {

Brace on next line.

> +	return ((arg & 0x7f800000) == 0x7f800000) &&
> +		(arg & 0x007fffff);
> +}
> +
> +void test_draw(unsigned u_c, unsigned u_a, unsigned r, unsigned g, unsigned b, unsigned a)
> +{
> +	unsigned pixel[4];
> +
> +	glUniform1ui(glGetUniformLocation(program, "c"), u_c);
> +	glUniform1ui(glGetUniformLocation(program, "a"), u_a);
> +	piglit_draw_rect(-1, -1, 2, 2);
> +	glReadPixels(0, 0, 1, 1, GL_RGBA, GL_FLOAT, pixel);
> +
> +	bool rmatch = pixel[0] == r || (is_nan(pixel[0]) && is_nan(r));
> +	bool gmatch = pixel[1] == g || (is_nan(pixel[1]) && is_nan(g));
> +	bool bmatch = pixel[2] == b || (is_nan(pixel[2]) && is_nan(b));
> +	bool amatch = pixel[3] == a || (is_nan(pixel[3]) && is_nan(a));
> +	if (!rmatch || !gmatch || !bmatch || !amatch)
> +		printf("Unexpected result c=%x, a=%x: %x %x %x %x != %x %x %x %x\n",
> +		       u_c, u_a,
> +		       pixel[0], pixel[1], pixel[2], pixel[3],
> +		       r, g, b, a);
> +}
> +
> +void run_test() {

Brace on next line.

> +	glBindFramebuffer(GL_FRAMEBUFFER, fb);
> +	glClearColor(0, 0, 0, 0);
> +
> +	printf("Testing without blending.\n");
> +	glDisable(GL_BLEND);
> +	test_draw(0, 0, 0, 0, 0, 0);
> +	test_draw(uINF, uINF, uINF, uINF, uINF, uINF);
> +	test_draw(uNAN, uNAN, uNAN, uNAN, uNAN, uNAN);
> +
> +	printf("Testing with blending src SRC_ALPHA + dst ZERO.\n");

src * SRC_ALPHA + dst * ZERO  ?

and below

> +	glEnable(GL_BLEND);
> +	glBlendFunc(GL_SRC_ALPHA, GL_ZERO);
> +	test_draw(0, uNAN, 0, 0, 0, uNAN); /* NaN * NaN = NaN? */
> +	test_draw(uNAN, 0, 0, 0, 0, 0);
> +	test_draw(0, uINF, 0, 0, 0, uINF);
> +	test_draw(uINF, 0, 0, 0, 0, 0);
> +	test_draw(uINF, uNAN, uNAN, uNAN, uNAN, uNAN); /* NaN * Inf = NaN */
> +	test_draw(uNAN, uINF, uNAN, uNAN, uNAN, uINF); /* NaN * Inf = NaN */
> +
> +	printf("Testing with blending src DST_ALPHA + dst ZERO.\n");
> +	glBlendFunc(GL_DST_ALPHA, GL_ZERO);
> +	/* Zero in DST_ALPHA */
> +	glClear(GL_COLOR_BUFFER_BIT);
> +	test_draw(uINF, uNAN, 0, 0, 0, 0);
> +	/* Get infinity into DST_ALPHA */
> +	glDisable(GL_BLEND);
> +	test_draw(0, uINF, 0, 0, 0, uINF);
> +	glEnable(GL_BLEND);
> +	test_draw(0, uINF, 0, 0, 0, uINF);
> +
> +	/* Get NaN into DST_ALPHA */
> +	glDisable(GL_BLEND);
> +	test_draw(0, uNAN, 0, 0, 0, uNAN);
> +	glEnable(GL_BLEND);
> +	test_draw(0, uINF, 0, 0, 0, uNAN);
> +}
> +
> +enum piglit_result piglit_display(void)
> +{
> +	return PIGLIT_PASS;
> +}
> +
> +void piglit_init(int argc, char **argv)
> +{
> +	piglit_require_extension("GL_ARB_shader_bit_encoding");

Maybe move the test to tests/spec/arb_shader_bit_encoding/ ?

Looks OK otherwise.

Reviewed-by: Brian Paul <brianp at vmware.com>


> +	program = piglit_build_simple_program(vs_text, fs_text);
> +	glUseProgram(program);
> +
> +	glGenFramebuffers(1, &fb);
> +	glBindFramebuffer(GL_FRAMEBUFFER, fb);
> +
> +	glGenRenderbuffers(1, &rb);
> +	glBindRenderbuffer(GL_RENDERBUFFER, rb);
> +
> +	glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
> +				  GL_RENDERBUFFER, rb);
> +
> +	printf("Testing GL_RGBA16F\n");
> +	glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA16F, 64, 64);
> +	run_test();
> +
> +	printf("Testing GL_RGBA32F\n");
> +	glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA32F, 64, 64);
> +	run_test();
> +
> +#if 0
> +	printf("Testing GL_RGBA8. Lots of failures expected.\n");
> +	glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 64, 64);
> +	run_test();
> +#endif
> +
> +	piglit_report_result(PIGLIT_PASS);
> +}
>



More information about the Piglit mailing list