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>