Commit c585b4de authored by Stefan Dösinger's avatar Stefan Dösinger Committed by Alexandre Julliard

wined3d: Duplicate GL textures for srgb switching.

This reduces the number of srgb switching reloads quite a lot. The only situation in which a reload is needed is if the rgb copy is modified on the GL side and the srgb copy is needed.
parent 2803516d
...@@ -33,8 +33,8 @@ void basetexture_init(struct IWineD3DBaseTextureClass *texture, UINT levels, DWO ...@@ -33,8 +33,8 @@ void basetexture_init(struct IWineD3DBaseTextureClass *texture, UINT levels, DWO
texture->filterType = (usage & WINED3DUSAGE_AUTOGENMIPMAP) ? WINED3DTEXF_LINEAR : WINED3DTEXF_NONE; texture->filterType = (usage & WINED3DUSAGE_AUTOGENMIPMAP) ? WINED3DTEXF_LINEAR : WINED3DTEXF_NONE;
texture->LOD = 0; texture->LOD = 0;
texture->dirty = TRUE; texture->dirty = TRUE;
texture->srgbDirty = TRUE;
texture->is_srgb = FALSE; texture->is_srgb = FALSE;
texture->srgb_mode_change_count = 0;
} }
void basetexture_cleanup(IWineD3DBaseTexture *iface) void basetexture_cleanup(IWineD3DBaseTexture *iface)
...@@ -48,6 +48,7 @@ void basetexture_cleanup(IWineD3DBaseTexture *iface) ...@@ -48,6 +48,7 @@ void basetexture_cleanup(IWineD3DBaseTexture *iface)
ENTER_GL(); ENTER_GL();
TRACE("(%p) : Deleting texture %d\n", This, This->baseTexture.textureName); TRACE("(%p) : Deleting texture %d\n", This, This->baseTexture.textureName);
glDeleteTextures(1, &This->baseTexture.textureName); glDeleteTextures(1, &This->baseTexture.textureName);
glDeleteTextures(1, &This->baseTexture.srgbTextureName);
LEAVE_GL(); LEAVE_GL();
} }
...@@ -63,10 +64,13 @@ void basetexture_unload(IWineD3DBaseTexture *iface) ...@@ -63,10 +64,13 @@ void basetexture_unload(IWineD3DBaseTexture *iface)
ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD); ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
ENTER_GL(); ENTER_GL();
glDeleteTextures(1, &This->baseTexture.textureName); glDeleteTextures(1, &This->baseTexture.textureName);
glDeleteTextures(1, &This->baseTexture.srgbTextureName);
This->baseTexture.textureName = 0; This->baseTexture.textureName = 0;
This->baseTexture.srgbTextureName = 0;
LEAVE_GL(); LEAVE_GL();
} }
This->baseTexture.dirty = TRUE; This->baseTexture.dirty = TRUE;
This->baseTexture.srgbDirty = TRUE;
} }
/* There is no OpenGL equivalent of setLOD, getLOD. All they do anyway is prioritize texture loading /* There is no OpenGL equivalent of setLOD, getLOD. All they do anyway is prioritize texture loading
...@@ -173,54 +177,67 @@ BOOL basetexture_set_dirty(IWineD3DBaseTexture *iface, BOOL dirty) ...@@ -173,54 +177,67 @@ BOOL basetexture_set_dirty(IWineD3DBaseTexture *iface, BOOL dirty)
{ {
BOOL old; BOOL old;
IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface; IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface;
old = This->baseTexture.dirty; old = This->baseTexture.dirty || This->baseTexture.srgbDirty;
This->baseTexture.dirty = dirty; This->baseTexture.dirty = dirty;
This->baseTexture.srgbDirty = dirty;
return old; return old;
} }
BOOL basetexture_get_dirty(IWineD3DBaseTexture *iface) BOOL basetexture_get_dirty(IWineD3DBaseTexture *iface)
{ {
IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface; IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface;
return This->baseTexture.dirty; return This->baseTexture.dirty || This->baseTexture.srgbDirty;
} }
HRESULT basetexture_bind(IWineD3DBaseTexture *iface) HRESULT basetexture_bind(IWineD3DBaseTexture *iface, BOOL srgb, BOOL *set_surface_desc)
{ {
IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface; IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface;
HRESULT hr = WINED3D_OK; HRESULT hr = WINED3D_OK;
UINT textureDimensions; UINT textureDimensions;
BOOL isNewTexture = FALSE; BOOL isNewTexture = FALSE;
GLuint *texture;
DWORD *states;
TRACE("(%p) : About to bind texture\n", This); TRACE("(%p) : About to bind texture\n", This);
This->baseTexture.is_srgb = srgb; /* SRGB mode cache for PreLoad calls outside drawprim */
if(srgb) {
texture = &This->baseTexture.srgbTextureName;
states = This->baseTexture.srgbstates;
} else {
texture = &This->baseTexture.textureName;
states = This->baseTexture.states;
}
textureDimensions = IWineD3DBaseTexture_GetTextureDimensions(iface); textureDimensions = IWineD3DBaseTexture_GetTextureDimensions(iface);
ENTER_GL(); ENTER_GL();
/* Generate a texture name if we don't already have one */ /* Generate a texture name if we don't already have one */
if (This->baseTexture.textureName == 0) { if (*texture == 0) {
glGenTextures(1, &This->baseTexture.textureName); *set_surface_desc = TRUE;
glGenTextures(1, texture);
checkGLcall("glGenTextures"); checkGLcall("glGenTextures");
TRACE("Generated texture %d\n", This->baseTexture.textureName); TRACE("Generated texture %d\n", *texture);
if (This->resource.pool == WINED3DPOOL_DEFAULT) { if (This->resource.pool == WINED3DPOOL_DEFAULT) {
/* Tell opengl to try and keep this texture in video ram (well mostly) */ /* Tell opengl to try and keep this texture in video ram (well mostly) */
GLclampf tmp; GLclampf tmp;
tmp = 0.9f; tmp = 0.9f;
glPrioritizeTextures(1, &This->baseTexture.textureName, &tmp); glPrioritizeTextures(1, texture, &tmp);
} }
/* Initialise the state of the texture object /* Initialise the state of the texture object
to the openGL defaults, not the directx defaults */ to the openGL defaults, not the directx defaults */
This->baseTexture.states[WINED3DTEXSTA_ADDRESSU] = WINED3DTADDRESS_WRAP; states[WINED3DTEXSTA_ADDRESSU] = WINED3DTADDRESS_WRAP;
This->baseTexture.states[WINED3DTEXSTA_ADDRESSV] = WINED3DTADDRESS_WRAP; states[WINED3DTEXSTA_ADDRESSV] = WINED3DTADDRESS_WRAP;
This->baseTexture.states[WINED3DTEXSTA_ADDRESSW] = WINED3DTADDRESS_WRAP; states[WINED3DTEXSTA_ADDRESSW] = WINED3DTADDRESS_WRAP;
This->baseTexture.states[WINED3DTEXSTA_BORDERCOLOR] = 0; states[WINED3DTEXSTA_BORDERCOLOR] = 0;
This->baseTexture.states[WINED3DTEXSTA_MAGFILTER] = WINED3DTEXF_LINEAR; states[WINED3DTEXSTA_MAGFILTER] = WINED3DTEXF_LINEAR;
This->baseTexture.states[WINED3DTEXSTA_MINFILTER] = WINED3DTEXF_POINT; /* GL_NEAREST_MIPMAP_LINEAR */ states[WINED3DTEXSTA_MINFILTER] = WINED3DTEXF_POINT; /* GL_NEAREST_MIPMAP_LINEAR */
This->baseTexture.states[WINED3DTEXSTA_MIPFILTER] = WINED3DTEXF_LINEAR; /* GL_NEAREST_MIPMAP_LINEAR */ states[WINED3DTEXSTA_MIPFILTER] = WINED3DTEXF_LINEAR; /* GL_NEAREST_MIPMAP_LINEAR */
This->baseTexture.states[WINED3DTEXSTA_MAXMIPLEVEL] = 0; states[WINED3DTEXSTA_MAXMIPLEVEL] = 0;
This->baseTexture.states[WINED3DTEXSTA_MAXANISOTROPY] = 0; states[WINED3DTEXSTA_MAXANISOTROPY] = 0;
This->baseTexture.states[WINED3DTEXSTA_SRGBTEXTURE] = 0; states[WINED3DTEXSTA_SRGBTEXTURE] = 0;
This->baseTexture.states[WINED3DTEXSTA_ELEMENTINDEX] = 0; states[WINED3DTEXSTA_ELEMENTINDEX] = 0;
This->baseTexture.states[WINED3DTEXSTA_DMAPOFFSET] = 0; states[WINED3DTEXSTA_DMAPOFFSET] = 0;
This->baseTexture.states[WINED3DTEXSTA_TSSADDRESSW] = WINED3DTADDRESS_WRAP; states[WINED3DTEXSTA_TSSADDRESSW] = WINED3DTADDRESS_WRAP;
IWineD3DBaseTexture_SetDirty(iface, TRUE); IWineD3DBaseTexture_SetDirty(iface, TRUE);
isNewTexture = TRUE; isNewTexture = TRUE;
...@@ -228,16 +245,18 @@ HRESULT basetexture_bind(IWineD3DBaseTexture *iface) ...@@ -228,16 +245,18 @@ HRESULT basetexture_bind(IWineD3DBaseTexture *iface)
/* This means double binding the texture at creation, but keeps the code simpler all /* This means double binding the texture at creation, but keeps the code simpler all
* in all, and the run-time path free from additional checks * in all, and the run-time path free from additional checks
*/ */
glBindTexture(textureDimensions, This->baseTexture.textureName); glBindTexture(textureDimensions, *texture);
checkGLcall("glBindTexture"); checkGLcall("glBindTexture");
glTexParameteri(textureDimensions, GL_GENERATE_MIPMAP_SGIS, GL_TRUE); glTexParameteri(textureDimensions, GL_GENERATE_MIPMAP_SGIS, GL_TRUE);
checkGLcall("glTexParameteri(textureDimensions, GL_GENERATE_MIPMAP_SGIS, GL_TRUE)"); checkGLcall("glTexParameteri(textureDimensions, GL_GENERATE_MIPMAP_SGIS, GL_TRUE)");
} }
} else {
*set_surface_desc = FALSE;
} }
/* Bind the texture */ /* Bind the texture */
if (This->baseTexture.textureName != 0) { if (*texture != 0) {
glBindTexture(textureDimensions, This->baseTexture.textureName); glBindTexture(textureDimensions, *texture);
checkGLcall("glBindTexture"); checkGLcall("glBindTexture");
if (isNewTexture) { if (isNewTexture) {
/* For a new texture we have to set the textures levels after binding the texture. /* For a new texture we have to set the textures levels after binding the texture.
...@@ -298,31 +317,37 @@ void basetexture_apply_state_changes(IWineD3DBaseTexture *iface, ...@@ -298,31 +317,37 @@ void basetexture_apply_state_changes(IWineD3DBaseTexture *iface,
const DWORD samplerStates[WINED3D_HIGHEST_SAMPLER_STATE + 1]) const DWORD samplerStates[WINED3D_HIGHEST_SAMPLER_STATE + 1])
{ {
IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface; IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface;
DWORD state; DWORD state, *states;
GLint textureDimensions = IWineD3DBaseTexture_GetTextureDimensions(iface); GLint textureDimensions = IWineD3DBaseTexture_GetTextureDimensions(iface);
BOOL cond_np2 = IWineD3DBaseTexture_IsCondNP2(iface); BOOL cond_np2 = IWineD3DBaseTexture_IsCondNP2(iface);
if(This->baseTexture.is_srgb) {
states = This->baseTexture.srgbstates;
} else {
states = This->baseTexture.states;
}
/* ApplyStateChanges relies on the correct texture being bound and loaded. */ /* ApplyStateChanges relies on the correct texture being bound and loaded. */
if(samplerStates[WINED3DSAMP_ADDRESSU] != This->baseTexture.states[WINED3DTEXSTA_ADDRESSU]) { if(samplerStates[WINED3DSAMP_ADDRESSU] != states[WINED3DTEXSTA_ADDRESSU]) {
state = samplerStates[WINED3DSAMP_ADDRESSU]; state = samplerStates[WINED3DSAMP_ADDRESSU];
apply_wrap(textureDimensions, state, GL_TEXTURE_WRAP_S, cond_np2); apply_wrap(textureDimensions, state, GL_TEXTURE_WRAP_S, cond_np2);
This->baseTexture.states[WINED3DTEXSTA_ADDRESSU] = state; states[WINED3DTEXSTA_ADDRESSU] = state;
} }
if(samplerStates[WINED3DSAMP_ADDRESSV] != This->baseTexture.states[WINED3DTEXSTA_ADDRESSV]) { if(samplerStates[WINED3DSAMP_ADDRESSV] != states[WINED3DTEXSTA_ADDRESSV]) {
state = samplerStates[WINED3DSAMP_ADDRESSV]; state = samplerStates[WINED3DSAMP_ADDRESSV];
apply_wrap(textureDimensions, state, GL_TEXTURE_WRAP_T, cond_np2); apply_wrap(textureDimensions, state, GL_TEXTURE_WRAP_T, cond_np2);
This->baseTexture.states[WINED3DTEXSTA_ADDRESSV] = state; states[WINED3DTEXSTA_ADDRESSV] = state;
} }
if(samplerStates[WINED3DSAMP_ADDRESSW] != This->baseTexture.states[WINED3DTEXSTA_ADDRESSW]) { if(samplerStates[WINED3DSAMP_ADDRESSW] != states[WINED3DTEXSTA_ADDRESSW]) {
state = samplerStates[WINED3DSAMP_ADDRESSW]; state = samplerStates[WINED3DSAMP_ADDRESSW];
apply_wrap(textureDimensions, state, GL_TEXTURE_WRAP_R, cond_np2); apply_wrap(textureDimensions, state, GL_TEXTURE_WRAP_R, cond_np2);
This->baseTexture.states[WINED3DTEXSTA_ADDRESSW] = state; states[WINED3DTEXSTA_ADDRESSW] = state;
} }
if(samplerStates[WINED3DSAMP_BORDERCOLOR] != This->baseTexture.states[WINED3DTEXSTA_BORDERCOLOR]) { if(samplerStates[WINED3DSAMP_BORDERCOLOR] != states[WINED3DTEXSTA_BORDERCOLOR]) {
float col[4]; float col[4];
state = samplerStates[WINED3DSAMP_BORDERCOLOR]; state = samplerStates[WINED3DSAMP_BORDERCOLOR];
...@@ -330,10 +355,10 @@ void basetexture_apply_state_changes(IWineD3DBaseTexture *iface, ...@@ -330,10 +355,10 @@ void basetexture_apply_state_changes(IWineD3DBaseTexture *iface,
TRACE("Setting border color for %u to %x\n", textureDimensions, state); TRACE("Setting border color for %u to %x\n", textureDimensions, state);
glTexParameterfv(textureDimensions, GL_TEXTURE_BORDER_COLOR, &col[0]); glTexParameterfv(textureDimensions, GL_TEXTURE_BORDER_COLOR, &col[0]);
checkGLcall("glTexParameteri(..., GL_TEXTURE_BORDER_COLOR, ...)"); checkGLcall("glTexParameteri(..., GL_TEXTURE_BORDER_COLOR, ...)");
This->baseTexture.states[WINED3DTEXSTA_BORDERCOLOR] = state; states[WINED3DTEXSTA_BORDERCOLOR] = state;
} }
if(samplerStates[WINED3DSAMP_MAGFILTER] != This->baseTexture.states[WINED3DTEXSTA_MAGFILTER]) { if(samplerStates[WINED3DSAMP_MAGFILTER] != states[WINED3DTEXSTA_MAGFILTER]) {
GLint glValue; GLint glValue;
state = samplerStates[WINED3DSAMP_MAGFILTER]; state = samplerStates[WINED3DSAMP_MAGFILTER];
if (state > WINED3DTEXF_ANISOTROPIC) { if (state > WINED3DTEXF_ANISOTROPIC) {
...@@ -347,26 +372,26 @@ void basetexture_apply_state_changes(IWineD3DBaseTexture *iface, ...@@ -347,26 +372,26 @@ void basetexture_apply_state_changes(IWineD3DBaseTexture *iface,
!cond_np2) { !cond_np2) {
glTexParameteri(textureDimensions, GL_TEXTURE_MAX_ANISOTROPY_EXT, samplerStates[WINED3DSAMP_MAXANISOTROPY]); glTexParameteri(textureDimensions, GL_TEXTURE_MAX_ANISOTROPY_EXT, samplerStates[WINED3DSAMP_MAXANISOTROPY]);
} }
This->baseTexture.states[WINED3DTEXSTA_MAGFILTER] = state; states[WINED3DTEXSTA_MAGFILTER] = state;
} }
} }
if((samplerStates[WINED3DSAMP_MINFILTER] != This->baseTexture.states[WINED3DTEXSTA_MINFILTER] || if((samplerStates[WINED3DSAMP_MINFILTER] != states[WINED3DTEXSTA_MINFILTER] ||
samplerStates[WINED3DSAMP_MIPFILTER] != This->baseTexture.states[WINED3DTEXSTA_MIPFILTER] || samplerStates[WINED3DSAMP_MIPFILTER] != states[WINED3DTEXSTA_MIPFILTER] ||
samplerStates[WINED3DSAMP_MAXMIPLEVEL] != This->baseTexture.states[WINED3DTEXSTA_MAXMIPLEVEL])) { samplerStates[WINED3DSAMP_MAXMIPLEVEL] != states[WINED3DTEXSTA_MAXMIPLEVEL])) {
GLint glValue; GLint glValue;
This->baseTexture.states[WINED3DTEXSTA_MIPFILTER] = samplerStates[WINED3DSAMP_MIPFILTER]; states[WINED3DTEXSTA_MIPFILTER] = samplerStates[WINED3DSAMP_MIPFILTER];
This->baseTexture.states[WINED3DTEXSTA_MINFILTER] = samplerStates[WINED3DSAMP_MINFILTER]; states[WINED3DTEXSTA_MINFILTER] = samplerStates[WINED3DSAMP_MINFILTER];
This->baseTexture.states[WINED3DTEXSTA_MAXMIPLEVEL] = samplerStates[WINED3DSAMP_MAXMIPLEVEL]; states[WINED3DTEXSTA_MAXMIPLEVEL] = samplerStates[WINED3DSAMP_MAXMIPLEVEL];
if (This->baseTexture.states[WINED3DTEXSTA_MINFILTER] > WINED3DTEXF_ANISOTROPIC || if (states[WINED3DTEXSTA_MINFILTER] > WINED3DTEXF_ANISOTROPIC ||
This->baseTexture.states[WINED3DTEXSTA_MIPFILTER] > WINED3DTEXF_LINEAR) states[WINED3DTEXSTA_MIPFILTER] > WINED3DTEXF_LINEAR)
{ {
FIXME("Unrecognized or unsupported D3DSAMP_MINFILTER value %d D3DSAMP_MIPFILTER value %d\n", FIXME("Unrecognized or unsupported D3DSAMP_MINFILTER value %d D3DSAMP_MIPFILTER value %d\n",
This->baseTexture.states[WINED3DTEXSTA_MINFILTER], states[WINED3DTEXSTA_MINFILTER],
This->baseTexture.states[WINED3DTEXSTA_MIPFILTER]); states[WINED3DTEXSTA_MIPFILTER]);
} }
glValue = This->baseTexture.minMipLookup glValue = This->baseTexture.minMipLookup
[min(max(samplerStates[WINED3DSAMP_MINFILTER],WINED3DTEXF_NONE), WINED3DTEXF_ANISOTROPIC)] [min(max(samplerStates[WINED3DSAMP_MINFILTER],WINED3DTEXF_NONE), WINED3DTEXF_ANISOTROPIC)]
...@@ -379,24 +404,24 @@ void basetexture_apply_state_changes(IWineD3DBaseTexture *iface, ...@@ -379,24 +404,24 @@ void basetexture_apply_state_changes(IWineD3DBaseTexture *iface,
checkGLcall("glTexParameter GL_TEXTURE_MIN_FILTER, ..."); checkGLcall("glTexParameter GL_TEXTURE_MIN_FILTER, ...");
if(!cond_np2) { if(!cond_np2) {
if(This->baseTexture.states[WINED3DTEXSTA_MIPFILTER] == WINED3DTEXF_NONE) { if(states[WINED3DTEXSTA_MIPFILTER] == WINED3DTEXF_NONE) {
glValue = 0; glValue = 0;
} else if(This->baseTexture.states[WINED3DTEXSTA_MAXMIPLEVEL] >= This->baseTexture.levels) { } else if(states[WINED3DTEXSTA_MAXMIPLEVEL] >= This->baseTexture.levels) {
glValue = This->baseTexture.levels - 1; glValue = This->baseTexture.levels - 1;
} else { } else {
glValue = This->baseTexture.states[WINED3DTEXSTA_MAXMIPLEVEL]; glValue = states[WINED3DTEXSTA_MAXMIPLEVEL];
} }
glTexParameteri(textureDimensions, GL_TEXTURE_BASE_LEVEL, glValue); glTexParameteri(textureDimensions, GL_TEXTURE_BASE_LEVEL, glValue);
} }
} }
if(samplerStates[WINED3DSAMP_MAXANISOTROPY] != This->baseTexture.states[WINED3DTEXSTA_MAXANISOTROPY]) { if(samplerStates[WINED3DSAMP_MAXANISOTROPY] != states[WINED3DTEXSTA_MAXANISOTROPY]) {
if (GL_SUPPORT(EXT_TEXTURE_FILTER_ANISOTROPIC) && !cond_np2) { if (GL_SUPPORT(EXT_TEXTURE_FILTER_ANISOTROPIC) && !cond_np2) {
glTexParameteri(textureDimensions, GL_TEXTURE_MAX_ANISOTROPY_EXT, samplerStates[WINED3DSAMP_MAXANISOTROPY]); glTexParameteri(textureDimensions, GL_TEXTURE_MAX_ANISOTROPY_EXT, samplerStates[WINED3DSAMP_MAXANISOTROPY]);
checkGLcall("glTexParameteri GL_TEXTURE_MAX_ANISOTROPY_EXT ..."); checkGLcall("glTexParameteri GL_TEXTURE_MAX_ANISOTROPY_EXT ...");
} else { } else {
WARN("Unsupported in local OpenGL implementation: glTexParameteri GL_TEXTURE_MAX_ANISOTROPY_EXT\n"); WARN("Unsupported in local OpenGL implementation: glTexParameteri GL_TEXTURE_MAX_ANISOTROPY_EXT\n");
} }
This->baseTexture.states[WINED3DTEXSTA_MAXANISOTROPY] = samplerStates[WINED3DSAMP_MAXANISOTROPY]; states[WINED3DTEXSTA_MAXANISOTROPY] = samplerStates[WINED3DSAMP_MAXANISOTROPY];
} }
} }
...@@ -97,9 +97,9 @@ static void WINAPI IWineD3DCubeTextureImpl_PreLoad(IWineD3DCubeTexture *iface) { ...@@ -97,9 +97,9 @@ static void WINAPI IWineD3DCubeTextureImpl_PreLoad(IWineD3DCubeTexture *iface) {
IWineD3DCubeTextureImpl *This = (IWineD3DCubeTextureImpl *)iface; IWineD3DCubeTextureImpl *This = (IWineD3DCubeTextureImpl *)iface;
IWineD3DDeviceImpl *device = This->resource.wineD3DDevice; IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
BOOL srgb_mode = This->baseTexture.is_srgb; BOOL srgb_mode = This->baseTexture.is_srgb;
BOOL srgb_was_toggled = FALSE; BOOL *dirty = srgb_mode ? &This->baseTexture.srgbDirty : &This->baseTexture.dirty;
TRACE("(%p) : About to load texture: dirtified(%d)\n", This, This->baseTexture.dirty); TRACE("(%p) : About to load texture: dirtified(%d)\n", This, *dirty);
/* We only have to activate a context for gl when we're not drawing. In most cases PreLoad will be called during draw /* 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 activated at the beginning of drawPrimitive * and a context was activated at the beginning of drawPrimitive
...@@ -109,10 +109,6 @@ static void WINAPI IWineD3DCubeTextureImpl_PreLoad(IWineD3DCubeTexture *iface) { ...@@ -109,10 +109,6 @@ static void WINAPI IWineD3DCubeTextureImpl_PreLoad(IWineD3DCubeTexture *iface) {
* offscreen render targets into their texture * offscreen render targets into their texture
*/ */
ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD); ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
} else if (GL_SUPPORT(EXT_TEXTURE_SRGB) && This->baseTexture.bindCount > 0) {
srgb_mode = device->stateBlock->samplerState[This->baseTexture.sampler][WINED3DSAMP_SRGBTEXTURE];
srgb_was_toggled = (This->baseTexture.is_srgb != srgb_mode);
This->baseTexture.is_srgb = srgb_mode;
} }
if (This->resource.format == WINED3DFMT_P8 || This->resource.format == WINED3DFMT_A8P8) { if (This->resource.format == WINED3DFMT_P8 || This->resource.format == WINED3DFMT_A8P8) {
...@@ -129,34 +125,19 @@ static void WINAPI IWineD3DCubeTextureImpl_PreLoad(IWineD3DCubeTexture *iface) { ...@@ -129,34 +125,19 @@ static void WINAPI IWineD3DCubeTextureImpl_PreLoad(IWineD3DCubeTexture *iface) {
} }
} }
/* If the texture is marked dirty or the srgb sampler setting has changed since the last load then reload the surfaces */ /* If the texture is marked dirty or the srgb sampler setting has changed since the last load then reload the surfaces */
if (This->baseTexture.dirty) { if (*dirty) {
for (i = 0; i < This->baseTexture.levels; i++) { for (i = 0; i < This->baseTexture.levels; i++) {
for (j = WINED3DCUBEMAP_FACE_POSITIVE_X; j <= WINED3DCUBEMAP_FACE_NEGATIVE_Z ; j++) { for (j = WINED3DCUBEMAP_FACE_POSITIVE_X; j <= WINED3DCUBEMAP_FACE_NEGATIVE_Z ; j++) {
IWineD3DSurface_LoadTexture(This->surfaces[j][i], srgb_mode); IWineD3DSurface_LoadTexture(This->surfaces[j][i], srgb_mode);
} }
} }
} else if (srgb_was_toggled) {
/* Loop is repeated in the else block with the extra surface_add_dirty_rect() line to avoid the
* alternative of checking srgb_was_toggled in every iteration, even when the texture is just dirty */
if (This->baseTexture.srgb_mode_change_count < 20)
++This->baseTexture.srgb_mode_change_count;
else
FIXME("Cubetexture (%p) has been reloaded at least 20 times due to WINED3DSAMP_SRGBTEXTURE changes on it\'s sampler\n", This);
for (i = 0; i < This->baseTexture.levels; i++) {
for (j = WINED3DCUBEMAP_FACE_POSITIVE_X; j <= WINED3DCUBEMAP_FACE_NEGATIVE_Z ; j++) {
surface_add_dirty_rect(This->surfaces[j][i], NULL);
surface_force_reload(This->surfaces[j][i]);
IWineD3DSurface_LoadTexture(This->surfaces[j][i], srgb_mode);
}
}
} else { } else {
TRACE("(%p) Texture not dirty, nothing to do\n" , iface); TRACE("(%p) Texture not dirty, nothing to do\n" , iface);
} }
/* No longer dirty */ /* No longer dirty */
This->baseTexture.dirty = FALSE; *dirty = FALSE;
return ; return;
} }
static void WINAPI IWineD3DCubeTextureImpl_UnLoad(IWineD3DCubeTexture *iface) { static void WINAPI IWineD3DCubeTextureImpl_UnLoad(IWineD3DCubeTexture *iface) {
...@@ -171,7 +152,8 @@ static void WINAPI IWineD3DCubeTextureImpl_UnLoad(IWineD3DCubeTexture *iface) { ...@@ -171,7 +152,8 @@ static void WINAPI IWineD3DCubeTextureImpl_UnLoad(IWineD3DCubeTexture *iface) {
for (i = 0; i < This->baseTexture.levels; i++) { for (i = 0; i < This->baseTexture.levels; i++) {
for (j = WINED3DCUBEMAP_FACE_POSITIVE_X; j <= WINED3DCUBEMAP_FACE_NEGATIVE_Z ; j++) { for (j = WINED3DCUBEMAP_FACE_POSITIVE_X; j <= WINED3DCUBEMAP_FACE_NEGATIVE_Z ; j++) {
IWineD3DSurface_UnLoad(This->surfaces[j][i]); IWineD3DSurface_UnLoad(This->surfaces[j][i]);
surface_set_texture_name(This->surfaces[j][i], 0); surface_set_texture_name(This->surfaces[j][i], 0, TRUE);
surface_set_texture_name(This->surfaces[j][i], 0, FALSE);
} }
} }
...@@ -223,19 +205,23 @@ static BOOL WINAPI IWineD3DCubeTextureImpl_GetDirty(IWineD3DCubeTexture *iface) ...@@ -223,19 +205,23 @@ static BOOL WINAPI IWineD3DCubeTextureImpl_GetDirty(IWineD3DCubeTexture *iface)
return basetexture_get_dirty((IWineD3DBaseTexture *)iface); return basetexture_get_dirty((IWineD3DBaseTexture *)iface);
} }
static HRESULT WINAPI IWineD3DCubeTextureImpl_BindTexture(IWineD3DCubeTexture *iface) { static HRESULT WINAPI IWineD3DCubeTextureImpl_BindTexture(IWineD3DCubeTexture *iface, BOOL srgb) {
IWineD3DCubeTextureImpl *This = (IWineD3DCubeTextureImpl *)iface; IWineD3DCubeTextureImpl *This = (IWineD3DCubeTextureImpl *)iface;
BOOL set_gl_texture_desc = This->baseTexture.textureName == 0; BOOL set_gl_texture_desc;
HRESULT hr; HRESULT hr;
TRACE("(%p) : relay to BaseTexture\n", This); TRACE("(%p) : relay to BaseTexture\n", This);
hr = basetexture_bind((IWineD3DBaseTexture *)iface); hr = basetexture_bind((IWineD3DBaseTexture *)iface, srgb, &set_gl_texture_desc);
if (set_gl_texture_desc && SUCCEEDED(hr)) { if (set_gl_texture_desc && SUCCEEDED(hr)) {
UINT i, j; UINT i, j;
for (i = 0; i < This->baseTexture.levels; ++i) { for (i = 0; i < This->baseTexture.levels; ++i) {
for (j = WINED3DCUBEMAP_FACE_POSITIVE_X; j <= WINED3DCUBEMAP_FACE_NEGATIVE_Z; ++j) { for (j = WINED3DCUBEMAP_FACE_POSITIVE_X; j <= WINED3DCUBEMAP_FACE_NEGATIVE_Z; ++j) {
surface_set_texture_name(This->surfaces[j][i], This->baseTexture.textureName); if(This->baseTexture.is_srgb) {
surface_set_texture_name(This->surfaces[j][i], This->baseTexture.textureName, TRUE);
} else {
surface_set_texture_name(This->surfaces[j][i], This->baseTexture.srgbTextureName, FALSE);
}
} }
} }
} }
...@@ -277,7 +263,8 @@ static void WINAPI IWineD3DCubeTextureImpl_Destroy(IWineD3DCubeTexture *iface, D ...@@ -277,7 +263,8 @@ static void WINAPI IWineD3DCubeTextureImpl_Destroy(IWineD3DCubeTexture *iface, D
if (This->surfaces[j][i] != NULL) { if (This->surfaces[j][i] != NULL) {
IWineD3DSurface *surface = This->surfaces[j][i]; IWineD3DSurface *surface = This->surfaces[j][i];
/* Clean out the texture name we gave to the surface so that the surface doesn't try and release it */ /* Clean out the texture name we gave to the surface so that the surface doesn't try and release it */
surface_set_texture_name(surface, 0); surface_set_texture_name(surface, 0, TRUE);
surface_set_texture_name(surface, 0, FALSE);
surface_set_texture_target(surface, 0); surface_set_texture_target(surface, 0);
/* Cleanup the container */ /* Cleanup the container */
IWineD3DSurface_SetContainer(This->surfaces[j][i], 0); IWineD3DSurface_SetContainer(This->surfaces[j][i], 0);
...@@ -357,6 +344,7 @@ static HRESULT WINAPI IWineD3DCubeTextureImpl_AddDirtyRect(IWineD3DCubeTexture ...@@ -357,6 +344,7 @@ static HRESULT WINAPI IWineD3DCubeTextureImpl_AddDirtyRect(IWineD3DCubeTexture
HRESULT hr = WINED3DERR_INVALIDCALL; HRESULT hr = WINED3DERR_INVALIDCALL;
IWineD3DCubeTextureImpl *This = (IWineD3DCubeTextureImpl *)iface; IWineD3DCubeTextureImpl *This = (IWineD3DCubeTextureImpl *)iface;
This->baseTexture.dirty = TRUE; This->baseTexture.dirty = TRUE;
This->baseTexture.srgbDirty = TRUE;
TRACE("(%p) : dirtyfication of faceType(%d) Level (0)\n", This, FaceType); TRACE("(%p) : dirtyfication of faceType(%d) Level (0)\n", This, FaceType);
if (FaceType <= WINED3DCUBEMAP_FACE_NEGATIVE_Z) { if (FaceType <= WINED3DCUBEMAP_FACE_NEGATIVE_Z) {
surface_add_dirty_rect(This->surfaces[FaceType][0], pDirtyRect); surface_add_dirty_rect(This->surfaces[FaceType][0], pDirtyRect);
......
...@@ -5922,7 +5922,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_UpdateSurface(IWineD3DDevice *iface, ...@@ -5922,7 +5922,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_UpdateSurface(IWineD3DDevice *iface,
/* Make sure the surface is loaded and up to date */ /* Make sure the surface is loaded and up to date */
IWineD3DSurface_PreLoad(pDestinationSurface); IWineD3DSurface_PreLoad(pDestinationSurface);
IWineD3DSurface_BindTexture(pDestinationSurface); IWineD3DSurface_BindTexture(pDestinationSurface, FALSE);
IWineD3DSurface_GetGlDesc(pDestinationSurface, &glDescription); IWineD3DSurface_GetGlDesc(pDestinationSurface, &glDescription);
......
...@@ -3344,8 +3344,10 @@ static void sampler(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DCont ...@@ -3344,8 +3344,10 @@ static void sampler(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DCont
checkGLcall("glActiveTextureARB"); checkGLcall("glActiveTextureARB");
if(stateblock->textures[sampler]) { if(stateblock->textures[sampler]) {
BOOL srgb = stateblock->samplerState[sampler][WINED3DSAMP_SRGBTEXTURE];
basetexture_setsrgbcache(stateblock->textures[sampler], srgb);
IWineD3DBaseTexture_PreLoad(stateblock->textures[sampler]); IWineD3DBaseTexture_PreLoad(stateblock->textures[sampler]);
IWineD3DBaseTexture_BindTexture(stateblock->textures[sampler]); IWineD3DBaseTexture_BindTexture(stateblock->textures[sampler], srgb);
IWineD3DBaseTexture_ApplyStateChanges(stateblock->textures[sampler], stateblock->textureState[sampler], stateblock->samplerState[sampler]); IWineD3DBaseTexture_ApplyStateChanges(stateblock->textures[sampler], stateblock->textureState[sampler], stateblock->samplerState[sampler]);
if (GL_SUPPORT(EXT_TEXTURE_LOD_BIAS)) { if (GL_SUPPORT(EXT_TEXTURE_LOD_BIAS)) {
......
...@@ -42,25 +42,38 @@ void surface_force_reload(IWineD3DSurface *iface) ...@@ -42,25 +42,38 @@ void surface_force_reload(IWineD3DSurface *iface)
{ {
IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface; IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
This->Flags &= ~SFLAG_ALLOCATED; This->Flags &= ~(SFLAG_ALLOCATED | SFLAG_SRGBALLOCATED);
} }
void surface_set_texture_name(IWineD3DSurface *iface, GLuint name) void surface_set_texture_name(IWineD3DSurface *iface, GLuint new_name, BOOL srgb)
{ {
IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface; IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
GLuint *name;
DWORD flag;
TRACE("(%p) : setting texture name %u\n", This, name); if(srgb)
{
name = &This->glDescription.srgbTextureName;
flag = SFLAG_INSRGBTEX;
}
else
{
name = &This->glDescription.textureName;
flag = SFLAG_INTEXTURE;
}
TRACE("(%p) : setting texture name %u\n", This, new_name);
if (!This->glDescription.textureName && name) if (!*name && new_name)
{ {
/* FIXME: We shouldn't need to remove SFLAG_INTEXTURE if the /* FIXME: We shouldn't need to remove SFLAG_INTEXTURE if the
* surface has no texture name yet. See if we can get rid of this. */ * surface has no texture name yet. See if we can get rid of this. */
if (This->Flags & SFLAG_INTEXTURE) if (This->Flags & flag)
ERR("Surface has SFLAG_INTEXTURE set, but no texture name\n"); ERR("Surface has SFLAG_INTEXTURE set, but no texture name\n");
IWineD3DSurface_ModifyLocation(iface, SFLAG_INTEXTURE, FALSE); IWineD3DSurface_ModifyLocation(iface, flag, FALSE);
} }
This->glDescription.textureName = name; *name = new_name;
surface_force_reload(iface); surface_force_reload(iface);
} }
...@@ -85,7 +98,7 @@ void surface_set_texture_target(IWineD3DSurface *iface, GLenum target) ...@@ -85,7 +98,7 @@ void surface_set_texture_target(IWineD3DSurface *iface, GLenum target)
surface_force_reload(iface); surface_force_reload(iface);
} }
static void surface_bind_and_dirtify(IWineD3DSurfaceImpl *This) { static void surface_bind_and_dirtify(IWineD3DSurfaceImpl *This, BOOL srgb) {
int active_sampler; int active_sampler;
/* We don't need a specific texture unit, but after binding the texture the current unit is dirty. /* We don't need a specific texture unit, but after binding the texture the current unit is dirty.
...@@ -108,7 +121,7 @@ static void surface_bind_and_dirtify(IWineD3DSurfaceImpl *This) { ...@@ -108,7 +121,7 @@ static void surface_bind_and_dirtify(IWineD3DSurfaceImpl *This) {
if (active_sampler != -1) { if (active_sampler != -1) {
IWineD3DDeviceImpl_MarkStateDirty(This->resource.wineD3DDevice, STATE_SAMPLER(active_sampler)); IWineD3DDeviceImpl_MarkStateDirty(This->resource.wineD3DDevice, STATE_SAMPLER(active_sampler));
} }
IWineD3DSurface_BindTexture((IWineD3DSurface *)This); IWineD3DSurface_BindTexture((IWineD3DSurface *)This, srgb);
} }
/* This function checks if the primary render target uses the 8bit paletted format. */ /* This function checks if the primary render target uses the 8bit paletted format. */
...@@ -125,11 +138,6 @@ static BOOL primary_render_target_is_p8(IWineD3DDeviceImpl *device) ...@@ -125,11 +138,6 @@ static BOOL primary_render_target_is_p8(IWineD3DDeviceImpl *device)
/* This call just downloads data, the caller is responsible for activating the /* This call just downloads data, the caller is responsible for activating the
* right context and binding the correct texture. */ * right context and binding the correct texture. */
static void surface_download_data(IWineD3DSurfaceImpl *This) { static void surface_download_data(IWineD3DSurfaceImpl *This) {
if (0 == This->glDescription.textureName) {
ERR("Surface does not have a texture, but SFLAG_INTEXTURE is set\n");
return;
}
/* Only support read back of converted P8 surfaces */ /* Only support read back of converted P8 surfaces */
if(This->Flags & SFLAG_CONVERTED && (This->resource.format != WINED3DFMT_P8)) { if(This->Flags & SFLAG_CONVERTED && (This->resource.format != WINED3DFMT_P8)) {
FIXME("Read back converted textures unsupported, format=%s\n", debug_d3dformat(This->resource.format)); FIXME("Read back converted textures unsupported, format=%s\n", debug_d3dformat(This->resource.format));
...@@ -404,8 +412,6 @@ static void surface_allocate_surface(IWineD3DSurfaceImpl *This, GLenum internal, ...@@ -404,8 +412,6 @@ static void surface_allocate_surface(IWineD3DSurfaceImpl *This, GLenum internal,
checkGLcall("glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE)"); checkGLcall("glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE)");
} }
LEAVE_GL(); LEAVE_GL();
This->Flags |= SFLAG_ALLOCATED;
} }
/* In D3D the depth stencil dimensions have to be greater than or equal to the /* In D3D the depth stencil dimensions have to be greater than or equal to the
...@@ -669,7 +675,7 @@ static void WINAPI IWineD3DSurfaceImpl_UnLoad(IWineD3DSurface *iface) { ...@@ -669,7 +675,7 @@ static void WINAPI IWineD3DSurfaceImpl_UnLoad(IWineD3DSurface *iface) {
IWineD3DSurface_ModifyLocation(iface, SFLAG_INDRAWABLE, FALSE); IWineD3DSurface_ModifyLocation(iface, SFLAG_INDRAWABLE, FALSE);
} }
IWineD3DSurface_ModifyLocation(iface, SFLAG_INTEXTURE, FALSE); IWineD3DSurface_ModifyLocation(iface, SFLAG_INTEXTURE, FALSE);
This->Flags &= ~SFLAG_ALLOCATED; This->Flags &= ~(SFLAG_ALLOCATED | SFLAG_SRGBALLOCATED);
/* Destroy PBOs, but load them into real sysmem before */ /* Destroy PBOs, but load them into real sysmem before */
if(This->Flags & SFLAG_PBO) { if(This->Flags & SFLAG_PBO) {
...@@ -956,7 +962,7 @@ static void read_from_framebuffer(IWineD3DSurfaceImpl *This, CONST RECT *rect, v ...@@ -956,7 +962,7 @@ static void read_from_framebuffer(IWineD3DSurfaceImpl *This, CONST RECT *rect, v
} }
/* Read the framebuffer contents into a texture */ /* Read the framebuffer contents into a texture */
static void read_from_framebuffer_texture(IWineD3DSurfaceImpl *This) static void read_from_framebuffer_texture(IWineD3DSurfaceImpl *This, BOOL srgb)
{ {
IWineD3DDeviceImpl *device = This->resource.wineD3DDevice; IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
IWineD3DSwapChainImpl *swapchain; IWineD3DSwapChainImpl *swapchain;
...@@ -964,15 +970,16 @@ static void read_from_framebuffer_texture(IWineD3DSurfaceImpl *This) ...@@ -964,15 +970,16 @@ static void read_from_framebuffer_texture(IWineD3DSurfaceImpl *This)
GLenum format, internal, type; GLenum format, internal, type;
CONVERT_TYPES convert; CONVERT_TYPES convert;
GLint prevRead; GLint prevRead;
BOOL alloc_flag = srgb ? SFLAG_SRGBALLOCATED : SFLAG_ALLOCATED;
d3dfmt_get_conv(This, TRUE /* We need color keying */, TRUE /* We will use textures */, &format, &internal, &type, &convert, &bpp, This->srgb); d3dfmt_get_conv(This, TRUE /* We need color keying */, TRUE /* We will use textures */, &format, &internal, &type, &convert, &bpp, srgb);
/* Activate the surface to read from. In some situations it isn't the currently active target(e.g. backbuffer /* Activate the surface to read from. In some situations it isn't the currently active target(e.g. backbuffer
* locking during offscreen rendering). RESOURCELOAD is ok because glCopyTexSubImage2D isn't affected by any * locking during offscreen rendering). RESOURCELOAD is ok because glCopyTexSubImage2D isn't affected by any
* states in the stateblock, and no driver was found yet that had bugs in that regard. * states in the stateblock, and no driver was found yet that had bugs in that regard.
*/ */
ActivateContext(device, (IWineD3DSurface *) This, CTXUSAGE_RESOURCELOAD); ActivateContext(device, (IWineD3DSurface *) This, CTXUSAGE_RESOURCELOAD);
surface_bind_and_dirtify(This); surface_bind_and_dirtify(This, srgb);
ENTER_GL(); ENTER_GL();
glGetIntegerv(GL_READ_BUFFER, &prevRead); glGetIntegerv(GL_READ_BUFFER, &prevRead);
...@@ -1004,9 +1011,10 @@ static void read_from_framebuffer_texture(IWineD3DSurfaceImpl *This) ...@@ -1004,9 +1011,10 @@ static void read_from_framebuffer_texture(IWineD3DSurfaceImpl *This)
LEAVE_GL(); LEAVE_GL();
} }
if(!(This->Flags & SFLAG_ALLOCATED)) { if(!(This->Flags & alloc_flag)) {
surface_allocate_surface(This, internal, This->pow2Width, surface_allocate_surface(This, internal, This->pow2Width,
This->pow2Height, format, type); This->pow2Height, format, type);
This->Flags |= alloc_flag;
} }
ENTER_GL(); ENTER_GL();
...@@ -2274,8 +2282,9 @@ BOOL palette9_changed(IWineD3DSurfaceImpl *This) { ...@@ -2274,8 +2282,9 @@ BOOL palette9_changed(IWineD3DSurfaceImpl *This) {
static HRESULT WINAPI IWineD3DSurfaceImpl_LoadTexture(IWineD3DSurface *iface, BOOL srgb_mode) { static HRESULT WINAPI IWineD3DSurfaceImpl_LoadTexture(IWineD3DSurface *iface, BOOL srgb_mode) {
IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface; IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
DWORD flag = srgb_mode ? SFLAG_INSRGBTEX : SFLAG_INTEXTURE;
if (!(This->Flags & SFLAG_INTEXTURE)) { if (!(This->Flags & flag)) {
TRACE("Reloading because surface is dirty\n"); TRACE("Reloading because surface is dirty\n");
} else if(/* Reload: gl texture has ck, now no ckey is set OR */ } else if(/* Reload: gl texture has ck, now no ckey is set OR */
((This->Flags & SFLAG_GLCKEY) && (!(This->CKeyFlags & WINEDDSD_CKSRCBLT))) || ((This->Flags & SFLAG_GLCKEY) && (!(This->CKeyFlags & WINEDDSD_CKSRCBLT))) ||
...@@ -2310,8 +2319,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LoadTexture(IWineD3DSurface *iface, BO ...@@ -2310,8 +2319,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LoadTexture(IWineD3DSurface *iface, BO
return WINED3DERR_INVALIDCALL; return WINED3DERR_INVALIDCALL;
} }
This->srgb = srgb_mode; IWineD3DSurface_LoadLocation(iface, flag, NULL /* no partial locking for textures yet */);
IWineD3DSurface_LoadLocation(iface, SFLAG_INTEXTURE, NULL /* no partial locking for textures yet */);
#if 0 #if 0
{ {
...@@ -2342,7 +2350,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LoadTexture(IWineD3DSurface *iface, BO ...@@ -2342,7 +2350,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LoadTexture(IWineD3DSurface *iface, BO
return WINED3D_OK; return WINED3D_OK;
} }
static void WINAPI IWineD3DSurfaceImpl_BindTexture(IWineD3DSurface *iface) { static void WINAPI IWineD3DSurfaceImpl_BindTexture(IWineD3DSurface *iface, BOOL srgb) {
/* TODO: check for locks */ /* TODO: check for locks */
IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface; IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
IWineD3DBaseTexture *baseTexture = NULL; IWineD3DBaseTexture *baseTexture = NULL;
...@@ -2351,11 +2359,13 @@ static void WINAPI IWineD3DSurfaceImpl_BindTexture(IWineD3DSurface *iface) { ...@@ -2351,11 +2359,13 @@ static void WINAPI IWineD3DSurfaceImpl_BindTexture(IWineD3DSurface *iface) {
TRACE("(%p)Checking to see if the container is a base texture\n", This); TRACE("(%p)Checking to see if the container is a base texture\n", This);
if (IWineD3DSurface_GetContainer(iface, &IID_IWineD3DBaseTexture, (void **)&baseTexture) == WINED3D_OK) { if (IWineD3DSurface_GetContainer(iface, &IID_IWineD3DBaseTexture, (void **)&baseTexture) == WINED3D_OK) {
TRACE("Passing to container\n"); TRACE("Passing to container\n");
IWineD3DBaseTexture_BindTexture(baseTexture); IWineD3DBaseTexture_BindTexture(baseTexture, srgb);
IWineD3DBaseTexture_Release(baseTexture); IWineD3DBaseTexture_Release(baseTexture);
} else { } else {
GLuint *name;
TRACE("(%p) : Binding surface\n", This); TRACE("(%p) : Binding surface\n", This);
name = srgb ? &This->glDescription.srgbTextureName : &This->glDescription.textureName;
if(!device->isInDraw) { if(!device->isInDraw) {
ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD); ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
} }
...@@ -2363,12 +2373,12 @@ static void WINAPI IWineD3DSurfaceImpl_BindTexture(IWineD3DSurface *iface) { ...@@ -2363,12 +2373,12 @@ static void WINAPI IWineD3DSurfaceImpl_BindTexture(IWineD3DSurface *iface) {
ENTER_GL(); ENTER_GL();
if (!This->glDescription.level) { if (!This->glDescription.level) {
if (!This->glDescription.textureName) { if (!*name) {
glGenTextures(1, &This->glDescription.textureName); glGenTextures(1, name);
checkGLcall("glGenTextures"); checkGLcall("glGenTextures");
TRACE("Surface %p given name %d\n", This, This->glDescription.textureName); TRACE("Surface %p given name %d\n", This, *name);
glBindTexture(This->glDescription.target, This->glDescription.textureName); glBindTexture(This->glDescription.target, *name);
checkGLcall("glBindTexture"); checkGLcall("glBindTexture");
glTexParameteri(This->glDescription.target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(This->glDescription.target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
checkGLcall("glTexParameteri(dimension, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)"); checkGLcall("glTexParameteri(dimension, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)");
...@@ -2382,7 +2392,7 @@ static void WINAPI IWineD3DSurfaceImpl_BindTexture(IWineD3DSurface *iface) { ...@@ -2382,7 +2392,7 @@ static void WINAPI IWineD3DSurfaceImpl_BindTexture(IWineD3DSurface *iface) {
checkGLcall("glTexParameteri(dimension, GL_TEXTURE_MAG_FILTER, GL_NEAREST)"); checkGLcall("glTexParameteri(dimension, GL_TEXTURE_MAG_FILTER, GL_NEAREST)");
} }
/* This is where we should be reducing the amount of GLMemoryUsed */ /* This is where we should be reducing the amount of GLMemoryUsed */
} else if (This->glDescription.textureName) { } else if (*name) {
/* Mipmap surfaces should have a base texture container */ /* Mipmap surfaces should have a base texture container */
ERR("Mipmap surface has a glTexture bound to it!\n"); ERR("Mipmap surface has a glTexture bound to it!\n");
} }
...@@ -2466,7 +2476,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_SaveSnapshot(IWineD3DSurface *iface, c ...@@ -2466,7 +2476,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_SaveSnapshot(IWineD3DSurface *iface, c
} else { /* bind the real texture, and make sure it up to date */ } else { /* bind the real texture, and make sure it up to date */
IWineD3DSurface_PreLoad(iface); IWineD3DSurface_PreLoad(iface);
surface_bind_and_dirtify(This); surface_bind_and_dirtify(This, FALSE);
} }
allocatedMemory = HeapAlloc(GetProcessHeap(), 0, width * height * 4); allocatedMemory = HeapAlloc(GetProcessHeap(), 0, width * height * 4);
ENTER_GL(); ENTER_GL();
...@@ -2554,7 +2564,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_SetFormat(IWineD3DSurface *iface, WINE ...@@ -2554,7 +2564,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_SetFormat(IWineD3DSurface *iface, WINE
This->glDescription.glFormatInternal = glDesc->glInternal; This->glDescription.glFormatInternal = glDesc->glInternal;
This->glDescription.glType = glDesc->glType; This->glDescription.glType = glDesc->glType;
This->Flags &= ~SFLAG_ALLOCATED; This->Flags &= ~(SFLAG_ALLOCATED | SFLAG_SRGBALLOCATED);
TRACE("(%p) : glFormat %d, glFotmatInternal %d, glType %d\n", This, TRACE("(%p) : glFormat %d, glFotmatInternal %d, glType %d\n", This,
This->glDescription.glFormat, This->glDescription.glFormatInternal, This->glDescription.glType); This->glDescription.glFormat, This->glDescription.glFormatInternal, This->glDescription.glType);
} }
...@@ -2598,7 +2608,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_SetMem(IWineD3DSurface *iface, void *M ...@@ -2598,7 +2608,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_SetMem(IWineD3DSurface *iface, void *M
/* For client textures opengl has to be notified */ /* For client textures opengl has to be notified */
if(This->Flags & SFLAG_CLIENT) { if(This->Flags & SFLAG_CLIENT) {
This->Flags &= ~SFLAG_ALLOCATED; This->Flags &= ~(SFLAG_ALLOCATED | SFLAG_SRGBALLOCATED);
IWineD3DSurface_PreLoad(iface); IWineD3DSurface_PreLoad(iface);
/* And hope that the app behaves correctly and did not free the old surface memory before setting a new pointer */ /* And hope that the app behaves correctly and did not free the old surface memory before setting a new pointer */
} }
...@@ -2613,7 +2623,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_SetMem(IWineD3DSurface *iface, void *M ...@@ -2613,7 +2623,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_SetMem(IWineD3DSurface *iface, void *M
This->Flags &= ~SFLAG_USERPTR; This->Flags &= ~SFLAG_USERPTR;
if(This->Flags & SFLAG_CLIENT) { if(This->Flags & SFLAG_CLIENT) {
This->Flags &= ~SFLAG_ALLOCATED; This->Flags &= ~(SFLAG_ALLOCATED | SFLAG_SRGBALLOCATED);
/* This respecifies an empty texture and opengl knows that the old memory is gone */ /* This respecifies an empty texture and opengl knows that the old memory is gone */
IWineD3DSurface_PreLoad(iface); IWineD3DSurface_PreLoad(iface);
} }
...@@ -3776,7 +3786,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_RealizePalette(IWineD3DSurface *iface) ...@@ -3776,7 +3786,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_RealizePalette(IWineD3DSurface *iface)
BOOL use_texture = (wined3d_settings.rendertargetlock_mode == RTL_READTEX || wined3d_settings.rendertargetlock_mode == RTL_TEXTEX); BOOL use_texture = (wined3d_settings.rendertargetlock_mode == RTL_READTEX || wined3d_settings.rendertargetlock_mode == RTL_TEXTEX);
/* Check if we have hardware palette conversion if we have convert is set to NO_CONVERSION */ /* Check if we have hardware palette conversion if we have convert is set to NO_CONVERSION */
d3dfmt_get_conv(This, TRUE, use_texture, &format, &internal, &type, &convert, &bpp, This->srgb); d3dfmt_get_conv(This, TRUE, use_texture, &format, &internal, &type, &convert, &bpp, FALSE);
if((This->resource.usage & WINED3DUSAGE_RENDERTARGET) && (convert == NO_CONVERSION)) if((This->resource.usage & WINED3DUSAGE_RENDERTARGET) && (convert == NO_CONVERSION))
{ {
...@@ -4205,7 +4215,8 @@ static void WINAPI IWineD3DSurfaceImpl_ModifyLocation(IWineD3DSurface *iface, DW ...@@ -4205,7 +4215,8 @@ static void WINAPI IWineD3DSurfaceImpl_ModifyLocation(IWineD3DSurface *iface, DW
} }
if(persistent) { if(persistent) {
if((This->Flags & SFLAG_INTEXTURE) && !(flag & SFLAG_INTEXTURE)) { if(((This->Flags & SFLAG_INTEXTURE) && !(flag & SFLAG_INTEXTURE)) ||
((This->Flags & SFLAG_INSRGBTEX) && !(flag & SFLAG_INSRGBTEX))) {
if (IWineD3DSurface_GetContainer(iface, &IID_IWineD3DBaseTexture, (void **)&texture) == WINED3D_OK) { if (IWineD3DSurface_GetContainer(iface, &IID_IWineD3DBaseTexture, (void **)&texture) == WINED3D_OK) {
TRACE("Passing to container\n"); TRACE("Passing to container\n");
IWineD3DBaseTexture_SetDirty(texture, TRUE); IWineD3DBaseTexture_SetDirty(texture, TRUE);
...@@ -4222,7 +4233,7 @@ static void WINAPI IWineD3DSurfaceImpl_ModifyLocation(IWineD3DSurface *iface, DW ...@@ -4222,7 +4233,7 @@ static void WINAPI IWineD3DSurfaceImpl_ModifyLocation(IWineD3DSurface *iface, DW
} }
} }
} else { } else {
if((This->Flags & SFLAG_INTEXTURE) && (flag & SFLAG_INTEXTURE)) { if((This->Flags & (SFLAG_INTEXTURE | SFLAG_INSRGBTEX)) && (flag & (SFLAG_INTEXTURE | SFLAG_INSRGBTEX))) {
if (IWineD3DSurface_GetContainer(iface, &IID_IWineD3DBaseTexture, (void **)&texture) == WINED3D_OK) { if (IWineD3DSurface_GetContainer(iface, &IID_IWineD3DBaseTexture, (void **)&texture) == WINED3D_OK) {
TRACE("Passing to container\n"); TRACE("Passing to container\n");
IWineD3DBaseTexture_SetDirty(texture, TRUE); IWineD3DBaseTexture_SetDirty(texture, TRUE);
...@@ -4231,6 +4242,10 @@ static void WINAPI IWineD3DSurfaceImpl_ModifyLocation(IWineD3DSurface *iface, DW ...@@ -4231,6 +4242,10 @@ static void WINAPI IWineD3DSurfaceImpl_ModifyLocation(IWineD3DSurface *iface, DW
} }
This->Flags &= ~flag; This->Flags &= ~flag;
} }
if(!(This->Flags & SFLAG_LOCATIONS)) {
ERR("%p: Surface does not have any up to date location\n", This);
}
} }
struct coords { struct coords {
...@@ -4451,6 +4466,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LoadLocation(IWineD3DSurface *iface, D ...@@ -4451,6 +4466,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LoadLocation(IWineD3DSurface *iface, D
int bpp; int bpp;
int width, pitch, outpitch; int width, pitch, outpitch;
BYTE *mem; BYTE *mem;
BOOL drawable_read_ok = TRUE;
if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) { if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) {
if (SUCCEEDED(IWineD3DSurface_GetContainer(iface, &IID_IWineD3DSwapChain, (void **)&swapchain))) { if (SUCCEEDED(IWineD3DSurface_GetContainer(iface, &IID_IWineD3DSwapChain, (void **)&swapchain))) {
...@@ -4461,6 +4477,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LoadLocation(IWineD3DSurface *iface, D ...@@ -4461,6 +4477,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LoadLocation(IWineD3DSurface *iface, D
/* With ORM_FBO, SFLAG_INTEXTURE and SFLAG_INDRAWABLE are the same for offscreen targets. /* With ORM_FBO, SFLAG_INTEXTURE and SFLAG_INDRAWABLE are the same for offscreen targets.
* Prefer SFLAG_INTEXTURE. */ * Prefer SFLAG_INTEXTURE. */
if (flag == SFLAG_INDRAWABLE) flag = SFLAG_INTEXTURE; if (flag == SFLAG_INDRAWABLE) flag = SFLAG_INTEXTURE;
drawable_read_ok = FALSE;
} }
} }
...@@ -4477,7 +4494,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LoadLocation(IWineD3DSurface *iface, D ...@@ -4477,7 +4494,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LoadLocation(IWineD3DSurface *iface, D
} }
if(!(This->Flags & SFLAG_LOCATIONS)) { if(!(This->Flags & SFLAG_LOCATIONS)) {
ERR("Surface does not have any up to date location\n"); ERR("%p: Surface does not have any up to date location\n", This);
This->Flags |= SFLAG_LOST; This->Flags |= SFLAG_LOST;
return WINED3DERR_DEVICELOST; return WINED3DERR_DEVICELOST;
} }
...@@ -4486,9 +4503,9 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LoadLocation(IWineD3DSurface *iface, D ...@@ -4486,9 +4503,9 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LoadLocation(IWineD3DSurface *iface, D
surface_prepare_system_memory(This); surface_prepare_system_memory(This);
/* Download the surface to system memory */ /* Download the surface to system memory */
if(This->Flags & SFLAG_INTEXTURE) { if(This->Flags & (SFLAG_INTEXTURE | SFLAG_INSRGBTEX)) {
if(!device->isInDraw) ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD); if(!device->isInDraw) ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
surface_bind_and_dirtify(This); surface_bind_and_dirtify(This, !(This->Flags & SFLAG_INTEXTURE));
surface_download_data(This); surface_download_data(This);
} else { } else {
...@@ -4500,7 +4517,15 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LoadLocation(IWineD3DSurface *iface, D ...@@ -4500,7 +4517,15 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LoadLocation(IWineD3DSurface *iface, D
if(This->Flags & SFLAG_INTEXTURE) { if(This->Flags & SFLAG_INTEXTURE) {
surface_blt_to_drawable(This, rect); surface_blt_to_drawable(This, rect);
} else { } else {
d3dfmt_get_conv(This, TRUE /* We need color keying */, FALSE /* We won't use textures */, &format, &internal, &type, &convert, &bpp, This->srgb); if((This->Flags & SFLAG_LOCATIONS) == SFLAG_INSRGBTEX) {
/* This needs a shader to convert the srgb data sampled from the GL texture into RGB
* values, otherwise we get incorrect values in the target. For now go the slow way
* via a system memory copy
*/
IWineD3DSurfaceImpl_LoadLocation(iface, SFLAG_INSYSMEM, rect);
}
d3dfmt_get_conv(This, TRUE /* We need color keying */, FALSE /* We won't use textures */, &format, &internal, &type, &convert, &bpp, FALSE);
/* The width is in 'length' not in bytes */ /* The width is in 'length' not in bytes */
width = This->currentDesc.Width; width = This->currentDesc.Width;
...@@ -4539,22 +4564,30 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LoadLocation(IWineD3DSurface *iface, D ...@@ -4539,22 +4564,30 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LoadLocation(IWineD3DSurface *iface, D
if((mem != This->resource.allocatedMemory) && !(This->Flags & SFLAG_PBO)) if((mem != This->resource.allocatedMemory) && !(This->Flags & SFLAG_PBO))
HeapFree(GetProcessHeap(), 0, mem); HeapFree(GetProcessHeap(), 0, mem);
} }
} else /* if(flag == SFLAG_INTEXTURE) */ { } else /* if(flag & (SFLAG_INTEXTURE | SFLAG_INSRGBTEX)) */ {
if (This->Flags & SFLAG_INDRAWABLE) { if (drawable_read_ok && (This->Flags & SFLAG_INDRAWABLE)) {
read_from_framebuffer_texture(This); read_from_framebuffer_texture(This, flag == SFLAG_INSRGBTEX);
} else { /* Upload from system memory */ } else { /* Upload from system memory */
d3dfmt_get_conv(This, TRUE /* We need color keying */, TRUE /* We will use textures */, &format, &internal, &type, &convert, &bpp, This->srgb); BOOL srgb = flag == SFLAG_INSRGBTEX;
DWORD alloc_flag = srgb ? SFLAG_SRGBALLOCATED : SFLAG_ALLOCATED;
if(!device->isInDraw) ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD); d3dfmt_get_conv(This, TRUE /* We need color keying */, TRUE /* We will use textures */, &format, &internal, &type, &convert, &bpp, srgb);
surface_bind_and_dirtify(This);
/* The only place where LoadTexture() might get called when isInDraw=1 if(srgb) {
* is ActivateContext where lastActiveRenderTarget is preloaded. if((This->Flags & (SFLAG_INTEXTURE | SFLAG_INSYSMEM)) == SFLAG_INTEXTURE) {
*/ /* Performance warning ... */
if(iface == device->lastActiveRenderTarget && device->isInDraw) FIXME("Downloading srgb texture to reload it as rgb\n");
ERR("Reading back render target but SFLAG_INDRAWABLE not set\n"); IWineD3DSurfaceImpl_LoadLocation(iface, SFLAG_INSYSMEM, rect);
}
} else {
if((This->Flags & SFLAG_LOCATIONS) == SFLAG_INSRGBTEX) {
/* Performance warning ... */
FIXME("Downloading srgb texture to reload it as srgb\n");
IWineD3DSurfaceImpl_LoadLocation(iface, SFLAG_INSYSMEM, rect);
}
}
/* Otherwise: System memory copy must be most up to date */ if(!device->isInDraw) ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
surface_bind_and_dirtify(This, srgb);
if(This->CKeyFlags & WINEDDSD_CKSRCBLT) { if(This->CKeyFlags & WINEDDSD_CKSRCBLT) {
This->Flags |= SFLAG_GLCKEY; This->Flags |= SFLAG_GLCKEY;
...@@ -4604,8 +4637,9 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LoadLocation(IWineD3DSurface *iface, D ...@@ -4604,8 +4637,9 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LoadLocation(IWineD3DSurface *iface, D
if ((This->Flags & SFLAG_NONPOW2) && !(This->Flags & SFLAG_OVERSIZE)) { if ((This->Flags & SFLAG_NONPOW2) && !(This->Flags & SFLAG_OVERSIZE)) {
TRACE("non power of two support\n"); TRACE("non power of two support\n");
if(!(This->Flags & SFLAG_ALLOCATED)) { if(!(This->Flags & alloc_flag)) {
surface_allocate_surface(This, internal, This->pow2Width, This->pow2Height, format, type); surface_allocate_surface(This, internal, This->pow2Width, This->pow2Height, format, type);
This->Flags |= alloc_flag;
} }
if (mem || (This->Flags & SFLAG_PBO)) { if (mem || (This->Flags & SFLAG_PBO)) {
surface_upload_data(This, internal, This->currentDesc.Width, This->currentDesc.Height, format, type, mem); surface_upload_data(This, internal, This->currentDesc.Width, This->currentDesc.Height, format, type, mem);
...@@ -4614,8 +4648,9 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LoadLocation(IWineD3DSurface *iface, D ...@@ -4614,8 +4648,9 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LoadLocation(IWineD3DSurface *iface, D
/* When making the realloc conditional, keep in mind that GL_APPLE_client_storage may be in use, and This->resource.allocatedMemory /* When making the realloc conditional, keep in mind that GL_APPLE_client_storage may be in use, and This->resource.allocatedMemory
* changed. So also keep track of memory changes. In this case the texture has to be reallocated * changed. So also keep track of memory changes. In this case the texture has to be reallocated
*/ */
if(!(This->Flags & SFLAG_ALLOCATED)) { if(!(This->Flags & alloc_flag)) {
surface_allocate_surface(This, internal, This->glRect.right - This->glRect.left, This->glRect.bottom - This->glRect.top, format, type); surface_allocate_surface(This, internal, This->glRect.right - This->glRect.left, This->glRect.bottom - This->glRect.top, format, type);
This->Flags |= alloc_flag;
} }
if (mem || (This->Flags & SFLAG_PBO)) { if (mem || (This->Flags & SFLAG_PBO)) {
surface_upload_data(This, internal, This->glRect.right - This->glRect.left, This->glRect.bottom - This->glRect.top, format, type, mem); surface_upload_data(This, internal, This->glRect.right - This->glRect.left, This->glRect.bottom - This->glRect.top, format, type, mem);
......
...@@ -1862,7 +1862,7 @@ HRESULT WINAPI IWineD3DBaseSurfaceImpl_LockRect(IWineD3DSurface *iface, WINED3DL ...@@ -1862,7 +1862,7 @@ HRESULT WINAPI IWineD3DBaseSurfaceImpl_LockRect(IWineD3DSurface *iface, WINED3DL
return WINED3D_OK; return WINED3D_OK;
} }
void WINAPI IWineD3DBaseSurfaceImpl_BindTexture(IWineD3DSurface *iface) { void WINAPI IWineD3DBaseSurfaceImpl_BindTexture(IWineD3DSurface *iface, BOOL srgb) {
ERR("Should not be called on base texture\n"); ERR("Should not be called on base texture\n");
return; return;
} }
......
...@@ -99,7 +99,7 @@ static void WINAPI IWineD3DTextureImpl_PreLoad(IWineD3DTexture *iface) { ...@@ -99,7 +99,7 @@ static void WINAPI IWineD3DTextureImpl_PreLoad(IWineD3DTexture *iface) {
IWineD3DTextureImpl *This = (IWineD3DTextureImpl *)iface; IWineD3DTextureImpl *This = (IWineD3DTextureImpl *)iface;
IWineD3DDeviceImpl *device = This->resource.wineD3DDevice; IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
BOOL srgb_mode = This->baseTexture.is_srgb; BOOL srgb_mode = This->baseTexture.is_srgb;
BOOL srgb_was_toggled = FALSE; BOOL *dirty = srgb_mode ? &This->baseTexture.srgbDirty : &This->baseTexture.dirty;
TRACE("(%p) : About to load texture\n", This); TRACE("(%p) : About to load texture\n", This);
...@@ -108,10 +108,6 @@ static void WINAPI IWineD3DTextureImpl_PreLoad(IWineD3DTexture *iface) { ...@@ -108,10 +108,6 @@ static void WINAPI IWineD3DTextureImpl_PreLoad(IWineD3DTexture *iface) {
* recursive calls * recursive calls
*/ */
ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD); ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
} else if (GL_SUPPORT(EXT_TEXTURE_SRGB) && This->baseTexture.bindCount > 0) {
srgb_mode = device->stateBlock->samplerState[This->baseTexture.sampler][WINED3DSAMP_SRGBTEXTURE];
srgb_was_toggled = This->baseTexture.is_srgb != srgb_mode;
This->baseTexture.is_srgb = srgb_mode;
} }
if (This->resource.format == WINED3DFMT_P8 || This->resource.format == WINED3DFMT_A8P8) { if (This->resource.format == WINED3DFMT_P8 || This->resource.format == WINED3DFMT_A8P8) {
...@@ -126,27 +122,16 @@ static void WINAPI IWineD3DTextureImpl_PreLoad(IWineD3DTexture *iface) { ...@@ -126,27 +122,16 @@ static void WINAPI IWineD3DTextureImpl_PreLoad(IWineD3DTexture *iface) {
} }
} }
/* If the texture is marked dirty or the srgb sampler setting has changed since the last load then reload the surfaces */ /* If the texture is marked dirty or the srgb sampler setting has changed since the last load then reload the surfaces */
if (This->baseTexture.dirty) { if (*dirty) {
for (i = 0; i < This->baseTexture.levels; i++) { for (i = 0; i < This->baseTexture.levels; i++) {
IWineD3DSurface_LoadTexture(This->surfaces[i], srgb_mode); IWineD3DSurface_LoadTexture(This->surfaces[i], srgb_mode);
} }
} else if (srgb_was_toggled) {
if (This->baseTexture.srgb_mode_change_count < 20)
++This->baseTexture.srgb_mode_change_count;
else
FIXME("Texture (%p) has been reloaded at least 20 times due to WINED3DSAMP_SRGBTEXTURE changes on it\'s sampler\n", This);
for (i = 0; i < This->baseTexture.levels; i++) {
surface_add_dirty_rect(This->surfaces[i], NULL);
surface_force_reload(This->surfaces[i]);
IWineD3DSurface_LoadTexture(This->surfaces[i], srgb_mode);
}
} else { } else {
TRACE("(%p) Texture not dirty, nothing to do\n" , iface); TRACE("(%p) Texture not dirty, nothing to do\n" , iface);
} }
/* No longer dirty */ /* No longer dirty */
This->baseTexture.dirty = FALSE; *dirty = FALSE;
return ; return ;
} }
...@@ -162,7 +147,8 @@ static void WINAPI IWineD3DTextureImpl_UnLoad(IWineD3DTexture *iface) { ...@@ -162,7 +147,8 @@ static void WINAPI IWineD3DTextureImpl_UnLoad(IWineD3DTexture *iface) {
*/ */
for (i = 0; i < This->baseTexture.levels; i++) { for (i = 0; i < This->baseTexture.levels; i++) {
IWineD3DSurface_UnLoad(This->surfaces[i]); IWineD3DSurface_UnLoad(This->surfaces[i]);
surface_set_texture_name(This->surfaces[i], 0); surface_set_texture_name(This->surfaces[i], 0, FALSE); /* Delete rgb name */
surface_set_texture_name(This->surfaces[i], 0, TRUE); /* delete srgb name */
} }
basetexture_unload((IWineD3DBaseTexture *)iface); basetexture_unload((IWineD3DBaseTexture *)iface);
...@@ -212,18 +198,22 @@ static BOOL WINAPI IWineD3DTextureImpl_GetDirty(IWineD3DTexture *iface) { ...@@ -212,18 +198,22 @@ static BOOL WINAPI IWineD3DTextureImpl_GetDirty(IWineD3DTexture *iface) {
return basetexture_get_dirty((IWineD3DBaseTexture *)iface); return basetexture_get_dirty((IWineD3DBaseTexture *)iface);
} }
static HRESULT WINAPI IWineD3DTextureImpl_BindTexture(IWineD3DTexture *iface) { static HRESULT WINAPI IWineD3DTextureImpl_BindTexture(IWineD3DTexture *iface, BOOL srgb) {
IWineD3DTextureImpl *This = (IWineD3DTextureImpl *)iface; IWineD3DTextureImpl *This = (IWineD3DTextureImpl *)iface;
BOOL set_gl_texture_desc = This->baseTexture.textureName == 0; BOOL set_gl_texture_desc;
HRESULT hr; HRESULT hr;
TRACE("(%p) : relay to BaseTexture\n", This); TRACE("(%p) : relay to BaseTexture\n", This);
hr = basetexture_bind((IWineD3DBaseTexture *)iface); hr = basetexture_bind((IWineD3DBaseTexture *)iface, srgb, &set_gl_texture_desc);
if (set_gl_texture_desc && SUCCEEDED(hr)) { if (set_gl_texture_desc && SUCCEEDED(hr)) {
UINT i; UINT i;
for (i = 0; i < This->baseTexture.levels; ++i) { for (i = 0; i < This->baseTexture.levels; ++i) {
surface_set_texture_name(This->surfaces[i], This->baseTexture.textureName); if(This->baseTexture.is_srgb) {
surface_set_texture_name(This->surfaces[i], This->baseTexture.srgbTextureName, TRUE);
} else {
surface_set_texture_name(This->surfaces[i], This->baseTexture.textureName, FALSE);
}
} }
/* Conditinal non power of two textures use a different clamping default. If we're using the GL_WINE_normalized_texrect /* Conditinal non power of two textures use a different clamping default. If we're using the GL_WINE_normalized_texrect
* partial driver emulation, we're dealing with a GL_TEXTURE_2D texture which has the address mode set to repeat - something * partial driver emulation, we're dealing with a GL_TEXTURE_2D texture which has the address mode set to repeat - something
...@@ -284,7 +274,8 @@ static void WINAPI IWineD3DTextureImpl_Destroy(IWineD3DTexture *iface, D3DCB_DES ...@@ -284,7 +274,8 @@ static void WINAPI IWineD3DTextureImpl_Destroy(IWineD3DTexture *iface, D3DCB_DES
for (i = 0; i < This->baseTexture.levels; i++) { for (i = 0; i < This->baseTexture.levels; i++) {
if (This->surfaces[i] != NULL) { if (This->surfaces[i] != NULL) {
/* Clean out the texture name we gave to the surface so that the surface doesn't try and release it */ /* Clean out the texture name we gave to the surface so that the surface doesn't try and release it */
surface_set_texture_name(This->surfaces[i], 0); surface_set_texture_name(This->surfaces[i], 0, TRUE);
surface_set_texture_name(This->surfaces[i], 0, FALSE);
surface_set_texture_target(This->surfaces[i], 0); surface_set_texture_target(This->surfaces[i], 0);
IWineD3DSurface_SetContainer(This->surfaces[i], 0); IWineD3DSurface_SetContainer(This->surfaces[i], 0);
D3DCB_DestroySurface(This->surfaces[i]); D3DCB_DestroySurface(This->surfaces[i]);
...@@ -359,6 +350,7 @@ static HRESULT WINAPI IWineD3DTextureImpl_UnlockRect(IWineD3DTexture *iface, UIN ...@@ -359,6 +350,7 @@ static HRESULT WINAPI IWineD3DTextureImpl_UnlockRect(IWineD3DTexture *iface, UIN
static HRESULT WINAPI IWineD3DTextureImpl_AddDirtyRect(IWineD3DTexture *iface, CONST RECT* pDirtyRect) { static HRESULT WINAPI IWineD3DTextureImpl_AddDirtyRect(IWineD3DTexture *iface, CONST RECT* pDirtyRect) {
IWineD3DTextureImpl *This = (IWineD3DTextureImpl *)iface; IWineD3DTextureImpl *This = (IWineD3DTextureImpl *)iface;
This->baseTexture.dirty = TRUE; This->baseTexture.dirty = TRUE;
This->baseTexture.srgbDirty = TRUE;
TRACE("(%p) : dirtyfication of surface Level (0)\n", This); TRACE("(%p) : dirtyfication of surface Level (0)\n", This);
surface_add_dirty_rect(This->surfaces[0], pDirtyRect); surface_add_dirty_rect(This->surfaces[0], pDirtyRect);
......
...@@ -57,7 +57,7 @@ static void volume_bind_and_dirtify(IWineD3DVolume *iface) { ...@@ -57,7 +57,7 @@ static void volume_bind_and_dirtify(IWineD3DVolume *iface) {
} }
if (SUCCEEDED(IWineD3DSurface_GetContainer(iface, &IID_IWineD3DVolumeTexture, (void **)&texture))) { if (SUCCEEDED(IWineD3DSurface_GetContainer(iface, &IID_IWineD3DVolumeTexture, (void **)&texture))) {
IWineD3DVolumeTexture_BindTexture(texture); IWineD3DVolumeTexture_BindTexture(texture, FALSE);
IWineD3DVolumeTexture_Release(texture); IWineD3DVolumeTexture_Release(texture);
} else { } else {
ERR("Volume should be part of a volume texture\n"); ERR("Volume should be part of a volume texture\n");
......
...@@ -113,11 +113,6 @@ static void WINAPI IWineD3DVolumeTextureImpl_PreLoad(IWineD3DVolumeTexture *ifac ...@@ -113,11 +113,6 @@ static void WINAPI IWineD3DVolumeTextureImpl_PreLoad(IWineD3DVolumeTexture *ifac
for (i = 0; i < This->baseTexture.levels; i++) for (i = 0; i < This->baseTexture.levels; i++)
IWineD3DVolume_LoadTexture(This->volumes[i], i, srgb_mode); IWineD3DVolume_LoadTexture(This->volumes[i], i, srgb_mode);
} else if (srgb_was_toggled) { } else if (srgb_was_toggled) {
if (This->baseTexture.srgb_mode_change_count < 20)
++This->baseTexture.srgb_mode_change_count;
else
FIXME("Volumetexture (%p) has been reloaded at least 20 times due to WINED3DSAMP_SRGBTEXTURE changes on it\'s sampler\n", This);
for (i = 0; i < This->baseTexture.levels; i++) { for (i = 0; i < This->baseTexture.levels; i++) {
volume_add_dirty_box(This->volumes[i], NULL); volume_add_dirty_box(This->volumes[i], NULL);
IWineD3DVolume_LoadTexture(This->volumes[i], i, srgb_mode); IWineD3DVolume_LoadTexture(This->volumes[i], i, srgb_mode);
...@@ -192,10 +187,11 @@ static BOOL WINAPI IWineD3DVolumeTextureImpl_GetDirty(IWineD3DVolumeTexture *ifa ...@@ -192,10 +187,11 @@ static BOOL WINAPI IWineD3DVolumeTextureImpl_GetDirty(IWineD3DVolumeTexture *ifa
return basetexture_get_dirty((IWineD3DBaseTexture *)iface); return basetexture_get_dirty((IWineD3DBaseTexture *)iface);
} }
static HRESULT WINAPI IWineD3DVolumeTextureImpl_BindTexture(IWineD3DVolumeTexture *iface) { static HRESULT WINAPI IWineD3DVolumeTextureImpl_BindTexture(IWineD3DVolumeTexture *iface, BOOL srgb) {
IWineD3DVolumeTextureImpl *This = (IWineD3DVolumeTextureImpl *)iface; IWineD3DVolumeTextureImpl *This = (IWineD3DVolumeTextureImpl *)iface;
BOOL dummy;
TRACE("(%p) : relay to BaseTexture\n", This); TRACE("(%p) : relay to BaseTexture\n", This);
return basetexture_bind((IWineD3DBaseTexture *)iface); return basetexture_bind((IWineD3DBaseTexture *)iface, srgb, &dummy);
} }
static UINT WINAPI IWineD3DVolumeTextureImpl_GetTextureDimensions(IWineD3DVolumeTexture *iface) { static UINT WINAPI IWineD3DVolumeTextureImpl_GetTextureDimensions(IWineD3DVolumeTexture *iface) {
......
...@@ -1357,16 +1357,16 @@ typedef enum winetexturestates { ...@@ -1357,16 +1357,16 @@ typedef enum winetexturestates {
typedef struct IWineD3DBaseTextureClass typedef struct IWineD3DBaseTextureClass
{ {
DWORD states[MAX_WINETEXTURESTATES]; DWORD states[MAX_WINETEXTURESTATES];
DWORD srgbstates[MAX_WINETEXTURESTATES];
UINT levels; UINT levels;
BOOL dirty; BOOL dirty, srgbDirty;
UINT textureName; UINT textureName, srgbTextureName;
float pow2Matrix[16]; float pow2Matrix[16];
UINT LOD; UINT LOD;
WINED3DTEXTUREFILTERTYPE filterType; WINED3DTEXTUREFILTERTYPE filterType;
LONG bindCount; LONG bindCount;
DWORD sampler; DWORD sampler;
BOOL is_srgb; BOOL is_srgb;
UINT srgb_mode_change_count;
const struct min_lookup *minMipLookup; const struct min_lookup *minMipLookup;
const GLenum *magLookup; const GLenum *magLookup;
struct color_fixup_desc shader_color_fixup; struct color_fixup_desc shader_color_fixup;
...@@ -1384,7 +1384,7 @@ typedef struct IWineD3DBaseTextureImpl ...@@ -1384,7 +1384,7 @@ typedef struct IWineD3DBaseTextureImpl
void basetexture_apply_state_changes(IWineD3DBaseTexture *iface, void basetexture_apply_state_changes(IWineD3DBaseTexture *iface,
const DWORD texture_states[WINED3D_HIGHEST_TEXTURE_STATE + 1], const DWORD texture_states[WINED3D_HIGHEST_TEXTURE_STATE + 1],
const DWORD sampler_states[WINED3D_HIGHEST_SAMPLER_STATE + 1]); const DWORD sampler_states[WINED3D_HIGHEST_SAMPLER_STATE + 1]);
HRESULT basetexture_bind(IWineD3DBaseTexture *iface); HRESULT basetexture_bind(IWineD3DBaseTexture *iface, BOOL srgb, BOOL *set_surface_desc);
void basetexture_cleanup(IWineD3DBaseTexture *iface); void basetexture_cleanup(IWineD3DBaseTexture *iface);
void basetexture_generate_mipmaps(IWineD3DBaseTexture *iface); void basetexture_generate_mipmaps(IWineD3DBaseTexture *iface);
WINED3DTEXTUREFILTERTYPE basetexture_get_autogen_filter_type(IWineD3DBaseTexture *iface); WINED3DTEXTUREFILTERTYPE basetexture_get_autogen_filter_type(IWineD3DBaseTexture *iface);
...@@ -1396,6 +1396,10 @@ HRESULT basetexture_set_autogen_filter_type(IWineD3DBaseTexture *iface, WINED3DT ...@@ -1396,6 +1396,10 @@ HRESULT basetexture_set_autogen_filter_type(IWineD3DBaseTexture *iface, WINED3DT
BOOL basetexture_set_dirty(IWineD3DBaseTexture *iface, BOOL dirty); BOOL basetexture_set_dirty(IWineD3DBaseTexture *iface, BOOL dirty);
DWORD basetexture_set_lod(IWineD3DBaseTexture *iface, DWORD new_lod); DWORD basetexture_set_lod(IWineD3DBaseTexture *iface, DWORD new_lod);
void basetexture_unload(IWineD3DBaseTexture *iface); void basetexture_unload(IWineD3DBaseTexture *iface);
static inline void basetexture_setsrgbcache(IWineD3DBaseTexture *iface, BOOL srgb) {
IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface;
This->baseTexture.is_srgb = srgb;
}
/***************************************************************************** /*****************************************************************************
* IWineD3DTexture implementation structure (extends IWineD3DBaseTextureImpl) * IWineD3DTexture implementation structure (extends IWineD3DBaseTextureImpl)
...@@ -1572,7 +1576,6 @@ struct IWineD3DSurfaceImpl ...@@ -1572,7 +1576,6 @@ struct IWineD3DSurfaceImpl
#define MAXLOCKCOUNT 50 /* After this amount of locks do not free the sysmem copy */ #define MAXLOCKCOUNT 50 /* After this amount of locks do not free the sysmem copy */
glDescriptor glDescription; glDescriptor glDescription;
BOOL srgb;
/* For GetDC */ /* For GetDC */
wineD3DSurface_DIB dib; wineD3DSurface_DIB dib;
...@@ -1641,7 +1644,7 @@ HRESULT WINAPI IWineD3DBaseSurfaceImpl_Blt(IWineD3DSurface *iface, const RECT *D ...@@ -1641,7 +1644,7 @@ HRESULT WINAPI IWineD3DBaseSurfaceImpl_Blt(IWineD3DSurface *iface, const RECT *D
HRESULT WINAPI IWineD3DBaseSurfaceImpl_BltFast(IWineD3DSurface *iface, DWORD dstx, DWORD dsty, HRESULT WINAPI IWineD3DBaseSurfaceImpl_BltFast(IWineD3DSurface *iface, DWORD dstx, DWORD dsty,
IWineD3DSurface *Source, const RECT *rsrc, DWORD trans); IWineD3DSurface *Source, const RECT *rsrc, DWORD trans);
HRESULT WINAPI IWineD3DBaseSurfaceImpl_LockRect(IWineD3DSurface *iface, WINED3DLOCKED_RECT* pLockedRect, CONST RECT* pRect, DWORD Flags); HRESULT WINAPI IWineD3DBaseSurfaceImpl_LockRect(IWineD3DSurface *iface, WINED3DLOCKED_RECT* pLockedRect, CONST RECT* pRect, DWORD Flags);
void WINAPI IWineD3DBaseSurfaceImpl_BindTexture(IWineD3DSurface *iface); void WINAPI IWineD3DBaseSurfaceImpl_BindTexture(IWineD3DSurface *iface, BOOL srgb);
const void *WINAPI IWineD3DBaseSurfaceImpl_GetData(IWineD3DSurface *iface); const void *WINAPI IWineD3DBaseSurfaceImpl_GetData(IWineD3DSurface *iface);
void get_drawable_size_swapchain(IWineD3DSurfaceImpl *This, UINT *width, UINT *height); void get_drawable_size_swapchain(IWineD3DSurfaceImpl *This, UINT *width, UINT *height);
...@@ -1659,22 +1662,23 @@ void flip_surface(IWineD3DSurfaceImpl *front, IWineD3DSurfaceImpl *back); ...@@ -1659,22 +1662,23 @@ void flip_surface(IWineD3DSurfaceImpl *front, IWineD3DSurfaceImpl *back);
#define SFLAG_DISCARD 0x00000010 /* ??? */ #define SFLAG_DISCARD 0x00000010 /* ??? */
#define SFLAG_LOCKED 0x00000020 /* Surface is locked atm */ #define SFLAG_LOCKED 0x00000020 /* Surface is locked atm */
#define SFLAG_INTEXTURE 0x00000040 /* The GL texture contains the newest surface content */ #define SFLAG_INTEXTURE 0x00000040 /* The GL texture contains the newest surface content */
#define SFLAG_INDRAWABLE 0x00000080 /* The gl drawable contains the most up to date data */ #define SFLAG_INSRGBTEX 0x00000080 /* The GL srgb texture contains the newest surface content */
#define SFLAG_INSYSMEM 0x00000100 /* The system memory copy is most up to date */ #define SFLAG_INDRAWABLE 0x00000100 /* The gl drawable contains the most up to date data */
#define SFLAG_NONPOW2 0x00000200 /* Surface sizes are not a power of 2 */ #define SFLAG_INSYSMEM 0x00000200 /* The system memory copy is most up to date */
#define SFLAG_DYNLOCK 0x00000400 /* Surface is often locked by the app */ #define SFLAG_NONPOW2 0x00000400 /* Surface sizes are not a power of 2 */
#define SFLAG_DYNCHANGE 0x00000C00 /* Surface contents are changed very often, implies DYNLOCK */ #define SFLAG_DYNLOCK 0x00000800 /* Surface is often locked by the app */
#define SFLAG_DCINUSE 0x00001000 /* Set between GetDC and ReleaseDC calls */ #define SFLAG_DCINUSE 0x00001000 /* Set between GetDC and ReleaseDC calls */
#define SFLAG_LOST 0x00002000 /* Surface lost flag for DDraw */ #define SFLAG_LOST 0x00002000 /* Surface lost flag for DDraw */
#define SFLAG_USERPTR 0x00004000 /* The application allocated the memory for this surface */ #define SFLAG_USERPTR 0x00004000 /* The application allocated the memory for this surface */
#define SFLAG_GLCKEY 0x00008000 /* The gl texture was created with a color key */ #define SFLAG_GLCKEY 0x00008000 /* The gl texture was created with a color key */
#define SFLAG_CLIENT 0x00010000 /* GL_APPLE_client_storage is used on that texture */ #define SFLAG_CLIENT 0x00010000 /* GL_APPLE_client_storage is used on that texture */
#define SFLAG_ALLOCATED 0x00020000 /* A gl texture is allocated for this surface */ #define SFLAG_ALLOCATED 0x00020000 /* A gl texture is allocated for this surface */
#define SFLAG_PBO 0x00040000 /* Has a PBO attached for speeding up data transfers for dynamically locked surfaces */ #define SFLAG_SRGBALLOCATED 0x00040000 /* A srgb gl texture is allocated for this surface */
#define SFLAG_NORMCOORD 0x00080000 /* Set if the GL texture coords are normalized(non-texture rectangle) */ #define SFLAG_PBO 0x00080000 /* Has a PBO attached for speeding up data transfers for dynamically locked surfaces */
#define SFLAG_DS_ONSCREEN 0x00100000 /* Is a depth stencil, last modified onscreen */ #define SFLAG_NORMCOORD 0x00100000 /* Set if the GL texture coords are normalized(non-texture rectangle) */
#define SFLAG_DS_OFFSCREEN 0x00200000 /* Is a depth stencil, last modified offscreen */ #define SFLAG_DS_ONSCREEN 0x00200000 /* Is a depth stencil, last modified onscreen */
#define SFLAG_INOVERLAYDRAW 0x00400000 /* Overlay drawing is in progress. Recursion prevention */ #define SFLAG_DS_OFFSCREEN 0x00400000 /* Is a depth stencil, last modified offscreen */
#define SFLAG_INOVERLAYDRAW 0x00800000 /* Overlay drawing is in progress. Recursion prevention */
/* In some conditions the surface memory must not be freed: /* In some conditions the surface memory must not be freed:
* SFLAG_OVERSIZE: Not all data can be kept in GL * SFLAG_OVERSIZE: Not all data can be kept in GL
...@@ -1682,7 +1686,6 @@ void flip_surface(IWineD3DSurfaceImpl *front, IWineD3DSurfaceImpl *back); ...@@ -1682,7 +1686,6 @@ void flip_surface(IWineD3DSurfaceImpl *front, IWineD3DSurfaceImpl *back);
* SFLAG_DIBSECTION: The dib code manages the memory * SFLAG_DIBSECTION: The dib code manages the memory
* SFLAG_LOCKED: The app requires access to the surface data * SFLAG_LOCKED: The app requires access to the surface data
* SFLAG_DYNLOCK: Avoid freeing the data for performance * SFLAG_DYNLOCK: Avoid freeing the data for performance
* SFLAG_DYNCHANGE: Same reason as DYNLOCK
* SFLAG_PBO: PBOs don't use 'normal' memory. It is either allocated by the driver or must be NULL. * SFLAG_PBO: PBOs don't use 'normal' memory. It is either allocated by the driver or must be NULL.
* SFLAG_CLIENT: OpenGL uses our memory as backup * SFLAG_CLIENT: OpenGL uses our memory as backup
*/ */
...@@ -1691,14 +1694,14 @@ void flip_surface(IWineD3DSurfaceImpl *front, IWineD3DSurfaceImpl *back); ...@@ -1691,14 +1694,14 @@ void flip_surface(IWineD3DSurfaceImpl *front, IWineD3DSurfaceImpl *back);
SFLAG_DIBSECTION | \ SFLAG_DIBSECTION | \
SFLAG_LOCKED | \ SFLAG_LOCKED | \
SFLAG_DYNLOCK | \ SFLAG_DYNLOCK | \
SFLAG_DYNCHANGE | \
SFLAG_USERPTR | \ SFLAG_USERPTR | \
SFLAG_PBO | \ SFLAG_PBO | \
SFLAG_CLIENT) SFLAG_CLIENT)
#define SFLAG_LOCATIONS (SFLAG_INSYSMEM | \ #define SFLAG_LOCATIONS (SFLAG_INSYSMEM | \
SFLAG_INTEXTURE | \ SFLAG_INTEXTURE | \
SFLAG_INDRAWABLE) SFLAG_INDRAWABLE | \
SFLAG_INSRGBTEX)
#define SFLAG_DS_LOCATIONS (SFLAG_DS_ONSCREEN | \ #define SFLAG_DS_LOCATIONS (SFLAG_DS_ONSCREEN | \
SFLAG_DS_OFFSCREEN) SFLAG_DS_OFFSCREEN)
...@@ -2056,7 +2059,7 @@ GLenum surface_get_gl_buffer(IWineD3DSurface *iface, IWineD3DSwapChain *swapchai ...@@ -2056,7 +2059,7 @@ GLenum surface_get_gl_buffer(IWineD3DSurface *iface, IWineD3DSwapChain *swapchai
void surface_load_ds_location(IWineD3DSurface *iface, DWORD location); void surface_load_ds_location(IWineD3DSurface *iface, DWORD location);
void surface_modify_ds_location(IWineD3DSurface *iface, DWORD location); void surface_modify_ds_location(IWineD3DSurface *iface, DWORD location);
void surface_set_compatible_renderbuffer(IWineD3DSurface *iface, unsigned int width, unsigned int height); void surface_set_compatible_renderbuffer(IWineD3DSurface *iface, unsigned int width, unsigned int height);
void surface_set_texture_name(IWineD3DSurface *iface, GLuint name); void surface_set_texture_name(IWineD3DSurface *iface, GLuint name, BOOL srgb_name);
void surface_set_texture_target(IWineD3DSurface *iface, GLenum target); void surface_set_texture_target(IWineD3DSurface *iface, GLenum target);
BOOL getColorBits(WINED3DFORMAT fmt, short *redSize, short *greenSize, short *blueSize, short *alphaSize, short *totalSize); BOOL getColorBits(WINED3DFORMAT fmt, short *redSize, short *greenSize, short *blueSize, short *alphaSize, short *totalSize);
......
...@@ -1830,7 +1830,7 @@ typedef struct _WINED3DINDEXBUFFER_DESC ...@@ -1830,7 +1830,7 @@ typedef struct _WINED3DINDEXBUFFER_DESC
typedef struct glDescriptor typedef struct glDescriptor
{ {
UINT textureName; UINT textureName, srgbTextureName;
int level; int level;
int /*GLenum*/ target; int /*GLenum*/ target;
int /*GLenum*/ glFormat; int /*GLenum*/ glFormat;
...@@ -2501,6 +2501,7 @@ interface IWineD3DSurface : IWineD3DResource ...@@ -2501,6 +2501,7 @@ interface IWineD3DSurface : IWineD3DResource
[in] BOOL srgb_mode [in] BOOL srgb_mode
); );
void BindTexture( void BindTexture(
[in] BOOL srgb
); );
HRESULT SaveSnapshot( HRESULT SaveSnapshot(
[in] const char *filename [in] const char *filename
...@@ -2589,6 +2590,7 @@ interface IWineD3DBaseTexture : IWineD3DResource ...@@ -2589,6 +2590,7 @@ interface IWineD3DBaseTexture : IWineD3DResource
BOOL GetDirty( BOOL GetDirty(
); );
HRESULT BindTexture( HRESULT BindTexture(
[in] BOOL srgb
); );
UINT GetTextureDimensions( UINT GetTextureDimensions(
); );
......
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