[Piglit] [PATCH] spec/arb_blend_func_extended: Add test for SIMD16 dual source blending

Iago Toral Quiroga itoral at igalia.com
Thu Mar 5 03:19:34 PST 2015


On Intel hardware at least, SIMD16 dual source rendering requires handling
pixel data in two sets of 8 pixels each. Incorrect implementations may fail
to map correct colors for each pixel group (for example by using the color
for the first group as the color for the second group or viceversa). However,
tests that render using solid colors across the entire polygon won't catch
these cases (since in that case the color is the same for boths groups of
pixels).

This test blends using a checker board pattern where each cell is
10px wide and 10px tall. This makes it so that the two sets of 8 pixels
issued during SIMD16 operation pack different color data for the pixels
involved, enabling testing of correct behavior in that case.
---

I sent this a few months ago, but since my SIMD16 dual source blending patch
for i965 never got reviewed this never became relevant. I have now updated my
version of that patch and hopefully I'll get it reviewed this time, so I am
sending the test here again too.

 tests/all.py                                       |   1 +
 .../execution/CMakeLists.gl.txt                    |   1 +
 .../execution/fbo-extended-blend-pattern.c         | 209 +++++++++++++++++++++
 3 files changed, 211 insertions(+)
 create mode 100644 tests/spec/arb_blend_func_extended/execution/fbo-extended-blend-pattern.c

diff --git a/tests/all.py b/tests/all.py
index d2ae5ea..1cc6e5f 100644
--- a/tests/all.py
+++ b/tests/all.py
@@ -3666,6 +3666,7 @@ add_plain_test(arb_blend_func_extended, ['arb_blend_func_extended-error-at-begin
 add_plain_test(arb_blend_func_extended, ['arb_blend_func_extended-getfragdataindex'])
 add_plain_test(arb_blend_func_extended, ['arb_blend_func_extended-fbo-extended-blend'])
 add_plain_test(arb_blend_func_extended, ['arb_blend_func_extended-fbo-extended-blend-explicit'])
+add_plain_test(arb_blend_func_extended, ['arb_blend_func_extended-fbo-extended-blend-pattern'])
 
 arb_base_instance = {}
 spec['ARB_base_instance'] = arb_base_instance
diff --git a/tests/spec/arb_blend_func_extended/execution/CMakeLists.gl.txt b/tests/spec/arb_blend_func_extended/execution/CMakeLists.gl.txt
index ebe0fa0..1db7fa1 100644
--- a/tests/spec/arb_blend_func_extended/execution/CMakeLists.gl.txt
+++ b/tests/spec/arb_blend_func_extended/execution/CMakeLists.gl.txt
@@ -12,4 +12,5 @@ link_libraries (
 
 piglit_add_executable (arb_blend_func_extended-fbo-extended-blend fbo-extended-blend.c)
 piglit_add_executable (arb_blend_func_extended-fbo-extended-blend-explicit fbo-extended-blend-explicit.c)
+piglit_add_executable (arb_blend_func_extended-fbo-extended-blend-pattern fbo-extended-blend-pattern.c)
 # vim: ft=cmake:
diff --git a/tests/spec/arb_blend_func_extended/execution/fbo-extended-blend-pattern.c b/tests/spec/arb_blend_func_extended/execution/fbo-extended-blend-pattern.c
new file mode 100644
index 0000000..488c380
--- /dev/null
+++ b/tests/spec/arb_blend_func_extended/execution/fbo-extended-blend-pattern.c
@@ -0,0 +1,209 @@
+/*
+ * Copyright (c) 2014 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 fbo-extended-blend-pattern.c
+ * @author Iago Toral Quiroga <itoral at igalia.com>
+ *
+ * On Intel hardware at least, SIMD16 dual source rendering requires handling
+ * pixel data in two sets of 8 pixels each. Incorrect implementations may fail
+ * to map correct colors for each pixel group (for example by using the color
+ * for the first group as the color for the second group or viceversa). However,
+ * tests that render using solid colors across the entire polygon won't catch
+ * these cases (since in that case the color is the same for boths groups of
+ * pixels).
+ *
+ * This test blends using a checker board pattern where each cell is
+ * 10px wide and 10px tall. This makes it so that the two sets of 8 pixels
+ * issued during SIMD16 operation pack different color data for the pixels
+ * involved, enabling testing of correct behavior in that case.
+ *
+ * This only tests with one specific blend mode. There is no need to test
+ * others, since the details of SIMD16 operation are independent of the
+ * specific blend mode we use and general testing of the multiple blend modes
+ * and parameters is already covered by the tests in fbo-extended-blend.c.
+ */
+
+#include "piglit-util-gl.h"
+
+PIGLIT_GL_TEST_CONFIG_BEGIN
+
+   config.supports_gl_compat_version = 30;
+   config.window_visual = PIGLIT_GL_VISUAL_RGB;
+
+PIGLIT_GL_TEST_CONFIG_END
+
+static const char *TestName = "fbo-extended-blend-pattern";
+
+static GLint max_ds_buffers;
+static GLuint fbo;
+
+static void
+check_error(int line)
+{
+   GLenum err = glGetError();
+   if (err) {
+      printf("%s: Unexpected error 0x%x at line %d\n", TestName, err, line);
+      piglit_report_result(PIGLIT_FAIL);
+   }
+}
+
+static GLint uniform_src0, uniform_src1, uniform_src2;
+
+static void blend(const float *src, const float *src1, const float *src2,
+                  const float *dst)
+{
+   glUniform4fv(uniform_src0, 1, dst);
+   piglit_draw_rect(0, 0, piglit_width, piglit_height);
+   glEnable(GL_BLEND);
+   glBlendFunc(GL_SRC_COLOR, GL_SRC1_COLOR);
+   glUniform4fv(uniform_src0, 1, src);
+   glUniform4fv(uniform_src1, 1, src1);
+   glUniform4fv(uniform_src2, 1, src2);
+   piglit_draw_rect(0, 0, piglit_width, piglit_height);
+   glDisable(GL_BLEND);
+}
+
+static const char *vs_text =
+   "#version 130\n"
+   "void main() {\n"
+   "  gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n"
+   "}\n"
+   ;
+
+static const char *fs_text =
+   "#version 130\n"
+   "#extension GL_ARB_explicit_attrib_location: require\n"
+   "uniform vec4 src0;\n"
+   "uniform vec4 src1;\n"
+   "uniform vec4 src2;\n"
+   "layout(location = 0, index = 0) out vec4 col0;\n"
+   "layout(location = 0, index = 1) out vec4 col1;\n"
+   "void main() {\n"
+   "   int a = int(gl_FragCoord.x) / 10;\n"
+   "   int b = int(gl_FragCoord.y) / 10;\n"
+   "   int c = int(mod(a + b, 2));\n"
+   "   col0 = src0;\n"
+   "   if (c == 0)\n"
+   "      col1 = src1;\n"
+   "   else\n"
+   "      col1 = src2;\n"
+   "}\n"
+   ;
+
+static void
+create_fbo(void)
+{
+   GLuint rb[32];
+   int i;
+
+   glGenFramebuffersEXT(1, &fbo);
+   glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
+
+   glGenRenderbuffersEXT(max_ds_buffers, rb);
+   check_error(__LINE__);
+
+   for (i = 0; i < max_ds_buffers; i++) {
+      glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, rb[i]);
+      check_error(__LINE__);
+
+      glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,
+                                   GL_COLOR_ATTACHMENT0 + i,
+                                   GL_RENDERBUFFER_EXT,
+                                   rb[i]);
+      check_error(__LINE__);
+
+      glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGBA,
+                               piglit_width, piglit_height);
+      check_error(__LINE__);
+   }
+}
+
+static enum piglit_result
+test(void)
+{
+   static const GLfloat dest_color[4] = { 1.0, 1.0, 1.0, 1.0 };
+   static const GLfloat test_color[4] = { 1.0, 0.0, 0.0, 1.0 };
+   static const GLfloat test_color1[4] = { 0.0, 1.0, 0.0, 1.0 };
+   static const GLfloat test_color2[4] = { 0.0, 0.0, 1.0, 1.0 };
+   GLfloat expected1[4] = { 1.0, 1.0, 0.0, 1.0 };
+   GLfloat expected2[4] = { 1.0, 0.0, 1.0, 1.0 };
+   GLuint prog;
+   int i;
+
+   if (max_ds_buffers > 1) {
+      printf("Test only supports 1 dual source blending color buffer\n");
+      max_ds_buffers = 1;
+   }
+
+   create_fbo();
+
+   glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
+
+   prog = piglit_build_simple_program(vs_text, fs_text);
+   glUseProgram(prog);
+
+   uniform_src0 = glGetUniformLocation(prog, "src0");
+   uniform_src1 = glGetUniformLocation(prog, "src1");
+   uniform_src2 = glGetUniformLocation(prog, "src2");
+
+   blend(test_color, test_color1, test_color2, dest_color);
+   for (i = 0; i < max_ds_buffers; i++) {
+      glReadBuffer(GL_COLOR_ATTACHMENT0_EXT + i);
+      check_error(__LINE__);
+
+      if (!piglit_probe_rect_rgba(0, 0, 10, 10, expected1)) /* cell (0,0) */
+         return PIGLIT_FAIL;
+      if (!piglit_probe_rect_rgba(10, 0, 10, 10, expected2)) /* cell (1,0) */
+         return PIGLIT_FAIL;
+      if (!piglit_probe_rect_rgba(0, 10, 10, 10, expected2)) /* cell (0,1) */
+         return PIGLIT_FAIL;
+      if (!piglit_probe_rect_rgba(10, 10, 10, 10, expected1)) /* cell (1,1) */
+         return PIGLIT_FAIL;
+   }
+
+   return PIGLIT_PASS;
+}
+
+enum piglit_result
+piglit_display(void)
+{
+   /* Should never be reached */
+   return PIGLIT_FAIL;
+}
+
+void
+piglit_init(int argc, char**argv)
+{
+   enum piglit_result result;
+   piglit_ortho_projection(piglit_width, piglit_height, GL_FALSE);
+
+   piglit_require_extension("GL_ARB_blend_func_extended");
+   piglit_require_extension("GL_ARB_explicit_attrib_location");
+
+   glGetIntegerv(GL_MAX_DUAL_SOURCE_DRAW_BUFFERS, &max_ds_buffers);
+
+   result = test();
+   piglit_report_result(result);
+}
+
-- 
1.9.1



More information about the Piglit mailing list