This is similar to ext_framebuffer_multisample-fast-clear except that
it tests a regular single-sampled texture. This is worth testing at
least on i965 because fast clears are handled differently when
multisampling is not used.
---
 tests/all.py                |   5 +
 tests/fbo/CMakeLists.gl.txt |   1 +
 tests/fbo/fbo-fast-clear.c  | 401 ++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 407 insertions(+)
 create mode 100644 tests/fbo/fbo-fast-clear.c

diff --git a/tests/all.py b/tests/all.py
index 07e3599..f5252f4 100644
--- a/tests/all.py
+++ b/tests/all.py
@@ -135,6 +135,8 @@ def add_fbo_formats_tests(adder, extension, suffix=''):
               'fbo-alphatest-formats{}'.format(suffix))
         adder(['fbo-colormask-formats', extension],
               'fbo-colormask-formats{}'.format(suffix))
+        adder(['fbo-fast-clear', extension],
+              'fbo-fast-clear{}'.format(suffix))
 
 
 def add_msaa_formats_tests(adder, extension):
@@ -2911,6 +2913,7 @@ with profile.group_manager(
     g(['fbo-drawbuffers-blend-add'])
     g(['fbo-drawbuffers-fragcolor'])
     g(['fbo-drawbuffers-maxtargets'])
+    g(['fbo-fast-clear'])
     g(['fbo-finish-deleted'])
     g(['fbo-flushing'])
     g(['fbo-flushing-2'])
@@ -3237,6 +3240,8 @@ with profile.group_manager(
     #   'fbo-blending-formats')
     g(['fbo-alphatest-formats', 'GL_EXT_texture_sRGB'],
       'fbo-alphatest-formats')
+    g(['fbo-fast-clear', 'GL_EXT_texture_sRGB'],
+      'fbo-fast-clear')
     add_msaa_formats_tests(g, 'GL_EXT_texture_sRGB')
     add_texwrap_format_tests(g, 'GL_EXT_texture_sRGB')
     add_texwrap_format_tests(g, 'GL_EXT_texture_sRGB-s3tc', '-s3tc')
diff --git a/tests/fbo/CMakeLists.gl.txt b/tests/fbo/CMakeLists.gl.txt
index 0476b10..bd0f7bc 100644
--- a/tests/fbo/CMakeLists.gl.txt
+++ b/tests/fbo/CMakeLists.gl.txt
@@ -43,6 +43,7 @@ piglit_add_executable (fbo-drawbuffers-maxtargets 
fbo-drawbuffers-maxtargets.c)
 piglit_add_executable (fbo-drawbuffers2-blend fbo-drawbuffers2-blend.c)
 piglit_add_executable (fbo-drawbuffers2-colormask fbo-drawbuffers2-colormask.c)
 piglit_add_executable (fbo-draw-buffers-blend fbo-draw-buffers-blend.c)
+piglit_add_executable (fbo-fast-clear fbo-fast-clear.c)
 piglit_add_executable (fbo-finish-deleted fbo-finish-deleted.c)
 piglit_add_executable (fbo-flushing fbo-flushing.c)
 piglit_add_executable (fbo-flushing-2 fbo-flushing-2.c)
diff --git a/tests/fbo/fbo-fast-clear.c b/tests/fbo/fbo-fast-clear.c
new file mode 100644
index 0000000..95c6ebe
--- /dev/null
+++ b/tests/fbo/fbo-fast-clear.c
@@ -0,0 +1,401 @@
+/*
+ * Copyright © 2015 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-fast-clear.c
+ *
+ * Clears a texture with various formats to various different colors
+ * and then samples from it in a shader to ensure that the expected
+ * color is returned. This includes verifying that when there are
+ * components missing they are overriden to the right value (such as
+ * GL_RED should report 0 for green and blue and 1 for the alpha). The
+ * main reason to do this is that the i965 driver has various
+ * different code paths to implement a fast clear optimisation and the
+ * path taken depends on the color chosen to a certain degree.
+ */
+
+#include "piglit-util-gl.h"
+#include "fbo-formats.h"
+
+PIGLIT_GL_TEST_CONFIG_BEGIN
+
+       config.supports_gl_compat_version = 21;
+       config.window_visual = PIGLIT_GL_VISUAL_RGBA | PIGLIT_GL_VISUAL_DOUBLE;
+
+PIGLIT_GL_TEST_CONFIG_END
+
+static const char
+vertex_source[] =
+       "attribute vec4 piglit_vertex;\n"
+       "\n"
+       "void\n"
+       "main()\n"
+       "{\n"
+       "        gl_Position = piglit_vertex;\n"
+       "}\n";
+
+static const char
+fragment_source_float[] =
+       "uniform sampler2D tex;\n"
+       "\n"
+       "void\n"
+       "main()\n"
+       "{\n"
+       "        gl_FragColor = texture2D(tex, vec2(0.5));\n"
+       "}\n";
+
+static const char
+fragment_source_int[] =
+       "#version 130\n"
+       "\n"
+       "uniform isampler2D tex;\n"
+       "\n"
+       "void\n"
+       "main()\n"
+       "{\n"
+       "        gl_FragColor = vec4(texelFetch(tex, ivec2(0), 0)) / 127.0;\n"
+       "}\n";
+
+static const char
+fragment_source_uint[] =
+       "#version 130\n"
+       "\n"
+       "uniform usampler2D tex;\n"
+       "\n"
+       "void\n"
+       "main()\n"
+       "{\n"
+       "        gl_FragColor = vec4(texelFetch(tex, ivec2(0), 0)) / 255.0;\n"
+       "}\n";
+
+static const struct test_desc *
+test_set = &test_sets[0];
+
+static const float
+clear_colors[][4] = {
+       { 0.0f, 0.0f, 0.0f, 0.0f },
+       { 1.0f, 1.0f, 1.0f, 1.0f },
+       { 0.0f, 0.0f, 1.0f, 0.0f },
+       { 1.0f, 0.0f, 0.0f, 1.0f },
+
+       { 0.25f, 0.5f, 0.75f, 1.0f },
+       { 0.75f, 0.5f, 0.25f, 0.0f },
+       { 0.5f, 0.25f, 0.75f, 0.5f },
+};
+
+static GLuint prog_float, prog_int, prog_uint;
+
+static enum piglit_result
+test_color(GLuint fbo,
+          int offset,
+          const struct format_desc *format,
+          GLenum clear_type,
+          const float *clear_color)
+{
+       float expected_color[4];
+       float alpha_override;
+       int i;
+
+       glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+
+       switch (clear_type) {
+       case GL_INT: {
+               GLint clear_color_int[4] = {
+                       clear_color[0] * 127,
+                       clear_color[1] * 127,
+                       clear_color[2] * 127,
+                       clear_color[3] * 127
+               };
+               if (prog_int == 0)
+                       return PIGLIT_SKIP;
+               glUseProgram(prog_int);
+               glClearBufferiv(GL_COLOR,
+                               0, /* draw buffer */
+                               clear_color_int);
+               alpha_override = 1.0f / 127.0f;
+               break;
+       }
+       case GL_UNSIGNED_INT: {
+               GLint clear_color_uint[4] = {
+                       clear_color[0] * 255,
+                       clear_color[1] * 255,
+                       clear_color[2] * 255,
+                       clear_color[3] * 255
+               };
+               if (prog_uint == 0)
+                       return PIGLIT_SKIP;
+               glUseProgram(prog_uint);
+               glClearBufferiv(GL_COLOR,
+                               0, /* draw buffer */
+                               clear_color_uint);
+               alpha_override = 1.0f / 255.0f;
+               break;
+       }
+       default:
+               glUseProgram(prog_float);
+               glClearColor(clear_color[0],
+                            clear_color[1],
+                            clear_color[2],
+                            clear_color[3]);
+               glClear(GL_COLOR_BUFFER_BIT);
+               alpha_override = 1.0f;
+               break;
+       }
+
+       memcpy(expected_color, clear_color, sizeof expected_color);
+
+       switch (format->base_internal_format) {
+       case GL_ALPHA:
+               expected_color[0] = 0.0f;
+               expected_color[1] = 0.0f;
+               expected_color[2] = 0.0f;
+               break;
+       case GL_INTENSITY:
+               expected_color[0] = clear_color[0];
+               expected_color[1] = clear_color[0];
+               expected_color[2] = clear_color[0];
+               expected_color[3] = clear_color[0];
+               break;
+       case GL_LUMINANCE:
+               expected_color[1] = clear_color[0];
+               expected_color[2] = clear_color[0];
+               expected_color[3] = alpha_override;
+               break;
+       case GL_LUMINANCE_ALPHA:
+               expected_color[1] = clear_color[0];
+               expected_color[2] = clear_color[0];
+               break;
+       case GL_RED:
+               expected_color[1] = 0.0f;
+               expected_color[2] = 0.0f;
+               expected_color[3] = alpha_override;
+               break;
+       case GL_RG:
+               expected_color[2] = 0.0f;
+               expected_color[3] = alpha_override;
+               break;
+       case GL_RGB:
+               expected_color[3] = alpha_override;
+               break;
+       }
+
+       if (strstr(format->name, "SRGB") ||
+           strstr(format->name, "SLUMINANCE")) {
+               for (i = 0; i < 3; i++) {
+                       expected_color[i] =
+                               piglit_srgb_to_linear(expected_color[i]);
+               }
+       }
+
+       glBindFramebuffer(GL_FRAMEBUFFER, piglit_winsys_fbo);
+       piglit_draw_rect(offset * 16 * 2.0f / piglit_width - 1.0f,
+                        -1.0f,
+                        16 * 2.0f / piglit_width,
+                        16 * 2.0f / piglit_height);
+       return piglit_probe_rect_rgba(offset * 16, 0, 16, 16,
+                                     expected_color) ?
+               PIGLIT_PASS :
+               PIGLIT_FAIL;
+}
+
+static enum piglit_result
+test_format(const struct format_desc *format)
+{
+       enum piglit_result result = PIGLIT_PASS;
+       enum piglit_result color_result;
+       GLint l_size, i_size, r_size, g_size, b_size, a_size;
+       GLenum type_param;
+       GLint type;
+       GLuint tex;
+       GLuint fbo;
+       int i;
+
+       if (format->internalformat == 3 || format->internalformat == 4)
+               return PIGLIT_SKIP;
+
+       /* Compressed formats aren't supported for multisampling */
+       if (strstr("COMPRESSED", format->name))
+               return PIGLIT_SKIP;
+
+       printf("Testing %s\n", format->name);
+
+       glGenTextures(1, &tex);
+       glBindTexture(GL_TEXTURE_2D, tex);
+
+       glTexParameteri(GL_TEXTURE_2D,
+                       GL_TEXTURE_MAG_FILTER,
+                       GL_NEAREST);
+       glTexParameteri(GL_TEXTURE_2D,
+                       GL_TEXTURE_MIN_FILTER,
+                       GL_NEAREST);
+       glTexParameteri(GL_TEXTURE_2D,
+                       GL_TEXTURE_MAX_LEVEL,
+                       0);
+
+       glTexImage2D(GL_TEXTURE_2D,
+                    0, /* level */
+                    format->internalformat,
+                    128, 128, /* width/height */
+                    0, /* border */
+                    GL_RGBA,
+                    GL_UNSIGNED_BYTE,
+                    NULL /* data */);
+
+       glGetTexLevelParameteriv(GL_TEXTURE_2D, 0,
+                                GL_TEXTURE_LUMINANCE_SIZE, &l_size);
+       glGetTexLevelParameteriv(GL_TEXTURE_2D, 0,
+                                GL_TEXTURE_ALPHA_SIZE, &a_size);
+       glGetTexLevelParameteriv(GL_TEXTURE_2D, 0,
+                                GL_TEXTURE_INTENSITY_SIZE, &i_size);
+       glGetTexLevelParameteriv(GL_TEXTURE_2D, 0,
+                                GL_TEXTURE_RED_SIZE, &r_size);
+       glGetTexLevelParameteriv(GL_TEXTURE_2D, 0,
+                                GL_TEXTURE_GREEN_SIZE, &g_size);
+       glGetTexLevelParameteriv(GL_TEXTURE_2D, 0,
+                                GL_TEXTURE_BLUE_SIZE, &b_size);
+
+       if (l_size > 0)
+               type_param = GL_TEXTURE_LUMINANCE_TYPE;
+       else if (i_size > 0)
+               type_param = GL_TEXTURE_INTENSITY_TYPE;
+       else if (r_size > 0)
+               type_param = GL_TEXTURE_RED_TYPE;
+       else if (a_size > 0)
+               type_param = GL_TEXTURE_ALPHA_TYPE;
+       else {
+               assert(0);
+               type_param = GL_NONE;
+       }
+       glGetTexLevelParameteriv(GL_TEXTURE_2D,
+                                0, /* level */
+                                type_param,
+                                &type);
+
+       switch (format->base_internal_format) {
+       case GL_ALPHA:
+               r_size = g_size = b_size = 8;
+               break;
+       case GL_INTENSITY:
+               r_size = g_size = b_size = a_size = i_size;
+               break;
+       case GL_LUMINANCE:
+               r_size = g_size = b_size = l_size;
+               a_size = 8;
+               break;
+       case GL_LUMINANCE_ALPHA:
+               r_size = g_size = b_size = l_size;
+               break;
+       case GL_RED:
+               g_size = b_size = a_size = 8;
+               break;
+       case GL_RG:
+               b_size = a_size = 8;
+               break;
+       case GL_RGB:
+               a_size = 8;
+               break;
+       }
+
+       /* We can't measure more bits than what the winsys buffer has */
+       r_size = MIN2(r_size, 8);
+       g_size = MIN2(g_size, 8);
+       b_size = MIN2(b_size, 8);
+       a_size = MIN2(a_size, 8);
+
+       piglit_set_tolerance_for_bits(r_size, g_size, b_size, a_size);
+
+       glGenFramebuffers(1, &fbo);
+       glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+       glFramebufferTexture2D(GL_FRAMEBUFFER,
+                              GL_COLOR_ATTACHMENT0,
+                              GL_TEXTURE_2D,
+                              tex,
+                              0);
+       if (glCheckFramebufferStatus(GL_FRAMEBUFFER) ==
+           GL_FRAMEBUFFER_COMPLETE) {
+               for (i = 0; i < ARRAY_SIZE(clear_colors); i++) {
+                       color_result = test_color(fbo, i, format, type,
+                                                 clear_colors[i]);
+                       if (color_result == PIGLIT_SKIP) {
+                               if (result == PIGLIT_PASS)
+                                       result = PIGLIT_SKIP;
+                               break;
+                       } else if (color_result == PIGLIT_FAIL) {
+                               result = PIGLIT_FAIL;
+                       }
+               }
+       } else {
+               printf("FBO not complete\n");
+               result = PIGLIT_SKIP;
+       }
+
+       glDeleteFramebuffers(1, &fbo);
+       glDeleteTextures(1, &tex);
+
+       return result;
+}
+
+enum piglit_result
+piglit_display()
+{
+       return fbo_formats_display(test_format);
+}
+
+static GLuint
+build_program(const char *fragment_source)
+{
+       GLint tex_location;
+       GLuint prog;
+
+       prog = piglit_build_simple_program(vertex_source, fragment_source);
+       glUseProgram(prog);
+       tex_location = glGetUniformLocation(prog, "tex");
+       glUniform1i(tex_location, 0);
+
+       return prog;
+}
+
+void
+piglit_init(int argc, char **argv)
+{
+       int test_set_index = 0;
+       int glsl_major, glsl_minor;
+       bool es;
+
+       if (argc >= 2)
+               test_set_index = fbo_lookup_test_set(argv[1]);
+
+       test_set = test_set + test_set_index;
+
+       fbo_formats_init_test_set(test_set_index,
+                                 GL_TRUE /* print_options */);
+
+       prog_float = build_program(fragment_source_float);
+
+       piglit_get_glsl_version(&es, &glsl_major, &glsl_minor);
+
+       if (!es && (glsl_major > 1 || (glsl_major == 1 && glsl_minor >= 3))) {
+               prog_int = build_program(fragment_source_int);
+               prog_uint = build_program(fragment_source_uint);
+       }
+}
-- 
1.9.3

_______________________________________________
Piglit mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/piglit

Reply via email to