[Piglit] [PATCH 2/2] multisample/formats: Check for spec-complient integer resolves

Matt Turner mattst88 at gmail.com
Tue May 10 21:42:03 UTC 2016


On Wed, May 4, 2016 at 4:23 PM, Jason Ekstrand <jason at jlekstrand.net> wrote:
> The i965 driver has historically done integer multisample resolves with a
> sort of integer averaging operation.  The spec used to not really say
> anything at all about integer formats when discussing multisampling.  Since
> the tests were written, the spec has been substantially clerified.  The new
> rule is that integer MSAA resolves are supposed to pick a single arbitrary
> sample for each texel rather than trying to combine them in any way.
>
> Signed-off-by: Jason Ekstrand <jason at jlekstrand.net>
> ---
>  tests/spec/ext_framebuffer_multisample/formats.cpp | 196 ++++++++++++++++-----
>  1 file changed, 155 insertions(+), 41 deletions(-)
>
> diff --git a/tests/spec/ext_framebuffer_multisample/formats.cpp b/tests/spec/ext_framebuffer_multisample/formats.cpp
> index 4b1feba..1024b45 100644
> --- a/tests/spec/ext_framebuffer_multisample/formats.cpp
> +++ b/tests/spec/ext_framebuffer_multisample/formats.cpp
> @@ -70,6 +70,44 @@ ColorGradientSunburst *test_pattern_vec4;
>  ColorGradientSunburst *test_pattern_ivec4;
>  ColorGradientSunburst *test_pattern_uvec4;
>
> +struct int_resolve_check_s {
> +       GLuint prog;
> +       GLint u_resolve;
> +       GLint u_msaa;
> +       GLint u_samples;
> +} int_resolve_check;
> +
> +const char int_resolve_check_vs[] =
> +       "#version 130\n"
> +       "in vec4 piglit_vertex;\n"
> +       "void main() {\n"
> +       "       gl_Position = piglit_vertex;\n"
> +       "}\n";
> +
> +/* The OpenGL ES 3.2 and OpenGL 4.4 specs both state:
> + *
> + *     "If the source for- mats are integer types or stencil values, a

formats

> + *     single sample’s value is selected for each pixel."

smart quote

> + *
> + * This shader checks exactly that condition, namely that the result of the
> + * resolve is exactly one of the sample values in the original image.
> + */
> +const char int_resolve_check_fs[] =
> +       "#version 130\n"
> +       "#extension GL_ARB_texture_multisample: require\n"
> +       "uniform isampler2DMS msaa;\n"
> +       "uniform isampler2D resolve;\n"
> +       "uniform int samples;\n"
> +       "void main() {\n"
> +       "       gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n"
> +       "       const vec4 green = vec4(0.0, 1.0, 0.0, 1.0);\n"
> +       "       ivec2 pos = ivec2(gl_FragCoord.xy);\n"
> +       "       ivec4 res = texelFetch(resolve, pos, 0);\n"
> +       "       for (int s = 0; s < samples; s++) {\n"
> +       "               if (res == texelFetch(msaa, pos, s))\n"
> +       "                       gl_FragColor = green;\n"

Could break here

> +       "       }\n"
> +       "}\n";
>
>  /**
>   * This class encapsulates the code necessary to draw the test pattern
> @@ -80,7 +118,7 @@ ColorGradientSunburst *test_pattern_uvec4;
>  class PatternRenderer
>  {
>  public:
> -       bool try_setup(GLenum internalformat);
> +       bool try_setup(GLenum internalformat, bool is_integer);
>         void set_piglit_tolerance();
>         void set_color_clamping_mode();
>         void draw();
> @@ -140,11 +178,18 @@ public:
>   * incomplete.
>   */
>  bool
> -PatternRenderer::try_setup(GLenum internalformat)
> +PatternRenderer::try_setup(GLenum internalformat, bool is_integer)
>  {
>         FboConfig config_downsampled(0, pattern_width, pattern_height);
>         config_downsampled.color_internalformat = internalformat;
>
> +       if (is_integer) {
> +               config_downsampled.color_format = GL_RGBA_INTEGER;
> +               config_downsampled.num_rb_attachments = 0;
> +               config_downsampled.num_tex_attachments = 1;
> +               config_downsampled.use_rect = false;
> +       }
> +
>         FboConfig config_msaa = config_downsampled;
>         config_msaa.num_samples = num_samples;
>
> @@ -497,7 +542,9 @@ test_format(const struct format_desc *format)
>          * supported, we might have received a GL error.  In either
>          * case just skip to the next format.
>          */
> -       bool setup_success = test_renderer.try_setup(format->internalformat);
> +       bool is_integer = (test_sets[test_index].basetype == GL_INT);
> +       bool setup_success = test_renderer.try_setup(format->internalformat,
> +                                                    is_integer);
>         if (glGetError() != GL_NO_ERROR) {
>                 printf("Error setting up test renderbuffers\n");
>                 return PIGLIT_SKIP;
> @@ -511,7 +558,8 @@ test_format(const struct format_desc *format)
>          * This shouldn't fail.
>          */
>         setup_success = ref_renderer.try_setup(test_renderer.is_srgb ?
> -                                              GL_SRGB8_ALPHA8 : GL_RGBA);
> +                                              GL_SRGB8_ALPHA8 : GL_RGBA,
> +                                              false);
>         if (!piglit_check_gl_error(GL_NO_ERROR)) {
>                 printf("Error setting up reference renderbuffers\n");
>                 return PIGLIT_FAIL;
> @@ -521,50 +569,99 @@ test_format(const struct format_desc *format)
>                 return PIGLIT_FAIL;
>         }
>
> -       /* Draw test and reference images, and read them into memory */
> -       test_renderer.set_piglit_tolerance();
>         test_renderer.draw();
>         float *test_image =
>                 test_renderer.read_image(format->base_internal_format);
> -       ref_renderer.draw();
> -       float *ref_image = ref_renderer.read_image(GL_RGBA);
> -
> -       /* Compute the expected image from the reference image */
> -       float *expected_image =
> -               compute_expected_image(ref_image,
> -                                      format->base_internal_format);
> -
> -       /* Check that the test image was correct */
> -       unsigned num_components =
> -               piglit_num_components(format->base_internal_format);
> -       float tolerance[4];
> -       piglit_compute_probe_tolerance(format->base_internal_format,
> -                                      tolerance);
> -       pass = piglit_compare_images_color(0, 0, pattern_width, pattern_height,
> -                                          num_components, tolerance,
> -                                          expected_image, test_image);
> -
> -
> -       /* Show both the test and expected images on screen so that
> -        * the user can diagnose problems. Pass image_count = 0 to
> -        * display image without any offset applied to raster position.
> -        */
> -       glViewport(0, 0, piglit_width, piglit_height);
> -       piglit_visualize_image(test_image, format->base_internal_format,
> -                              pattern_width, pattern_height,
> -                              0 /* image_count */,
> -                              false /* rhs */);
> -       piglit_visualize_image(expected_image, format->base_internal_format,
> -                              pattern_width, pattern_height,
> -                              0 /* image_count */,
> -                              true /* rhs */);
> +
> +       if (is_integer) {
> +               Fbo compare_fbo;
> +               compare_fbo.setup(FboConfig(0, pattern_width, pattern_height));
> +
> +               glBindFramebuffer(GL_DRAW_FRAMEBUFFER, compare_fbo.handle);
> +
> +               glUseProgram(int_resolve_check.prog);
> +               glUniform1i(int_resolve_check.u_msaa, 0);
> +               glUniform1i(int_resolve_check.u_resolve, 1);
> +               glUniform1i(int_resolve_check.u_samples, num_samples);
> +
> +               glActiveTexture(GL_TEXTURE0);
> +               glBindTexture(GL_TEXTURE_2D_MULTISAMPLE,
> +                             test_renderer.fbo_msaa.color_tex[0]);
> +
> +               glActiveTexture(GL_TEXTURE1);
> +               glBindTexture(GL_TEXTURE_2D,
> +                             test_renderer.fbo_downsampled.color_tex[0]);
> +
> +               glViewport(0, 0, pattern_width, pattern_height);
> +               piglit_draw_rect(-1.0, -1.0, 2.0, 2.0);
> +
> +               glBindFramebuffer(GL_READ_FRAMEBUFFER, compare_fbo.handle);
> +
> +               const float green[] = { 0.0, 1.0, 0.0, 1.0 };
> +               pass = piglit_probe_rect_rgb(0, 0, pattern_width,
> +                                            pattern_height, green);
> +
> +               /* Show both the test image and the check result on screen
> +                * so that the user can diagnose problems.
> +                */
> +               glViewport(0, 0, piglit_width, piglit_height);
> +               piglit_visualize_image(test_image, format->base_internal_format,
> +                                      pattern_width, pattern_height,
> +                                      0 /* image_count */,
> +                                      false /* rhs */);
> +
> +               glBindFramebuffer(GL_READ_FRAMEBUFFER, compare_fbo.handle);
> +               glBindFramebuffer(GL_DRAW_FRAMEBUFFER, piglit_winsys_fbo);
> +               glBlitFramebuffer(0, 0, pattern_width, pattern_height,
> +                                 pattern_width, 0,
> +                                 pattern_width * 2, pattern_height,
> +                                 GL_COLOR_BUFFER_BIT, GL_NEAREST);
> +       } else {
> +               /* Draw test and reference images, and read them into memory */
> +               test_renderer.set_piglit_tolerance();
> +               ref_renderer.draw();
> +               float *ref_image = ref_renderer.read_image(GL_RGBA);
> +
> +               /* Compute the expected image from the reference image */
> +               float *expected_image =
> +                       compute_expected_image(ref_image,
> +                                              format->base_internal_format);
> +
> +               /* Check that the test image was correct */
> +               unsigned num_components =
> +                       piglit_num_components(format->base_internal_format);
> +               float tolerance[4];
> +               piglit_compute_probe_tolerance(format->base_internal_format,
> +                                              tolerance);
> +               pass = piglit_compare_images_color(0, 0, pattern_width,
> +                                                  pattern_height,
> +                                                  num_components, tolerance,
> +                                                  expected_image, test_image);
> +
> +
> +               /* Show both the test and expected images on screen so that
> +                * the user can diagnose problems. Pass image_count = 0 to
> +                * display image without any offset applied to raster position.
> +                */
> +               glViewport(0, 0, piglit_width, piglit_height);
> +               piglit_visualize_image(test_image, format->base_internal_format,
> +                                      pattern_width, pattern_height,
> +                                      0 /* image_count */,
> +                                      false /* rhs */);
> +               piglit_visualize_image(expected_image,
> +                                      format->base_internal_format,
> +                                      pattern_width, pattern_height,
> +                                      0 /* image_count */,
> +                                      true /* rhs */);
> +
> +               free(ref_image);
> +               free(expected_image);
> +       }
>
>         /* Finally, if any error occurred, count that as a failure. */
>         pass = piglit_check_gl_error(GL_NO_ERROR) && pass;
>
>         free(test_image);
> -       free(ref_image);
> -       free(expected_image);
>
>         return pass ? PIGLIT_PASS : PIGLIT_FAIL;
>  }
> @@ -613,13 +710,30 @@ piglit_init(int argc, char **argv)
>
>         fbo_formats_init_test_set(test_set,
>                                   GL_TRUE /* print_options */);
> +
> +       bool is_integer = (test_sets[test_index].basetype == GL_INT);
> +
>         test_pattern_vec4 = new ColorGradientSunburst(GL_UNSIGNED_NORMALIZED);
>         test_pattern_vec4->compile();
> -       if (piglit_get_gl_version() >= 30) {
> +       if (is_integer) {
> +               piglit_require_gl_version(30);
> +               piglit_require_extension("GL_ARB_texture_multisample");
> +
>                 test_pattern_ivec4 = new ColorGradientSunburst(GL_INT);
>                 test_pattern_ivec4->compile();
>                 test_pattern_uvec4 = new ColorGradientSunburst(GL_UNSIGNED_INT);
>                 test_pattern_uvec4->compile();
> +
> +               int_resolve_check.prog =
> +                       piglit_build_simple_program(int_resolve_check_vs,
> +                                                   int_resolve_check_fs);
> +               glUseProgram(int_resolve_check.prog);
> +               int_resolve_check.u_resolve =
> +                       glGetUniformLocation(int_resolve_check.prog, "resolve");
> +               int_resolve_check.u_msaa =
> +                       glGetUniformLocation(int_resolve_check.prog, "msaa");
> +               int_resolve_check.u_samples =
> +                       glGetUniformLocation(int_resolve_check.prog, "samples");
>         }
>  }
>
> --

Both are

Reviewed-by: Matt Turner <mattst88 at gmail.com>


More information about the Piglit mailing list