On 25 September 2012 06:53, Brian Paul <span dir="ltr"><<a href="mailto:brianp@vmware.com" target="_blank">brianp@vmware.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 class="HOEnZb"><div class="h5">On 09/24/2012 05:49 PM, Paul Berry wrote:<br>
</div></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div class="h5">
Previously, meta logic was saving and restoring the value of<br>
GL_FRAMEBUFFER_SRGB in an ad-hoc fashion. As a result, it was not<br>
properly disabled and/or restored for some meta operations.<br>
<br>
This patch causes GL_FRAMEBUFFER_SRGB to be saved/restored in the<br>
conventional way of meta-ops (using _mesa_meta_begin() and<br>
_mesa_meta_end()). It is now reliably saved/restored for<br>
_mesa_meta_BlitFramebuffer, _mesa_meta_GenerateMipmap, and<br>
decompress_texture_image, and preserved for all other meta ops.<br>
<br>
Fixes piglit tests "ARB_framebuffer_sRGB/blit renderbuffer<br>
{linear_to_srgb,srgb} scaled {disabled,enabled}".<br>
---<br>
src/mesa/drivers/common/meta.c | 47 ++++++++++++++++++------------<u></u>------------<br>
src/mesa/drivers/common/meta.h | 1 +<br>
2 files changed, 21 insertions(+), 27 deletions(-)<br>
<br>
diff --git a/src/mesa/drivers/common/<u></u>meta.c b/src/mesa/drivers/common/<u></u>meta.c<br>
index 28a79b0..6689337 100644<br>
--- a/src/mesa/drivers/common/<u></u>meta.c<br>
+++ b/src/mesa/drivers/common/<u></u>meta.c<br>
@@ -187,6 +187,9 @@ struct save_state<br>
/** MESA_META_MULTISAMPLE */<br>
GLboolean MultisampleEnabled;<br>
<br>
+ /** MESA_META_FRAMEBUFFER_SRGB */<br>
+ GLboolean sRGBEnabled;<br>
+<br>
/** Miscellaneous (always disabled) */<br>
GLboolean Lighting;<br>
GLboolean RasterDiscard;<br>
@@ -773,6 +776,12 @@ _mesa_meta_begin(struct gl_context *ctx, GLbitfield state)<br>
_mesa_set_multisample(ctx, GL_FALSE);<br>
}<br>
<br></div></div>
+ if (state& MESA_META_FRAMEBUFFER_SRGB) {<div class="im"><br>
+ save->sRGBEnabled = ctx->Color.sRGBEnabled;<br>
+ if (ctx->Color.sRGBEnabled)<br>
+ _mesa_set_framebuffer_srgb(<u></u>ctx, GL_FALSE);<br>
+ }<br>
+<br>
/* misc */<br>
{<br>
save->Lighting = ctx->Light.Enabled;<br>
@@ -1075,6 +1084,11 @@ _mesa_meta_end(struct gl_context *ctx)<br>
_mesa_set_multisample(ctx, save->MultisampleEnabled);<br>
}<br>
<br></div>
+ if (state& MESA_META_FRAMEBUFFER_SRGB) {<div><div class="h5"><br>
+ if (ctx->Color.sRGBEnabled != save->sRGBEnabled)<br>
+ _mesa_set_framebuffer_srgb(<u></u>ctx, save->sRGBEnabled);<br>
+ }<br>
+<br>
/* misc */<br>
if (save->Lighting) {<br>
_mesa_set_enable(ctx, GL_LIGHTING, GL_TRUE);<br>
@@ -1394,7 +1408,6 @@ blitframebuffer_texture(struct gl_context *ctx,<br>
const GLuint srcLevel = readAtt->TextureLevel;<br>
const GLint baseLevelSave = texObj->BaseLevel;<br>
const GLint maxLevelSave = texObj->MaxLevel;<br>
- const GLenum fbo_srgb_save = ctx->Color.sRGBEnabled;<br>
const GLenum target = texObj->Target;<br>
GLuint sampler, samplerSave =<br>
ctx->Texture.Unit[ctx-><u></u>Texture.CurrentUnit].Sampler ?<br>
@@ -1433,15 +1446,14 @@ blitframebuffer_texture(struct gl_context *ctx,<br>
_mesa_SamplerParameteri(<u></u>sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);<br>
_mesa_SamplerParameteri(<u></u>sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);<br>
<br>
- /* Always do our blits with no sRGB decode or encode.*/<br>
+ /* Always do our blits with no sRGB decode or encode. Note that<br>
+ * GL_FRAMEBUFFER_SRGB has already been disabled by<br>
+ * _mesa_meta_begin().<br>
+ */<br>
if (ctx->Extensions.EXT_texture_<u></u>sRGB_decode) {<br>
_mesa_SamplerParameteri(<u></u>sampler, GL_TEXTURE_SRGB_DECODE_EXT,<br>
GL_SKIP_DECODE_EXT);<br>
}<br></div></div>
- if ((_mesa_is_desktop_gl(ctx)&& ctx->Extensions.EXT_<u></u>framebuffer_sRGB)<div class="im"><br>
- || _mesa_is_gles3(ctx)) {<br>
- _mesa_set_enable(ctx, GL_FRAMEBUFFER_SRGB_EXT, GL_FALSE);<br>
- }<br>
<br>
_mesa_TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);<br>
_mesa_set_enable(ctx, target, GL_TRUE);<br>
@@ -1500,9 +1512,6 @@ blitframebuffer_texture(struct gl_context *ctx,<br>
_mesa_TexParameteri(target, GL_TEXTURE_BASE_LEVEL, baseLevelSave);<br>
_mesa_TexParameteri(target, GL_TEXTURE_MAX_LEVEL, maxLevelSave);<br>
}<br></div>
- if (ctx->Extensions.EXT_<u></u>framebuffer_sRGB&& fbo_srgb_save) {<div class="im"><br>
- _mesa_set_enable(ctx, GL_FRAMEBUFFER_SRGB_EXT, GL_TRUE);<br>
- }<br>
<br>
_mesa_BindSampler(ctx-><u></u>Texture.CurrentUnit, samplerSave);<br>
_mesa_DeleteSamplers(1,&<u></u>sampler);<br>
@@ -1713,7 +1722,8 @@ _mesa_meta_Clear(struct gl_context *ctx, GLbitfield buffers)<br>
GLbitfield metaSave = (MESA_META_ALL -<br>
MESA_META_SCISSOR -<br>
MESA_META_PIXEL_STORE -<br>
- MESA_META_CONDITIONAL_RENDER);<br>
+ MESA_META_CONDITIONAL_RENDER -<br>
+ MESA_META_FRAMEBUFFER_SRGB);<br>
const GLuint stencilMax = (1<< ctx->DrawBuffer->Visual.<u></u>stencilBits) - 1;<br>
<br></div>
if (buffers& BUFFER_BITS_COLOR) {<div class="im"><br>
@@ -3236,7 +3246,6 @@ _mesa_meta_GenerateMipmap(<u></u>struct gl_context *ctx, GLenum target,<br>
const GLuint maxLevel = texObj->MaxLevel;<br>
const GLint maxLevelSave = texObj->MaxLevel;<br>
const GLboolean genMipmapSave = texObj->GenerateMipmap;<br>
- const GLenum srgbBufferSave = ctx->Color.sRGBEnabled;<br>
const GLuint fboSave = ctx->DrawBuffer->Name;<br>
const GLuint currentTexUnitSave = ctx->Texture.CurrentUnit;<br>
const GLboolean use_glsl_version = ctx->Extensions.ARB_vertex_<u></u>shader&&<br>
@@ -3330,12 +3339,6 @@ _mesa_meta_GenerateMipmap(<u></u>struct gl_context *ctx, GLenum target,<br>
else<br>
assert(!genMipmapSave);<br>
<br>
- if ((ctx->Extensions.EXT_<u></u>framebuffer_sRGB&&<br>
- _mesa_is_desktop_gl(ctx)) ||<br>
- _mesa_is_gles3(ctx)) {<br>
- _mesa_set_enable(ctx, GL_FRAMEBUFFER_SRGB_EXT, GL_FALSE);<br>
- }<br>
-<br>
/* Setup texture coordinates */<br>
setup_texture_coords(<u></u>faceTarget,<br>
slice,<br>
@@ -3452,10 +3455,6 @@ _mesa_meta_GenerateMipmap(<u></u>struct gl_context *ctx, GLenum target,<br>
_mesa_DrawArrays(GL_TRIANGLE_<u></u>FAN, 0, 4);<br>
}<br>
<br></div>
- if (ctx->Extensions.EXT_<u></u>framebuffer_sRGB&& srgbBufferSave) {<div class="im"><br>
- _mesa_set_enable(ctx, GL_FRAMEBUFFER_SRGB_EXT, GL_TRUE);<br>
- }<br>
-<br>
_mesa_lock_texture(ctx, texObj); /* relock */<br>
<br>
_mesa_BindSampler(ctx-><u></u>Texture.CurrentUnit, samplerSave);<br>
@@ -3734,12 +3733,6 @@ decompress_texture_image(<u></u>struct gl_context *ctx,<br>
_mesa_TexParameteri(target, GL_TEXTURE_MAX_LEVEL, texImage->Level);<br>
}<br>
<br>
- /* No sRGB decode or encode.*/<br></div>
- if ((_mesa_is_desktop_gl(ctx)&& ctx->Extensions.EXT_<u></u>framebuffer_sRGB)<div class="im"><br>
- || _mesa_is_gles3(ctx)) {<br>
- _mesa_set_enable(ctx, GL_FRAMEBUFFER_SRGB_EXT, GL_FALSE);<br>
- }<br>
-<br>
/* render quad w/ texture into renderbuffer */<br>
_mesa_DrawArrays(GL_TRIANGLE_<u></u>FAN, 0, 4);<br>
<br>
diff --git a/src/mesa/drivers/common/<u></u>meta.h b/src/mesa/drivers/common/<u></u>meta.h<br>
index d8dfb56..6ffc5b5 100644<br>
--- a/src/mesa/drivers/common/<u></u>meta.h<br>
+++ b/src/mesa/drivers/common/<u></u>meta.h<br>
@@ -56,6 +56,7 @@<br>
#define MESA_META_CLIP 0x40000<br>
#define MESA_META_SELECT_FEEDBACK 0x80000<br>
#define MESA_META_MULTISAMPLE 0x100000<br>
+#define MESA_META_FRAMEBUFFER_SRGB 0x200000<br>
/**\}*/<br>
<br>
extern void<br>
</div></blockquote>
<br>
Assuming you've checked all the _mesa_meta_begin() calls to check if the new MESA_META_FRAMEBUFFER_SRGB flag is needed,<br>
<br>
Reviewed-by: Brian Paul <<a href="mailto:brianp@vmware.com" target="_blank">brianp@vmware.com</a>><br>
<br>
</blockquote></div><br>I have checked all the _mesa_meta_begin() calls, but if someone wants to verify that my reasoning is correct, I would appreciate it. Specifically, I reasoned that:<br><br>- The calls to _mesa_meta_begin() in _mesa_meta_CopyPixels(), _mesa_meta_DrawPixels(), _mesa_meta_Bitmap(), and _mesa_meta_DrawTex() should *not* include MESA_META_FRAMEBUFFER_SRGB, because fragments produced by these calls are supposed to undergo normal fragment processing.<br>
<br>- The call to _mesa_meta_begin() in _mesa_meta_GenerateMipmap() *should* include MESA_META_FRAMEBUFFER_SRGB, because sRGB encoding during mipmap generation would cause different miplevels to have different brightness.<br>
<br>- The calls to _mesa_meta_begin() in _mesa_meta_CopyTexSubImage() don't need to include MESA_META_FRAMEBUFFER_SRGB, because the only operations that this function performs while meta is active are ReadPixels() and TexSubImage(), which won't be affected by the FRAMEBUFFER_SRGB setting.<br>
<br>- The call to _mesa_meta_begin() in decompress_texture_image() *should* include MESA_META_FRAMEBUFFER_SRGB, since the behaviour of textures shouldn't depend on the setting of MESA_META_FRAMEBUFFER_SRGB. <br><br>Do those sound right? I'm confident about the others.<br>