wined3d: Pass the requested srgb flag to PreLoad.

Add a new wined3d-internal PreLoad function to textures and surfaces
that takes a parameter specifying wether the rgb or srgb texture
should be loaded.
This commit is contained in:
Stefan Dösinger 2009-02-17 00:25:51 +01:00 committed by Alexandre Julliard
parent 68c251f327
commit 4386a827e9
8 changed files with 87 additions and 26 deletions

View File

@ -124,7 +124,7 @@ static void context_apply_attachment_filter_states(IWineD3DDevice *iface, IWineD
glGetIntegerv(GL_TEXTURE_BINDING_CUBE_MAP_ARB, &old_binding);
}
IWineD3DSurface_PreLoad(surface);
surface_internal_preload(surface, SRGB_RGB);
glBindTexture(bind_target, surface_impl->glDescription.textureName);
if (update_minfilter) glTexParameteri(bind_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
@ -1399,7 +1399,11 @@ static inline WineD3DContext *FindContext(IWineD3DDeviceImpl *This, IWineD3DSurf
/* Do that before switching the context:
* Read the back buffer of the old drawable into the destination texture
*/
IWineD3DSurface_PreLoad(This->lastActiveRenderTarget);
if(((IWineD3DSurfaceImpl *)This->lastActiveRenderTarget)->glDescription.srgbTextureName) {
surface_internal_preload(This->lastActiveRenderTarget, SRGB_BOTH);
} else {
surface_internal_preload(This->lastActiveRenderTarget, SRGB_RGB);
}
/* Assume that the drawable will be modified by some other things now */
IWineD3DSurface_ModifyLocation(This->lastActiveRenderTarget, SFLAG_INDRAWABLE, FALSE);

View File

@ -91,13 +91,22 @@ static DWORD WINAPI IWineD3DCubeTextureImpl_GetPriority(IWineD3DCubeTexture *ifa
return resource_get_priority((IWineD3DResource *)iface);
}
static void WINAPI IWineD3DCubeTextureImpl_PreLoad(IWineD3DCubeTexture *iface) {
void cubetexture_internal_preload(IWineD3DBaseTexture *iface, enum WINED3DSRGB srgb) {
/* Override the IWineD3DResource Preload method */
unsigned int i,j;
IWineD3DCubeTextureImpl *This = (IWineD3DCubeTextureImpl *)iface;
IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
BOOL srgb_mode = This->baseTexture.is_srgb;
BOOL *dirty = srgb_mode ? &This->baseTexture.srgbDirty : &This->baseTexture.dirty;
BOOL srgb_mode;
BOOL *dirty;
switch(srgb) {
case SRGB_RGB: srgb_mode = FALSE; break;
case SRGB_BOTH: cubetexture_internal_preload(iface, SRGB_RGB);
case SRGB_SRGB: srgb_mode = TRUE; break;
/* DONTKNOW, and shut up the compiler */
default: srgb_mode = This->baseTexture.is_srgb; break;
}
dirty = srgb_mode ? &This->baseTexture.srgbDirty : &This->baseTexture.dirty;
TRACE("(%p) : About to load texture: dirtified(%d)\n", This, *dirty);
@ -140,6 +149,10 @@ static void WINAPI IWineD3DCubeTextureImpl_PreLoad(IWineD3DCubeTexture *iface) {
return;
}
static void WINAPI IWineD3DCubeTextureImpl_PreLoad(IWineD3DCubeTexture *iface) {
cubetexture_internal_preload((IWineD3DBaseTexture *) iface, SRGB_ANY);
}
static void WINAPI IWineD3DCubeTextureImpl_UnLoad(IWineD3DCubeTexture *iface) {
unsigned int i, j;
IWineD3DCubeTextureImpl *This = (IWineD3DCubeTextureImpl *)iface;

View File

@ -921,6 +921,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateTexture(IWineD3DDevice *iface,
tmpH = max(1, tmpH >> 1);
}
object->baseTexture.shader_color_fixup = glDesc->color_fixup;
object->baseTexture.internal_preload = texture_internal_preload;
TRACE("(%p) : Created texture %p\n", This, object);
return WINED3D_OK;
@ -1043,6 +1044,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateVolumeTexture(IWineD3DDevice *ifa
tmpD = max(1, tmpD >> 1);
}
object->baseTexture.shader_color_fixup = glDesc->color_fixup;
object->baseTexture.internal_preload = volumetexture_internal_preload;
*ppVolumeTexture = (IWineD3DVolumeTexture *) object;
TRACE("(%p) : Created volume texture %p\n", This, object);
@ -1241,6 +1243,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateCubeTexture(IWineD3DDevice *iface
tmpW = max(1, tmpW >> 1);
}
object->baseTexture.shader_color_fixup = glDesc->color_fixup;
object->baseTexture.internal_preload = cubetexture_internal_preload;
TRACE("(%p) : Created Cube Texture %p\n", This, object);
*ppCubeTexture = (IWineD3DCubeTexture *) object;
@ -5529,9 +5532,10 @@ static HRESULT WINAPI IWineD3DDeviceImpl_UpdateTexture (IWineD3DDevice *iface, I
}
if (WINED3D_OK == hr) {
IWineD3DBaseTextureImpl *pDestImpl = (IWineD3DBaseTextureImpl *) pDestinationTexture;
/* Make sure that the destination texture is loaded */
IWineD3DBaseTexture_PreLoad(pDestinationTexture);
pDestImpl->baseTexture.internal_preload(pDestinationTexture, SRGB_RGB);
/* Update every surface level of the texture */
levels = IWineD3DBaseTexture_GetLevelCount(pDestinationTexture);
@ -5921,7 +5925,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_UpdateSurface(IWineD3DDevice *iface,
LEAVE_GL();
/* Make sure the surface is loaded and up to date */
IWineD3DSurface_PreLoad(pDestinationSurface);
surface_internal_preload(pDestinationSurface, SRGB_RGB);
IWineD3DSurface_BindTexture(pDestinationSurface, FALSE);
IWineD3DSurface_GetGlDesc(pDestinationSurface, &glDescription);

View File

@ -3345,8 +3345,8 @@ static void sampler(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DCont
if(stateblock->textures[sampler]) {
BOOL srgb = stateblock->samplerState[sampler][WINED3DSAMP_SRGBTEXTURE];
basetexture_setsrgbcache(stateblock->textures[sampler], srgb);
IWineD3DBaseTexture_PreLoad(stateblock->textures[sampler]);
IWineD3DBaseTextureImpl *tex_impl = (IWineD3DBaseTextureImpl *) stateblock->textures[sampler];
tex_impl->baseTexture.internal_preload(stateblock->textures[sampler], srgb ? SRGB_SRGB : SRGB_RGB);
IWineD3DBaseTexture_BindTexture(stateblock->textures[sampler], srgb);
IWineD3DBaseTexture_ApplyStateChanges(stateblock->textures[sampler], stateblock->textureState[sampler], stateblock->samplerState[sampler]);

View File

@ -584,7 +584,7 @@ static ULONG WINAPI IWineD3DSurfaceImpl_Release(IWineD3DSurface *iface)
IWineD3DSurface IWineD3DResource parts follow
**************************************************** */
static void WINAPI IWineD3DSurfaceImpl_PreLoad(IWineD3DSurface *iface)
void surface_internal_preload(IWineD3DSurface *iface, enum WINED3DSRGB srgb)
{
/* TODO: check for locks */
IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface;
@ -593,8 +593,9 @@ static void WINAPI IWineD3DSurfaceImpl_PreLoad(IWineD3DSurface *iface)
TRACE("(%p)Checking to see if the container is a base texture\n", This);
if (IWineD3DSurface_GetContainer(iface, &IID_IWineD3DBaseTexture, (void **)&baseTexture) == WINED3D_OK) {
IWineD3DBaseTextureImpl *tex_impl = (IWineD3DBaseTextureImpl *) baseTexture;
TRACE("Passing to container\n");
IWineD3DBaseTexture_PreLoad(baseTexture);
tex_impl->baseTexture.internal_preload(baseTexture, SRGB_RGB);
IWineD3DBaseTexture_Release(baseTexture);
} else {
TRACE("(%p) : About to load surface\n", This);
@ -613,7 +614,7 @@ static void WINAPI IWineD3DSurfaceImpl_PreLoad(IWineD3DSurface *iface)
}
}
IWineD3DSurface_LoadTexture(iface, FALSE);
IWineD3DSurface_LoadTexture(iface, srgb == SRGB_SRGB ? TRUE : FALSE);
if (This->resource.pool == WINED3DPOOL_DEFAULT) {
/* Tell opengl to try and keep this texture in video ram (well mostly) */
@ -627,6 +628,10 @@ static void WINAPI IWineD3DSurfaceImpl_PreLoad(IWineD3DSurface *iface)
return;
}
static void WINAPI IWineD3DSurfaceImpl_PreLoad(IWineD3DSurface *iface) {
surface_internal_preload(iface, SRGB_ANY);
}
static void surface_remove_pbo(IWineD3DSurfaceImpl *This) {
This->resource.heapMemory = HeapAlloc(GetProcessHeap() ,0 , This->resource.size + RESOURCE_ALIGNMENT);
This->resource.allocatedMemory =
@ -1505,7 +1510,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_GetDC(IWineD3DSurface *iface, HDC *pHD
if(!This->hDC) {
IWineD3DBaseSurfaceImpl_CreateDIBSection(iface);
if(This->Flags & SFLAG_CLIENT) {
IWineD3DSurface_PreLoad(iface);
surface_internal_preload(iface, SRGB_RGB);
}
/* Use the dib section from now on if we are not using a PBO */
@ -2475,7 +2480,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_SaveSnapshot(IWineD3DSurface *iface, c
LEAVE_GL();
} else { /* bind the real texture, and make sure it up to date */
IWineD3DSurface_PreLoad(iface);
surface_internal_preload(iface, SRGB_RGB);
surface_bind_and_dirtify(This, FALSE);
}
allocatedMemory = HeapAlloc(GetProcessHeap(), 0, width * height * 4);
@ -2608,8 +2613,10 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_SetMem(IWineD3DSurface *iface, void *M
/* For client textures opengl has to be notified */
if(This->Flags & SFLAG_CLIENT) {
DWORD oldFlags = This->Flags;
This->Flags &= ~(SFLAG_ALLOCATED | SFLAG_SRGBALLOCATED);
IWineD3DSurface_PreLoad(iface);
if(oldFlags & SFLAG_ALLOCATED) surface_internal_preload(iface, SRGB_RGB);
if(oldFlags & SFLAG_SRGBALLOCATED) surface_internal_preload(iface, SRGB_SRGB);
/* And hope that the app behaves correctly and did not free the old surface memory before setting a new pointer */
}
@ -2623,9 +2630,11 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_SetMem(IWineD3DSurface *iface, void *M
This->Flags &= ~SFLAG_USERPTR;
if(This->Flags & SFLAG_CLIENT) {
DWORD oldFlags = This->Flags;
This->Flags &= ~(SFLAG_ALLOCATED | SFLAG_SRGBALLOCATED);
/* This respecifies an empty texture and opengl knows that the old memory is gone */
IWineD3DSurface_PreLoad(iface);
if(oldFlags & SFLAG_ALLOCATED) surface_internal_preload(iface, SRGB_RGB);
if(oldFlags & SFLAG_SRGBALLOCATED) surface_internal_preload(iface, SRGB_SRGB);
}
}
return WINED3D_OK;
@ -2775,7 +2784,7 @@ static inline void fb_copy_to_texture_direct(IWineD3DSurfaceImpl *This, IWineD3D
ActivateContext(myDevice, SrcSurface, CTXUSAGE_BLIT);
IWineD3DSurface_PreLoad((IWineD3DSurface *) This);
surface_internal_preload((IWineD3DSurface *) This, SRGB_RGB);
ENTER_GL();
/* Bind the target texture */
@ -2868,12 +2877,12 @@ static inline void fb_copy_to_texture_hwstretch(IWineD3DSurfaceImpl *This, IWine
TRACE("Using hwstretch blit\n");
/* Activate the Proper context for reading from the source surface, set it up for blitting */
ActivateContext(myDevice, SrcSurface, CTXUSAGE_BLIT);
IWineD3DSurface_PreLoad((IWineD3DSurface *) This);
surface_internal_preload((IWineD3DSurface *) This, SRGB_RGB);
noBackBufferBackup = !swapchain && wined3d_settings.offscreen_rendering_mode == ORM_FBO;
if(!noBackBufferBackup && Src->glDescription.textureName == 0) {
/* Get it a description */
IWineD3DSurface_PreLoad(SrcSurface);
surface_internal_preload(SrcSurface, SRGB_RGB);
}
ENTER_GL();
@ -3433,7 +3442,7 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *This, const
}
/* Now load the surface */
IWineD3DSurface_PreLoad((IWineD3DSurface *) Src);
surface_internal_preload((IWineD3DSurface *) Src, SRGB_RGB);
/* Activate the destination context, set it up for blitting */
ActivateContext(myDevice, (IWineD3DSurface *) This, CTXUSAGE_BLIT);
@ -4572,13 +4581,13 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LoadLocation(IWineD3DSurface *iface, D
if(srgb) {
if((This->Flags & (SFLAG_INTEXTURE | SFLAG_INSYSMEM)) == SFLAG_INTEXTURE) {
/* Performance warning ... */
FIXME("Downloading srgb texture to reload it as rgb\n");
FIXME("%p: Downloading rgb texture to reload it as srgb\n", This);
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");
FIXME("%p: Downloading srgb texture to reload it as rgb\n", This);
IWineD3DSurfaceImpl_LoadLocation(iface, SFLAG_INSYSMEM, rect);
}
}

View File

@ -92,17 +92,26 @@ static DWORD WINAPI IWineD3DTextureImpl_GetPriority(IWineD3DTexture *iface) {
return resource_get_priority((IWineD3DResource *)iface);
}
static void WINAPI IWineD3DTextureImpl_PreLoad(IWineD3DTexture *iface) {
void texture_internal_preload(IWineD3DBaseTexture *iface, enum WINED3DSRGB srgb) {
/* Override the IWineD3DResource PreLoad method */
unsigned int i;
IWineD3DTextureImpl *This = (IWineD3DTextureImpl *)iface;
IWineD3DDeviceImpl *device = This->resource.wineD3DDevice;
BOOL srgb_mode = This->baseTexture.is_srgb;
BOOL *dirty = srgb_mode ? &This->baseTexture.srgbDirty : &This->baseTexture.dirty;
BOOL srgb_mode;
BOOL *dirty;
TRACE("(%p) : About to load texture\n", This);
switch(srgb) {
case SRGB_RGB: srgb_mode = FALSE; break;
case SRGB_BOTH: texture_internal_preload(iface, SRGB_RGB);
case SRGB_SRGB: srgb_mode = TRUE; break;
/* DONTKNOW, and shut up the compiler */
default: srgb_mode = This->baseTexture.is_srgb; break;
}
dirty = srgb_mode ? &This->baseTexture.srgbDirty : &This->baseTexture.dirty;
if(!device->isInDraw) {
/* ActivateContext sets isInDraw to TRUE when loading a pbuffer into a texture, thus no danger of
* recursive calls
@ -136,6 +145,10 @@ static void WINAPI IWineD3DTextureImpl_PreLoad(IWineD3DTexture *iface) {
return ;
}
static void WINAPI IWineD3DTextureImpl_PreLoad(IWineD3DTexture *iface) {
texture_internal_preload((IWineD3DBaseTexture *) iface, SRGB_ANY);
}
static void WINAPI IWineD3DTextureImpl_UnLoad(IWineD3DTexture *iface) {
unsigned int i;
IWineD3DTextureImpl *This = (IWineD3DTextureImpl *)iface;

View File

@ -90,7 +90,7 @@ static DWORD WINAPI IWineD3DVolumeTextureImpl_GetPriority(IWineD3DVolumeTexture
return resource_get_priority((IWineD3DResource *)iface);
}
static void WINAPI IWineD3DVolumeTextureImpl_PreLoad(IWineD3DVolumeTexture *iface) {
void volumetexture_internal_preload(IWineD3DBaseTexture *iface, enum WINED3DSRGB srgb) {
/* Overrider the IWineD3DResource Preload method */
int i;
IWineD3DVolumeTextureImpl *This = (IWineD3DVolumeTextureImpl *)iface;
@ -127,6 +127,10 @@ static void WINAPI IWineD3DVolumeTextureImpl_PreLoad(IWineD3DVolumeTexture *ifac
return ;
}
static void WINAPI IWineD3DVolumeTextureImpl_PreLoad(IWineD3DVolumeTexture *iface) {
volumetexture_internal_preload((IWineD3DBaseTexture *) iface, SRGB_ANY);
}
static void WINAPI IWineD3DVolumeTextureImpl_UnLoad(IWineD3DVolumeTexture *iface) {
unsigned int i;
IWineD3DVolumeTextureImpl *This = (IWineD3DVolumeTextureImpl *)iface;

View File

@ -1351,6 +1351,14 @@ typedef enum winetexturestates {
MAX_WINETEXTURESTATES = 13,
} winetexturestates;
enum WINED3DSRGB
{
SRGB_ANY = 0, /* Uses the cached value(e.g. external calls) */
SRGB_RGB = 1, /* Loads the rgb texture */
SRGB_SRGB = 2, /* Loads the srgb texture */
SRGB_BOTH = 3, /* Loads both textures */
};
/*****************************************************************************
* IWineD3DBaseTexture implementation structure (extends IWineD3DResourceImpl)
*/
@ -1370,8 +1378,14 @@ typedef struct IWineD3DBaseTextureClass
const struct min_lookup *minMipLookup;
const GLenum *magLookup;
struct color_fixup_desc shader_color_fixup;
void (*internal_preload)(IWineD3DBaseTexture *iface, enum WINED3DSRGB srgb);
} IWineD3DBaseTextureClass;
void texture_internal_preload(IWineD3DBaseTexture *iface, enum WINED3DSRGB srgb);
void cubetexture_internal_preload(IWineD3DBaseTexture *iface, enum WINED3DSRGB srgb);
void volumetexture_internal_preload(IWineD3DBaseTexture *iface, enum WINED3DSRGB srgb);
void surface_internal_preload(IWineD3DSurface *iface, enum WINED3DSRGB srgb);
typedef struct IWineD3DBaseTextureImpl
{
/* IUnknown & WineD3DResource Information */