meta: fix broken sRGB mipmap generation

If we're generating a mipmap for an sRGB texture we need to bypass
sRGB->linear conversion.  Otherwise the destination mipmap level
(drawn with a textured quad) will have the wrong colors.
If we can't turn of sRGB->linear conversion (GL_EXT_texture_sRGB_decode)
we need to use the software fallback for mipmap generation.

Note: This is a candidate for the 7.11 branch.
(cherry picked from commit 1e939f5374)
This commit is contained in:
Brian Paul 2011-09-17 11:26:54 -06:00 committed by Marek Olšák
parent a74400ca30
commit 2781baaa64

View file

@ -2294,6 +2294,15 @@ _mesa_meta_check_generate_mipmap_fallback(struct gl_context *ctx, GLenum target,
return GL_TRUE;
}
if (_mesa_get_format_color_encoding(baseImage->TexFormat) == GL_SRGB &&
!ctx->Extensions.EXT_texture_sRGB_decode) {
/* The texture format is sRGB but we can't turn off sRGB->linear
* texture sample conversion. So we won't be able to generate the
* right colors when rendering. Need to use a fallback.
*/
return GL_TRUE;
}
/*
* Test that we can actually render in the texture's format.
*/
@ -2356,6 +2365,8 @@ _mesa_meta_GenerateMipmap(struct gl_context *ctx, GLenum target,
const GLenum wrapSSave = texObj->Sampler.WrapS;
const GLenum wrapTSave = texObj->Sampler.WrapT;
const GLenum wrapRSave = texObj->Sampler.WrapR;
const GLenum srgbDecodeSave = texObj->Sampler.sRGBDecode;
const GLenum srgbBufferSave = ctx->Color.sRGBEnabled;
const GLuint fboSave = ctx->DrawBuffer->Name;
const GLuint original_active_unit = ctx->Texture.CurrentUnit;
GLenum faceTarget;
@ -2417,6 +2428,15 @@ _mesa_meta_GenerateMipmap(struct gl_context *ctx, GLenum target,
_mesa_TexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
_mesa_TexParameteri(target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
/* We don't want to encode or decode sRGB values; treat them as linear */
if (ctx->Extensions.EXT_texture_sRGB_decode) {
_mesa_TexParameteri(target, GL_TEXTURE_SRGB_DECODE_EXT,
GL_SKIP_DECODE_EXT);
}
if (ctx->Extensions.EXT_framebuffer_sRGB) {
_mesa_Disable(GL_FRAMEBUFFER_SRGB_EXT);
}
_mesa_set_enable(ctx, target, GL_TRUE);
/* setup texcoords once (XXX what about border?) */
@ -2632,6 +2652,14 @@ _mesa_meta_GenerateMipmap(struct gl_context *ctx, GLenum target,
_mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
}
if (ctx->Extensions.EXT_texture_sRGB_decode) {
_mesa_TexParameteri(target, GL_TEXTURE_SRGB_DECODE_EXT,
srgbDecodeSave);
}
if (ctx->Extensions.EXT_framebuffer_sRGB && srgbBufferSave) {
_mesa_Enable(GL_FRAMEBUFFER_SRGB_EXT);
}
_mesa_lock_texture(ctx, texObj); /* relock */
_mesa_meta_end(ctx);