[Mesa-dev] [PATCH 1/3] meta: Implement sensible behavior for BlitFramebuffer with sRGB.

Christoph Bumiller e0425955 at student.tuwien.ac.at
Wed Aug 1 02:59:50 PDT 2012


On 01.08.2012 07:52, Kenneth Graunke wrote:
> On 07/31/2012 06:04 PM, Eric Anholt wrote:
>> Prior to GL 4.2 spec, there was no guidance on how to implement
>> BlitFramebuffer for sRGB.  Mesa chose to implement skipping decode and encode,
>> providing a reasonable behavior for sRGB -> sRGB or RGB -> RGB, but providing
>> something absurd for mixing and matching the two.
>>
>> In GL 4.2, some text appeared in the spec saying to skip decode (search for
>> "no linearization").  The only non-absurd interpretation of that would be to
>> have no encode (same as Mesa's current implementation), otherwise sRGB -> sRGB
>> blits wouldn't work.
>>
>> However, it seems clear that you should be able to blit sRGB to RGB and RGB to
>> sRGB and get appropriate conversion.  The ARB has been discussing the issue,
>> and appears to agree.  So, instead implement the same behavior as gallium, and
>> always do the decode if the texture is sRGB, and do the encode if the
>> application asked for it.
>>

I was just about to revert that patch (gallium: specify resource_resolve
destination via a pipe_surface), because it does not match the behaviour
of the NVIDIA binary driver, and I discovered that I accidentally had
sRGB decode disabled (by previously unidentified not-set bit in sampler
state I didn't see the blob set for resolve), so disabling sRGB encode
(which is what the app has set) counter-acted that and made rendering
look correct.
If fix the decode setting AND honor the write setting, I get wrong
results again.

That is, an sRGB -> sRGB blit should never change the values, regardless
of the setting of GL_FRAMEBUFFER_SRGB.

EXT_framebuffer_sRGB suggests that only drawing (i.e. where you have
blending) should be affected:

Should sRGB framebuffer support affect the pixel path?

        RESOLVED:  No.

        sRGB conversion only applies to color reads for blending and
        color writes.  Color reads for glReadPixels, glCopyPixels,
        or glAccum have no sRGB conversion applied.

>> Breaks piglit fbo-srgb-blit, which was expecting our previous no-conversion
>> behavior.
>> ---
>>  src/mesa/drivers/common/meta.c |   14 +++++---------
>>  1 file changed, 5 insertions(+), 9 deletions(-)
>>
>> diff --git a/src/mesa/drivers/common/meta.c b/src/mesa/drivers/common/meta.c
>> index 6846bbc..e35f0c8 100644
>> --- a/src/mesa/drivers/common/meta.c
>> +++ b/src/mesa/drivers/common/meta.c
>> @@ -1357,7 +1357,6 @@ blitframebuffer_texture(struct gl_context *ctx,
>>           const GLenum wrapSSave = texObj->Sampler.WrapS;
>>           const GLenum wrapTSave = texObj->Sampler.WrapT;
>>           const GLenum srgbSave = texObj->Sampler.sRGBDecode;
>> -         const GLenum fbo_srgb_save = ctx->Color.sRGBEnabled;
>>           const GLenum target = texObj->Target;
>>  
>>           if (drawAtt->Texture == readAtt->Texture) {
>> @@ -1390,14 +1389,14 @@ blitframebuffer_texture(struct gl_context *ctx,
>>           _mesa_TexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
>>           _mesa_TexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
>>  
>> -	 /* Always do our blits with no sRGB decode or encode.*/
>> +	 /* Always do sRGB decode on the read, and do sRGB encode on the write
>> +          * if we've been asked to on this framebuffer by leaving
>> +          * GL_FRAMEBUFFER_SRGB in place.
>> +          */
>>  	 if (ctx->Extensions.EXT_texture_sRGB_decode) {
>>  	    _mesa_TexParameteri(target, GL_TEXTURE_SRGB_DECODE_EXT,
>> -				GL_SKIP_DECODE_EXT);
>> +				GL_DECODE_EXT);
>>  	 }
> 
> Wait, won't this "break" sRGB -> sRGB blits?
> 
> I guess I'd expect that:
> 
> 1. Blitting from a RGBA source to an RGBA destination should be an exact
> copy: no decoding/encoding should occur, regardless of any enable bits.
> 
> 2. Blitting from an sRGBA source to an sRGBA destination should also be
> an exact copy---both buffers should then contain the same pixel values.
> 
> These seem pretty clear, and also match Mesa's current behavior.
> 
> With your patch, if an application had set GL_FRAMEBUFFER_SRGB_EXT to
> GL_TRUE, then I believe case 2 would result in the two buffers having
> different values: non-decoded source values would get encoded.
> 
> One could argue that such an application is being stupid, but honestly
> as confusing as these specs are, I don't know what stupid is anymore.
> 
> I feel like blits should follow these rules for mixed formats:
> 
> 3. Blitting from an sRGBA source to an RGBA destination should
> optionally decode the values based on whether the application has set
> GL_TEXTURE_SRGB_DECODE_EXT to GL_DECODE_EXT or GL_SKIP_DECODE_EXT.  The
> other knob, GL_FRAMEBUFFER_SRGB_EXT, should be ignored since it controls
> writes and the destination is an ordinary format (RGBA).
> 
> 4. Blitting from an RGBA source to an sRGBA destination should
> optionally encode the values based on whether the application has set
> GL_FRAMEBUFFER_SRGB_EXT to true or false.  The other knob,
> GL_TEXTURE_SRGB_DECODE_EXT, should be ignored since it controls
> reads/texturing and the source is not an sRGB format.
> 
> These four rules allow you to copy SRGB->SRGB and RGB->RGB unmodified,
> while also allowing you to decode SRGB values into a linear buffer, or
> encode linear values into an SRGB buffer.  That seems like it covers all
> the cases anyone would want to do.
> 
>> -         if (ctx->Extensions.EXT_framebuffer_sRGB) {
>> -            _mesa_set_enable(ctx, GL_FRAMEBUFFER_SRGB_EXT, GL_FALSE);
>> -         }
>>  
>>           _mesa_TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
>>           _mesa_set_enable(ctx, target, GL_TRUE);
>> @@ -1463,9 +1462,6 @@ blitframebuffer_texture(struct gl_context *ctx,
>>  	 if (ctx->Extensions.EXT_texture_sRGB_decode) {
>>  	    _mesa_TexParameteri(target, GL_TEXTURE_SRGB_DECODE_EXT, srgbSave);
>>  	 }
>> -	 if (ctx->Extensions.EXT_framebuffer_sRGB && fbo_srgb_save) {
>> -	    _mesa_set_enable(ctx, GL_FRAMEBUFFER_SRGB_EXT, GL_TRUE);
>> -	 }
>>  
>>           /* Done with color buffer */
>>           mask &= ~GL_COLOR_BUFFER_BIT;
>>
> 
> Regardless of what we decide to do here, I also wonder if any updates
> are necessary to the i965 BLT or blorp code.  meta blits are the last
> resort in i965, and I definitely saw different behavior in L4D2 by
> commenting out the BLT and blorp and only using meta.
> 
> We should at least make sure that BLT/blorp either follow the same rules
> as meta, or refuse to blit in these cases.
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/mesa-dev



More information about the mesa-dev mailing list