On 22 June 2012 13:28, Anuj Phogat <span dir="ltr"><<a href="mailto:anuj.phogat@gmail.com" target="_blank">anuj.phogat@gmail.com</a>></span> wrote:<br><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

<div><div>On Fri, Jun 15, 2012 at 8:32 AM, Paul Berry <<a href="mailto:stereotype441@gmail.com" target="_blank">stereotype441@gmail.com</a>> wrote:<br>
> From the GL spec, version 4.2, section 4.1.11 (Additional Multisample<br>
> Fragment Operations):<br>
><br>
>    If a framebuffer object is not bound, after all operations have<br>
>    been completed on the multisample buffer, the sample values for<br>
>    each color in the multisample buffer are combined to produce a<br>
>    single color value, and that value is written into the<br>
>    corresponding color buffers selected by DrawBuffer or<br>
>    DrawBuffers. An implementation may defer the writing of the color<br>
>    buffers until a later time, but the state of the framebuffer must<br>
>    behave as if the color buffers were updated as each fragment was<br>
>    processed. The method of combination is not specified. If the<br>
>    framebuffer contains sRGB values, then it is recommended that the<br>
>    an average of sample values is computed in a linearized space, as<br>
>    for blending (see section 4.1.7).<br>
><br>
> This patch adds a new "srgb" mode to the MSAA accuracy test, which<br>
> verifies that the formula used by the implementation to blend sRGB<br>
> samples matches the GL spec's recommendations.  When an "srgb"<br>
> accuracy test is requested, the test is modified to do the following<br>
> things:<br>
><br>
> - Render using a buffer format of SRGB8_ALPHA8 instead of RGBA.<br>
><br>
> - When manually downsampling the reference image, enable<br>
>  FRAMEBUFFER_SRGB, so that the data output by the manual downsampler<br>
>  gets converted from linear color space into sRGB color space.  This<br>
>  ensures that the reference image is generated according to the<br>
>  spec's recommendations.<br>
><br>
> - Convert pixels from sRGB color space to linear color space before<br>
>  comparing the test image and the reference image.  This ensures that<br>
>  the RMS error is computed in linear color space, so that the RMS<br>
>  error computed for sRGB mode is comparable with the RMS error<br>
>  computed for linear RGBA color.<br>
<br>
</div></div>This test fails on NVIDIA's proprietary drivers. Here is the output i see for<br>
different sample counts: <a href="http://pastebin.com/p6XAUAX0" target="_blank">http://pastebin.com/p6XAUAX0</a><br></blockquote><div><br>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.<br>
<br>For more information see the email discussion "Looking for advice on how MSAA should behave under sRGB" on the Mesa mailing list.<br><br>I'll add more information to the commit message.<br> </div><blockquote class="gmail_quote" style="margin:0pt 0pt 0pt 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">


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