[Piglit] [PATCH 14/16] msaa: Verify accuracy of sRGB MSAA resolves.

Paul Berry stereotype441 at gmail.com
Fri Jun 22 14:54:53 PDT 2012


On 22 June 2012 13:28, Anuj Phogat <anuj.phogat at gmail.com> wrote:

> On Fri, Jun 15, 2012 at 8:32 AM, Paul Berry <stereotype441 at gmail.com>
> wrote:
> > From the GL spec, version 4.2, section 4.1.11 (Additional Multisample
> > Fragment Operations):
> >
> >    If a framebuffer object is not bound, after all operations have
> >    been completed on the multisample buffer, the sample values for
> >    each color in the multisample buffer are combined to produce a
> >    single color value, and that value is written into the
> >    corresponding color buffers selected by DrawBuffer or
> >    DrawBuffers. An implementation may defer the writing of the color
> >    buffers until a later time, but the state of the framebuffer must
> >    behave as if the color buffers were updated as each fragment was
> >    processed. The method of combination is not specified. If the
> >    framebuffer contains sRGB values, then it is recommended that the
> >    an average of sample values is computed in a linearized space, as
> >    for blending (see section 4.1.7).
> >
> > This patch adds a new "srgb" mode to the MSAA accuracy test, which
> > verifies that the formula used by the implementation to blend sRGB
> > samples matches the GL spec's recommendations.  When an "srgb"
> > accuracy test is requested, the test is modified to do the following
> > things:
> >
> > - Render using a buffer format of SRGB8_ALPHA8 instead of RGBA.
> >
> > - When manually downsampling the reference image, enable
> >  FRAMEBUFFER_SRGB, so that the data output by the manual downsampler
> >  gets converted from linear color space into sRGB color space.  This
> >  ensures that the reference image is generated according to the
> >  spec's recommendations.
> >
> > - Convert pixels from sRGB color space to linear color space before
> >  comparing the test image and the reference image.  This ensures that
> >  the RMS error is computed in linear color space, so that the RMS
> >  error computed for sRGB mode is comparable with the RMS error
> >  computed for linear RGBA color.
>
> This test fails on NVIDIA's proprietary drivers. Here is the output i see
> for
> different sample counts: http://pastebin.com/p6XAUAX0
>

Sorry, I should have explained this in the commit message.  nVidia's linux
driver, as near as I can tell, does not follow the GL spec's
recommendations when it comes to sRGB MSAA.  Instead of doing sRGB-correct
blending for sRGB buffers, and linear blending for non-sRGB buffers,
nVidia's linux driver appears to do sRGB-correct blending when blitting to
a window on the screen, and linear blending when blitting to an fbo.
Technically, the nVidia driver isn't in violation of the spec, since
sRGB-correct blending is only a recommendation, not a requirement, but I
figured it would be reasonable to make the test agree with the spec's
recommendations.

For more information see the email discussion "Looking for advice on how
MSAA should behave under sRGB" on the Mesa mailing list.

I'll add more information to the commit message.


>
> > ---
> >  tests/all.tests                                    |    2 +-
> >  .../spec/ext_framebuffer_multisample/accuracy.cpp  |    3 +
> >  tests/spec/ext_framebuffer_multisample/common.cpp  |   55
> ++++++++++++++++---
> >  tests/spec/ext_framebuffer_multisample/common.h    |    7 ++-
> >  4 files changed, 55 insertions(+), 12 deletions(-)
> >
> > diff --git a/tests/all.tests b/tests/all.tests
> > index 2a636f3..755eace 100644
> > --- a/tests/all.tests
> > +++ b/tests/all.tests
> > @@ -1333,7 +1333,7 @@
> ext_framebuffer_multisample['renderbuffer-samples'] =
> concurrent_test('ext_frame
> >  ext_framebuffer_multisample['samples'] =
> concurrent_test('ext_framebuffer_multisample-samples')
> >
> >  for num_samples in MSAA_SAMPLE_COUNTS:
> > -        for test_type in ('color', 'stencil_draw', 'stencil_resolve',
> > +        for test_type in ('color', 'srgb', 'stencil_draw',
> 'stencil_resolve',
> >                           'depth_draw', 'depth_resolve'):
> >                 for options in power_set(('small', 'depthstencil')):
> >                         test_name = ' '.join(['accuracy',
> str(num_samples), test_type]
> > diff --git a/tests/spec/ext_framebuffer_multisample/accuracy.cpp
> b/tests/spec/ext_framebuffer_multisample/accuracy.cpp
> > index 1b7ac1c..0462db0 100644
> > --- a/tests/spec/ext_framebuffer_multisample/accuracy.cpp
> > +++ b/tests/spec/ext_framebuffer_multisample/accuracy.cpp
> > @@ -56,6 +56,7 @@ print_usage_and_exit(char *prog_name)
> >        printf("Usage: %s <num_samples> <test_type> [options]\n"
> >               "  where <test_type> is one of:\n"
> >               "    color: test downsampling of color buffer\n"
> > +              "    srgb: test downsampling of srgb color buffer\n"
> >               "    stencil_draw: test drawing using MSAA stencil
> buffer\n"
> >               "    stencil_resolve: test resolve of MSAA stencil
> buffer\n"
> >               "    depth_draw: test drawing using MSAA depth buffer\n"
> > @@ -105,6 +106,8 @@ piglit_init(int argc, char **argv)
> >        test_type_enum test_type;
> >        if (strcmp(argv[2], "color") == 0) {
> >                test_type = TEST_TYPE_COLOR;
> > +       } else if (strcmp(argv[2], "srgb") == 0) {
> > +               test_type = TEST_TYPE_SRGB;
> >        } else if (strcmp(argv[2], "stencil_draw") == 0) {
> >                test_type = TEST_TYPE_STENCIL_DRAW;
> >        } else if (strcmp(argv[2], "stencil_resolve") == 0) {
> > diff --git a/tests/spec/ext_framebuffer_multisample/common.cpp
> b/tests/spec/ext_framebuffer_multisample/common.cpp
> > index e1060a8..c211363 100644
> > --- a/tests/spec/ext_framebuffer_multisample/common.cpp
> > +++ b/tests/spec/ext_framebuffer_multisample/common.cpp
> > @@ -342,7 +342,8 @@ DownsampleProg::compile(int supersample_factor)
> >  }
> >
> >  void
> > -DownsampleProg::run(const Fbo *src_fbo, int dest_width, int dest_height)
> > +DownsampleProg::run(const Fbo *src_fbo, int dest_width, int dest_height,
> > +                   bool srgb)
> >  {
> >        float w = dest_width;
> >        float h = dest_height;
> > @@ -363,7 +364,15 @@ DownsampleProg::run(const Fbo *src_fbo, int
> dest_width, int dest_height)
> >        glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_data), vertex_data,
> >                     GL_STREAM_DRAW);
> >
> > +       if (srgb) {
> > +               /* If we're testing sRGB color, instruct OpenGL to
> > +                * convert the output of the fragment shader from
> > +                * linear color space to sRGB color space.
> > +                */
> > +               glEnable(GL_FRAMEBUFFER_SRGB);
> > +       }
> >        glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, (void *) 0);
> > +       glDisable(GL_FRAMEBUFFER_SRGB);
> >  }
> >
> >  void
> > @@ -1156,11 +1165,12 @@ Stats::is_better_than(double rms_error_threshold)
> >  }
> >
> >  Test::Test(TestPattern *pattern, ManifestProgram *manifest_program,
> > -          bool test_resolve, GLbitfield blit_type)
> > +          bool test_resolve, GLbitfield blit_type, bool srgb)
> >        : pattern(pattern),
> >          manifest_program(manifest_program),
> >          test_resolve(test_resolve),
> > -         blit_type(blit_type)
> > +         blit_type(blit_type),
> > +         srgb(srgb)
> >  {
> >  }
> >
> > @@ -1176,6 +1186,8 @@ Test::init(int num_samples, bool small, bool
> combine_depth_stencil,
> >        FboConfig test_fbo_config(0,
> >                                  small ? 16 : pattern_width,
> >                                  small ? 16 : pattern_height);
> > +       if (srgb)
> > +               test_fbo_config.color_internalformat = GL_SRGB8_ALPHA8;
> >        test_fbo_config.combine_depth_stencil = combine_depth_stencil;
> >        test_fbo.setup(test_fbo_config);
> >
> > @@ -1235,7 +1247,7 @@ Test::downsample_color(int downsampled_width, int
> downsampled_height)
> >        downsample_fbo.set_viewport();
> >        downsample_prog.run(&supersample_fbo,
> >                            downsample_fbo.config.width,
> > -                           downsample_fbo.config.height);
> > +                           downsample_fbo.config.height, srgb);
> >  }
> >
> >  /**
> > @@ -1371,6 +1383,20 @@ Test::draw_reference_image()
> >  }
> >
> >  /**
> > + * Convert from sRGB color space to linear color space, using the
> > + * formula from the GL 3.0 spec, section 4.1.8 (sRGB Texture Color
> > + * Conversion).
> > + */
> > +float
> > +decode_srgb(float x)
> > +{
> > +       if (x <= 0.0405)
> > +               return x / 12.92;
> > +       else
> > +               return pow((x + 0.055) / 1.055, 2.4);
> > +}
> > +
> > +/**
> >  * Measure the accuracy of MSAA downsampling.  Pixels that are fully
> >  * on or off in the reference image are required to be fully on or off
> >  * in the test image.  Pixels that are not fully on or off in the
> > @@ -1403,6 +1429,14 @@ Test::measure_accuracy()
> >                                int pixel_pos = 4*(y*pattern_width + x) +
> c;
> >                                float ref = reference_data[pixel_pos];
> >                                float test = test_data[pixel_pos];
> > +                               /* When testing sRGB, compare pixels
> > +                                * linearly so that the measured error
> > +                                * is comparable to the non-sRGB case.
> > +                                */
> > +                               if (srgb && c < 3) {
> > +                                       ref = decode_srgb(ref);
> > +                                       test = decode_srgb(test);
> > +                               }
> >                                if (ref <= 0.0)
> >                                        unlit_stats.record(test - ref);
> >                                else if (ref >= 1.0)
> > @@ -1464,29 +1498,32 @@ create_test(test_type_enum test_type, int
> n_samples, bool small,
> >        Test *test = NULL;
> >        switch (test_type) {
> >        case TEST_TYPE_COLOR:
> > -               test = new Test(new Triangles(), NULL, false, 0);
> > +               test = new Test(new Triangles(), NULL, false, 0, false);
> > +               break;
> > +       case TEST_TYPE_SRGB:
> > +               test = new Test(new Triangles(), NULL, false, 0, true);
> >                break;
> >        case TEST_TYPE_STENCIL_DRAW:
> >                test = new Test(new StencilSunburst(),
> >                                new ManifestStencil(),
> > -                               false, 0);
> > +                               false, 0, false);
> >                break;
> >        case TEST_TYPE_STENCIL_RESOLVE:
> >                test = new Test(new StencilSunburst(),
> >                                new ManifestStencil(),
> >                                true,
> > -                               GL_STENCIL_BUFFER_BIT);
> > +                               GL_STENCIL_BUFFER_BIT, false);
> >                break;
> >        case TEST_TYPE_DEPTH_DRAW:
> >                test = new Test(new DepthSunburst(),
> >                                new ManifestDepth(),
> > -                               false, 0);
> > +                               false, 0, false);
> >                break;
> >        case TEST_TYPE_DEPTH_RESOLVE:
> >                test = new Test(new DepthSunburst(),
> >                                new ManifestDepth(),
> >                                true,
> > -                               GL_DEPTH_BUFFER_BIT);
> > +                               GL_DEPTH_BUFFER_BIT, false);
> >                break;
> >        default:
> >                printf("Unrecognized test type\n");
> > diff --git a/tests/spec/ext_framebuffer_multisample/common.h
> b/tests/spec/ext_framebuffer_multisample/common.h
> > index e7cc9b7..a248dbc 100644
> > --- a/tests/spec/ext_framebuffer_multisample/common.h
> > +++ b/tests/spec/ext_framebuffer_multisample/common.h
> > @@ -31,6 +31,7 @@
> >
> >  enum test_type_enum {
> >        TEST_TYPE_COLOR,
> > +       TEST_TYPE_SRGB,
> >        TEST_TYPE_STENCIL_DRAW,
> >        TEST_TYPE_STENCIL_RESOLVE,
> >        TEST_TYPE_DEPTH_DRAW,
> > @@ -139,7 +140,8 @@ class DownsampleProg
> >  {
> >  public:
> >        void compile(int supersample_factor);
> > -       void run(const Fbo *src_fbo, int dest_width, int dest_height);
> > +       void run(const Fbo *src_fbo, int dest_width, int dest_height,
> > +                bool srgb);
> >
> >  private:
> >        GLint prog;
> > @@ -424,7 +426,7 @@ class Test
> >  {
> >  public:
> >        Test(TestPattern *pattern, ManifestProgram *manifest_program,
> > -            bool test_resolve, GLbitfield blit_type);
> > +            bool test_resolve, GLbitfield blit_type, bool srgb);
> >        void init(int num_samples, bool small, bool combine_depth_stencil,
> >                  int pattern_width, int pattern_height,
> >                  int supersample_factor);
> > @@ -497,6 +499,7 @@ private:
> >        int pattern_width;
> >        int pattern_height;
> >        int supersample_factor;
> > +       bool srgb;
> >        DownsampleProg downsample_prog;
> >  };
> >
> > --
> > 1.7.7.6
> >
> > _______________________________________________
> > Piglit mailing list
> > Piglit at lists.freedesktop.org
> > http://lists.freedesktop.org/mailman/listinfo/piglit
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/piglit/attachments/20120622/30cd2da5/attachment-0001.html>


More information about the Piglit mailing list