mesa/swrast: handle sRGB FBOs correctly (v2)
From reading EXT_texture_sRGB and EXT_framebuffer_sRGB and interactions with FBO I've found that swrast is converting the sRGB values to linear for blending when an sRGB texture is bound as an FBO. According to the spec and further explained in the framebuffer_sRGB spec this behaviour is not required unless the GL_FRAMEBUFFER_SRGB is enabled and the Visual/config exposes GL_FRAMEBUFFER_SRGB_CAPABLE_EXT. This patch fixes swrast to use a separate Fetch call for FBOs bound to SRGB and avoid the conversions. v2: export _mesa_get_texture_dimensions as per Brian's comments. Signed-off-by: Dave Airlie <airlied@redhat.com>
This commit is contained in:
parent
31351dc029
commit
a988ddf379
|
@ -759,7 +759,7 @@ texfetch_funcs[MESA_FORMAT_COUNT] =
|
|||
};
|
||||
|
||||
|
||||
static FetchTexelFuncF
|
||||
FetchTexelFuncF
|
||||
_mesa_get_texel_fetch_func(gl_format format, GLuint dims)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
|
|
|
@ -34,6 +34,9 @@
|
|||
extern StoreTexelFunc
|
||||
_mesa_get_texel_store_func(gl_format format);
|
||||
|
||||
extern FetchTexelFuncF
|
||||
_mesa_get_texel_fetch_func(gl_format format, GLuint dims);
|
||||
|
||||
extern void
|
||||
_mesa_set_fetch_functions(struct gl_texture_image *texImage, GLuint dims);
|
||||
|
||||
|
|
|
@ -932,8 +932,8 @@ _mesa_max_texture_levels(struct gl_context *ctx, GLenum target)
|
|||
/**
|
||||
* Return number of dimensions per mipmap level for the given texture target.
|
||||
*/
|
||||
static GLint
|
||||
get_texture_dimensions(GLenum target)
|
||||
GLint
|
||||
_mesa_get_texture_dimensions(GLenum target)
|
||||
{
|
||||
switch (target) {
|
||||
case GL_TEXTURE_1D:
|
||||
|
@ -1158,7 +1158,7 @@ _mesa_init_teximage_fields(struct gl_context *ctx, GLenum target,
|
|||
|
||||
img->TexFormat = format;
|
||||
|
||||
dims = get_texture_dimensions(target);
|
||||
dims = _mesa_get_texture_dimensions(target);
|
||||
|
||||
_mesa_set_fetch_functions(img, dims);
|
||||
}
|
||||
|
|
|
@ -126,6 +126,8 @@ _mesa_test_proxy_teximage(struct gl_context *ctx, GLenum target, GLint level,
|
|||
extern GLuint
|
||||
_mesa_tex_target_to_face(GLenum target);
|
||||
|
||||
extern GLint
|
||||
_mesa_get_texture_dimensions(GLenum target);
|
||||
|
||||
/**
|
||||
* Lock a texture for updating. See also _mesa_lock_context_textures().
|
||||
|
|
|
@ -20,6 +20,7 @@ struct texture_renderbuffer
|
|||
struct gl_renderbuffer Base; /**< Base class object */
|
||||
struct gl_texture_image *TexImage;
|
||||
StoreTexelFunc Store;
|
||||
FetchTexelFuncF Fetchf;
|
||||
GLint Yoffset; /**< Layer for 1D array textures. */
|
||||
GLint Zoffset; /**< Layer for 2D array textures, or slice
|
||||
* for 3D textures
|
||||
|
@ -48,7 +49,7 @@ texture_get_row(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count
|
|||
GLchan *rgbaOut = (GLchan *) values;
|
||||
for (i = 0; i < count; i++) {
|
||||
GLfloat rgba[4];
|
||||
trb->TexImage->FetchTexelf(trb->TexImage, x + i, y, z, rgba);
|
||||
trb->Fetchf(trb->TexImage, x + i, y, z, rgba);
|
||||
UNCLAMPED_FLOAT_TO_RGBA_CHAN(rgbaOut + 4 * i, rgba);
|
||||
}
|
||||
}
|
||||
|
@ -56,7 +57,7 @@ texture_get_row(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count
|
|||
GLushort *zValues = (GLushort *) values;
|
||||
for (i = 0; i < count; i++) {
|
||||
GLfloat flt;
|
||||
trb->TexImage->FetchTexelf(trb->TexImage, x + i, y, z, &flt);
|
||||
trb->Fetchf(trb->TexImage, x + i, y, z, &flt);
|
||||
zValues[i] = (GLushort) (flt * 0xffff);
|
||||
}
|
||||
}
|
||||
|
@ -67,7 +68,7 @@ texture_get_row(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count
|
|||
*/
|
||||
for (i = 0; i < count; i++) {
|
||||
GLfloat flt;
|
||||
trb->TexImage->FetchTexelf(trb->TexImage, x + i, y, z, &flt);
|
||||
trb->Fetchf(trb->TexImage, x + i, y, z, &flt);
|
||||
#if 0
|
||||
/* this should work, but doesn't (overflow due to low precision) */
|
||||
zValues[i] = (GLuint) (flt * scale);
|
||||
|
@ -81,7 +82,7 @@ texture_get_row(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count
|
|||
GLuint *zValues = (GLuint *) values;
|
||||
for (i = 0; i < count; i++) {
|
||||
GLfloat flt;
|
||||
trb->TexImage->FetchTexelf(trb->TexImage, x + i, y, z, &flt);
|
||||
trb->Fetchf(trb->TexImage, x + i, y, z, &flt);
|
||||
zValues[i] = ((GLuint) (flt * 0xffffff)) << 8;
|
||||
}
|
||||
}
|
||||
|
@ -89,7 +90,7 @@ texture_get_row(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint count
|
|||
GLuint *zValues = (GLuint *) values;
|
||||
for (i = 0; i < count; i++) {
|
||||
GLfloat flt;
|
||||
trb->TexImage->FetchTexelf(trb->TexImage, x + i, y, z, &flt);
|
||||
trb->Fetchf(trb->TexImage, x + i, y, z, &flt);
|
||||
zValues[i] = (GLuint) (flt * 0xffffff);
|
||||
}
|
||||
}
|
||||
|
@ -112,7 +113,7 @@ texture_get_values(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint co
|
|||
GLchan *rgbaOut = (GLchan *) values;
|
||||
for (i = 0; i < count; i++) {
|
||||
GLfloat rgba[4];
|
||||
trb->TexImage->FetchTexelf(trb->TexImage, x[i], y[i] + trb->Yoffset,
|
||||
trb->Fetchf(trb->TexImage, x[i], y[i] + trb->Yoffset,
|
||||
z, rgba);
|
||||
UNCLAMPED_FLOAT_TO_RGBA_CHAN(rgbaOut + 4 * i, rgba);
|
||||
}
|
||||
|
@ -121,7 +122,7 @@ texture_get_values(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint co
|
|||
GLushort *zValues = (GLushort *) values;
|
||||
for (i = 0; i < count; i++) {
|
||||
GLfloat flt;
|
||||
trb->TexImage->FetchTexelf(trb->TexImage, x[i], y[i] + trb->Yoffset,
|
||||
trb->Fetchf(trb->TexImage, x[i], y[i] + trb->Yoffset,
|
||||
z, &flt);
|
||||
zValues[i] = (GLushort) (flt * 0xffff);
|
||||
}
|
||||
|
@ -130,7 +131,7 @@ texture_get_values(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint co
|
|||
GLuint *zValues = (GLuint *) values;
|
||||
for (i = 0; i < count; i++) {
|
||||
GLfloat flt;
|
||||
trb->TexImage->FetchTexelf(trb->TexImage, x[i], y[i] + trb->Yoffset,
|
||||
trb->Fetchf(trb->TexImage, x[i], y[i] + trb->Yoffset,
|
||||
z, &flt);
|
||||
#if 0
|
||||
zValues[i] = (GLuint) (flt * 0xffffffff);
|
||||
|
@ -143,7 +144,7 @@ texture_get_values(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint co
|
|||
GLuint *zValues = (GLuint *) values;
|
||||
for (i = 0; i < count; i++) {
|
||||
GLfloat flt;
|
||||
trb->TexImage->FetchTexelf(trb->TexImage, x[i], y[i] + trb->Yoffset,
|
||||
trb->Fetchf(trb->TexImage, x[i], y[i] + trb->Yoffset,
|
||||
z, &flt);
|
||||
zValues[i] = ((GLuint) (flt * 0xffffff)) << 8;
|
||||
}
|
||||
|
@ -152,7 +153,7 @@ texture_get_values(struct gl_context *ctx, struct gl_renderbuffer *rb, GLuint co
|
|||
GLuint *zValues = (GLuint *) values;
|
||||
for (i = 0; i < count; i++) {
|
||||
GLfloat flt;
|
||||
trb->TexImage->FetchTexelf(trb->TexImage, x[i], y[i] + trb->Yoffset,
|
||||
trb->Fetchf(trb->TexImage, x[i], y[i] + trb->Yoffset,
|
||||
z, &flt);
|
||||
zValues[i] = (GLuint) (flt * 0xffffff);
|
||||
}
|
||||
|
@ -517,8 +518,6 @@ wrap_texture(struct gl_context *ctx, struct gl_renderbuffer_attachment *att)
|
|||
_mesa_reference_renderbuffer(&att->Renderbuffer, &(trb->Base));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Update the renderbuffer wrapper for rendering to a texture.
|
||||
* For example, update the width, height of the RB based on the texture size,
|
||||
|
@ -542,6 +541,8 @@ update_wrapper(struct gl_context *ctx, const struct gl_renderbuffer_attachment *
|
|||
trb->Store = store_nop;
|
||||
}
|
||||
|
||||
trb->Fetchf = trb->TexImage->FetchTexelf;
|
||||
|
||||
if (att->Texture->Target == GL_TEXTURE_1D_ARRAY_EXT) {
|
||||
trb->Yoffset = att->Zoffset;
|
||||
trb->Zoffset = 0;
|
||||
|
@ -582,6 +583,17 @@ update_wrapper(struct gl_context *ctx, const struct gl_renderbuffer_attachment *
|
|||
trb->Base.DataType = GL_UNSIGNED_INT;
|
||||
trb->Base._BaseFormat = GL_DEPTH_COMPONENT;
|
||||
break;
|
||||
/* SRGB formats pre EXT_framebuffer_sRGB don't do sRGB translations on FBO readback */
|
||||
case MESA_FORMAT_SRGB8:
|
||||
trb->Fetchf = _mesa_get_texel_fetch_func(MESA_FORMAT_RGB888, _mesa_get_texture_dimensions(att->Texture->Target));
|
||||
trb->Base.DataType = CHAN_TYPE;
|
||||
trb->Base._BaseFormat = GL_RGBA;
|
||||
break;
|
||||
case MESA_FORMAT_SRGBA8:
|
||||
trb->Fetchf = _mesa_get_texel_fetch_func(MESA_FORMAT_RGBA8888, _mesa_get_texture_dimensions(att->Texture->Target));
|
||||
trb->Base.DataType = CHAN_TYPE;
|
||||
trb->Base._BaseFormat = GL_RGBA;
|
||||
break;
|
||||
default:
|
||||
trb->Base.DataType = CHAN_TYPE;
|
||||
trb->Base._BaseFormat = GL_RGBA;
|
||||
|
|
Loading…
Reference in New Issue