On 11/05/2017 10:46 AM, Ilia Mirkin wrote:
On Sun, Nov 5, 2017 at 12:31 PM, Brian Paul <bri...@vmware.com> wrote:
On 11/04/2017 02:44 PM, Ilia Mirkin wrote:

See what happens when doing 0 * Inf and NaN.

Signed-off-by: Ilia Mirkin <imir...@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 <imir...@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/ ?

Well, it's really a blending test, where I just like to use the shader
bit encoding stuff to avoid any questions about whether the
infinity/NaN are *really* making it through to the shader outputs. I'd
be concerned about using float uniforms. I guess a UBO would be safe
enough though?

Probably.



Looks OK otherwise.

Reviewed-by: Brian Paul <bri...@vmware.com>

Thanks. I actually followed up with a v2 which includes arguments to
pass in for different expectaitons (e.g. 0*inf = nan, and whether
GL_ZERO counts as 0 wins or doing the IEEE calc. It's tricky since if
there's no DST, it seems reasonable for the GPU to never even load the
DST and not find out that the DST has an infinity. This is the i965
behavior.)

But do you think it's reasonable to have this type of program in
piglit? It's not really a test, more of a debugging/informational aid.

I'm fine with it.  Maybe someday this won't be undefined behavior.

v2 R-b.



So far I've confirmed that NVIDIA blob drivers on Kepler do it the
0*inf=0 way, both compat and core.




+       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);
+}



_______________________________________________
Piglit mailing list
Piglit@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/piglit

Reply via email to