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