Matteo Bruni : wined3d: Use GL_FRAMEBUFFER_SRGB when possible.

Alexandre Julliard julliard at winehq.org
Wed Aug 15 14:08:32 CDT 2012


Module: wine
Branch: master
Commit: 152a09ce75b97b1139e358428cea2c371a8b6804
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=152a09ce75b97b1139e358428cea2c371a8b6804

Author: Matteo Bruni <mbruni at codeweavers.com>
Date:   Wed Aug 15 00:38:23 2012 +0200

wined3d: Use GL_FRAMEBUFFER_SRGB when possible.

---

 dlls/wined3d/arb_program_shader.c |   15 +++++++++++++++
 dlls/wined3d/directx.c            |   10 ++++++++++
 dlls/wined3d/shader.c             |   13 +++++++++++--
 dlls/wined3d/utils.c              |    3 ++-
 dlls/wined3d/wined3d_gl.h         |    7 +++++++
 include/wine/wined3d.h            |    1 +
 6 files changed, 46 insertions(+), 3 deletions(-)

diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c
index 744b6af..c8799df 100644
--- a/dlls/wined3d/arb_program_shader.c
+++ b/dlls/wined3d/arb_program_shader.c
@@ -6495,6 +6495,20 @@ static void textransform(struct wined3d_context *context, const struct wined3d_s
         fragment_prog_arbfp(context, state, state_id);
 }
 
+static void state_srgbwrite(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
+{
+    const struct wined3d_gl_info *gl_info = context->gl_info;
+    const struct wined3d_surface *rt = state->fb->render_targets[0];
+
+    TRACE("context %p, state %p, state_id %#x.\n", context, state, state_id);
+
+    if (state->render_states[WINED3D_RS_SRGBWRITEENABLE]
+            && rt->resource.format->flags & WINED3DFMT_FLAG_SRGB_WRITE)
+        gl_info->gl_ops.gl.p_glEnable(GL_FRAMEBUFFER_SRGB);
+    else
+        gl_info->gl_ops.gl.p_glDisable(GL_FRAMEBUFFER_SRGB);
+}
+
 static const struct StateEntryTemplate arbfp_fragmentstate_template[] =
 {
     {STATE_RENDER(WINED3D_RS_TEXTUREFACTOR),              { STATE_RENDER(WINED3D_RS_TEXTUREFACTOR),             state_texfactor_arbfp   }, WINED3D_GL_EXT_NONE             },
@@ -6624,6 +6638,7 @@ static const struct StateEntryTemplate arbfp_fragmentstate_template[] =
     {STATE_RENDER(WINED3D_RS_FOGVERTEXMODE),              { STATE_RENDER(WINED3D_RS_FOGENABLE),                 NULL                    }, WINED3D_GL_EXT_NONE             },
     {STATE_RENDER(WINED3D_RS_FOGSTART),                   { STATE_RENDER(WINED3D_RS_FOGSTART),                  state_fogstartend       }, WINED3D_GL_EXT_NONE             },
     {STATE_RENDER(WINED3D_RS_FOGEND),                     { STATE_RENDER(WINED3D_RS_FOGSTART),                  NULL                    }, WINED3D_GL_EXT_NONE             },
+    {STATE_RENDER(WINED3D_RS_SRGBWRITEENABLE),            { STATE_RENDER(WINED3D_RS_SRGBWRITEENABLE),           state_srgbwrite         }, ARB_FRAMEBUFFER_SRGB            },
     {STATE_RENDER(WINED3D_RS_SRGBWRITEENABLE),            { STATE_PIXELSHADER,                                  NULL                    }, WINED3D_GL_EXT_NONE             },
     {STATE_RENDER(WINED3D_RS_FOGCOLOR),                   { STATE_RENDER(WINED3D_RS_FOGCOLOR),                  state_fogcolor          }, WINED3D_GL_EXT_NONE             },
     {STATE_RENDER(WINED3D_RS_FOGDENSITY),                 { STATE_RENDER(WINED3D_RS_FOGDENSITY),                state_fogdensity        }, WINED3D_GL_EXT_NONE             },
diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c
index e47b4e1..58397e9 100644
--- a/dlls/wined3d/directx.c
+++ b/dlls/wined3d/directx.c
@@ -100,6 +100,7 @@ static const struct wined3d_extension_map gl_extension_map[] =
     {"GL_ARB_fragment_program",             ARB_FRAGMENT_PROGRAM          },
     {"GL_ARB_fragment_shader",              ARB_FRAGMENT_SHADER           },
     {"GL_ARB_framebuffer_object",           ARB_FRAMEBUFFER_OBJECT        },
+    {"GL_ARB_framebuffer_sRGB",             ARB_FRAMEBUFFER_SRGB          },
     {"GL_ARB_geometry_shader4",             ARB_GEOMETRY_SHADER4          },
     {"GL_ARB_half_float_pixel",             ARB_HALF_FLOAT_PIXEL          },
     {"GL_ARB_half_float_vertex",            ARB_HALF_FLOAT_VERTEX         },
@@ -2731,6 +2732,13 @@ static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter)
         /* GL_ARB_half_float_vertex is a subset of GL_NV_half_float. */
         gl_info->supported[ARB_HALF_FLOAT_VERTEX] = TRUE;
     }
+    if (gl_info->supported[ARB_FRAMEBUFFER_SRGB] && !gl_info->supported[EXT_TEXTURE_SRGB_DECODE])
+    {
+        /* Current wined3d sRGB infrastructure requires EXT_texture_sRGB_decode
+         * for GL_ARB_framebuffer_sRGB support (without EXT_texture_sRGB_decode
+         * we never render to sRGB surfaces). */
+        gl_info->supported[ARB_FRAMEBUFFER_SRGB] = FALSE;
+    }
 
     ENTER_GL();
 
@@ -4608,6 +4616,8 @@ HRESULT CDECL wined3d_get_device_caps(const struct wined3d *wined3d, UINT adapte
         caps->PrimitiveMiscCaps |= WINED3DPMISCCAPS_SEPARATEALPHABLEND;
     if (gl_info->supported[EXT_DRAW_BUFFERS2])
         caps->PrimitiveMiscCaps |= WINED3DPMISCCAPS_INDEPENDENTWRITEMASKS;
+    if (gl_info->supported[ARB_FRAMEBUFFER_SRGB])
+        caps->PrimitiveMiscCaps |= WINED3DPMISCCAPS_POSTBLENDSRGBCONVERT;
 
     caps->RasterCaps               = WINED3DPRASTERCAPS_DITHER    |
                                      WINED3DPRASTERCAPS_PAT       |
diff --git a/dlls/wined3d/shader.c b/dlls/wined3d/shader.c
index 1abafbb..2244ccd 100644
--- a/dlls/wined3d/shader.c
+++ b/dlls/wined3d/shader.c
@@ -1901,14 +1901,23 @@ void find_ps_compile_args(const struct wined3d_state *state,
         const struct wined3d_shader *shader, struct ps_compile_args *args)
 {
     struct wined3d_device *device = shader->device;
+    const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
     const struct wined3d_texture *texture;
     UINT i;
 
     memset(args, 0, sizeof(*args)); /* FIXME: Make sure all bits are set. */
-    if (state->render_states[WINED3D_RS_SRGBWRITEENABLE])
+    if (!gl_info->supported[ARB_FRAMEBUFFER_SRGB] && state->render_states[WINED3D_RS_SRGBWRITEENABLE])
     {
         const struct wined3d_surface *rt = state->fb->render_targets[0];
-        if (rt->resource.format->flags & WINED3DFMT_FLAG_SRGB_WRITE) args->srgb_correction = 1;
+        if (rt->resource.format->flags & WINED3DFMT_FLAG_SRGB_WRITE)
+        {
+            static unsigned int warned = 0;
+
+            args->srgb_correction = 1;
+            if (state->render_states[WINED3D_RS_ALPHABLENDENABLE] && !warned++)
+                WARN("Blending into a sRGB render target with no GL_ARB_framebuffer_sRGB "
+                        "support, expect rendering artifacts.\n");
+        }
     }
 
     if (shader->reg_maps.shader_version.major == 1
diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c
index 0be3972..0dcb431 100644
--- a/dlls/wined3d/utils.c
+++ b/dlls/wined3d/utils.c
@@ -3138,7 +3138,8 @@ void gen_ffp_frag_op(const struct wined3d_device *device, const struct wined3d_s
                 break;
         }
     }
-    if (state->render_states[WINED3D_RS_SRGBWRITEENABLE]
+    if (!gl_info->supported[ARB_FRAMEBUFFER_SRGB]
+            && state->render_states[WINED3D_RS_SRGBWRITEENABLE]
             && rt->resource.format->flags & WINED3DFMT_FLAG_SRGB_WRITE)
     {
         settings->sRGB_write = 1;
diff --git a/dlls/wined3d/wined3d_gl.h b/dlls/wined3d/wined3d_gl.h
index b87bc63..128937a 100644
--- a/dlls/wined3d/wined3d_gl.h
+++ b/dlls/wined3d/wined3d_gl.h
@@ -933,6 +933,7 @@ enum wined3d_gl_extension
     ARB_FRAGMENT_PROGRAM,
     ARB_FRAGMENT_SHADER,
     ARB_FRAMEBUFFER_OBJECT,
+    ARB_FRAMEBUFFER_SRGB,
     ARB_GEOMETRY_SHADER4,
     ARB_HALF_FLOAT_PIXEL,
     ARB_HALF_FLOAT_VERTEX,
@@ -1255,6 +1256,12 @@ enum wined3d_gl_extension
 #define GL_TEXTURE_STENCIL_SIZE                             0x88f1
 #endif
 
+/* GL_ARB_framebuffer_sRGB */
+#ifndef GL_ARB_framebuffer_sRGB
+#define GL_ARB_framebuffer_sRGB 1
+#define GL_FRAMEBUFFER_SRGB                                 0x8db9
+#endif
+
 /* GL_ARB_geometry_shader4 */
 #ifndef GL_ARB_geometry_shader4
 #define GL_ARB_geometry_shader4 1
diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h
index 5208a79..4a11ff2 100644
--- a/include/wine/wined3d.h
+++ b/include/wine/wined3d.h
@@ -1015,6 +1015,7 @@ enum wined3d_display_rotation
 #define WINED3DPMISCCAPS_MRTINDEPENDENTBITDEPTHS                0x00040000
 #define WINED3DPMISCCAPS_MRTPOSTPIXELSHADERBLENDING             0x00080000
 #define WINED3DPMISCCAPS_FOGVERTEXCLAMPED                       0x00100000
+#define WINED3DPMISCCAPS_POSTBLENDSRGBCONVERT                   0x00200000
 
 #define WINED3DPS20_MAX_DYNAMICFLOWCONTROLDEPTH                 24
 #define WINED3DPS20_MIN_DYNAMICFLOWCONTROLDEPTH                 0




More information about the wine-cvs mailing list