[Mesa-dev] [PATCH] mesa: fix glGetTexImage for srgb textures when srgb decode is skipped
Mike Kaplinskiy
mike.kaplinskiy at gmail.com
Mon May 23 21:33:03 PDT 2011
I see; that sounds fine. I was a bit wary of changing the code since I
don't know what else calls it. Would something like the attached work?
I also included an attempt at changing the tex-srgb piglit test to
check for glGetTexImage.
On Mon, May 23, 2011 at 11:57 AM, Roland Scheidegger <sroland at vmware.com> wrote:
> I'd support that as well, sounds more sane than doing
> nonlinear-to-linear plus linear-to-linear - when I did the fast-path
> srgb texgetimage patch I didn't notice there is already other code which
> is switching the fetch functions for GL_SKIP_DECODE_EXT.
> Sounds to me though wine is doing something inefficient in the first
> place, since I don't think d3d apps would generally do something which
> would really require reading back the texture image.
>
> Roland
>
>
> Am 23.05.2011 16:45, schrieb Brian Paul:
>> I think another approach would be to temporarily set the
>> Sampler.sRGBDecode field to GL_SKIP_DECODE_EXT, use the non-sRGB path
>> to get the texels, then restore Sampler.sRGBDecode to its original
>> value. Call _mesa_set_fetch_functions() as needed to choose the
>> non-decoding texel fetch functions. Then we could avoid the
>> linear_to_nonlinear() function altogether.
>>
>> We should probably have a piglit test to exercise glGetTexImage with
>> sRGB textures...
>>
>> -Brian
>>
>>
>> On Sat, May 21, 2011 at 5:37 PM, Mike Kaplinskiy
>> <mike.kaplinskiy at gmail.com> wrote:
>>> Sorry looks like I edited that comment a few too many times. Here's an
>>> updated patch with the comment fixed.
>>>
>>> On Sat, May 21, 2011 at 7:15 PM, Mike Kaplinskiy
>>> <mike.kaplinskiy at gmail.com> wrote:
>>>> This fixes the loading screen for Assassins Creed Brotherhood running
>>>> under wine for me [exposed by a fast-path that actually fixed it at
>>>> be0a2f62f3a5bc6f05c3c7c6b674f2688aee031d]. May also fix bug 37150.
>>>>
>>>
>>> _______________________________________________
>>> mesa-dev mailing list
>>> mesa-dev at lists.freedesktop.org
>>> http://lists.freedesktop.org/mailman/listinfo/mesa-dev
>>>
>>>
>> _______________________________________________
>> mesa-dev mailing list
>> mesa-dev at lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/mesa-dev
>
>
-------------- next part --------------
From 793c985d421a78fe2f08af70eff66b411e148957 Mon Sep 17 00:00:00 2001
From: Mike Kaplinskiy <mike.kaplinskiy at gmail.com>
Date: Sat, 21 May 2011 19:05:29 -0400
Subject: [PATCH] mesa: fix glGetTexImage for cases when srgb decode is
skipped
---
src/mesa/main/texgetimage.c | 119 +++++++------------------------------------
1 files changed, 18 insertions(+), 101 deletions(-)
diff --git a/src/mesa/main/texgetimage.c b/src/mesa/main/texgetimage.c
index b23317c..4234b40 100644
--- a/src/mesa/main/texgetimage.c
+++ b/src/mesa/main/texgetimage.c
@@ -40,6 +40,7 @@
#include "pack.h"
#include "pbo.h"
#include "texgetimage.h"
+#include "texfetch.h"
#include "teximage.h"
@@ -220,110 +221,14 @@ get_tex_ycbcr(struct gl_context *ctx, GLuint dimensions,
}
-#if FEATURE_EXT_texture_sRGB
-
-
/**
- * Convert a float value from linear space to a
- * non-linear sRGB value in [0, 255].
- * Not terribly efficient.
- */
-static INLINE GLfloat
-linear_to_nonlinear(GLfloat cl)
-{
- /* can't have values outside [0, 1] */
- GLfloat cs;
- if (cl < 0.0031308f) {
- cs = 12.92f * cl;
- }
- else {
- cs = (GLfloat)(1.055 * pow(cl, 0.41666) - 0.055);
- }
- return cs;
-}
-
-
-/**
- * glGetTexImagefor sRGB pixels;
- */
-static void
-get_tex_srgb(struct gl_context *ctx, GLuint dimensions,
- GLenum format, GLenum type, GLvoid *pixels,
- const struct gl_texture_image *texImage)
-{
- const GLint width = texImage->Width;
- const GLint height = texImage->Height;
- const GLint depth = texImage->Depth;
- const GLbitfield transferOps = 0x0;
- GLint img, row;
- GLfloat (*rgba)[4] = (GLfloat (*)[4]) malloc(4 * width * sizeof(GLfloat));
-
- if (!rgba) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage");
- return;
- }
-
- for (img = 0; img < depth; img++) {
- for (row = 0; row < height; row++) {
- void *dest = _mesa_image_address(dimensions, &ctx->Pack, pixels,
- width, height, format, type,
- img, row, 0);
-
- GLint col;
-
- /* convert row to RGBA format */
- for (col = 0; col < width; col++) {
- texImage->FetchTexelf(texImage, col, row, img, rgba[col]);
- if (texImage->_BaseFormat == GL_LUMINANCE) {
- rgba[col][RCOMP] = linear_to_nonlinear(rgba[col][RCOMP]);
- rgba[col][GCOMP] = 0.0;
- rgba[col][BCOMP] = 0.0;
- }
- else if (texImage->_BaseFormat == GL_LUMINANCE_ALPHA) {
- rgba[col][RCOMP] = linear_to_nonlinear(rgba[col][RCOMP]);
- rgba[col][GCOMP] = 0.0;
- rgba[col][BCOMP] = 0.0;
- }
- else if (texImage->_BaseFormat == GL_RGB ||
- texImage->_BaseFormat == GL_RGBA) {
- rgba[col][RCOMP] = linear_to_nonlinear(rgba[col][RCOMP]);
- rgba[col][GCOMP] = linear_to_nonlinear(rgba[col][GCOMP]);
- rgba[col][BCOMP] = linear_to_nonlinear(rgba[col][BCOMP]);
- }
- }
- _mesa_pack_rgba_span_float(ctx, width, (GLfloat (*)[4]) rgba,
- format, type, dest,
- &ctx->Pack, transferOps);
- }
- }
-
- free(rgba);
-}
-
-
-#else /* FEATURE_EXT_texture_sRGB */
-
-
-static INLINE void
-get_tex_srgb(struct gl_context *ctx, GLuint dimensions,
- GLenum format, GLenum type, GLvoid *pixels,
- const struct gl_texture_image *texImage)
-{
- ASSERT_NO_FEATURE();
-}
-
-
-#endif /* FEATURE_EXT_texture_sRGB */
-
-
-/**
- * glGetTexImagefor RGBA, Luminance, etc. pixels.
+ * glGetTexImage for (s)RGBA, Luminance, etc. pixels.
* This is the slow way since we use texture sampling.
*/
static void
get_tex_rgba(struct gl_context *ctx, GLuint dimensions,
GLenum format, GLenum type, GLvoid *pixels,
- const struct gl_texture_image *texImage)
+ struct gl_texture_image *texImage)
{
const GLint width = texImage->Width;
const GLint height = texImage->Height;
@@ -334,12 +239,22 @@ get_tex_rgba(struct gl_context *ctx, GLuint dimensions,
GLbitfield transferOps = 0x0;
GLint img, row;
GLfloat (*rgba)[4] = (GLfloat (*)[4]) malloc(4 * width * sizeof(GLfloat));
+ const GLboolean is_sampler_srgb_decode =
+ _mesa_get_format_color_encoding(texImage->TexFormat) == GL_SRGB &&
+ texImage->TexObject->Sampler.sRGBDecode == GL_DECODE_EXT;
if (!rgba) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage");
return;
}
+ /* glGetTexImage always returns sRGB data for sRGB textures. Make sure the
+ * fetch functions return sRGB data without linearizing it. */
+ if (is_sampler_srgb_decode) {
+ texImage->TexObject->Sampler.sRGBDecode = GL_SKIP_DECODE_EXT;
+ _mesa_set_fetch_functions(texImage, dimensions);
+ }
+
for (img = 0; img < depth; img++) {
for (row = 0; row < height; row++) {
void *dest = _mesa_image_address(dimensions, &ctx->Pack, pixels,
@@ -389,6 +304,11 @@ get_tex_rgba(struct gl_context *ctx, GLuint dimensions,
}
}
+ if (is_sampler_srgb_decode) {
+ texImage->TexObject->Sampler.sRGBDecode = GL_DECODE_EXT;
+ _mesa_set_fetch_functions(texImage, dimensions);
+ }
+
free(rgba);
}
@@ -548,9 +468,6 @@ _mesa_get_teximage(struct gl_context *ctx, GLenum target, GLint level,
else if (format == GL_YCBCR_MESA) {
get_tex_ycbcr(ctx, dimensions, format, type, pixels, texImage);
}
- else if (_mesa_get_format_color_encoding(texImage->TexFormat) == GL_SRGB) {
- get_tex_srgb(ctx, dimensions, format, type, pixels, texImage);
- }
else {
get_tex_rgba(ctx, dimensions, format, type, pixels, texImage);
}
--
1.7.4.4
-------------- next part --------------
From 4127816431e1b13c7f65ac59080485521191b84c Mon Sep 17 00:00:00 2001
From: Mike Kaplinskiy <mike.kaplinskiy at gmail.com>
Date: Tue, 24 May 2011 00:29:35 -0400
Subject: [PATCH] tex-srgb: check glGetTexImage as well
---
tests/texturing/tex-srgb.c | 19 ++++++++++++++-----
1 files changed, 14 insertions(+), 5 deletions(-)
diff --git a/tests/texturing/tex-srgb.c b/tests/texturing/tex-srgb.c
index 1f53508..5b73d54 100644
--- a/tests/texturing/tex-srgb.c
+++ b/tests/texturing/tex-srgb.c
@@ -68,7 +68,6 @@ static void fill_level(int level, const GLfloat *color)
int size = SIZE / (1 << level);
int i;
- /* Update a square inside the texture to red */
data = malloc(size * size * 4 * sizeof(GLfloat));
for (i = 0; i < 4 * size * size; i += 4) {
data[i + 0] = color[0];
@@ -93,6 +92,10 @@ srgb_tex_test(int srgb_format)
have_decode = glutExtensionSupported("GL_EXT_texture_sRGB_decode");
+ memcpy(expected_green, green, sizeof(float) * 4);
+ memcpy(expected_srgb_green, green, sizeof(float) * 4);
+ expected_srgb_green[1] = nonlinear_to_linear(255.0*green[1]);
+
glGenTextures(1, &tex);
glBindTexture(GL_TEXTURE_2D, tex);
@@ -108,10 +111,20 @@ srgb_tex_test(int srgb_format)
glEnable(GL_TEXTURE_2D);
piglit_draw_rect_tex(0, 0, 20, 20, 0, 0, 1, 1);
+ if (!piglit_probe_texel_rect_rgba(GL_TEXTURE_2D, 0, 0, 0, SIZE, SIZE,
+ expected_green)) {
+ pass = GL_FALSE;
+ }
+
if (have_decode) {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SRGB_DECODE_EXT,
GL_SKIP_DECODE_EXT);
+ if (!piglit_probe_texel_rect_rgba(GL_TEXTURE_2D, 0, 0, 0, SIZE,
+ SIZE, expected_green)) {
+ pass = GL_FALSE;
+ }
+
piglit_draw_rect_tex(20, 0, 20, 20, 0, 0, 1, 1);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SRGB_DECODE_EXT,
@@ -120,10 +133,6 @@ srgb_tex_test(int srgb_format)
piglit_draw_rect_tex(40, 0, 20, 20, 0, 0, 1, 1);
}
- memcpy(expected_green, green, sizeof(float) * 4);
- memcpy(expected_srgb_green, green, sizeof(float) * 4);
- expected_srgb_green[1] = nonlinear_to_linear(255.0*green[1]);
-
if (!piglit_probe_rect_rgb(0, 0, 20, 20, expected_srgb_green))
pass = GL_FALSE;
--
1.7.4.4
More information about the mesa-dev
mailing list