Commit 1769ea38 authored by Józef Kucia's avatar Józef Kucia Committed by Alexandre Julliard

wined3d: Add support for separate sRGB formats.

parent 6fa62b26
...@@ -435,7 +435,8 @@ static const struct IDirect3D8Vtbl d3d8_vtbl = ...@@ -435,7 +435,8 @@ static const struct IDirect3D8Vtbl d3d8_vtbl =
BOOL d3d8_init(struct d3d8 *d3d8) BOOL d3d8_init(struct d3d8 *d3d8)
{ {
DWORD flags = WINED3D_LEGACY_DEPTH_BIAS | WINED3D_VIDMEM_ACCOUNTING DWORD flags = WINED3D_LEGACY_DEPTH_BIAS | WINED3D_VIDMEM_ACCOUNTING
| WINED3D_HANDLE_RESTORE | WINED3D_PIXEL_CENTER_INTEGER; | WINED3D_HANDLE_RESTORE | WINED3D_PIXEL_CENTER_INTEGER
| WINED3D_SRGB_READ_WRITE_CONTROL;
d3d8->IDirect3D8_iface.lpVtbl = &d3d8_vtbl; d3d8->IDirect3D8_iface.lpVtbl = &d3d8_vtbl;
d3d8->refcount = 1; d3d8->refcount = 1;
......
...@@ -670,7 +670,8 @@ static const struct IDirect3D9ExVtbl d3d9_vtbl = ...@@ -670,7 +670,8 @@ static const struct IDirect3D9ExVtbl d3d9_vtbl =
BOOL d3d9_init(struct d3d9 *d3d9, BOOL extended) BOOL d3d9_init(struct d3d9 *d3d9, BOOL extended)
{ {
DWORD flags = WINED3D_PRESENT_CONVERSION | WINED3D_HANDLE_RESTORE | WINED3D_PIXEL_CENTER_INTEGER; DWORD flags = WINED3D_PRESENT_CONVERSION | WINED3D_HANDLE_RESTORE | WINED3D_PIXEL_CENTER_INTEGER
| WINED3D_SRGB_READ_WRITE_CONTROL;
if (!extended) if (!extended)
flags |= WINED3D_VIDMEM_ACCOUNTING; flags |= WINED3D_VIDMEM_ACCOUNTING;
......
...@@ -60,7 +60,8 @@ struct FvfToDecl ...@@ -60,7 +60,8 @@ struct FvfToDecl
#define DDRAW_STRIDE_ALIGNMENT 8 #define DDRAW_STRIDE_ALIGNMENT 8
#define DDRAW_WINED3D_FLAGS (WINED3D_LEGACY_DEPTH_BIAS | WINED3D_VIDMEM_ACCOUNTING \ #define DDRAW_WINED3D_FLAGS (WINED3D_LEGACY_DEPTH_BIAS | WINED3D_VIDMEM_ACCOUNTING \
| WINED3D_RESTORE_MODE_ON_ACTIVATE | WINED3D_FOCUS_MESSAGES | WINED3D_PIXEL_CENTER_INTEGER) | WINED3D_RESTORE_MODE_ON_ACTIVATE | WINED3D_FOCUS_MESSAGES | WINED3D_PIXEL_CENTER_INTEGER \
| WINED3D_SRGB_READ_WRITE_CONTROL)
enum ddraw_device_state enum ddraw_device_state
{ {
......
...@@ -214,7 +214,7 @@ static void context_attach_surface_fbo(struct wined3d_context *context, ...@@ -214,7 +214,7 @@ static void context_attach_surface_fbo(struct wined3d_context *context,
case WINED3D_LOCATION_TEXTURE_SRGB: case WINED3D_LOCATION_TEXTURE_SRGB:
srgb = location == WINED3D_LOCATION_TEXTURE_SRGB; srgb = location == WINED3D_LOCATION_TEXTURE_SRGB;
gl_info->fbo_ops.glFramebufferTexture2D(fbo_target, GL_COLOR_ATTACHMENT0 + idx, gl_info->fbo_ops.glFramebufferTexture2D(fbo_target, GL_COLOR_ATTACHMENT0 + idx,
surface->texture_target, surface_get_texture_name(surface, gl_info, srgb), surface->texture_target, surface_get_texture_name(surface, context, srgb),
surface->texture_level); surface->texture_level);
checkGLcall("glFramebufferTexture2D()"); checkGLcall("glFramebufferTexture2D()");
break; break;
...@@ -2470,7 +2470,8 @@ BOOL context_apply_clear_state(struct wined3d_context *context, const struct win ...@@ -2470,7 +2470,8 @@ BOOL context_apply_clear_state(struct wined3d_context *context, const struct win
gl_info->gl_ops.gl.p_glEnable(GL_SCISSOR_TEST); gl_info->gl_ops.gl.p_glEnable(GL_SCISSOR_TEST);
if (gl_info->supported[ARB_FRAMEBUFFER_SRGB]) if (gl_info->supported[ARB_FRAMEBUFFER_SRGB])
{ {
if (device->state.render_states[WINED3D_RS_SRGBWRITEENABLE]) if (!(context->d3d_info->wined3d_creation_flags & WINED3D_SRGB_READ_WRITE_CONTROL)
|| device->state.render_states[WINED3D_RS_SRGBWRITEENABLE])
gl_info->gl_ops.gl.p_glEnable(GL_FRAMEBUFFER_SRGB); gl_info->gl_ops.gl.p_glEnable(GL_FRAMEBUFFER_SRGB);
else else
gl_info->gl_ops.gl.p_glDisable(GL_FRAMEBUFFER_SRGB); gl_info->gl_ops.gl.p_glDisable(GL_FRAMEBUFFER_SRGB);
......
...@@ -403,32 +403,28 @@ void device_clear_render_targets(struct wined3d_device *device, UINT rt_count, c ...@@ -403,32 +403,28 @@ void device_clear_render_targets(struct wined3d_device *device, UINT rt_count, c
} }
} }
if (!gl_info->supported[ARB_FRAMEBUFFER_SRGB] if (!gl_info->supported[ARB_FRAMEBUFFER_SRGB] && needs_srgb_write(context, &device->state, fb))
&& device->state.render_states[WINED3D_RS_SRGBWRITEENABLE])
{ {
if (fb->render_targets[0]->format_flags & WINED3DFMT_FLAG_SRGB_WRITE) if (rt_count > 1)
{ WARN("Clearing multiple sRGB render targets with no GL_ARB_framebuffer_sRGB "
if (rt_count > 1) "support, this might cause graphical issues.\n");
WARN("Clearing multiple sRGB render targets with no GL_ARB_framebuffer_sRGB "
"support, this might cause graphical issues.\n"); corrected_color.r = color->r < wined3d_srgb_const1[0]
? color->r * wined3d_srgb_const0[3]
corrected_color.r = color->r < wined3d_srgb_const1[0] : pow(color->r, wined3d_srgb_const0[0]) * wined3d_srgb_const0[1]
? color->r * wined3d_srgb_const0[3] - wined3d_srgb_const0[2];
: pow(color->r, wined3d_srgb_const0[0]) * wined3d_srgb_const0[1] corrected_color.r = min(max(corrected_color.r, 0.0f), 1.0f);
- wined3d_srgb_const0[2]; corrected_color.g = color->g < wined3d_srgb_const1[0]
corrected_color.r = min(max(corrected_color.r, 0.0f), 1.0f); ? color->g * wined3d_srgb_const0[3]
corrected_color.g = color->g < wined3d_srgb_const1[0] : pow(color->g, wined3d_srgb_const0[0]) * wined3d_srgb_const0[1]
? color->g * wined3d_srgb_const0[3] - wined3d_srgb_const0[2];
: pow(color->g, wined3d_srgb_const0[0]) * wined3d_srgb_const0[1] corrected_color.g = min(max(corrected_color.g, 0.0f), 1.0f);
- wined3d_srgb_const0[2]; corrected_color.b = color->b < wined3d_srgb_const1[0]
corrected_color.g = min(max(corrected_color.g, 0.0f), 1.0f); ? color->b * wined3d_srgb_const0[3]
corrected_color.b = color->b < wined3d_srgb_const1[0] : pow(color->b, wined3d_srgb_const0[0]) * wined3d_srgb_const0[1]
? color->b * wined3d_srgb_const0[3] - wined3d_srgb_const0[2];
: pow(color->b, wined3d_srgb_const0[0]) * wined3d_srgb_const0[1] corrected_color.b = min(max(corrected_color.b, 0.0f), 1.0f);
- wined3d_srgb_const0[2]; color = &corrected_color;
corrected_color.b = min(max(corrected_color.b, 0.0f), 1.0f);
color = &corrected_color;
}
} }
gl_info->gl_ops.gl.p_glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); gl_info->gl_ops.gl.p_glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
......
...@@ -3365,7 +3365,7 @@ static void wined3d_adapter_init_limits(struct wined3d_gl_info *gl_info) ...@@ -3365,7 +3365,7 @@ static void wined3d_adapter_init_limits(struct wined3d_gl_info *gl_info)
} }
/* Context activation is done by the caller. */ /* Context activation is done by the caller. */
static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter) static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter, DWORD wined3d_creation_flags)
{ {
static const struct static const struct
{ {
...@@ -3739,6 +3739,7 @@ static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter) ...@@ -3739,6 +3739,7 @@ static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter)
adapter->d3d_info.limits.ffp_blend_stages = fragment_caps.MaxTextureBlendStages; adapter->d3d_info.limits.ffp_blend_stages = fragment_caps.MaxTextureBlendStages;
adapter->d3d_info.limits.ffp_textures = fragment_caps.MaxSimultaneousTextures; adapter->d3d_info.limits.ffp_textures = fragment_caps.MaxSimultaneousTextures;
adapter->d3d_info.shader_color_key = fragment_caps.wined3d_caps & WINED3D_FRAGMENT_CAP_COLOR_KEY; adapter->d3d_info.shader_color_key = fragment_caps.wined3d_caps & WINED3D_FRAGMENT_CAP_COLOR_KEY;
adapter->d3d_info.wined3d_creation_flags = wined3d_creation_flags;
TRACE("Max texture stages: %u.\n", adapter->d3d_info.limits.ffp_blend_stages); TRACE("Max texture stages: %u.\n", adapter->d3d_info.limits.ffp_blend_stages);
if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT]) if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT])
...@@ -5827,7 +5828,7 @@ static void wined3d_adapter_init_fb_cfgs(struct wined3d_adapter *adapter, HDC dc ...@@ -5827,7 +5828,7 @@ static void wined3d_adapter_init_fb_cfgs(struct wined3d_adapter *adapter, HDC dc
} }
} }
static BOOL wined3d_adapter_init(struct wined3d_adapter *adapter, UINT ordinal) static BOOL wined3d_adapter_init(struct wined3d_adapter *adapter, UINT ordinal, DWORD wined3d_creation_flags)
{ {
static const DWORD supported_gl_versions[] = static const DWORD supported_gl_versions[] =
{ {
...@@ -5904,7 +5905,7 @@ static BOOL wined3d_adapter_init(struct wined3d_adapter *adapter, UINT ordinal) ...@@ -5904,7 +5905,7 @@ static BOOL wined3d_adapter_init(struct wined3d_adapter *adapter, UINT ordinal)
supported_gl_versions[i] >> 16, supported_gl_versions[i] & 0xffff); supported_gl_versions[i] >> 16, supported_gl_versions[i] & 0xffff);
} }
if (!wined3d_adapter_init_gl_caps(adapter)) if (!wined3d_adapter_init_gl_caps(adapter, wined3d_creation_flags))
{ {
ERR("Failed to initialize GL caps for adapter %p.\n", adapter); ERR("Failed to initialize GL caps for adapter %p.\n", adapter);
wined3d_caps_gl_ctx_destroy(&caps_gl_ctx); wined3d_caps_gl_ctx_destroy(&caps_gl_ctx);
...@@ -5998,7 +5999,7 @@ HRESULT wined3d_init(struct wined3d *wined3d, DWORD flags) ...@@ -5998,7 +5999,7 @@ HRESULT wined3d_init(struct wined3d *wined3d, DWORD flags)
return WINED3D_OK; return WINED3D_OK;
} }
if (!wined3d_adapter_init(&wined3d->adapters[0], 0)) if (!wined3d_adapter_init(&wined3d->adapters[0], 0, flags))
{ {
WARN("Failed to initialize adapter.\n"); WARN("Failed to initialize adapter.\n");
return E_FAIL; return E_FAIL;
......
...@@ -2615,18 +2615,14 @@ void find_ps_compile_args(const struct wined3d_state *state, const struct wined3 ...@@ -2615,18 +2615,14 @@ void find_ps_compile_args(const struct wined3d_state *state, const struct wined3
UINT i; UINT i;
memset(args, 0, sizeof(*args)); /* FIXME: Make sure all bits are set. */ memset(args, 0, sizeof(*args)); /* FIXME: Make sure all bits are set. */
if (!gl_info->supported[ARB_FRAMEBUFFER_SRGB] && state->render_states[WINED3D_RS_SRGBWRITEENABLE]) if (!gl_info->supported[ARB_FRAMEBUFFER_SRGB] && needs_srgb_write(context, state, state->fb))
{ {
unsigned int rt_fmt_flags = state->fb->render_targets[0]->format_flags; static unsigned int warned = 0;
if (rt_fmt_flags & WINED3DFMT_FLAG_SRGB_WRITE)
{
static unsigned int warned = 0;
args->srgb_correction = 1; args->srgb_correction = 1;
if (state->render_states[WINED3D_RS_ALPHABLENDENABLE] && !warned++) if (state->render_states[WINED3D_RS_ALPHABLENDENABLE] && !warned++)
WARN("Blending into a sRGB render target with no GL_ARB_framebuffer_sRGB " WARN("Blending into a sRGB render target with no GL_ARB_framebuffer_sRGB "
"support, expect rendering artifacts.\n"); "support, expect rendering artifacts.\n");
}
} }
if (shader->reg_maps.shader_version.major == 1 if (shader->reg_maps.shader_version.major == 1
......
...@@ -3477,7 +3477,7 @@ static enum wined3d_texture_address wined3d_texture_address_mode(const struct wi ...@@ -3477,7 +3477,7 @@ static enum wined3d_texture_address wined3d_texture_address_mode(const struct wi
} }
static void wined3d_sampler_desc_from_sampler_states(struct wined3d_sampler_desc *desc, static void wined3d_sampler_desc_from_sampler_states(struct wined3d_sampler_desc *desc,
const struct wined3d_gl_info *gl_info, const DWORD *sampler_states, const struct wined3d_texture *texture) const struct wined3d_context *context, const DWORD *sampler_states, const struct wined3d_texture *texture)
{ {
union union
{ {
...@@ -3513,7 +3513,8 @@ static void wined3d_sampler_desc_from_sampler_states(struct wined3d_sampler_desc ...@@ -3513,7 +3513,8 @@ static void wined3d_sampler_desc_from_sampler_states(struct wined3d_sampler_desc
desc->max_anisotropy = 1; desc->max_anisotropy = 1;
desc->compare = texture->resource.format_flags & WINED3DFMT_FLAG_SHADOW; desc->compare = texture->resource.format_flags & WINED3DFMT_FLAG_SHADOW;
desc->comparison_func = WINED3D_CMP_LESSEQUAL; desc->comparison_func = WINED3D_CMP_LESSEQUAL;
desc->srgb_decode = sampler_states[WINED3D_SAMP_SRGB_TEXTURE]; desc->srgb_decode = !(context->d3d_info->wined3d_creation_flags & WINED3D_SRGB_READ_WRITE_CONTROL)
|| sampler_states[WINED3D_SAMP_SRGB_TEXTURE];
if (!(texture->resource.format_flags & WINED3DFMT_FLAG_FILTERING)) if (!(texture->resource.format_flags & WINED3DFMT_FLAG_FILTERING))
{ {
...@@ -3525,7 +3526,7 @@ static void wined3d_sampler_desc_from_sampler_states(struct wined3d_sampler_desc ...@@ -3525,7 +3526,7 @@ static void wined3d_sampler_desc_from_sampler_states(struct wined3d_sampler_desc
if (texture->flags & WINED3D_TEXTURE_COND_NP2) if (texture->flags & WINED3D_TEXTURE_COND_NP2)
{ {
desc->mip_filter = WINED3D_TEXF_NONE; desc->mip_filter = WINED3D_TEXF_NONE;
if (gl_info->supported[WINED3D_GL_NORMALIZED_TEXRECT]) if (context->gl_info->supported[WINED3D_GL_NORMALIZED_TEXRECT])
desc->min_filter = WINED3D_TEXF_POINT; desc->min_filter = WINED3D_TEXF_POINT;
} }
} }
...@@ -3563,7 +3564,7 @@ static void sampler(struct wined3d_context *context, const struct wined3d_state ...@@ -3563,7 +3564,7 @@ static void sampler(struct wined3d_context *context, const struct wined3d_state
struct gl_texture *gl_tex; struct gl_texture *gl_tex;
unsigned int base_level; unsigned int base_level;
wined3d_sampler_desc_from_sampler_states(&desc, gl_info, sampler_states, texture); wined3d_sampler_desc_from_sampler_states(&desc, context, sampler_states, texture);
wined3d_texture_bind(texture, context, srgb); wined3d_texture_bind(texture, context, srgb);
if (!gl_info->supported[ARB_SAMPLER_OBJECTS]) if (!gl_info->supported[ARB_SAMPLER_OBJECTS])
...@@ -4785,12 +4786,11 @@ static void psorigin(struct wined3d_context *context, const struct wined3d_state ...@@ -4785,12 +4786,11 @@ static void psorigin(struct wined3d_context *context, const struct wined3d_state
void state_srgbwrite(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) void state_srgbwrite(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
{ {
unsigned int rt_fmt_flags = state->fb->render_targets[0]->format_flags;
const struct wined3d_gl_info *gl_info = context->gl_info; const struct wined3d_gl_info *gl_info = context->gl_info;
TRACE("context %p, state %p, state_id %#x.\n", context, state, state_id); TRACE("context %p, state %p, state_id %#x.\n", context, state, state_id);
if (state->render_states[WINED3D_RS_SRGBWRITEENABLE] && rt_fmt_flags & WINED3DFMT_FLAG_SRGB_WRITE) if (needs_srgb_write(context, state, state->fb))
gl_info->gl_ops.gl.p_glEnable(GL_FRAMEBUFFER_SRGB); gl_info->gl_ops.gl.p_glEnable(GL_FRAMEBUFFER_SRGB);
else else
gl_info->gl_ops.gl.p_glDisable(GL_FRAMEBUFFER_SRGB); gl_info->gl_ops.gl.p_glDisable(GL_FRAMEBUFFER_SRGB);
......
...@@ -153,7 +153,7 @@ void wined3d_texture_bind(struct wined3d_texture *texture, ...@@ -153,7 +153,7 @@ void wined3d_texture_bind(struct wined3d_texture *texture,
TRACE("texture %p, context %p, srgb %#x.\n", texture, context, srgb); TRACE("texture %p, context %p, srgb %#x.\n", texture, context, srgb);
if (gl_info->supported[EXT_TEXTURE_SRGB_DECODE]) if (!needs_separate_srgb_gl_texture(context))
srgb = FALSE; srgb = FALSE;
/* sRGB mode cache for preload() calls outside drawprim. */ /* sRGB mode cache for preload() calls outside drawprim. */
...@@ -439,14 +439,13 @@ void wined3d_texture_load(struct wined3d_texture *texture, ...@@ -439,14 +439,13 @@ void wined3d_texture_load(struct wined3d_texture *texture,
struct wined3d_context *context, BOOL srgb) struct wined3d_context *context, BOOL srgb)
{ {
UINT sub_count = texture->level_count * texture->layer_count; UINT sub_count = texture->level_count * texture->layer_count;
const struct wined3d_gl_info *gl_info = context->gl_info;
const struct wined3d_d3d_info *d3d_info = context->d3d_info; const struct wined3d_d3d_info *d3d_info = context->d3d_info;
DWORD flag; DWORD flag;
UINT i; UINT i;
TRACE("texture %p, context %p, srgb %#x.\n", texture, context, srgb); TRACE("texture %p, context %p, srgb %#x.\n", texture, context, srgb);
if (gl_info->supported[EXT_TEXTURE_SRGB_DECODE]) if (!needs_separate_srgb_gl_texture(context))
srgb = FALSE; srgb = FALSE;
if (srgb) if (srgb)
......
...@@ -58,8 +58,11 @@ static const struct wined3d_format_channels formats[] = ...@@ -58,8 +58,11 @@ static const struct wined3d_format_channels formats[] =
{WINED3DFMT_DXT4, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0}, {WINED3DFMT_DXT4, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0},
{WINED3DFMT_DXT5, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0}, {WINED3DFMT_DXT5, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0},
{WINED3DFMT_BC1_UNORM, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0}, {WINED3DFMT_BC1_UNORM, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0},
{WINED3DFMT_BC1_UNORM_SRGB, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0},
{WINED3DFMT_BC2_UNORM, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0}, {WINED3DFMT_BC2_UNORM, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0},
{WINED3DFMT_BC2_UNORM_SRGB, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0},
{WINED3DFMT_BC3_UNORM, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0}, {WINED3DFMT_BC3_UNORM, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0},
{WINED3DFMT_BC3_UNORM_SRGB, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0},
{WINED3DFMT_MULTI2_ARGB8, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0}, {WINED3DFMT_MULTI2_ARGB8, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0},
{WINED3DFMT_G8R8_G8B8, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0}, {WINED3DFMT_G8R8_G8B8, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0},
{WINED3DFMT_R8G8_B8G8, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0}, {WINED3DFMT_R8G8_B8G8, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0},
...@@ -961,17 +964,17 @@ static const struct wined3d_format_texture_info format_texture_info[] = ...@@ -961,17 +964,17 @@ static const struct wined3d_format_texture_info format_texture_info[] =
WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
| WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_COMPRESSED, | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_COMPRESSED,
EXT_TEXTURE_COMPRESSION_S3TC, NULL}, EXT_TEXTURE_COMPRESSION_S3TC, NULL},
{WINED3DFMT_BC1_UNORM, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, 0, {WINED3DFMT_BC1_UNORM, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, 0,
GL_RGBA, GL_UNSIGNED_BYTE, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0,
WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
| WINED3DFMT_FLAG_COMPRESSED, | WINED3DFMT_FLAG_COMPRESSED,
EXT_TEXTURE_COMPRESSION_S3TC, NULL}, EXT_TEXTURE_COMPRESSION_S3TC, NULL},
{WINED3DFMT_BC2_UNORM, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, 0, {WINED3DFMT_BC2_UNORM, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 0,
GL_RGBA, GL_UNSIGNED_BYTE, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0,
WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
| WINED3DFMT_FLAG_COMPRESSED, | WINED3DFMT_FLAG_COMPRESSED,
EXT_TEXTURE_COMPRESSION_S3TC, NULL}, EXT_TEXTURE_COMPRESSION_S3TC, NULL},
{WINED3DFMT_BC3_UNORM, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, 0, {WINED3DFMT_BC3_UNORM, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 0,
GL_RGBA, GL_UNSIGNED_BYTE, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0,
WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
| WINED3DFMT_FLAG_COMPRESSED, | WINED3DFMT_FLAG_COMPRESSED,
...@@ -1344,6 +1347,20 @@ static const struct wined3d_format_texture_info format_texture_info[] = ...@@ -1344,6 +1347,20 @@ static const struct wined3d_format_texture_info format_texture_info[] =
ARB_FRAMEBUFFER_OBJECT, NULL}, ARB_FRAMEBUFFER_OBJECT, NULL},
}; };
struct wined3d_format_srgb_info
{
enum wined3d_format_id srgb_format_id;
enum wined3d_format_id base_format_id;
};
static const struct wined3d_format_srgb_info format_srgb_info[] =
{
{WINED3DFMT_BC1_UNORM_SRGB, WINED3DFMT_BC1_UNORM},
{WINED3DFMT_BC2_UNORM_SRGB, WINED3DFMT_BC2_UNORM},
{WINED3DFMT_BC3_UNORM_SRGB, WINED3DFMT_BC3_UNORM},
{WINED3DFMT_R8G8B8A8_UNORM_SRGB, WINED3DFMT_R8G8B8A8_UNORM},
};
static inline int getFmtIdx(enum wined3d_format_id format_id) static inline int getFmtIdx(enum wined3d_format_id format_id)
{ {
/* First check if the format is at the position of its value. /* First check if the format is at the position of its value.
...@@ -2172,7 +2189,7 @@ static void init_format_fbo_compat_info(struct wined3d_caps_gl_ctx *ctx) ...@@ -2172,7 +2189,7 @@ static void init_format_fbo_compat_info(struct wined3d_caps_gl_ctx *ctx)
static void query_internal_format(struct wined3d_adapter *adapter, static void query_internal_format(struct wined3d_adapter *adapter,
struct wined3d_format *format, const struct wined3d_format_texture_info *texture_info, struct wined3d_format *format, const struct wined3d_format_texture_info *texture_info,
struct wined3d_gl_info *gl_info, BOOL srgb_write_supported) struct wined3d_gl_info *gl_info, BOOL srgb_write_supported, BOOL srgb_format)
{ {
GLint count, multisample_types[MAX_MULTISAMPLE_TYPES]; GLint count, multisample_types[MAX_MULTISAMPLE_TYPES];
unsigned int i, max_log2; unsigned int i, max_log2;
...@@ -2184,7 +2201,7 @@ static void query_internal_format(struct wined3d_adapter *adapter, ...@@ -2184,7 +2201,7 @@ static void query_internal_format(struct wined3d_adapter *adapter,
query_format_flag(gl_info, format, format->glInternal, GL_FILTER, query_format_flag(gl_info, format, format->glInternal, GL_FILTER,
WINED3DFMT_FLAG_FILTERING, "filtering"); WINED3DFMT_FLAG_FILTERING, "filtering");
if (format->glGammaInternal != format->glInternal) if (srgb_format || format->glGammaInternal != format->glInternal)
{ {
query_format_flag(gl_info, format, format->glGammaInternal, GL_SRGB_READ, query_format_flag(gl_info, format, format->glGammaInternal, GL_SRGB_READ,
WINED3DFMT_FLAG_SRGB_READ, "sRGB read"); WINED3DFMT_FLAG_SRGB_READ, "sRGB read");
...@@ -2211,7 +2228,7 @@ static void query_internal_format(struct wined3d_adapter *adapter, ...@@ -2211,7 +2228,7 @@ static void query_internal_format(struct wined3d_adapter *adapter,
else if (format->id != WINED3DFMT_R32G32B32A32_FLOAT && format->id != WINED3DFMT_R32_FLOAT) else if (format->id != WINED3DFMT_R32G32B32A32_FLOAT && format->id != WINED3DFMT_R32_FLOAT)
format_clear_flag(format, WINED3DFMT_FLAG_VTF); format_clear_flag(format, WINED3DFMT_FLAG_VTF);
if (format->glGammaInternal != format->glInternal) if (srgb_format || format->glGammaInternal != format->glInternal)
{ {
/* Filter sRGB capabilities if EXT_texture_sRGB is not supported. */ /* Filter sRGB capabilities if EXT_texture_sRGB is not supported. */
if (!gl_info->supported[EXT_TEXTURE_SRGB]) if (!gl_info->supported[EXT_TEXTURE_SRGB])
...@@ -2272,8 +2289,8 @@ static BOOL init_format_texture_info(struct wined3d_adapter *adapter, struct win ...@@ -2272,8 +2289,8 @@ static BOOL init_format_texture_info(struct wined3d_adapter *adapter, struct win
{ {
struct fragment_caps fragment_caps; struct fragment_caps fragment_caps;
struct shader_caps shader_caps; struct shader_caps shader_caps;
unsigned int i, j;
BOOL srgb_write; BOOL srgb_write;
unsigned int i;
adapter->fragment_pipe->get_caps(gl_info, &fragment_caps); adapter->fragment_pipe->get_caps(gl_info, &fragment_caps);
adapter->shader_backend->shader_get_caps(gl_info, &shader_caps); adapter->shader_backend->shader_get_caps(gl_info, &shader_caps);
...@@ -2282,8 +2299,8 @@ static BOOL init_format_texture_info(struct wined3d_adapter *adapter, struct win ...@@ -2282,8 +2299,8 @@ static BOOL init_format_texture_info(struct wined3d_adapter *adapter, struct win
for (i = 0; i < sizeof(format_texture_info) / sizeof(*format_texture_info); ++i) for (i = 0; i < sizeof(format_texture_info) / sizeof(*format_texture_info); ++i)
{ {
int fmt_idx = getFmtIdx(format_texture_info[i].id); int srgb_fmt_idx = -1, fmt_idx = getFmtIdx(format_texture_info[i].id);
struct wined3d_format *format; struct wined3d_format *format, *srgb_format;
if (fmt_idx == -1) if (fmt_idx == -1)
{ {
...@@ -2330,11 +2347,51 @@ static BOOL init_format_texture_info(struct wined3d_adapter *adapter, struct win ...@@ -2330,11 +2347,51 @@ static BOOL init_format_texture_info(struct wined3d_adapter *adapter, struct win
format->flags[WINED3D_GL_RES_TYPE_RB] |= format_texture_info[i].flags; format->flags[WINED3D_GL_RES_TYPE_RB] |= format_texture_info[i].flags;
format->flags[WINED3D_GL_RES_TYPE_RB] &= ~WINED3DFMT_FLAG_TEXTURE; format->flags[WINED3D_GL_RES_TYPE_RB] &= ~WINED3DFMT_FLAG_TEXTURE;
query_internal_format(adapter, format, &format_texture_info[i], gl_info, srgb_write); if (format->glGammaInternal != format->glInternal
&& !(adapter->d3d_info.wined3d_creation_flags & WINED3D_SRGB_READ_WRITE_CONTROL))
{
format->glGammaInternal = format->glInternal;
format_clear_flag(format, WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE);
}
query_internal_format(adapter, format, &format_texture_info[i], gl_info, srgb_write, FALSE);
/* Texture conversion stuff */ /* Texture conversion stuff */
format->convert = format_texture_info[i].convert; format->convert = format_texture_info[i].convert;
format->conv_byte_count = format_texture_info[i].conv_byte_count; format->conv_byte_count = format_texture_info[i].conv_byte_count;
for (j = 0; j < sizeof(format_srgb_info) / sizeof(*format_srgb_info); ++j)
{
if (format_srgb_info[j].base_format_id == format->id)
{
srgb_fmt_idx = getFmtIdx(format_srgb_info[j].srgb_format_id);
if (srgb_fmt_idx == -1)
{
ERR("Format %s (%#x) not found.\n",
debug_d3dformat(format_srgb_info[j].srgb_format_id),
format_srgb_info[j].srgb_format_id);
return FALSE;
}
break;
}
}
if (srgb_fmt_idx == -1)
continue;
srgb_format = &gl_info->formats[srgb_fmt_idx];
*srgb_format = *format;
srgb_format->id = format_srgb_info[j].srgb_format_id;
if (gl_info->supported[EXT_TEXTURE_SRGB]
&& !(adapter->d3d_info.wined3d_creation_flags & WINED3D_SRGB_READ_WRITE_CONTROL))
{
srgb_format->glInternal = format_texture_info[i].gl_srgb_internal;
srgb_format->glGammaInternal = format_texture_info[i].gl_srgb_internal;
format_set_flag(srgb_format, WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE);
query_internal_format(adapter, srgb_format, &format_texture_info[i], gl_info, srgb_write, TRUE);
}
} }
return TRUE; return TRUE;
...@@ -4414,7 +4471,6 @@ void gen_ffp_frag_op(const struct wined3d_context *context, const struct wined3d ...@@ -4414,7 +4471,6 @@ void gen_ffp_frag_op(const struct wined3d_context *context, const struct wined3d
unsigned int i; unsigned int i;
DWORD ttff; DWORD ttff;
DWORD cop, aop, carg0, carg1, carg2, aarg0, aarg1, aarg2; DWORD cop, aop, carg0, carg1, carg2, aarg0, aarg1, aarg2;
unsigned int rt_fmt_flags = state->fb->render_targets[0]->format_flags;
const struct wined3d_gl_info *gl_info = context->gl_info; const struct wined3d_gl_info *gl_info = context->gl_info;
const struct wined3d_d3d_info *d3d_info = context->d3d_info; const struct wined3d_d3d_info *d3d_info = context->d3d_info;
...@@ -4628,14 +4684,7 @@ void gen_ffp_frag_op(const struct wined3d_context *context, const struct wined3d ...@@ -4628,14 +4684,7 @@ void gen_ffp_frag_op(const struct wined3d_context *context, const struct wined3d
break; break;
} }
} }
if (!gl_info->supported[ARB_FRAMEBUFFER_SRGB] settings->sRGB_write = !gl_info->supported[ARB_FRAMEBUFFER_SRGB] && needs_srgb_write(context, state, state->fb);
&& state->render_states[WINED3D_RS_SRGBWRITEENABLE]
&& rt_fmt_flags & WINED3DFMT_FLAG_SRGB_WRITE)
{
settings->sRGB_write = 1;
} else {
settings->sRGB_write = 0;
}
if (d3d_info->vs_clipping || !use_vs(state) || !state->render_states[WINED3D_RS_CLIPPING] if (d3d_info->vs_clipping || !use_vs(state) || !state->render_states[WINED3D_RS_CLIPPING]
|| !state->render_states[WINED3D_RS_CLIPPLANEENABLE]) || !state->render_states[WINED3D_RS_CLIPPLANEENABLE])
{ {
......
...@@ -1875,6 +1875,7 @@ struct wined3d_d3d_info ...@@ -1875,6 +1875,7 @@ struct wined3d_d3d_info
BOOL vs_clipping; BOOL vs_clipping;
BOOL shader_color_key; BOOL shader_color_key;
DWORD valid_rt_mask; DWORD valid_rt_mask;
DWORD wined3d_creation_flags;
}; };
/* The adapter structure */ /* The adapter structure */
...@@ -2526,10 +2527,16 @@ static inline struct wined3d_surface *surface_from_resource(struct wined3d_resou ...@@ -2526,10 +2527,16 @@ static inline struct wined3d_surface *surface_from_resource(struct wined3d_resou
return CONTAINING_RECORD(resource, struct wined3d_surface, resource); return CONTAINING_RECORD(resource, struct wined3d_surface, resource);
} }
static inline BOOL needs_separate_srgb_gl_texture(const struct wined3d_context *context)
{
return !context->gl_info->supported[EXT_TEXTURE_SRGB_DECODE]
&& context->d3d_info->wined3d_creation_flags & WINED3D_SRGB_READ_WRITE_CONTROL;
}
static inline GLuint surface_get_texture_name(const struct wined3d_surface *surface, static inline GLuint surface_get_texture_name(const struct wined3d_surface *surface,
const struct wined3d_gl_info *gl_info, BOOL srgb) const struct wined3d_context *context, BOOL srgb)
{ {
return srgb && !gl_info->supported[EXT_TEXTURE_SRGB_DECODE] return srgb && needs_separate_srgb_gl_texture(context)
? surface->container->texture_srgb.name : surface->container->texture_rgb.name; ? surface->container->texture_srgb.name : surface->container->texture_rgb.name;
} }
...@@ -3371,6 +3378,14 @@ static inline void context_apply_state(struct wined3d_context *context, ...@@ -3371,6 +3378,14 @@ static inline void context_apply_state(struct wined3d_context *context,
state_table[rep].apply(context, state, rep); state_table[rep].apply(context, state, rep);
} }
static inline BOOL needs_srgb_write(const struct wined3d_context *context,
const struct wined3d_state *state, const struct wined3d_fb_state *fb)
{
return (!(context->d3d_info->wined3d_creation_flags & WINED3D_SRGB_READ_WRITE_CONTROL)
|| state->render_states[WINED3D_RS_SRGBWRITEENABLE])
&& fb->render_targets[0]->format_flags & WINED3DFMT_FLAG_SRGB_WRITE;
}
/* The WNDCLASS-Name for the fake window which we use to retrieve the GL capabilities */ /* The WNDCLASS-Name for the fake window which we use to retrieve the GL capabilities */
#define WINED3D_OPENGL_WINDOW_CLASS_NAME "WineD3D_OpenGL" #define WINED3D_OPENGL_WINDOW_CLASS_NAME "WineD3D_OpenGL"
......
...@@ -1230,6 +1230,7 @@ enum wined3d_display_rotation ...@@ -1230,6 +1230,7 @@ enum wined3d_display_rotation
#define WINED3D_HANDLE_RESTORE 0x00000040 #define WINED3D_HANDLE_RESTORE 0x00000040
#define WINED3D_PIXEL_CENTER_INTEGER 0x00000080 #define WINED3D_PIXEL_CENTER_INTEGER 0x00000080
#define WINED3D_LEGACY_FFP_LIGHTING 0x00000100 #define WINED3D_LEGACY_FFP_LIGHTING 0x00000100
#define WINED3D_SRGB_READ_WRITE_CONTROL 0x00000200
#define WINED3D_RESZ_CODE 0x7fa05000 #define WINED3D_RESZ_CODE 0x7fa05000
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment