wined3d: Use EXT_texture_sRGB_decode to avoid sRGB texture duplication.
This commit is contained in:
parent
a97c1ad15e
commit
75c8e9f7b4
|
@ -240,6 +240,7 @@ void basetexture_set_dirty(IWineD3DBaseTextureImpl *texture, BOOL dirty)
|
|||
/* Context activation is done by the caller. */
|
||||
HRESULT basetexture_bind(IWineD3DBaseTextureImpl *texture, BOOL srgb, BOOL *set_surface_desc)
|
||||
{
|
||||
const struct wined3d_gl_info *gl_info = &texture->resource.device->adapter->gl_info;
|
||||
HRESULT hr = WINED3D_OK;
|
||||
GLenum textureDimensions;
|
||||
BOOL isNewTexture = FALSE;
|
||||
|
@ -248,7 +249,7 @@ HRESULT basetexture_bind(IWineD3DBaseTextureImpl *texture, BOOL srgb, BOOL *set_
|
|||
TRACE("texture %p, srgb %#x, set_surface_desc %p.\n", texture, srgb, set_surface_desc);
|
||||
|
||||
texture->baseTexture.is_srgb = srgb; /* SRGB mode cache for PreLoad calls outside drawprim */
|
||||
gl_tex = basetexture_get_gl_texture(texture, srgb);
|
||||
gl_tex = basetexture_get_gl_texture(texture, gl_info, srgb);
|
||||
|
||||
textureDimensions = texture->baseTexture.target;
|
||||
|
||||
|
@ -279,7 +280,10 @@ HRESULT basetexture_bind(IWineD3DBaseTextureImpl *texture, BOOL srgb, BOOL *set_
|
|||
gl_tex->states[WINED3DTEXSTA_MIPFILTER] = WINED3DTEXF_LINEAR; /* GL_NEAREST_MIPMAP_LINEAR */
|
||||
gl_tex->states[WINED3DTEXSTA_MAXMIPLEVEL] = 0;
|
||||
gl_tex->states[WINED3DTEXSTA_MAXANISOTROPY] = 1;
|
||||
gl_tex->states[WINED3DTEXSTA_SRGBTEXTURE] = 0;
|
||||
if (gl_info->supported[EXT_TEXTURE_SRGB_DECODE])
|
||||
gl_tex->states[WINED3DTEXSTA_SRGBTEXTURE] = TRUE;
|
||||
else
|
||||
gl_tex->states[WINED3DTEXSTA_SRGBTEXTURE] = srgb;
|
||||
gl_tex->states[WINED3DTEXSTA_SHADOW] = FALSE;
|
||||
basetexture_set_dirty(texture, TRUE);
|
||||
isNewTexture = TRUE;
|
||||
|
@ -374,7 +378,7 @@ void basetexture_apply_state_changes(IWineD3DBaseTextureImpl *texture,
|
|||
|
||||
TRACE("texture %p, samplerStates %p\n", texture, samplerStates);
|
||||
|
||||
gl_tex = basetexture_get_gl_texture(texture, texture->baseTexture.is_srgb);
|
||||
gl_tex = basetexture_get_gl_texture(texture, gl_info, texture->baseTexture.is_srgb);
|
||||
|
||||
/* This function relies on the correct texture being bound and loaded. */
|
||||
|
||||
|
@ -495,6 +499,14 @@ void basetexture_apply_state_changes(IWineD3DBaseTextureImpl *texture,
|
|||
gl_tex->states[WINED3DTEXSTA_MAXANISOTROPY] = aniso;
|
||||
}
|
||||
|
||||
/* These should always be the same unless EXT_texture_sRGB_decode is supported. */
|
||||
if (samplerStates[WINED3DSAMP_SRGBTEXTURE] != gl_tex->states[WINED3DTEXSTA_SRGBTEXTURE])
|
||||
{
|
||||
glTexParameteri(textureDimensions, GL_TEXTURE_SRGB_DECODE_EXT,
|
||||
samplerStates[WINED3DSAMP_SRGBTEXTURE] ? GL_DECODE_EXT : GL_SKIP_DECODE_EXT);
|
||||
checkGLcall("glTexParameteri(GL_TEXTURE_SRGB_DECODE_EXT)");
|
||||
}
|
||||
|
||||
if (!(texture->resource.format->flags & WINED3DFMT_FLAG_SHADOW)
|
||||
!= !gl_tex->states[WINED3DTEXSTA_SHADOW])
|
||||
{
|
||||
|
|
|
@ -112,7 +112,8 @@ static void context_destroy_fbo(struct wined3d_context *context, GLuint *fbo)
|
|||
}
|
||||
|
||||
/* GL locking is done by the caller */
|
||||
static void context_apply_attachment_filter_states(IWineD3DSurfaceImpl *surface, DWORD location)
|
||||
static void context_apply_attachment_filter_states(const struct wined3d_context *context,
|
||||
IWineD3DSurfaceImpl *surface, DWORD location)
|
||||
{
|
||||
/* Update base texture states array */
|
||||
if (surface->container.type == WINED3D_CONTAINER_TEXTURE)
|
||||
|
@ -127,7 +128,8 @@ static void context_apply_attachment_filter_states(IWineD3DSurfaceImpl *surface,
|
|||
{
|
||||
case SFLAG_INTEXTURE:
|
||||
case SFLAG_INSRGBTEX:
|
||||
gl_tex = basetexture_get_gl_texture(texture, location == SFLAG_INSRGBTEX);
|
||||
gl_tex = basetexture_get_gl_texture(texture,
|
||||
context->gl_info, location == SFLAG_INSRGBTEX);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -219,7 +221,7 @@ void context_attach_depth_stencil_fbo(struct wined3d_context *context,
|
|||
else
|
||||
{
|
||||
surface_prepare_texture(depth_stencil, gl_info, FALSE);
|
||||
context_apply_attachment_filter_states(depth_stencil, SFLAG_INTEXTURE);
|
||||
context_apply_attachment_filter_states(context, depth_stencil, SFLAG_INTEXTURE);
|
||||
|
||||
if (format_flags & WINED3DFMT_FLAG_DEPTH)
|
||||
{
|
||||
|
@ -278,9 +280,9 @@ static void context_attach_surface_fbo(const struct wined3d_context *context,
|
|||
case SFLAG_INSRGBTEX:
|
||||
srgb = location == SFLAG_INSRGBTEX;
|
||||
surface_prepare_texture(surface, gl_info, srgb);
|
||||
context_apply_attachment_filter_states(surface, location);
|
||||
context_apply_attachment_filter_states(context, surface, location);
|
||||
gl_info->fbo_ops.glFramebufferTexture2D(fbo_target, GL_COLOR_ATTACHMENT0 + idx,
|
||||
surface->texture_target, surface_get_texture_name(surface, srgb),
|
||||
surface->texture_target, surface_get_texture_name(surface, gl_info, srgb),
|
||||
surface->texture_level);
|
||||
break;
|
||||
|
||||
|
@ -457,10 +459,10 @@ static void context_apply_fbo_entry(struct wined3d_context *context, GLenum targ
|
|||
for (i = 0; i < gl_info->limits.buffers; ++i)
|
||||
{
|
||||
if (entry->render_targets[i])
|
||||
context_apply_attachment_filter_states(entry->render_targets[i], entry->location);
|
||||
context_apply_attachment_filter_states(context, entry->render_targets[i], entry->location);
|
||||
}
|
||||
if (entry->depth_stencil)
|
||||
context_apply_attachment_filter_states(entry->depth_stencil, SFLAG_INTEXTURE);
|
||||
context_apply_attachment_filter_states(context, entry->depth_stencil, SFLAG_INTEXTURE);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -39,16 +39,15 @@ static HRESULT cubetexture_bind(IWineD3DBaseTextureImpl *texture, BOOL srgb)
|
|||
if (set_gl_texture_desc && SUCCEEDED(hr))
|
||||
{
|
||||
UINT sub_count = texture->baseTexture.level_count * texture->baseTexture.layer_count;
|
||||
const struct wined3d_gl_info *gl_info = &texture->resource.device->adapter->gl_info;
|
||||
BOOL srgb_tex = !gl_info->supported[EXT_TEXTURE_SRGB_DECODE] && texture->baseTexture.is_srgb;
|
||||
GLuint name = srgb_tex ? texture->baseTexture.texture_srgb.name : texture->baseTexture.texture_rgb.name;
|
||||
UINT i;
|
||||
|
||||
for (i = 0; i < sub_count; ++i)
|
||||
{
|
||||
IWineD3DSurfaceImpl *surface = surface_from_resource(texture->baseTexture.sub_resources[i]);
|
||||
|
||||
if (texture->baseTexture.is_srgb)
|
||||
surface_set_texture_name(surface, texture->baseTexture.texture_srgb.name, TRUE);
|
||||
else
|
||||
surface_set_texture_name(surface, texture->baseTexture.texture_rgb.name, FALSE);
|
||||
surface_set_texture_name(surface, name, srgb_tex);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -60,6 +59,7 @@ static void cubetexture_preload(IWineD3DBaseTextureImpl *texture, enum WINED3DSR
|
|||
{
|
||||
UINT sub_count = texture->baseTexture.level_count * texture->baseTexture.layer_count;
|
||||
IWineD3DDeviceImpl *device = texture->resource.device;
|
||||
const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
|
||||
struct wined3d_context *context = NULL;
|
||||
struct gl_texture *gl_tex;
|
||||
BOOL srgb_mode;
|
||||
|
@ -86,7 +86,7 @@ static void cubetexture_preload(IWineD3DBaseTextureImpl *texture, enum WINED3DSR
|
|||
break;
|
||||
}
|
||||
|
||||
gl_tex = basetexture_get_gl_texture(texture, srgb_mode);
|
||||
gl_tex = basetexture_get_gl_texture(texture, gl_info, srgb_mode);
|
||||
|
||||
/* We only have to activate a context for gl when we're not drawing.
|
||||
* In most cases PreLoad will be called during draw and a context was
|
||||
|
|
|
@ -4283,6 +4283,7 @@ void surface_load_ds_location(IWineD3DSurfaceImpl *surface, struct wined3d_conte
|
|||
|
||||
void surface_modify_location(IWineD3DSurfaceImpl *surface, DWORD flag, BOOL persistent)
|
||||
{
|
||||
const struct wined3d_gl_info *gl_info = &surface->resource.device->adapter->gl_info;
|
||||
IWineD3DSurfaceImpl *overlay;
|
||||
|
||||
TRACE("surface %p, location %s, persistent %#x.\n",
|
||||
|
@ -4301,6 +4302,12 @@ void surface_modify_location(IWineD3DSurfaceImpl *surface, DWORD flag, BOOL pers
|
|||
}
|
||||
}
|
||||
|
||||
if (flag & (SFLAG_INTEXTURE | SFLAG_INSRGBTEX)
|
||||
&& gl_info->supported[EXT_TEXTURE_SRGB_DECODE])
|
||||
{
|
||||
flag |= (SFLAG_INTEXTURE | SFLAG_INSRGBTEX);
|
||||
}
|
||||
|
||||
if (persistent)
|
||||
{
|
||||
if (((surface->flags & SFLAG_INTEXTURE) && !(flag & SFLAG_INTEXTURE))
|
||||
|
@ -4388,6 +4395,11 @@ HRESULT surface_load_location(IWineD3DSurfaceImpl *surface, DWORD flag, const RE
|
|||
}
|
||||
}
|
||||
|
||||
if (flag == SFLAG_INSRGBTEX && gl_info->supported[EXT_TEXTURE_SRGB_DECODE])
|
||||
{
|
||||
flag = SFLAG_INTEXTURE;
|
||||
}
|
||||
|
||||
if (surface->flags & flag)
|
||||
{
|
||||
TRACE("Location already up to date\n");
|
||||
|
@ -4648,6 +4660,12 @@ HRESULT surface_load_location(IWineD3DSurfaceImpl *surface, DWORD flag, const RE
|
|||
surface->flags |= (SFLAG_INTEXTURE | SFLAG_INDRAWABLE);
|
||||
}
|
||||
|
||||
if (surface->flags & (SFLAG_INTEXTURE | SFLAG_INSRGBTEX)
|
||||
&& gl_info->supported[EXT_TEXTURE_SRGB_DECODE])
|
||||
{
|
||||
surface->flags |= (SFLAG_INTEXTURE | SFLAG_INSRGBTEX);
|
||||
}
|
||||
|
||||
return WINED3D_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -38,18 +38,17 @@ static HRESULT texture_bind(IWineD3DBaseTextureImpl *texture, BOOL srgb)
|
|||
hr = basetexture_bind(texture, srgb, &set_gl_texture_desc);
|
||||
if (set_gl_texture_desc && SUCCEEDED(hr))
|
||||
{
|
||||
UINT i;
|
||||
const struct wined3d_gl_info *gl_info = &texture->resource.device->adapter->gl_info;
|
||||
BOOL srgb_tex = !gl_info->supported[EXT_TEXTURE_SRGB_DECODE] && texture->baseTexture.is_srgb;
|
||||
struct gl_texture *gl_tex;
|
||||
UINT i;
|
||||
|
||||
if (texture->baseTexture.is_srgb)
|
||||
gl_tex = &texture->baseTexture.texture_srgb;
|
||||
else
|
||||
gl_tex = &texture->baseTexture.texture_rgb;
|
||||
gl_tex = basetexture_get_gl_texture(texture, gl_info, srgb_tex);
|
||||
|
||||
for (i = 0; i < texture->baseTexture.level_count; ++i)
|
||||
{
|
||||
IWineD3DSurfaceImpl *surface = surface_from_resource(texture->baseTexture.sub_resources[i]);
|
||||
surface_set_texture_name(surface, gl_tex->name, texture->baseTexture.is_srgb);
|
||||
surface_set_texture_name(surface, gl_tex->name, srgb_tex);
|
||||
}
|
||||
|
||||
/* Conditinal non power of two textures use a different clamping
|
||||
|
@ -89,6 +88,7 @@ static HRESULT texture_bind(IWineD3DBaseTextureImpl *texture, BOOL srgb)
|
|||
static void texture_preload(IWineD3DBaseTextureImpl *texture, enum WINED3DSRGB srgb)
|
||||
{
|
||||
IWineD3DDeviceImpl *device = texture->resource.device;
|
||||
const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
|
||||
struct wined3d_context *context = NULL;
|
||||
struct gl_texture *gl_tex;
|
||||
unsigned int i;
|
||||
|
@ -115,7 +115,7 @@ static void texture_preload(IWineD3DBaseTextureImpl *texture, enum WINED3DSRGB s
|
|||
break;
|
||||
}
|
||||
|
||||
gl_tex = basetexture_get_gl_texture(texture, srgb_mode);
|
||||
gl_tex = basetexture_get_gl_texture(texture, gl_info, srgb_mode);
|
||||
|
||||
if (!device->isInDraw)
|
||||
{
|
||||
|
|
|
@ -1197,13 +1197,19 @@ static BOOL init_format_texture_info(struct wined3d_gl_info *gl_info)
|
|||
format->flags |= format_texture_info[i].flags;
|
||||
format->heightscale = 1.0f;
|
||||
|
||||
if (format->glGammaInternal != format->glInternal)
|
||||
{
|
||||
/* Filter sRGB capabilities if EXT_texture_sRGB is not supported. */
|
||||
if (!gl_info->supported[EXT_TEXTURE_SRGB]
|
||||
&& format->glGammaInternal != format->glInternal)
|
||||
if (!gl_info->supported[EXT_TEXTURE_SRGB])
|
||||
{
|
||||
format->glGammaInternal = format->glInternal;
|
||||
format->flags &= ~(WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE);
|
||||
}
|
||||
else if (gl_info->supported[EXT_TEXTURE_SRGB_DECODE])
|
||||
{
|
||||
format->glInternal = format->glGammaInternal;
|
||||
}
|
||||
}
|
||||
|
||||
/* Texture conversion stuff */
|
||||
format->convert = format_texture_info[i].convert;
|
||||
|
|
|
@ -1908,9 +1908,12 @@ static inline IWineD3DBaseTextureImpl *basetexture_from_resource(struct wined3d_
|
|||
return CONTAINING_RECORD(resource, IWineD3DBaseTextureImpl, resource);
|
||||
}
|
||||
|
||||
static inline struct gl_texture *basetexture_get_gl_texture(IWineD3DBaseTextureImpl *texture, BOOL srgb)
|
||||
static inline struct gl_texture *basetexture_get_gl_texture(IWineD3DBaseTextureImpl *texture,
|
||||
const struct wined3d_gl_info *gl_info, BOOL srgb)
|
||||
{
|
||||
return srgb ? &texture->baseTexture.texture_srgb : &texture->baseTexture.texture_rgb;
|
||||
return srgb && !gl_info->supported[EXT_TEXTURE_SRGB_DECODE]
|
||||
? &texture->baseTexture.texture_srgb
|
||||
: &texture->baseTexture.texture_rgb;
|
||||
}
|
||||
|
||||
void basetexture_apply_state_changes(IWineD3DBaseTextureImpl *texture,
|
||||
|
@ -2160,9 +2163,11 @@ static inline IWineD3DSurfaceImpl *surface_from_resource(struct wined3d_resource
|
|||
return CONTAINING_RECORD(resource, IWineD3DSurfaceImpl, resource);
|
||||
}
|
||||
|
||||
static inline GLuint surface_get_texture_name(IWineD3DSurfaceImpl *surface, BOOL srgb)
|
||||
static inline GLuint surface_get_texture_name(IWineD3DSurfaceImpl *surface,
|
||||
const struct wined3d_gl_info *gl_info, BOOL srgb)
|
||||
{
|
||||
return srgb ? surface->texture_name_srgb : surface->texture_name;
|
||||
return srgb && !gl_info->supported[EXT_TEXTURE_SRGB_DECODE]
|
||||
? surface->texture_name_srgb : surface->texture_name;
|
||||
}
|
||||
|
||||
void surface_add_dirty_rect(IWineD3DSurfaceImpl *surface, const RECT *dirty_rect) DECLSPEC_HIDDEN;
|
||||
|
|
Loading…
Reference in New Issue