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
...@@ -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)) {
......
...@@ -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