wined3d: Enable the loading and reloading of gamma corrected textures.

This commit is contained in:
Phil Costin 2007-06-06 23:13:16 +00:00 committed by Alexandre Julliard
parent e7578dca36
commit 622f62d352
6 changed files with 82 additions and 18 deletions

View File

@ -105,6 +105,8 @@ static void WINAPI IWineD3DCubeTextureImpl_PreLoad(IWineD3DCubeTexture *iface) {
BOOL setGlTextureDesc = FALSE; BOOL setGlTextureDesc = FALSE;
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_was_toggled = FALSE;
TRACE("(%p) : About to load texture: dirtified(%d)\n", This, This->baseTexture.dirty); TRACE("(%p) : About to load texture: dirtified(%d)\n", This, This->baseTexture.dirty);
@ -120,23 +122,46 @@ static void WINAPI IWineD3DCubeTextureImpl_PreLoad(IWineD3DCubeTexture *iface) {
ENTER_GL(); ENTER_GL();
ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD); ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
LEAVE_GL(); LEAVE_GL();
} 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;
} }
IWineD3DCubeTexture_BindTexture(iface); IWineD3DCubeTexture_BindTexture(iface);
ENTER_GL(); ENTER_GL();
/* If were dirty 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 (This->baseTexture.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++) {
if(setGlTextureDesc) if(setGlTextureDesc)
IWineD3DSurface_SetGlTextureDesc(This->surfaces[j][i], This->baseTexture.textureName, cube_targets[j]); IWineD3DSurface_SetGlTextureDesc(This->surfaces[j][i], This->baseTexture.textureName, cube_targets[j]);
IWineD3DSurface_LoadTexture(This->surfaces[j][i], FALSE); IWineD3DSurface_LoadTexture(This->surfaces[j][i], srgb_mode);
} }
} }
/* No longer dirty */ } else if (srgb_was_toggled) {
This->baseTexture.dirty = FALSE; /* Loop is repeated in the else block with the extra AddDirtyRect 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++) {
IWineD3DSurfaceImpl_AddDirtyRect(This->surfaces[j][i], NULL);
IWineD3DSurface_SetGlTextureDesc(This->surfaces[j][i], This->baseTexture.textureName, cube_targets[j]);
IWineD3DSurface_LoadTexture(This->surfaces[j][i], srgb_mode);
}
}
} else {
TRACE("(%p) Texture not dirty, nothing to do\n" , iface);
} }
LEAVE_GL(); LEAVE_GL();
/* No longer dirty */
This->baseTexture.dirty = FALSE;
return ; return ;
} }

View File

@ -138,6 +138,10 @@ static void WINAPI IWineD3DDeviceImpl_AddResource(IWineD3DDevice *iface, IWineD3
_basetexture.filterType = (Usage & WINED3DUSAGE_AUTOGENMIPMAP) ? WINED3DTEXF_LINEAR : WINED3DTEXF_NONE; \ _basetexture.filterType = (Usage & WINED3DUSAGE_AUTOGENMIPMAP) ? WINED3DTEXF_LINEAR : WINED3DTEXF_NONE; \
_basetexture.LOD = 0; \ _basetexture.LOD = 0; \
_basetexture.dirty = TRUE; \ _basetexture.dirty = TRUE; \
_basetexture.is_srgb = FALSE; \
_basetexture.srgb_mode_change_count = 0; \
_basetexture.is_srgb = FALSE; \
_basetexture.srgb_mode_change_count = 0; \
} }
/********************************************************** /**********************************************************

View File

@ -1052,7 +1052,7 @@ static HRESULT WINAPI IWineD3DStateBlockImpl_InitStartupStateBlock(IWineD3DStat
This->samplerState[i][WINED3DSAMP_MIPMAPLODBIAS ] = 0; This->samplerState[i][WINED3DSAMP_MIPMAPLODBIAS ] = 0;
This->samplerState[i][WINED3DSAMP_MAXMIPLEVEL ] = 0; This->samplerState[i][WINED3DSAMP_MAXMIPLEVEL ] = 0;
This->samplerState[i][WINED3DSAMP_MAXANISOTROPY ] = 1; This->samplerState[i][WINED3DSAMP_MAXANISOTROPY ] = 1;
This->samplerState[i][WINED3DSAMP_SRGBTEXTURE ] = 0; /* TODO: Gamma correction value*/ This->samplerState[i][WINED3DSAMP_SRGBTEXTURE ] = 0;
This->samplerState[i][WINED3DSAMP_ELEMENTINDEX ] = 0; /* TODO: Indicates which element of a multielement texture to use */ This->samplerState[i][WINED3DSAMP_ELEMENTINDEX ] = 0; /* TODO: Indicates which element of a multielement texture to use */
This->samplerState[i][WINED3DSAMP_DMAPOFFSET ] = 0; /* TODO: Vertex offset in the presampled displacement map */ This->samplerState[i][WINED3DSAMP_DMAPOFFSET ] = 0; /* TODO: Vertex offset in the presampled displacement map */
} }

View File

@ -98,6 +98,8 @@ static void WINAPI IWineD3DTextureImpl_PreLoad(IWineD3DTexture *iface) {
BOOL setGlTextureDesc = FALSE; BOOL setGlTextureDesc = FALSE;
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_was_toggled = FALSE;
TRACE("(%p) : About to load texture\n", This); TRACE("(%p) : About to load texture\n", This);
@ -110,26 +112,40 @@ static void WINAPI IWineD3DTextureImpl_PreLoad(IWineD3DTexture *iface) {
ENTER_GL(); ENTER_GL();
ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD); ActivateContext(device, device->lastActiveRenderTarget, CTXUSAGE_RESOURCELOAD);
LEAVE_GL(); LEAVE_GL();
} 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;
} }
IWineD3DTexture_BindTexture(iface); IWineD3DTexture_BindTexture(iface);
ENTER_GL(); ENTER_GL();
/* If were dirty 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 (This->baseTexture.dirty) {
for (i = 0; i < This->baseTexture.levels; i++) { for (i = 0; i < This->baseTexture.levels; i++) {
if(setGlTextureDesc) if(setGlTextureDesc)
IWineD3DSurface_SetGlTextureDesc(This->surfaces[i], This->baseTexture.textureName, IWineD3DTexture_GetTextureDimensions(iface)); IWineD3DSurface_SetGlTextureDesc(This->surfaces[i], This->baseTexture.textureName, IWineD3DTexture_GetTextureDimensions(iface));
IWineD3DSurface_LoadTexture(This->surfaces[i], FALSE); 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);
/* No longer dirty */ for (i = 0; i < This->baseTexture.levels; i++) {
This->baseTexture.dirty = FALSE; IWineD3DSurfaceImpl_AddDirtyRect(This->surfaces[i], NULL);
IWineD3DSurface_SetGlTextureDesc(This->surfaces[i], This->baseTexture.textureName, IWineD3DTexture_GetTextureDimensions(iface));
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);
} }
LEAVE_GL(); LEAVE_GL();
/* No longer dirty */
This->baseTexture.dirty = FALSE;
return ; return ;
} }

View File

@ -95,6 +95,8 @@ static void WINAPI IWineD3DVolumeTextureImpl_PreLoad(IWineD3DVolumeTexture *ifac
int i; int i;
IWineD3DVolumeTextureImpl *This = (IWineD3DVolumeTextureImpl *)iface; IWineD3DVolumeTextureImpl *This = (IWineD3DVolumeTextureImpl *)iface;
IWineD3DDeviceImpl *device = This->resource.wineD3DDevice; IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
BOOL srgb_mode = This->baseTexture.is_srgb;
BOOL srgb_was_toggled = FALSE;
TRACE("(%p) : About to load texture\n", This); TRACE("(%p) : About to load texture\n", This);
@ -103,18 +105,33 @@ static void WINAPI IWineD3DVolumeTextureImpl_PreLoad(IWineD3DVolumeTexture *ifac
ENTER_GL(); ENTER_GL();
if(!device->isInDraw) { if(!device->isInDraw) {
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 were dirty then reload the volumes */ /* 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 (This->baseTexture.dirty) {
for (i = 0; i < This->baseTexture.levels; i++) { for (i = 0; i < This->baseTexture.levels; i++)
IWineD3DVolume_LoadTexture(This->volumes[i], i, FALSE); IWineD3DVolume_LoadTexture(This->volumes[i], i, srgb_mode);
} } 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);
/* No longer dirty */ for (i = 0; i < This->baseTexture.levels; i++) {
This->baseTexture.dirty = FALSE; IWineD3DVolume_AddDirtyBox(This->volumes[i], NULL);
IWineD3DVolume_LoadTexture(This->volumes[i], i, srgb_mode);
}
} else {
TRACE("(%p) Texture not dirty, nothing to do\n" , iface);
} }
LEAVE_GL(); LEAVE_GL();
/* No longer dirty */
This->baseTexture.dirty = FALSE;
return ; return ;
} }

View File

@ -883,6 +883,8 @@ typedef struct IWineD3DBaseTextureClass
DWORD states[MAX_WINETEXTURESTATES]; DWORD states[MAX_WINETEXTURESTATES];
LONG bindCount; LONG bindCount;
DWORD sampler; DWORD sampler;
BOOL is_srgb;
UINT srgb_mode_change_count;
} IWineD3DBaseTextureClass; } IWineD3DBaseTextureClass;
typedef struct IWineD3DBaseTextureImpl typedef struct IWineD3DBaseTextureImpl