From ba5eb14768b107955caff9720186075148fdaf53 Mon Sep 17 00:00:00 2001 From: Oliver Stieber Date: Mon, 14 Mar 2005 10:12:52 +0000 Subject: [PATCH] Encapsulate texture, surface encapsulated. Added BindTexture, GetTextureDimensions, UnBindTexture. Proper GetContainer support for surface. SetContainer added to surface and volume. SetInPbufferState added to surface (until gl context management is implemented). Minor changes: - BaseTexture no longer 'holds' a reference to IWineD3DDevice to prevent circular referencing. - Better managment of referinging for texture. - Some TODO's for implementing a context manager. - Better preload implementation. - Fix compile warning in device.c Set/GetSamplerState. - Add QueryInterface support for surface. - Format X8R8G8B8 added to locking. --- dlls/wined3d/basetexture.c | 73 +++++++++++-- dlls/wined3d/cubetexture.c | 143 ++++++++++++++++++-------- dlls/wined3d/device.c | 148 +++++++++++++------------- dlls/wined3d/surface.c | 171 ++++++++++++++++++++++++------- dlls/wined3d/texture.c | 124 +++++++++++++++++----- dlls/wined3d/volume.c | 47 ++++++++- dlls/wined3d/volumetexture.c | 143 +++++++++++++++----------- dlls/wined3d/wined3d_private.h | 32 +++--- include/wine/wined3d_interface.h | 36 ++++++- 9 files changed, 657 insertions(+), 260 deletions(-) diff --git a/dlls/wined3d/basetexture.c b/dlls/wined3d/basetexture.c index 69a8ef37c6f..9a646937513 100644 --- a/dlls/wined3d/basetexture.c +++ b/dlls/wined3d/basetexture.c @@ -2,7 +2,8 @@ * IWineD3DBaseTexture Implementation * * Copyright 2002-2004 Jason Edmeades - * Raphael Junqueira + * Copyright 2002-2004 Raphael Junqueira + * Copyright 2005 Oliver Stieber * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -57,7 +58,6 @@ ULONG WINAPI IWineD3DBaseTextureImpl_Release(IWineD3DBaseTexture *iface) { ULONG ref = InterlockedDecrement(&This->resource.ref); TRACE("(%p) : Releasing from %ld\n", This, ref + 1); if (ref == 0) { - IWineD3DDevice_Release((IWineD3DDevice *)This->resource.wineD3DDevice); HeapFree(GetProcessHeap(), 0, This); } else { IUnknown_Release(This->resource.parent); /* Released the reference to the d3dx object */ @@ -107,16 +107,35 @@ HRESULT WINAPI IWineD3DBaseTextureImpl_GetParent(IWineD3DBaseTexture *iface, IUn /* ****************************************************** IWineD3DBaseTexture IWineD3DBaseTexture parts follow ****************************************************** */ + +/* There is no OpenGL equivilent of setLOD, getLOD, all they do it priortise testure loading + * so just pretend that they work unless something really needs a failure. */ DWORD WINAPI IWineD3DBaseTextureImpl_SetLOD(IWineD3DBaseTexture *iface, DWORD LODNew) { IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface; - FIXME("(%p) : stub\n", This); - return 0; + + if (This->baseTexture.pool != D3DPOOL_MANAGED) { + return D3DERR_INVALIDCALL; + } + + if(LODNew >= This->baseTexture.levels) + LODNew = This->baseTexture.levels - 1; + This->baseTexture.LOD = LODNew; + + TRACE("(%p) : set bogus LOD to %d \n", This, This->baseTexture.LOD); + + return This->baseTexture.LOD; } DWORD WINAPI IWineD3DBaseTextureImpl_GetLOD(IWineD3DBaseTexture *iface) { IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface; - FIXME("(%p) : stub\n", This); - return 0; + + if (This->baseTexture.pool != D3DPOOL_MANAGED) { + return D3DERR_INVALIDCALL; + } + + TRACE("(%p) : returning %d \n", This, This->baseTexture.LOD); + + return This->baseTexture.LOD; } DWORD WINAPI IWineD3DBaseTextureImpl_GetLevelCount(IWineD3DBaseTexture *iface) { @@ -127,18 +146,29 @@ DWORD WINAPI IWineD3DBaseTextureImpl_GetLevelCount(IWineD3DBaseTexture *iface) { HRESULT WINAPI IWineD3DBaseTextureImpl_SetAutoGenFilterType(IWineD3DBaseTexture *iface, D3DTEXTUREFILTERTYPE FilterType) { IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface; - FIXME("(%p) : stub\n", This); + + if (!(This->baseTexture.usage & D3DUSAGE_AUTOGENMIPMAP)) { + TRACE("(%p) : returning invalid call\n", This); + return D3DERR_INVALIDCALL; + } + This->baseTexture.filterType = FilterType; + TRACE("(%p) : \n", This); return D3D_OK; } D3DTEXTUREFILTERTYPE WINAPI IWineD3DBaseTextureImpl_GetAutoGenFilterType(IWineD3DBaseTexture *iface) { IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface; FIXME("(%p) : stub\n", This); - return D3DTEXF_NONE; + if (!(This->baseTexture.usage & D3DUSAGE_AUTOGENMIPMAP)) { + return D3DTEXF_NONE; + } + return This->baseTexture.filterType; + return D3DTEXF_LINEAR; /* default */ } void WINAPI IWineD3DBaseTextureImpl_GenerateMipSubLevels(IWineD3DBaseTexture *iface) { IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface; + /* TODO: implement filters using GL_SGI_generate_mipmaps http://oss.sgi.com/projects/ogl-sample/registry/SGIS/generate_mipmap.txt */ FIXME("(%p) : stub\n", This); return ; } @@ -157,11 +187,29 @@ BOOL WINAPI IWineD3DBaseTextureImpl_GetDirty(IWineD3DBaseTexture *iface) { return This->baseTexture.dirty; } +HRESULT WINAPI IWineD3DBaseTextureImpl_BindTexture(IWineD3DBaseTexture *iface) { + IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface; + FIXME("(%p) : This shouldn't be called\n", This); + return D3D_OK; +} +HRESULT WINAPI IWineD3DBaseTextureImpl_UnBindTexture(IWineD3DBaseTexture *iface) { + IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface; + FIXME("(%p) : This shouldn't be called\n", This); + return D3D_OK; +} + +UINT WINAPI IWineD3DBaseTextureImpl_GetTextureDimensions(IWineD3DBaseTexture *iface){ + IWineD3DBaseTextureImpl *This = (IWineD3DBaseTextureImpl *)iface; + FIXME("(%p) : This shouldn't be called\n", This); + return D3D_OK; +} + IWineD3DBaseTextureVtbl IWineD3DBaseTexture_Vtbl = { IWineD3DBaseTextureImpl_QueryInterface, IWineD3DBaseTextureImpl_AddRef, IWineD3DBaseTextureImpl_Release, + /* IWineD3DResource */ IWineD3DBaseTextureImpl_GetParent, IWineD3DBaseTextureImpl_GetDevice, IWineD3DBaseTextureImpl_SetPrivateData, @@ -171,6 +219,8 @@ IWineD3DBaseTextureVtbl IWineD3DBaseTexture_Vtbl = IWineD3DBaseTextureImpl_GetPriority, IWineD3DBaseTextureImpl_PreLoad, IWineD3DBaseTextureImpl_GetType, + + /*IWineD3DBaseTexture*/ IWineD3DBaseTextureImpl_SetLOD, IWineD3DBaseTextureImpl_GetLOD, IWineD3DBaseTextureImpl_GetLevelCount, @@ -178,5 +228,10 @@ IWineD3DBaseTextureVtbl IWineD3DBaseTexture_Vtbl = IWineD3DBaseTextureImpl_GetAutoGenFilterType, IWineD3DBaseTextureImpl_GenerateMipSubLevels, IWineD3DBaseTextureImpl_SetDirty, - IWineD3DBaseTextureImpl_GetDirty + IWineD3DBaseTextureImpl_GetDirty, + /* internal */ + IWineD3DBaseTextureImpl_BindTexture, + IWineD3DBaseTextureImpl_UnBindTexture, + IWineD3DBaseTextureImpl_GetTextureDimensions + }; diff --git a/dlls/wined3d/cubetexture.c b/dlls/wined3d/cubetexture.c index 8f1938f3af4..db621113897 100644 --- a/dlls/wined3d/cubetexture.c +++ b/dlls/wined3d/cubetexture.c @@ -1,5 +1,5 @@ /* - * IDirect3DCubeTexture9 implementation + * IWineD3DCubeTexture implementation * * Copyright 2002-2005 Jason Edmeades * Copyright 2002-2005 Raphael Junqueira @@ -79,12 +79,17 @@ ULONG WINAPI IWineD3DCubeTextureImpl_Release(IWineD3DCubeTexture *iface) { for (i = 0; i < This->baseTexture.levels; i++) { for (j = 0; j < 6; j++) { if (This->surfaces[j][i] != NULL) { - TRACE("(%p) : Releasing surface %p\n", This, This->surfaces[j][i]); + TRACE("(%p) : Releasing surface%d %d %p\n", This, j, i, This->surfaces[j][i]); IWineD3DSurface_Release((IWineD3DSurface *) This->surfaces[j][i]); } } } - IWineD3DDevice_Release((IWineD3DDevice *)This->resource.wineD3DDevice); + if(This->baseTexture.textureName != 0){ + ENTER_GL(); + TRACE("Deleting texture %d\n", This->baseTexture.textureName); + glDeleteTextures(1, &This->baseTexture.textureName); + LEAVE_GL(); + } HeapFree(GetProcessHeap(), 0, This); } else { IUnknown_Release(This->resource.parent); /* Released the reference to the d3dx object */ @@ -127,47 +132,56 @@ void WINAPI IWineD3DCubeTextureImpl_PreLoad(IWineD3DCubeTexture *iface) { TRACE("(%p) : About to load texture: dirtified(%d)\n", This, This->baseTexture.dirty); ENTER_GL(); - - for (i = 0; i < This->baseTexture.levels; i++) { - if (i == 0 && This->surfaces[0][0]->textureName != 0 && This->baseTexture.dirty == FALSE) { - glEnable(GL_TEXTURE_CUBE_MAP_ARB); - glBindTexture(GLTEXTURECUBEMAP, This->surfaces[0][0]->textureName); - checkGLcall("glBindTexture"); - TRACE("Texture %p (level %d) given name %d\n", This->surfaces[0][0], i, This->surfaces[0][0]->textureName); - /* No need to walk through all mip-map levels, since already all assigned */ - i = This->baseTexture.levels; - - } else { - if (i == 0) { - if (This->surfaces[0][0]->textureName == 0) { - glGenTextures(1, &This->surfaces[0][0]->textureName); - checkGLcall("glGenTextures"); - TRACE("Texture %p (level %d) given name %d\n", This->surfaces[0][i], i, This->surfaces[0][0]->textureName); - } - - glBindTexture(GLTEXTURECUBEMAP, This->surfaces[0][0]->textureName); - checkGLcall("glBindTexture"); - - TRACE("Setting GL_TEXTURE_MAX_LEVEL to %d\n", This->baseTexture.levels - 1); - glTexParameteri(GLTEXTURECUBEMAP, GL_TEXTURE_MAX_LEVEL, This->baseTexture.levels - 1); - checkGLcall("glTexParameteri(GL_TEXTURE_CUBE, GL_TEXTURE_MAX_LEVEL, This->levels - 1)"); - } - - for (j = 0; j < 6; j++) { - IWineD3DSurface_LoadTexture((IWineD3DSurface *) This->surfaces[j][i], cube_targets[j], i); -#if 0 - static int gen = 0; - char buffer[4096]; - snprintf(buffer, sizeof(buffer), "/tmp/cube%d_face%d_level%d_%d.png", This->surfaces[0][0]->textureName, j, i, ++gen); - IWineD3DSurfaceImpl_SaveSnapshot((IWineD3DSurface *) This->surfaces[j][i], buffer); +#if 0 /* TODO: context manager support */ + IWineD3DContextManager_PushState(This->contextManager, GL_TEXTURE_CUBE_MAP_ARB, ENABLED, NOW /* make sure the state is applied now */); +#else + glEnable(GL_TEXTURE_CUBE_MAP_ARB); #endif - } - /* Removed glTexParameterf now TextureStageStates are initialized at startup */ - This->baseTexture.dirty = FALSE; - } + + /* Generate a texture name if we don't already have one */ + if (This->baseTexture.textureName == 0) { + glGenTextures(1, &This->baseTexture.textureName); + checkGLcall("glGenTextures"); + TRACE("Generated texture %d\n", This->baseTexture.textureName); + if (This->baseTexture.pool == D3DPOOL_DEFAULT) { + /* Tell opengl to try and keep this texture in video ram (well mostly) */ + GLclampf tmp; + tmp = 0.9f; + glPrioritizeTextures(1, &This->baseTexture.textureName, &tmp); + } } - LEAVE_GL(); + /* Bind the texture */ + if (This->baseTexture.textureName != 0) { + glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, This->baseTexture.textureName); + checkGLcall("glBindTexture"); + } else { /* this only happened if we've run out of openGL textures */ + WARN("This texture doesn't have an openGL texture assigned to it\n"); + return; + } + + /* If were dirty then reload the surfaces */ + if(This->baseTexture.dirty != FALSE) { + for (i = 0; i < This->baseTexture.levels; i++) { + for (j = 0; j < 6; j++) + IWineD3DSurface_LoadTexture((IWineD3DSurface *) This->surfaces[j][i], cube_targets[j], i); + } + /* No longer dirty */ + This->baseTexture.dirty = FALSE; + + } + + /* Always need to reset the number of mipmap levels when rebinding as it is + a property of the active texture unit, and another texture may have set it + to a different value */ + TRACE("Setting GL_TEXTURE_MAX_LEVEL to %d\n", This->baseTexture.levels - 1); + glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MAX_LEVEL, This->baseTexture.levels - 1); + checkGLcall("glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, This->baseTexture.levels)"); + +#if 0 /* TODO: context manager support */ + IWineD3DContextManager_PopState(This->contextManager, GL_TEXTURE_CUBE_MAP_ARB, DISABLED, DELAYED); +#endif + LEAVE_GL(); return ; } @@ -209,13 +223,51 @@ void WINAPI IWineD3DCubeTextureImpl_GenerateMipSubLevels(IWineD3DCubeTexture *if /* Internal function, No d3d mapping */ BOOL WINAPI IWineD3DCubeTextureImpl_SetDirty(IWineD3DCubeTexture *iface, BOOL dirty) { - return IWineD3DBaseTextureImpl_SetDirty((IWineD3DBaseTexture *)iface, TRUE); + return IWineD3DBaseTextureImpl_SetDirty((IWineD3DBaseTexture *)iface, dirty); } +/* Internal function, No d3d mapping */ BOOL WINAPI IWineD3DCubeTextureImpl_GetDirty(IWineD3DCubeTexture *iface) { return IWineD3DBaseTextureImpl_GetDirty((IWineD3DBaseTexture *)iface); } +HRESULT WINAPI IWineD3DCubeTextureImpl_BindTexture(IWineD3DCubeTexture *iface) { + IWineD3DCubeTextureImpl *This = (IWineD3DCubeTextureImpl *)iface; + TRACE("(%p) : %d \n", This, This->baseTexture.textureName); + ENTER_GL(); +#if 0 /* TODO: context manager support */ + IWineD3DContextManager_PushState(This->contextManager, GL_TEXTURE_CUBE_MAP_ARB, ENABLED, NOW /* make sure the state is applied now */); +#else + glEnable(GL_TEXTURE_CUBE_MAP_ARB); +#endif + glBindTexture(GLTEXTURECUBEMAP, This->baseTexture.textureName); + LEAVE_GL(); + return D3D_OK; +} + +HRESULT WINAPI IWineD3DCubeTextureImpl_UnBindTexture(IWineD3DCubeTexture *iface) { + IWineD3DCubeTextureImpl *This = (IWineD3DCubeTextureImpl *)iface; + TRACE("(%p) \n", This); + ENTER_GL(); + + glBindTexture(GLTEXTURECUBEMAP, 0); +#if 0 /* TODO: context manager support */ + IWineD3DContextManager_PopState(This->contextManager, GL_TEXTURE_CUBE_MAP_ARB, ENABLED, NOW /* make sure the state is applied now */); +#else + glDisable(GL_TEXTURE_CUBE_MAP_ARB); +#endif + + LEAVE_GL(); + return D3D_OK; +} + +UINT WINAPI IWineD3DCubeTextureImpl_GetTextureDimensions(IWineD3DCubeTexture *iface){ + IWineD3DCubeTextureImpl *This = (IWineD3DCubeTextureImpl *)iface; + TRACE("(%p) \n", This); + + return GLTEXTURECUBEMAP; +} + /* ******************************************* IWineD3DCubeTexture IWineD3DCubeTexture parts follow ******************************************* */ @@ -281,9 +333,11 @@ HRESULT WINAPI IWineD3DCubeTextureImpl_AddDirtyRect(IWineD3DCubeTexture *iface, IWineD3DCubeTextureVtbl IWineD3DCubeTexture_Vtbl = { + /* IUnknown */ IWineD3DCubeTextureImpl_QueryInterface, IWineD3DCubeTextureImpl_AddRef, IWineD3DCubeTextureImpl_Release, + /* IWineD3DResource */ IWineD3DCubeTextureImpl_GetParent, IWineD3DCubeTextureImpl_GetDevice, IWineD3DCubeTextureImpl_SetPrivateData, @@ -293,6 +347,7 @@ IWineD3DCubeTextureVtbl IWineD3DCubeTexture_Vtbl = IWineD3DCubeTextureImpl_GetPriority, IWineD3DCubeTextureImpl_PreLoad, IWineD3DCubeTextureImpl_GetType, + /*base texture */ IWineD3DCubeTextureImpl_SetLOD, IWineD3DCubeTextureImpl_GetLOD, IWineD3DCubeTextureImpl_GetLevelCount, @@ -301,6 +356,10 @@ IWineD3DCubeTextureVtbl IWineD3DCubeTexture_Vtbl = IWineD3DCubeTextureImpl_GenerateMipSubLevels, IWineD3DCubeTextureImpl_SetDirty, IWineD3DCubeTextureImpl_GetDirty, + IWineD3DCubeTextureImpl_BindTexture, + IWineD3DCubeTextureImpl_UnBindTexture, + IWineD3DCubeTextureImpl_GetTextureDimensions, + /* cube texture */ IWineD3DCubeTextureImpl_GetLevelDesc, IWineD3DCubeTextureImpl_GetCubeMapSurface, IWineD3DCubeTextureImpl_LockRect, diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index c1f83863158..48225e614d5 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -54,6 +54,15 @@ WINE_DECLARE_DEBUG_CHANNEL(d3d_shader); *pp##type = (IWineD3D##type *) object; \ } +#define D3DINITILIZEBASETEXTURE(_basetexture) { \ + _basetexture.usage = Usage; \ + _basetexture.levels = Levels; \ + _basetexture.format = Format; \ + _basetexture.pool = Pool; \ + _basetexture.filterType = (Usage & D3DUSAGE_AUTOGENMIPMAP) ? D3DTEXF_LINEAR : D3DTEXF_NONE; \ + _basetexture.LOD = 0; \ +} + /********************************************************** * Global variable / Constants follow **********************************************************/ @@ -524,12 +533,10 @@ HRESULT WINAPI IWineD3DDeviceImpl_CreateTexture(IWineD3DDevice *iface, UINT Wid TRACE("(%p), Width(%d) Height(%d) Levels(%d) Usage(%ld) .... \n", This, Width, Height, Levels, Usage); - D3DCREATERESOURCEOBJECTINSTANCE(object, Texture, D3DRTYPE_TEXTURE) + D3DCREATERESOURCEOBJECTINSTANCE(object, Texture, D3DRTYPE_TEXTURE); + D3DINITILIZEBASETEXTURE(object->baseTexture); object->width = Width; object->height = Height; - object->usage = Usage; - object->baseTexture.format = Format; - object->baseTexture.levels = Levels; /* Calculate levels for mip mapping */ if (Levels == 0) { @@ -551,13 +558,13 @@ HRESULT WINAPI IWineD3DDeviceImpl_CreateTexture(IWineD3DDevice *iface, UINT Wid for (i = 0; i < object->baseTexture.levels; i++) { /* use the callback to create the texture surface */ - hr = D3DCB_CreateSurface(This->parent, tmpW, tmpH, Format, Usage, Pool, i, (IWineD3DSurface **)&object->surfaces[i],NULL); + hr = D3DCB_CreateSurface(This->parent, tmpW, tmpH, Format, Usage, Pool, i, &object->surfaces[i],NULL); if(hr!= D3D_OK){ int j; FIXME("Failed to create surface %p \n",object); /* clean up */ for(j=0;jsurfaces[j]); + IWineD3DSurface_Release(object->surfaces[j]); } /* heap free object */ HeapFree(GetProcessHeap(),0,object); @@ -566,7 +573,7 @@ HRESULT WINAPI IWineD3DDeviceImpl_CreateTexture(IWineD3DDevice *iface, UINT Wid return hr; } - object->surfaces[i]->container = (IUnknown*) object; + IWineD3DSurface_SetContainer(object->surfaces[i], (IUnknown *)object); TRACE("Created surface level %d @ %p\n", i, object->surfaces[i]); /* calculate the next mipmap level */ tmpW = max(1, tmpW >> 1); @@ -592,13 +599,8 @@ HRESULT WINAPI IWineD3DDeviceImpl_CreateVolumeTexture(IWineD3DDevice *iface, UINT tmpH; UINT tmpD; - object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IWineD3DVolumeTextureImpl)); - if (NULL == object) { - *ppVolumeTexture = NULL; - return D3DERR_OUTOFVIDEOMEMORY; - } - D3DCREATERESOURCEOBJECTINSTANCE(object, VolumeTexture, D3DRTYPE_VOLUMETEXTURE); + D3DINITILIZEBASETEXTURE(object->baseTexture); TRACE("(%p) : W(%d) H(%d) D(%d), Lvl(%d) Usage(%ld), Fmt(%u,%s), Pool(%s)\n", This, Width, Height, Depth, Levels, Usage, Format, debug_d3dformat(Format), debug_d3dpool(Pool)); @@ -606,9 +608,6 @@ HRESULT WINAPI IWineD3DDeviceImpl_CreateVolumeTexture(IWineD3DDevice *iface, object->width = Width; object->height = Height; object->depth = Depth; - object->usage = Usage; - object->baseTexture.levels = Levels; - object->baseTexture.format = Format; /* Calculate levels for mip mapping */ if (Levels == 0) { @@ -617,9 +616,9 @@ HRESULT WINAPI IWineD3DDeviceImpl_CreateVolumeTexture(IWineD3DDevice *iface, tmpH = Height; tmpD = Depth; while (tmpW > 1 && tmpH > 1 && tmpD > 1) { - tmpW = max(1, tmpW / 2); - tmpH = max(1, tmpH / 2); - tmpD = max(1, tmpD / 2); + tmpW = max(1, tmpW >> 1); + tmpH = max(1, tmpH >> 1); + tmpD = max(1, tmpD >> 1); object->baseTexture.levels++; } TRACE("Calculated levels = %d\n", object->baseTexture.levels); @@ -632,14 +631,14 @@ HRESULT WINAPI IWineD3DDeviceImpl_CreateVolumeTexture(IWineD3DDevice *iface, for (i = 0; i < object->baseTexture.levels; i++) { - /* Create the volume - No entry point for this seperately?? */ + /* Create the volume */ D3DCB_CreateVolume(This->parent, Width, Height, Depth, Format, Pool, Usage, (IWineD3DVolume **)&object->volumes[i], pSharedHandle); - object->volumes[i]->container = (IUnknown*) object; + IWineD3DVolume_SetContainer(object->volumes[i], (IUnknown *)object); - tmpW = max(1, tmpW / 2); - tmpH = max(1, tmpH / 2); - tmpD = max(1, tmpD / 2); + tmpW = max(1, tmpW >> 1); + tmpH = max(1, tmpH >> 1); + tmpD = max(1, tmpD >> 1); } *ppVolumeTexture = (IWineD3DVolumeTexture *) object; @@ -693,17 +692,15 @@ HRESULT WINAPI IWineD3DDeviceImpl_CreateCubeTexture(IWineD3DDevice *iface, UINT IWineD3DCubeTextureImpl *object; /** NOTE: impl ref allowed since this is a create function **/ unsigned int i,j; UINT tmpW; - HRESULT hr; + HRESULT hr; D3DCREATERESOURCEOBJECTINSTANCE(object, CubeTexture, D3DRTYPE_CUBETEXTURE); - + D3DINITILIZEBASETEXTURE(object->baseTexture); + TRACE("(%p) Create Cube Texture \n", This); - object->edgeLength = EdgeLength; - object->baseTexture.format = Format; - object->baseTexture.levels = Levels; - object->usage = Usage; - + object->edgeLength = EdgeLength; + /* Calculate levels for mip mapping */ if (Levels == 0) { object->baseTexture.levels++; @@ -723,30 +720,30 @@ HRESULT WINAPI IWineD3DDeviceImpl_CreateCubeTexture(IWineD3DDevice *iface, UINT for (j = 0; j < 6; j++) { hr=D3DCB_CreateSurface(This->parent, tmpW, tmpW, Format, Usage, Pool, - i /* Level */, (IWineD3DSurface **)&object->surfaces[j][i],pSharedHandle); + i /* Level */, &object->surfaces[j][i],pSharedHandle); if(hr!= D3D_OK){ /* clean up */ int k; - int l; - for(l=0;lsurfaces[j][i]); - } - for(k=0;ksurfaces[l][j]); + int l; + for (l=0;lsurfaces[j][i]); + } + for (k=0;ksurfaces[l][j]); } } - + FIXME("(%p) Failed to create surface\n",object); HeapFree(GetProcessHeap(),0,object); *ppCubeTexture = NULL; return hr; - } - object->surfaces[j][i]->container = (IUnknown*) object; + } + IWineD3DSurface_SetContainer(object->surfaces[j][i], (IUnknown *)object); TRACE("Created surface level %d @ %p, \n", i, object->surfaces[j][i]); } - tmpW = max(1, tmpW / 2); + tmpW = max(1, tmpW >> 1); } TRACE("(%p) : Created Cube Texture %p\n", This, object); @@ -1809,10 +1806,10 @@ HRESULT WINAPI IWineD3DDeviceImpl_SetViewport(IWineD3DDevice *iface, CONST WINED glDepthRange(pViewport->MinZ, pViewport->MaxZ); checkGLcall("glDepthRange"); - /* Note: GL requires lower left, DirectX supplies upper left */ - glViewport(pViewport->X, (This->renderTarget->currentDesc.Height - (pViewport->Y + pViewport->Height)), - pViewport->Width, pViewport->Height); + /* TODO: replace usage of renderTarget with context management */ + glViewport(pViewport->X, (((IWineD3DSurfaceImpl *)This->renderTarget)->currentDesc.Height - (pViewport->Y + pViewport->Height)), + pViewport->Width, pViewport->Height); checkGLcall("glViewport"); LEAVE_GL(); @@ -2714,14 +2711,14 @@ HRESULT WINAPI IWineD3DDeviceImpl_GetRenderState(IWineD3DDevice *iface, D3DRENDE return D3D_OK; } -HRESULT WINAPI IWineD3DDeviceImpl_SetSamplerState(IWineD3DDevice *iface, DWORD Sampler, D3DSAMPLERSTATETYPE Type, DWORD Value){ +HRESULT WINAPI IWineD3DDeviceImpl_SetSamplerState(IWineD3DDevice *iface, DWORD Sampler, WINED3DSAMPLERSTATETYPE Type, DWORD Value){ IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; FIXME("(%p) : stub\n", This); return D3D_OK; } -HRESULT WINAPI IWineD3DDeviceImpl_GetSamplerState(IWineD3DDevice *iface, DWORD Sampler, D3DSAMPLERSTATETYPE Type, DWORD* Value){ +HRESULT WINAPI IWineD3DDeviceImpl_GetSamplerState(IWineD3DDevice *iface, DWORD Sampler, WINED3DSAMPLERSTATETYPE Type, DWORD* Value){ IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; FIXME("(%p) : stub\n", This); @@ -3495,13 +3492,24 @@ HRESULT WINAPI IWineD3DDeviceImpl_SetTexture(IWineD3DDevice *iface, DWORD Stage, FIXME("Program using multiple concurrent textures which this opengl implementation doesn't support\n"); } - /* Decrement the count of the previous texture */ + /** NOTE: MSDN says that setTexture increases the reference count, + * and the the application nust set the texture back to null (or have a leaky application), + * This means we should pass the refcount upto the parent + *******************************/ if (NULL != oldTexture) { - IWineD3DBaseTexture_Release(oldTexture); + + IUnknown *textureParent; + IWineD3DBaseTexture_GetParent(oldTexture, (IUnknown **)&textureParent); + IUnknown_Release(textureParent); + IUnknown_Release(textureParent); /** NOTE: Twice because GetParent adds a ref **/ + oldTexture = NULL; } + if (NULL != pTexture) { - IWineD3DBaseTexture_AddRef((IWineD3DBaseTexture *) This->updateStateBlock->textures[Stage]); + IUnknown *textureParent; + IWineD3DBaseTexture_GetParent(This->updateStateBlock->textures[Stage], (IUnknown **)&textureParent); + /** NOTE: GetParent will increase the ref count for me, I won't clean up untill the texture is set to NULL **/ /* Now setup the texture appropraitly */ textureType = IWineD3DBaseTexture_GetType(pTexture); @@ -3726,27 +3734,29 @@ HRESULT WINAPI IWineD3DDeviceImpl_BeginScene(IWineD3DDevice *iface) { HRESULT WINAPI IWineD3DDeviceImpl_EndScene(IWineD3DDevice *iface) { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; TRACE("(%p)\n", This); - ENTER_GL(); - + /* We only have to do this if we need to read the, swapbuffers performs a flush for us */ glFlush(); checkGLcall("glFlush"); - if ((This->frontBuffer != This->renderTarget) && (This->backBuffer != This->renderTarget)) { + TRACE("End Scene\n"); + if(This->renderTarget != NULL){ - /* If we are rendering to a texture (surface) then flag it as dirty. - A surfaces container is either the appropriate texture or the device itself - depending on how the surface was created. */ - if (This->renderTarget != NULL && ((IWineD3DDeviceImpl *)This->renderTarget->container != This)) { - - IWineD3DBaseTexture *cont = (IWineD3DBaseTexture *)This->renderTarget->container; - /** always dirtify for now. we must find a better way to see that surface have been modified */ - This->renderTarget->inPBuffer = TRUE; - This->renderTarget->inTexture = FALSE; - IWineD3DBaseTexture_SetDirty(cont, TRUE); - IWineD3DBaseTexture_PreLoad(cont); - This->renderTarget->inPBuffer = FALSE; + /* If the container of the rendertarget is a texture then we need to save the data from the pbuffer */ + IUnknown *targetContainer = NULL; + if (D3D_OK == IWineD3DSurface_GetContainer(This->renderTarget, &IID_IWineD3DBaseTexture, (void **)&targetContainer)) { + TRACE("RenderTarget is either standalone of a texture.\n"); + /** always dirtify for now. we must find a better way to see that surface have been modified + (Modifications should will only occur via draw-primitive, but we do need better locking + switching to render-to-texture should remove the overhead though. + */ + IWineD3DSurface_SetPBufferState(This->renderTarget, TRUE /* inPBuffer */, FALSE /* inTexture */); + IWineD3DBaseTexture_SetDirty((IWineD3DBaseTexture *)targetContainer, TRUE); + IWineD3DBaseTexture_PreLoad((IWineD3DBaseTexture *)targetContainer); + IWineD3DSurface_SetPBufferState(This->renderTarget, FALSE /* inPBuffer */, FALSE /* inTexture */); + IUnknown_Release(targetContainer); } + } LEAVE_GL(); @@ -3899,14 +3909,14 @@ HRESULT WINAPI IWineD3DDeviceImpl_Clear(IWineD3DDevice *iface, DWORD Count, CONS /* Note gl uses lower left, width/height */ TRACE("(%p) %p Rect=(%ld,%ld)->(%ld,%ld) glRect=(%ld,%ld), len=%ld, hei=%ld\n", This, curRect, curRect->x1, curRect->y1, curRect->x2, curRect->y2, - curRect->x1, (This->renderTarget->currentDesc.Height - curRect->y2), + curRect->x1, (((IWineD3DSurfaceImpl *)This->renderTarget)->currentDesc.Height - curRect->y2), curRect->x2 - curRect->x1, curRect->y2 - curRect->y1); - glScissor(curRect->x1, (This->renderTarget->currentDesc.Height - curRect->y2), + glScissor(curRect->x1, (((IWineD3DSurfaceImpl *)This->renderTarget)->currentDesc.Height - curRect->y2), curRect->x2 - curRect->x1, curRect->y2 - curRect->y1); checkGLcall("glScissor"); } else { glScissor(This->stateBlock->viewport.X, - (This->renderTarget->currentDesc.Height - (This->stateBlock->viewport.Y + This->stateBlock->viewport.Height)), + (((IWineD3DSurfaceImpl *)This->renderTarget)->currentDesc.Height - (This->stateBlock->viewport.Y + This->stateBlock->viewport.Height)), This->stateBlock->viewport.Width, This->stateBlock->viewport.Height); checkGLcall("glScissor"); diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c index 835ecae74f9..9082ca1f0cb 100644 --- a/dlls/wined3d/surface.c +++ b/dlls/wined3d/surface.c @@ -4,6 +4,7 @@ * Copyright 2002-2005 Jason Edmeades * Copyright 2002-2003 Raphael Junqueira * Copyright 2004 Christian Costa + * Copyright 2005 Oliver Stieber * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -32,7 +33,18 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d_surface); HRESULT WINAPI IWineD3DSurfaceImpl_QueryInterface(IWineD3DSurface *iface, REFIID riid, LPVOID *ppobj) { IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface; - WARN("(%p)->(%s,%p) should not be called\n",This,debugstr_guid(riid),ppobj); + /* Warn ,but be nice about things */ + TRACE("(%p)->(%s,%p) \n", This,debugstr_guid(riid),ppobj); + if (riid == NULL) { + ERR("Probably FIXME: Calling query interface with NULL riid\n"); + } + if (IsEqualGUID(riid, &IID_IUnknown) + || IsEqualGUID(riid, &IID_IWineD3DResource) + || IsEqualGUID(riid, &IID_IWineD3DSurface)) { + IUnknown_AddRef((IUnknown*)iface); + *ppobj = This; + return D3D_OK; + } return E_NOINTERFACE; } @@ -40,7 +52,6 @@ ULONG WINAPI IWineD3DSurfaceImpl_AddRef(IWineD3DSurface *iface) { IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface; ULONG ref = InterlockedIncrement(&This->resource.ref); TRACE("(%p) : AddRef increasing from %ld\n", This,ref - 1); - IUnknown_AddRef(This->resource.parent); return ref; } @@ -49,11 +60,16 @@ ULONG WINAPI IWineD3DSurfaceImpl_Release(IWineD3DSurface *iface) { ULONG ref = InterlockedDecrement(&This->resource.ref); TRACE("(%p) : Releasing from %ld\n", This, ref + 1); if (ref == 0) { + if (This->textureName != 0) { /* release the openGL texture.. */ + ENTER_GL(); + TRACE("Deleting texture %d\n", This->textureName); + glDeleteTextures(1, &This->textureName); + LEAVE_GL(); + } HeapFree(GetProcessHeap(), 0, This->allocatedMemory); IWineD3DDevice_Release((IWineD3DDevice *)This->resource.wineD3DDevice); HeapFree(GetProcessHeap(), 0, This); - } else { - IUnknown_Release(This->resource.parent); /* Released the reference to the d3dx object */ + } return ref; } @@ -86,7 +102,57 @@ DWORD WINAPI IWineD3DSurfaceImpl_GetPriority(IWineD3DSurface *iface) { } void WINAPI IWineD3DSurfaceImpl_PreLoad(IWineD3DSurface *iface) { - return IWineD3DResourceImpl_PreLoad((IWineD3DResource *)iface); + /* TODO: re-write the way textures and managed, + * use a 'opengl context manager' to manage RenderTarget surfaces + ** *********************************************************/ + + /* TODO: check for locks */ + IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface; + IWineD3DBaseTexture *baseTexture = NULL; + TRACE("(%p)Checking to see if the container is a base textuer\n", This); + if (IWineD3DSurface_GetContainer(iface, &IID_IWineD3DBaseTexture, (void **)&baseTexture) == D3D_OK) { + TRACE("Passing to conatiner\n"); + IWineD3DBaseTexture_PreLoad(baseTexture); + IWineD3DBaseTexture_Release(baseTexture); + } else{ + TRACE("(%p) : About to load surface\n", This); + ENTER_GL(); +#if 0 /* TODO: context manager support */ + IWineD3DContextManager_PushState(This->contextManager, GL_TEXTURE_2D, ENABLED, NOW /* make sure the state is applied now */); +#endif + glEnable(GL_TEXTURE_2D); /* make sure texture support is enabled in this context */ + if (This->currentDesc.Level == 0 && This->textureName == 0) { + glGenTextures(1, &This->textureName); + checkGLcall("glGenTextures"); + TRACE("Surface %p given name %d\n", This, This->textureName); + glBindTexture(GL_TEXTURE_2D, This->textureName); + checkGLcall("glBindTexture"); + IWineD3DSurface_LoadTexture((IWineD3DSurface *) This, GL_TEXTURE_2D, This->currentDesc.Level); + /* This is where we should be reducing the amount of GLMemoryUsed */ + }else { + if (This->currentDesc.Level == 0) { + glBindTexture(GL_TEXTURE_2D, This->textureName); + checkGLcall("glBindTexture"); + IWineD3DSurface_LoadTexture((IWineD3DSurface *) This, GL_TEXTURE_2D, This->currentDesc.Level); + } else if (This->textureName != 0) { /* NOTE: the level 0 surface of a mpmapped texture must be loaded first! */ + /* assume this is a coding error not a real error for now */ + FIXME("Mipmap surface has a glTexture bound to it!\n"); + } + } + if (This->currentDesc.Pool == D3DPOOL_DEFAULT) { + /* Tell opengl to try and keep this texture in video ram (well mostly) */ + GLclampf tmp; + tmp = 0.9f; + glPrioritizeTextures(1, &This->textureName, &tmp); + } + /* TODO: disable texture support, if it wastn't enabled when we entered. */ +#if 0 /* TODO: context manager support */ + IWineD3DContextManager_PopState(This->contextManager, GL_TEXTURE_2D, DISABLED,DELAYED + /* we don't care when the state is disabled(if atall) */); +#endif + LEAVE_GL(); + } + return; } D3DRESOURCETYPE WINAPI IWineD3DSurfaceImpl_GetType(IWineD3DSurface *iface) { @@ -101,19 +167,21 @@ HRESULT WINAPI IWineD3DSurfaceImpl_GetParent(IWineD3DSurface *iface, IUnknown ** IWineD3DSurface IWineD3DSurface parts follow ****************************************************** */ -HRESULT WINAPI IWineD3DSurfaceImpl_GetContainer(IWineD3DSurface *iface, REFIID riid, void** ppContainer) { +HRESULT WINAPI IWineD3DSurfaceImpl_GetContainer(IWineD3DSurface* iface, REFIID riid, void** ppContainer) { IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface; - + HRESULT hr; + if (ppContainer == NULL) { + ERR("Get container called witout a null ppContainer\n"); + return E_NOINTERFACE; + } + TRACE("(%p) : Relaying to queryInterface %p %p\n", This, ppContainer, *ppContainer); /** From MSDN: - * If the surface is created using CreateImageSurface/CreateOffscreenPlainSurface, CreateRenderTarget, - * or CreateDepthStencilSurface, the surface is considered stand alone. In this case, - * GetContainer will return the Direct3D device used to create the surface. + * If the surface is created using CreateImageSurface/CreateOffscreenPlainSurface, CreateRenderTarget, + * or CreateDepthStencilSurface, the surface is considered stand alone. In this case, + * GetContainer will return the Direct3D device used to create the surface. */ - WARN("Query of container implementation currently ignores riid\n"); - *ppContainer = This->container; - IUnknown_AddRef((IUnknown *)*ppContainer); - TRACE("(%p) : returning %p\n", This, *ppContainer); - return D3D_OK; + hr = IUnknown_QueryInterface(This->container, riid, ppContainer); + return hr; } HRESULT WINAPI IWineD3DSurfaceImpl_GetDesc(IWineD3DSurface *iface, WINED3DSURFACE_DESC *pDesc) { @@ -150,14 +218,15 @@ HRESULT WINAPI IWineD3DSurfaceImpl_LockRect(IWineD3DSurface *iface, D3DLOCKED_RE /*return D3DERR_INVALIDCALL; */ } - if (This == This->resource.wineD3DDevice->backBuffer || This == This->resource.wineD3DDevice->renderTarget || This == This->resource.wineD3DDevice->frontBuffer || This->resource.wineD3DDevice->depthStencilBuffer) { - if (This == This->resource.wineD3DDevice->backBuffer) { + if (iface == This->resource.wineD3DDevice->backBuffer || iface == This->resource.wineD3DDevice->renderTarget || + iface == This->resource.wineD3DDevice->frontBuffer || iface == This->resource.wineD3DDevice->depthStencilBuffer) { + if (iface == This->resource.wineD3DDevice->backBuffer) { TRACE("(%p, backBuffer) : rect@%p flags(%08lx), output lockedRect@%p, memory@%p\n", This, pRect, Flags, pLockedRect, This->allocatedMemory); - } else if (This == This->resource.wineD3DDevice->frontBuffer) { + } else if (iface == This->resource.wineD3DDevice->frontBuffer) { TRACE("(%p, frontBuffer) : rect@%p flags(%08lx), output lockedRect@%p, memory@%p\n", This, pRect, Flags, pLockedRect, This->allocatedMemory); - } else if (This == This->resource.wineD3DDevice->renderTarget) { + } else if (iface == This->resource.wineD3DDevice->renderTarget) { TRACE("(%p, renderTarget) : rect@%p flags(%08lx), output lockedRect@%p, memory@%p\n", This, pRect, Flags, pLockedRect, This->allocatedMemory); - } else if (This == This->resource.wineD3DDevice->depthStencilBuffer) { + } else if (iface == This->resource.wineD3DDevice->depthStencilBuffer) { TRACE("(%p, stencilBuffer) : rect@%p flags(%08lx), output lockedRect@%p, memory@%p\n", This, pRect, Flags, pLockedRect, This->allocatedMemory); } } else { @@ -202,7 +271,7 @@ HRESULT WINAPI IWineD3DSurfaceImpl_LockRect(IWineD3DSurface *iface, D3DLOCKED_RE } else if (D3DUSAGE_RENDERTARGET & This->currentDesc.Usage && !(Flags&D3DLOCK_DISCARD)) { /* render surfaces */ - if (This == This->resource.wineD3DDevice->backBuffer || This == This->resource.wineD3DDevice->renderTarget || This == This->resource.wineD3DDevice->frontBuffer) { + if (iface == This->resource.wineD3DDevice->backBuffer || iface == This->resource.wineD3DDevice->renderTarget || iface == This->resource.wineD3DDevice->frontBuffer) { GLint prev_store; GLenum prev_read; @@ -221,11 +290,11 @@ HRESULT WINAPI IWineD3DSurfaceImpl_LockRect(IWineD3DSurface *iface, D3DLOCKED_RE glGetIntegerv(GL_PACK_SWAP_BYTES, &prev_store); vcheckGLcall("glIntegerv"); - if (This == This->resource.wineD3DDevice->backBuffer) { + if (iface == This->resource.wineD3DDevice->backBuffer) { glReadBuffer(GL_BACK); - } else if (This == This->resource.wineD3DDevice->frontBuffer || This == This->resource.wineD3DDevice->renderTarget) { + } else if (iface == This->resource.wineD3DDevice->frontBuffer || iface == This->resource.wineD3DDevice->renderTarget) { glReadBuffer(GL_FRONT); - } else if (This == This->resource.wineD3DDevice->depthStencilBuffer) { + } else if (iface == This->resource.wineD3DDevice->depthStencilBuffer) { ERR("Stencil Buffer lock unsupported for now\n"); } vcheckGLcall("glReadBuffer"); @@ -266,15 +335,20 @@ HRESULT WINAPI IWineD3DSurfaceImpl_LockRect(IWineD3DSurface *iface, D3DLOCKED_RE if (Flags & (D3DLOCK_NO_DIRTY_UPDATE | D3DLOCK_READONLY)) { /* Don't dirtify */ } else { + IWineD3DBaseTexture *pBaseTexture; /** * Dirtify on lock * as seen in msdn docs */ IWineD3DSurface_AddDirtyRect(iface, &This->lockedRect); - /** Dirtify Container if needed */ - if ((NULL != This->container) && ((IWineD3DDeviceImpl *)This->container != This->resource.wineD3DDevice)) { - IWineD3DBaseTexture_SetDirty((IWineD3DBaseTexture *)This->container, TRUE); + /** Dirtify Container if needed */ + if (D3D_OK == IWineD3DSurface_GetContainer(iface, &IID_IWineD3DBaseTexture, (void **)&pBaseTexture) && pBaseTexture != NULL) { + TRACE("Making container dirty\n"); + IWineD3DBaseTexture_SetDirty(pBaseTexture, TRUE); + IWineD3DBaseTexture_Release(pBaseTexture); + }else{ + TRACE("Surface is standalone, no need to dirty the container\n"); } } @@ -293,14 +367,15 @@ HRESULT WINAPI IWineD3DSurfaceImpl_UnlockRect(IWineD3DSurface *iface) { return D3DERR_INVALIDCALL; } - if (This == This->resource.wineD3DDevice->backBuffer || This == This->resource.wineD3DDevice->frontBuffer || This->resource.wineD3DDevice->depthStencilBuffer || This == This->resource.wineD3DDevice->renderTarget) { - if (This == This->resource.wineD3DDevice->backBuffer) { + if (iface== This->resource.wineD3DDevice->backBuffer || iface == This->resource.wineD3DDevice->frontBuffer || + iface == This->resource.wineD3DDevice->depthStencilBuffer || iface == This->resource.wineD3DDevice->renderTarget) { + if (iface == This->resource.wineD3DDevice->backBuffer) { TRACE("(%p, backBuffer) : dirtyfied(%d)\n", This, This->Dirty); - } else if (This == This->resource.wineD3DDevice->frontBuffer) { + } else if (iface == This->resource.wineD3DDevice->frontBuffer) { TRACE("(%p, frontBuffer) : dirtyfied(%d)\n", This, This->Dirty); - } else if (This == This->resource.wineD3DDevice->depthStencilBuffer) { + } else if (iface == This->resource.wineD3DDevice->depthStencilBuffer) { TRACE("(%p, stencilBuffer) : dirtyfied(%d)\n", This, This->Dirty); - } else if (This == This->resource.wineD3DDevice->renderTarget) { + } else if (iface == This->resource.wineD3DDevice->renderTarget) { TRACE("(%p, renderTarget) : dirtyfied(%d)\n", This, This->Dirty); } } else { @@ -319,7 +394,7 @@ HRESULT WINAPI IWineD3DSurfaceImpl_UnlockRect(IWineD3DSurface *iface) { */ } else if (D3DUSAGE_RENDERTARGET & This->currentDesc.Usage) { /* render surfaces */ - if (This == This->resource.wineD3DDevice->backBuffer || This == This->resource.wineD3DDevice->frontBuffer || This == This->resource.wineD3DDevice->renderTarget) { + if (iface == This->resource.wineD3DDevice->backBuffer || iface == This->resource.wineD3DDevice->frontBuffer || iface == This->resource.wineD3DDevice->renderTarget) { GLint prev_store; GLenum prev_draw; GLint prev_rasterpos[4]; @@ -375,9 +450,9 @@ HRESULT WINAPI IWineD3DSurfaceImpl_UnlockRect(IWineD3DSurface *iface) { checkGLcall("glTranslatef(0.5, 0.5, 0)"); } - if (This == This->resource.wineD3DDevice->backBuffer) { + if (iface == This->resource.wineD3DDevice->backBuffer) { glDrawBuffer(GL_BACK); - } else if (This == This->resource.wineD3DDevice->frontBuffer || This == This->resource.wineD3DDevice->renderTarget) { + } else if (iface == This->resource.wineD3DDevice->frontBuffer || iface == This->resource.wineD3DDevice->renderTarget) { glDrawBuffer(GL_FRONT); } vcheckGLcall("glDrawBuffer"); @@ -406,6 +481,7 @@ HRESULT WINAPI IWineD3DSurfaceImpl_UnlockRect(IWineD3DSurface *iface) { vcheckGLcall("glDrawPixels"); } break; + case WINED3DFMT_X8R8G8B8: /* FIXME: there's no alpha change with D3DFMT_X8R8G8B8 but were using GL_BGRA */ case WINED3DFMT_A8R8G8B8: { glPixelStorei(GL_PACK_SWAP_BYTES, TRUE); @@ -443,7 +519,7 @@ HRESULT WINAPI IWineD3DSurfaceImpl_UnlockRect(IWineD3DSurface *iface) { } else if (D3DUSAGE_DEPTHSTENCIL & This->currentDesc.Usage) { /* stencil surfaces */ - if (This == This->resource.wineD3DDevice->depthStencilBuffer) { + if (iface == This->resource.wineD3DDevice->depthStencilBuffer) { FIXME("TODO stencil depth surface unlocking surf@%p usage(%lu)\n", This, This->currentDesc.Usage); } else { FIXME("unsupported unlocking to StencilDepth surface surf@%p usage(%lu)\n", This, This->currentDesc.Usage); @@ -755,11 +831,29 @@ extern HRESULT WINAPI IWineD3DSurfaceImpl_AddDirtyRect(IWineD3DSurface *iface, C return D3D_OK; } +HRESULT WINAPI IWineD3DSurfaceImpl_SetContainer(IWineD3DSurface *iface, IUnknown *container) { + IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface; + TRACE("Setting container to %p from %p\n", container, This->container); + This->container = container; + return D3D_OK; +} + +/* TODO: replace this function with context management routines */ +HRESULT WINAPI IWineD3DSurfaceImpl_SetPBufferState(IWineD3DSurface *iface, BOOL inPBuffer, BOOL inTexture) { + IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface; + + This->inPBuffer = inPBuffer; + This->inTexture = inTexture; + return D3D_OK; +} + IWineD3DSurfaceVtbl IWineD3DSurface_Vtbl = { + /* IUnknown */ IWineD3DSurfaceImpl_QueryInterface, IWineD3DSurfaceImpl_AddRef, IWineD3DSurfaceImpl_Release, + /* IWineD3DResource */ IWineD3DSurfaceImpl_GetParent, IWineD3DSurfaceImpl_GetDevice, IWineD3DSurfaceImpl_SetPrivateData, @@ -769,6 +863,7 @@ IWineD3DSurfaceVtbl IWineD3DSurface_Vtbl = IWineD3DSurfaceImpl_GetPriority, IWineD3DSurfaceImpl_PreLoad, IWineD3DSurfaceImpl_GetType, + /* IWineD3DSurface */ IWineD3DSurfaceImpl_GetContainer, IWineD3DSurfaceImpl_GetDesc, IWineD3DSurfaceImpl_LockRect, @@ -779,5 +874,7 @@ IWineD3DSurfaceVtbl IWineD3DSurface_Vtbl = IWineD3DSurfaceImpl_CleanDirtyRect, IWineD3DSurfaceImpl_AddDirtyRect, IWineD3DSurfaceImpl_LoadTexture, - IWineD3DSurfaceImpl_SaveSnapshot + IWineD3DSurfaceImpl_SaveSnapshot, + IWineD3DSurfaceImpl_SetContainer, + IWineD3DSurfaceImpl_SetPBufferState }; diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c index 2d6a4b9bcc1..989edb400c4 100644 --- a/dlls/wined3d/texture.c +++ b/dlls/wined3d/texture.c @@ -2,7 +2,8 @@ * IDirect3DTexture9 implementation * * Copyright 2002-2005 Jason Edmeades - * Raphael Junqueira + * Copyright 2002-2005 Raphael Junqueira + * Copyright 2005 Oliver Stieber * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -57,12 +58,22 @@ ULONG WINAPI IWineD3DTextureImpl_Release(IWineD3DTexture *iface) { ref = InterlockedDecrement(&This->resource.ref); if (ref == 0) { int i; + for (i = 0; i < This->baseTexture.levels; i++) { if (This->surfaces[i] != NULL) { - TRACE("(%p) : Releasing surface %p\n", This, This->surfaces[i]); - IWineD3DSurface_Release((IWineD3DSurface *) This->surfaces[i]); + /* Because the surfaces were created using a callback we need to release there parent otehrwise we leave the parent hanging */ + IUnknown* surfaceParent; + IWineD3DSurface_GetParent(This->surfaces[i], &surfaceParent); + IUnknown_Release(surfaceParent); + IUnknown_Release(surfaceParent); } } + if (This->baseTexture.textureName != 0) { + ENTER_GL(); + TRACE("Deleting texture %d\n", This->baseTexture.textureName); + glDeleteTextures(1, &This->baseTexture.textureName); + LEAVE_GL(); + } IWineD3DDevice_Release((IWineD3DDevice *)This->resource.wineD3DDevice); HeapFree(GetProcessHeap(), 0, This); } else { @@ -107,31 +118,41 @@ void WINAPI IWineD3DTextureImpl_PreLoad(IWineD3DTexture *iface) { ENTER_GL(); - for (i = 0; i < This->baseTexture.levels; i++) { - if (i == 0 && This->surfaces[i]->textureName != 0 && This->baseTexture.dirty == FALSE) { - glBindTexture(GL_TEXTURE_2D, This->surfaces[i]->textureName); - checkGLcall("glBindTexture"); - TRACE("Texture %p (level %d) given name %d\n", This->surfaces[i], i, This->surfaces[i]->textureName); - /* No need to walk through all mip-map levels, since already all assigned */ - i = This->baseTexture.levels; - - } else { - if (i == 0) { - if (This->surfaces[i]->textureName == 0) { - glGenTextures(1, &This->surfaces[i]->textureName); - checkGLcall("glGenTextures"); - TRACE("Texture %p (level %d) given name %d\n", This->surfaces[i], i, This->surfaces[i]->textureName); - } - - glBindTexture(GL_TEXTURE_2D, This->surfaces[i]->textureName); - checkGLcall("glBindTexture"); - } - IWineD3DSurface_LoadTexture((IWineD3DSurface *) This->surfaces[i], GL_TEXTURE_2D, i); - } +#if 0 /* TODO: context manager support */ + IWineD3DContextManager_PushState(This->contextManager, GL_TEXTURE_2D, ENABLED, NOW /* make sure the state is applied now */); +#endif + + /* Generate a texture name if we don't already have one */ + if (This->baseTexture.textureName == 0) { + glGenTextures(1, &This->baseTexture.textureName); + checkGLcall("glGenTextures"); + TRACE("Generated texture %d\n", This->baseTexture.textureName); + if (This->baseTexture.pool == D3DPOOL_DEFAULT) { + /* Tell opengl to try and keep this texture in video ram (well mostly) */ + GLclampf tmp; + tmp = 0.9f; + glPrioritizeTextures(1, &This->baseTexture.textureName, &tmp); + } } - /* No longer dirty */ - This->baseTexture.dirty = FALSE; + /* Bind the texture */ + if (This->baseTexture.textureName != 0) { + glBindTexture(GL_TEXTURE_2D, This->baseTexture.textureName); + checkGLcall("glBindTexture"); + } else { /* this only happened if we've run out of openGL textures */ + WARN("This texture doesn't have an openGL texture assigned to it\n"); + return; + } + + /* If were dirty then reload the surfaces */ + if(This->baseTexture.dirty != FALSE) { + for (i = 0; i < This->baseTexture.levels; i++) { + IWineD3DSurface_LoadTexture(This->surfaces[i], GL_TEXTURE_2D, i); + } + + /* No longer dirty */ + This->baseTexture.dirty = FALSE; + } /* Always need to reset the number of mipmap levels when rebinding as it is a property of the active texture unit, and another texture may have set it @@ -139,6 +160,11 @@ void WINAPI IWineD3DTextureImpl_PreLoad(IWineD3DTexture *iface) { TRACE("Setting GL_TEXTURE_MAX_LEVEL to %d\n", This->baseTexture.levels - 1); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, This->baseTexture.levels - 1); checkGLcall("glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, This->levels)"); + /* TODO: disable texture support, if it wastn't enabled when we entered. */ +#if 0 /* TODO: context manager support */ + IWineD3DContextManager_PopState(This->contextManager, GL_TEXTURE_2D, DISABLED,DELAYED + /* we don't care when the state is disabled(if atall) */); +#endif LEAVE_GL(); @@ -189,6 +215,45 @@ BOOL WINAPI IWineD3DTextureImpl_GetDirty(IWineD3DTexture *iface) { return IWineD3DBaseTextureImpl_GetDirty((IWineD3DBaseTexture *)iface); } +HRESULT WINAPI IWineD3DTextureImpl_BindTexture(IWineD3DTexture *iface) { + IWineD3DTextureImpl *This = (IWineD3DTextureImpl *)iface; + TRACE("(%p) : %d \n", This, This->baseTexture.textureName); +#if 0 /* TODO: context manager support */ + IWineD3DContextManager_PushState(This->contextManager, GL_TEXTURE_2D, ENABLED, NOW /* make sure the state is applied now */); +#endif + ENTER_GL(); + IWineD3DTexture_PreLoad(iface); /* make sure the textures is preloaded */ +#if 1 /* TODO: context manager support */ + glEnable(GL_TEXTURE_2D); /* all this enable disable stuff is a bit of a mess */ +#endif + glBindTexture(GL_TEXTURE_2D, This->baseTexture.textureName); + LEAVE_GL(); + return D3D_OK; +} + +HRESULT WINAPI IWineD3DTextureImpl_UnBindTexture(IWineD3DTexture *iface) { + IWineD3DTextureImpl *This = (IWineD3DTextureImpl *)iface; + TRACE("(%p) \n", This); +#if 0 /* TODO: context manager support */ + IWineD3DContextManager_PopState(This->contextManager, GL_TEXTURE_2D, DISABLED, DELAYED); +#endif + ENTER_GL(); +#if 1 /* TODO: context manager support */ + glBindTexture(GL_TEXTURE_2D, 0); +#endif + glDisable(GL_TEXTURE_2D); /* This should be queued! so that we don't keep enabling and disabling states. */ + LEAVE_GL(); + return D3D_OK; +} + +UINT WINAPI IWineD3DTextureImpl_GetTextureDimensions(IWineD3DTexture *iface) { + IWineD3DTextureImpl *This = (IWineD3DTextureImpl *)iface; + TRACE("(%p) \n", This); + + return GL_TEXTURE_2D; +} + + /* ******************************************* IWineD3DTexture IWineD3DTexture parts follow ******************************************* */ @@ -250,9 +315,11 @@ HRESULT WINAPI IWineD3DTextureImpl_AddDirtyRect(IWineD3DTexture *iface, CONST RE IWineD3DTextureVtbl IWineD3DTexture_Vtbl = { + /* IUnknown */ IWineD3DTextureImpl_QueryInterface, IWineD3DTextureImpl_AddRef, IWineD3DTextureImpl_Release, + /* IWineD3DResource */ IWineD3DTextureImpl_GetParent, IWineD3DTextureImpl_GetDevice, IWineD3DTextureImpl_SetPrivateData, @@ -262,6 +329,7 @@ IWineD3DTextureVtbl IWineD3DTexture_Vtbl = IWineD3DTextureImpl_GetPriority, IWineD3DTextureImpl_PreLoad, IWineD3DTextureImpl_GetType, + /* IWineD3DBaseTexture */ IWineD3DTextureImpl_SetLOD, IWineD3DTextureImpl_GetLOD, IWineD3DTextureImpl_GetLevelCount, @@ -270,6 +338,10 @@ IWineD3DTextureVtbl IWineD3DTexture_Vtbl = IWineD3DTextureImpl_GenerateMipSubLevels, IWineD3DTextureImpl_SetDirty, IWineD3DTextureImpl_GetDirty, + IWineD3DTextureImpl_BindTexture, + IWineD3DTextureImpl_UnBindTexture, + IWineD3DTextureImpl_GetTextureDimensions, + /* IWineD3DTexture */ IWineD3DTextureImpl_GetLevelDesc, IWineD3DTextureImpl_GetSurfaceLevel, IWineD3DTextureImpl_LockRect, diff --git a/dlls/wined3d/volume.c b/dlls/wined3d/volume.c index 08c0bd9a63c..765ce6ecf3f 100644 --- a/dlls/wined3d/volume.c +++ b/dlls/wined3d/volume.c @@ -54,8 +54,7 @@ ULONG WINAPI IWineD3DVolumeImpl_Release(IWineD3DVolume *iface) { TRACE("(%p) : Releasing from %ld\n", This, This->ref); ref = InterlockedDecrement(&This->ref); if (ref == 0) { - HeapFree(GetProcessHeap(), 0, This->allocatedMemory); - IWineD3DDevice_Release((IWineD3DDevice *)This->wineD3DDevice); + HeapFree(GetProcessHeap(), 0, This->allocatedMemory); HeapFree(GetProcessHeap(), 0, This); } else { IUnknown_Release(This->parent); /* Released the reference to the d3dx object */ @@ -232,11 +231,50 @@ HRESULT WINAPI IWineD3DVolumeImpl_AddDirtyBox(IWineD3DVolume *iface, CONST D3DBO return D3D_OK; } +HRESULT WINAPI IWineD3DVolumeImpl_SetContainer(IWineD3DVolume *iface, IUnknown* container){ + IWineD3DVolumeImpl *This = (IWineD3DVolumeImpl *)iface; + + This->container = container; + return D3D_OK; +} + +HRESULT WINAPI IWineD3DVolumeImpl_LoadTexture(IWineD3DVolume *iface, GLenum gl_level) { + IWineD3DVolumeImpl *This = (IWineD3DVolumeImpl *)iface; + IWineD3DDeviceImpl *myDevice = This->wineD3DDevice; + + TRACE("Calling glTexImage3D %x level=%d, intfmt=%x, w=%d, h=%d,d=%d, 0=%d, glFmt=%x, glType=%x, Mem=%p\n", + GL_TEXTURE_3D, + gl_level, + D3DFmt2GLIntFmt(myDevice, This->currentDesc.Format), + This->currentDesc.Width, + This->currentDesc.Height, + This->currentDesc.Depth, + 0, + D3DFmt2GLFmt(myDevice, This->currentDesc.Format), + D3DFmt2GLType(myDevice, This->currentDesc.Format), + This->allocatedMemory); + glTexImage3D(GL_TEXTURE_3D, + gl_level, + D3DFmt2GLIntFmt(myDevice, This->currentDesc.Format), + This->currentDesc.Width, + This->currentDesc.Height, + This->currentDesc.Depth, + 0, + D3DFmt2GLFmt(myDevice, This->currentDesc.Format), + D3DFmt2GLType(myDevice, This->currentDesc.Format), + This->allocatedMemory); + checkGLcall("glTexImage3D"); + return D3D_OK; + +} + IWineD3DVolumeVtbl IWineD3DVolume_Vtbl = { + /* IUnknown */ IWineD3DVolumeImpl_QueryInterface, IWineD3DVolumeImpl_AddRef, IWineD3DVolumeImpl_Release, + /* IWineD3DVolume */ IWineD3DVolumeImpl_GetParent, IWineD3DVolumeImpl_GetDevice, IWineD3DVolumeImpl_SetPrivateData, @@ -246,6 +284,9 @@ IWineD3DVolumeVtbl IWineD3DVolume_Vtbl = IWineD3DVolumeImpl_GetDesc, IWineD3DVolumeImpl_LockBox, IWineD3DVolumeImpl_UnlockBox, + /* Internal interface */ IWineD3DVolumeImpl_AddDirtyBox, - IWineD3DVolumeImpl_CleanDirtyBox + IWineD3DVolumeImpl_CleanDirtyBox, + IWineD3DVolumeImpl_LoadTexture, + IWineD3DVolumeImpl_SetContainer }; diff --git a/dlls/wined3d/volumetexture.c b/dlls/wined3d/volumetexture.c index 20bd6fc7877..2f7aaf36f41 100644 --- a/dlls/wined3d/volumetexture.c +++ b/dlls/wined3d/volumetexture.c @@ -1,8 +1,9 @@ /* - * IDirect3DVolumeTexture9 implementation + * IWineD3DVolumeTexture implementation * * Copyright 2002-2005 Jason Edmeades - * Raphael Junqueira + * Copyright 2002-2005 Raphael Junqueira + * Copyright 2005 Oliver Stieber * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -63,7 +64,12 @@ ULONG WINAPI IWineD3DVolumeTextureImpl_Release(IWineD3DVolumeTexture *iface) { IWineD3DVolume_Release((IWineD3DSurface *) This->volumes[i]); } } - IWineD3DDevice_Release((IWineD3DDevice *)This->resource.wineD3DDevice); + if(This->baseTexture.textureName != 0){ + ENTER_GL(); + TRACE("Deleting texture %d\n", This->baseTexture.textureName); + glDeleteTextures(1, &This->baseTexture.textureName); + LEAVE_GL(); + } HeapFree(GetProcessHeap(), 0, This); } else { IUnknown_Release(This->resource.parent); /* Released the reference to the d3dx object */ @@ -100,66 +106,53 @@ DWORD WINAPI IWineD3DVolumeTextureImpl_GetPriority(IWineD3DVolumeTexture *iface) void WINAPI IWineD3DVolumeTextureImpl_PreLoad(IWineD3DVolumeTexture *iface) { /* Overrider the IWineD3DResource Preload method */ - unsigned int i; + UINT i; IWineD3DVolumeTextureImpl *This = (IWineD3DVolumeTextureImpl *)iface; TRACE("(%p) : About to load texture\n", This); ENTER_GL(); +#if 0 /* TODO: context manager support */ + IWineD3DContextManager_PushState(This->contextManager, GL_TEXTURE_3D, ENABLED, NOW /* make sure the state is applied now */); +#endif + glEnable(GL_TEXTURE_3D); /* make sure texture support is enabled in this context */ - for (i = 0; i < This->baseTexture.levels; i++) { - - if (i == 0 && This->volumes[i]->textureName != 0 && This->baseTexture.dirty == FALSE) { - glBindTexture(GL_TEXTURE_3D, This->volumes[i]->textureName); - checkGLcall("glBindTexture"); - TRACE("Texture %p (level %d) given name %d\n", This->volumes[i], i, This->volumes[i]->textureName); - /* No need to walk through all mip-map levels, since already all assigned */ - i = This->baseTexture.levels; - - } else { - - if (i == 0) { - if (This->volumes[i]->textureName == 0) { - glGenTextures(1, &This->volumes[i]->textureName); - checkGLcall("glGenTextures"); - TRACE("Texture %p (level %d) given name %d\n", This->volumes[i], i, This->volumes[i]->textureName); - } - - glBindTexture(GL_TEXTURE_3D, This->volumes[i]->textureName); - checkGLcall("glBindTexture"); - - TRACE("Setting GL_TEXTURE_MAX_LEVEL to %d\n", This->baseTexture.levels - 1); - glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, This->baseTexture.levels - 1); - checkGLcall("glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, This->levels - 1)"); - } - - TRACE("Calling glTexImage3D %x i=%d, intfmt=%x, w=%d, h=%d,d=%d, 0=%d, glFmt=%x, glType=%x, Mem=%p\n", - GL_TEXTURE_3D, - i, - D3DFmt2GLIntFmt(This->resource.wineD3DDevice, This->volumes[i]->currentDesc.Format), - This->volumes[i]->currentDesc.Width, - This->volumes[i]->currentDesc.Height, - This->volumes[i]->currentDesc.Depth, - 0, - D3DFmt2GLFmt(This->resource.wineD3DDevice, This->volumes[i]->currentDesc.Format), - D3DFmt2GLType(This->resource.wineD3DDevice, This->volumes[i]->currentDesc.Format), - This->volumes[i]->allocatedMemory); - glTexImage3D(GL_TEXTURE_3D, - i, - D3DFmt2GLIntFmt(This->resource.wineD3DDevice, This->volumes[i]->currentDesc.Format), - This->volumes[i]->currentDesc.Width, - This->volumes[i]->currentDesc.Height, - This->volumes[i]->currentDesc.Depth, - 0, - D3DFmt2GLFmt(This->resource.wineD3DDevice, This->volumes[i]->currentDesc.Format), - D3DFmt2GLType(This->resource.wineD3DDevice, This->volumes[i]->currentDesc.Format), - This->volumes[i]->allocatedMemory); - checkGLcall("glTexImage3D"); - - This->baseTexture.dirty = FALSE; - } + /* Generate a texture name if we don't already have one */ + if (This->baseTexture.textureName == 0) { + glGenTextures(1, &This->baseTexture.textureName); + checkGLcall("glGenTextures"); + TRACE("Generated texture %d\n", This->baseTexture.textureName); + if (This->baseTexture.pool == D3DPOOL_DEFAULT) { + /* Tell opengl to try and keep this texture in video ram (well mostly) */ + GLclampf tmp; + tmp = 0.9f; + glPrioritizeTextures(1, &This->baseTexture.textureName, &tmp); + } } + /* Bind the texture */ + if (This->baseTexture.textureName != 0) { + glBindTexture(GL_TEXTURE_3D, This->baseTexture.textureName); + checkGLcall("glBindTexture"); + } else { /* this only happened if we've run out of openGL textures */ + WARN("This texture doesn't have an openGL texture assigned to it\n"); + return; + } + + /* If were dirty then reload the volumes */ + if(This->baseTexture.dirty != FALSE) { + for (i = 0; i < This->baseTexture.levels; i++) { + IWineD3DVolume_LoadTexture(This->volumes[i], i); + } + + /* No longer dirty */ + This->baseTexture.dirty = FALSE; + } + + + TRACE("Setting GL_TEXTURE_MAX_LEVEL to %d\n", This->baseTexture.levels - 1); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, This->baseTexture.levels - 1); + checkGLcall("glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, This->levels - 1)"); LEAVE_GL(); return ; @@ -202,13 +195,42 @@ void WINAPI IWineD3DVolumeTextureImpl_GenerateMipSubLevels(IWineD3DVolumeTexture /* Internal function, No d3d mapping */ BOOL WINAPI IWineD3DVolumeTextureImpl_SetDirty(IWineD3DVolumeTexture *iface, BOOL dirty) { - return IWineD3DBaseTextureImpl_SetDirty((IWineD3DBaseTexture *)iface, TRUE); + return IWineD3DBaseTextureImpl_SetDirty((IWineD3DBaseTexture *)iface, dirty); } BOOL WINAPI IWineD3DVolumeTextureImpl_GetDirty(IWineD3DVolumeTexture *iface) { return IWineD3DBaseTextureImpl_GetDirty((IWineD3DBaseTexture *)iface); } +HRESULT WINAPI IWineD3DVolumeTextureImpl_BindTexture(IWineD3DVolumeTexture *iface) { + IWineD3DVolumeTextureImpl *This = (IWineD3DVolumeTextureImpl *)iface; + TRACE("(%p) : %d \n", This, This->baseTexture.textureName); + /* make sure that there is a texture to bind */ + IWineD3DVolumeTexture_PreLoad(iface); + ENTER_GL(); + glEnable(GL_TEXTURE_3D); /* all this enable disable stuff is a bit of a mess */ + /* FIXME: change to use this->textureName */ + glBindTexture(GL_TEXTURE_3D, This->baseTexture.textureName); + LEAVE_GL(); + return D3D_OK; +} + +HRESULT WINAPI IWineD3DVolumeTextureImpl_UnBindTexture(IWineD3DVolumeTexture *iface) { + IWineD3DVolumeTextureImpl *This = (IWineD3DVolumeTextureImpl *)iface; + TRACE("(%p) \n", This); + ENTER_GL(); + glBindTexture(GL_TEXTURE_3D, 0); + glDisable(GL_TEXTURE_3D); + LEAVE_GL(); + return D3D_OK; +} + +UINT WINAPI IWineD3DVolumeTextureImpl_GetTextureDimensions(IWineD3DVolumeTexture *iface) { + IWineD3DVolumeTextureImpl *This = (IWineD3DVolumeTextureImpl *)iface; + TRACE("(%p) \n", This); + return GL_TEXTURE_3D; +} + /* ******************************************* IWineD3DVolumeTexture IWineD3DVolumeTexture parts follow ******************************************* */ @@ -272,12 +294,13 @@ HRESULT WINAPI IWineD3DVolumeTextureImpl_AddDirtyBox(IWineD3DVolumeTexture *ifac return IWineD3DVolume_AddDirtyBox((IWineD3DVolume *) This->volumes[0], pDirtyBox); } - IWineD3DVolumeTextureVtbl IWineD3DVolumeTexture_Vtbl = { + /* IUnknown */ IWineD3DVolumeTextureImpl_QueryInterface, IWineD3DVolumeTextureImpl_AddRef, IWineD3DVolumeTextureImpl_Release, + /* resource */ IWineD3DVolumeTextureImpl_GetParent, IWineD3DVolumeTextureImpl_GetDevice, IWineD3DVolumeTextureImpl_SetPrivateData, @@ -287,6 +310,7 @@ IWineD3DVolumeTextureVtbl IWineD3DVolumeTexture_Vtbl = IWineD3DVolumeTextureImpl_GetPriority, IWineD3DVolumeTextureImpl_PreLoad, IWineD3DVolumeTextureImpl_GetType, + /* BaseTexture */ IWineD3DVolumeTextureImpl_SetLOD, IWineD3DVolumeTextureImpl_GetLOD, IWineD3DVolumeTextureImpl_GetLevelCount, @@ -295,6 +319,11 @@ IWineD3DVolumeTextureVtbl IWineD3DVolumeTexture_Vtbl = IWineD3DVolumeTextureImpl_GenerateMipSubLevels, IWineD3DVolumeTextureImpl_SetDirty, IWineD3DVolumeTextureImpl_GetDirty, + /* not in d3d */ + IWineD3DVolumeTextureImpl_BindTexture, + IWineD3DVolumeTextureImpl_UnBindTexture, + IWineD3DVolumeTextureImpl_GetTextureDimensions, + /* volume texture */ IWineD3DVolumeTextureImpl_GetLevelDesc, IWineD3DVolumeTextureImpl_GetVolumeLevel, IWineD3DVolumeTextureImpl_LockBox, diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 683c59408dd..cf51c92f9c2 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -377,19 +377,19 @@ typedef struct IWineD3DDeviceImpl D3DDEVTYPE devType; /* Render Target Support */ - IWineD3DSurfaceImpl *frontBuffer; - IWineD3DSurfaceImpl *backBuffer; - IWineD3DSurfaceImpl *depthStencilBuffer; + IWineD3DSurface *frontBuffer; + IWineD3DSurface *backBuffer; + IWineD3DSurface *depthStencilBuffer; - IWineD3DSurfaceImpl *renderTarget; - IWineD3DSurfaceImpl *stencilBufferTarget; + IWineD3DSurface *renderTarget; + IWineD3DSurface *stencilBufferTarget; /* palettes texture management */ - PALETTEENTRY palettes[MAX_PALETTES][256]; - UINT currentPalette; + PALETTEENTRY palettes[MAX_PALETTES][256]; + UINT currentPalette; /* For rendering to a texture using glCopyTexImage */ - BOOL renderUpsideDown; + BOOL renderUpsideDown; /* Cursor management */ BOOL bCursorVisible; @@ -474,6 +474,11 @@ typedef struct IWineD3DBaseTextureClass UINT levels; BOOL dirty; D3DFORMAT format; + D3DPOOL pool; + DWORD usage; + UINT textureName; + UINT LOD; + D3DTEXTUREFILTERTYPE filterType; } IWineD3DBaseTextureClass; @@ -499,11 +504,10 @@ typedef struct IWineD3DTextureImpl IWineD3DBaseTextureClass baseTexture; /* IWineD3DTexture */ - IWineD3DSurfaceImpl *surfaces[MAX_LEVELS]; + IWineD3DSurface *surfaces[MAX_LEVELS]; UINT width; UINT height; - DWORD usage; } IWineD3DTextureImpl; @@ -520,10 +524,10 @@ typedef struct IWineD3DCubeTextureImpl IWineD3DBaseTextureClass baseTexture; /* IWineD3DCubeTexture */ - IWineD3DSurfaceImpl *surfaces[6][MAX_LEVELS]; + IWineD3DSurface *surfaces[6][MAX_LEVELS]; UINT edgeLength; - DWORD usage; + } IWineD3DCubeTextureImpl; extern IWineD3DCubeTextureVtbl IWineD3DCubeTexture_Vtbl; @@ -543,7 +547,6 @@ typedef struct IWineD3DVolumeImpl IWineD3DDeviceImpl *wineD3DDevice; D3DVOLUME_DESC currentDesc; - UINT textureName; BYTE *allocatedMemory; IUnknown *container; UINT bytesPerPixel; @@ -570,12 +573,11 @@ typedef struct IWineD3DVolumeTextureImpl IWineD3DBaseTextureClass baseTexture; /* IWineD3DVolumeTexture */ - IWineD3DVolumeImpl *volumes[MAX_LEVELS]; + IWineD3DVolume *volumes[MAX_LEVELS]; UINT width; UINT height; UINT depth; - DWORD usage; } IWineD3DVolumeTextureImpl; extern IWineD3DVolumeTextureVtbl IWineD3DVolumeTexture_Vtbl; diff --git a/include/wine/wined3d_interface.h b/include/wine/wined3d_interface.h index 684f5a36cf5..1f322534e9c 100644 --- a/include/wine/wined3d_interface.h +++ b/include/wine/wined3d_interface.h @@ -685,6 +685,9 @@ DECLARE_INTERFACE_(IWineD3DBaseTexture,IWineD3DResource) STDMETHOD_(void, GenerateMipSubLevels)(THIS) PURE; STDMETHOD_(BOOL, SetDirty)(THIS_ BOOL) PURE; STDMETHOD_(BOOL, GetDirty)(THIS) PURE; + STDMETHOD(BindTexture)(THIS) PURE; + STDMETHOD(UnBindTexture)(THIS) PURE; + STDMETHOD_(UINT, GetTextureDimensions)(THIS) PURE; }; #undef INTERFACE @@ -713,6 +716,10 @@ DECLARE_INTERFACE_(IWineD3DBaseTexture,IWineD3DResource) #define IWineD3DBaseTexture_GenerateMipSubLevels(p) (p)->lpVtbl->GenerateMipSubLevels(p) #define IWineD3DBaseTexture_SetDirty(p,a) (p)->lpVtbl->SetDirty(p,a) #define IWineD3DBaseTexture_GetDirty(p) (p)->lpVtbl->GetDirty(p) +/*** internal methods ***/ +#define IWineD3DBaseTexture_BindTexture(p) (p)->lpVtbl->BindTexture(p) +#define IWineD3DBaseTexture_UnBindTexture(p) (p)->lpVtbl->UnBindTexture(p) +#define IWineD3DBaseTexture_GetTextureDimensions(p) (p)->lpVtbl->GetTextureDimensions(p) #endif /***************************************************************************** @@ -744,6 +751,9 @@ DECLARE_INTERFACE_(IWineD3DTexture,IWineD3DBaseTexture) STDMETHOD_(void, GenerateMipSubLevels)(THIS) PURE; STDMETHOD_(BOOL, SetDirty)(THIS_ BOOL) PURE; STDMETHOD_(BOOL, GetDirty)(THIS) PURE; + STDMETHOD(BindTexture)(THIS) PURE; + STDMETHOD(UnBindTexture)(THIS) PURE; + STDMETHOD_(UINT, GetTextureDimensions)(THIS) PURE; /*** IWineD3DTexture methods ***/ STDMETHOD(GetLevelDesc)(THIS_ UINT Level, WINED3DSURFACE_DESC* pDesc) PURE; STDMETHOD(GetSurfaceLevel)(THIS_ UINT Level, IWineD3DSurface** ppSurfaceLevel) PURE; @@ -777,6 +787,9 @@ DECLARE_INTERFACE_(IWineD3DTexture,IWineD3DBaseTexture) #define IWineD3DTexture_GenerateMipSubLevels(p) (p)->lpVtbl->GenerateMipSubLevels(p) #define IWineD3DTexture_SetDirty(p,a) (p)->lpVtbl->SetDirty(p,a) #define IWineD3DTexture_GetDirty(p) (p)->lpVtbl->GetDirty(p) +#define IWineD3DTexture_BindTexture(p) (p)->lpVtbl->BindTexture(p) +#define IWineD3DTexture_UnBindTexture(p) (p)->lpVtbl->UnBindTexture(p) +#define IWineD3DTexture_GetTextureDimensions(p) (p)->lpVtbl->GetTextureDimensions(p) /*** IWineD3DTexture methods ***/ #define IWineD3DTexture_GetLevelDesc(p,a,b) (p)->lpVtbl->GetLevelDesc(p,a,b) #define IWineD3DTexture_GetSurfaceLevel(p,a,b) (p)->lpVtbl->GetSurfaceLevel(p,a,b) @@ -814,6 +827,9 @@ DECLARE_INTERFACE_(IWineD3DCubeTexture,IWineD3DBaseTexture) STDMETHOD_(void, GenerateMipSubLevels)(THIS) PURE; STDMETHOD_(BOOL, SetDirty)(THIS_ BOOL) PURE; STDMETHOD_(BOOL, GetDirty)(THIS) PURE; + STDMETHOD(BindTexture)(THIS) PURE; + STDMETHOD(UnBindTexture)(THIS) PURE; + STDMETHOD_(UINT, GetTextureDimensions)(THIS) PURE; /*** IWineD3DCubeTexture methods ***/ STDMETHOD(GetLevelDesc)(THIS_ UINT Level,WINED3DSURFACE_DESC* pDesc) PURE; STDMETHOD(GetCubeMapSurface)(THIS_ D3DCUBEMAP_FACES FaceType, UINT Level, IWineD3DSurface** ppCubeMapSurface) PURE; @@ -847,6 +863,9 @@ DECLARE_INTERFACE_(IWineD3DCubeTexture,IWineD3DBaseTexture) #define IWineD3DCubeTexture_GenerateMipSubLevels(p) (p)->lpVtbl->GenerateMipSubLevels(p) #define IWineD3DCubeTexture_SetDirty(p,a) (p)->lpVtbl->SetDirty(p,a) #define IWineD3DCubeTexture_GetDirty(p) (p)->lpVtbl->GetDirty(p) +#define IWineD3DCubeTexture_BindTexture(p) (p)->lpVtbl->BindTexture(p) +#define IWineD3DCubeTexture_UnBindTexture(p) (p)->lpVtbl->UnBindTexture(p) +#define IWineD3DCubeTexture_GetTextureDimensions(p) (p)->lpVtbl->GetTextureDimensions(p) /*** IWineD3DCubeTexture methods ***/ #define IWineD3DCubeTexture_GetLevelDesc(p,a,b) (p)->lpVtbl->GetLevelDesc(p,a,b) #define IWineD3DCubeTexture_GetCubeMapSurface(p,a,b,c) (p)->lpVtbl->GetCubeMapSurface(p,a,b,c) @@ -885,6 +904,9 @@ DECLARE_INTERFACE_(IWineD3DVolumeTexture,IWineD3DBaseTexture) STDMETHOD_(void, GenerateMipSubLevels)(THIS) PURE; STDMETHOD_(BOOL, SetDirty)(THIS_ BOOL) PURE; STDMETHOD_(BOOL, GetDirty)(THIS) PURE; + STDMETHOD(BindTexture)(THIS) PURE; + STDMETHOD(UnBindTexture)(THIS) PURE; + STDMETHOD_(UINT, GetTextureDimensions)(THIS) PURE; /*** IWineD3DVolumeTexture methods ***/ STDMETHOD(GetLevelDesc)(THIS_ UINT Level, WINED3DVOLUME_DESC *pDesc) PURE; STDMETHOD(GetVolumeLevel)(THIS_ UINT Level, IWineD3DVolume** ppVolumeLevel) PURE; @@ -918,7 +940,9 @@ DECLARE_INTERFACE_(IWineD3DVolumeTexture,IWineD3DBaseTexture) #define IWineD3DVolumeTexture_GenerateMipSubLevels(p) (p)->lpVtbl->GenerateMipSubLevels(p) #define IWineD3DVolumeTexture_SetDirty(p,a) (p)->lpVtbl->SetDirty(p,a) #define IWineD3DVolumeTexture_GetDirty(p) (p)->lpVtbl->GetDirty(p) - +#define IWineD3DVolumeTexture_BindTexture(p) (p)->lpVtbl->BindTexture(p) +#define IWineD3DVolumeTexture_UnBindTexture(p) (p)->lpVtbl->UnBindTexture(p) +#define IWineD3DVolumeTexture_GetTextureDimensions(p) (p)->lpVtbl->GetTextureDimensions(p) /*** IWineD3DVolumeTexture methods ***/ #define IWineD3DVolumeTexture_GetLevelDesc(p,a,b) (p)->lpVtbl->GetLevelDesc(p,a,b) #define IWineD3DVolumeTexture_GetVolumeLevel(p,a,b) (p)->lpVtbl->GetVolumeLevel(p,a,b) @@ -959,6 +983,9 @@ DECLARE_INTERFACE_(IWineD3DSurface,IWineD3DResource) STDMETHOD(AddDirtyRect)(THIS_ CONST RECT* pRect) PURE; STDMETHOD(LoadTexture)(THIS_ UINT gl_target, UINT gl_level) PURE; STDMETHOD(SaveSnapshot)(THIS_ const char *filename) PURE; + STDMETHOD(SetContainer)(THIS_ IUnknown *container) PURE; + STDMETHOD(SetPBufferState)(THIS_ BOOL inPBuffer, BOOL inTexture) PURE; + }; #undef INTERFACE @@ -968,7 +995,6 @@ DECLARE_INTERFACE_(IWineD3DSurface,IWineD3DResource) #define IWineD3DSurface_AddRef(p) (p)->lpVtbl->AddRef(p) #define IWineD3DSurface_Release(p) (p)->lpVtbl->Release(p) /*** IWineD3DResource methods ***/ -/*** IWineD3DResource methods ***/ #define IWineD3DSurface_GetParent(p,a) (p)->lpVtbl->GetParent(p,a) #define IWineD3DSurface_GetDevice(p,a) (p)->lpVtbl->GetDevice(p,a) #define IWineD3DSurface_SetPrivateData(p,a,b,c,d) (p)->lpVtbl->SetPrivateData(p,a,b,c,d) @@ -990,6 +1016,8 @@ DECLARE_INTERFACE_(IWineD3DSurface,IWineD3DResource) #define IWineD3DSurface_AddDirtyRect(p,a) (p)->lpVtbl->AddDirtyRect(p,a) #define IWineD3DSurface_LoadTexture(p,a,b) (p)->lpVtbl->LoadTexture(p,a,b) #define IWineD3DSurface_SaveSnapshot(p,a) (p)->lpVtbl->SaveSnapshot(p,a) +#define IWineD3DSurface_SetContainer(p,a) (p)->lpVtbl->SetContainer(p,a) +#define IWineD3DSurface_SetPBufferState(p,a,b) (p)->lpVtbl->SetPBufferState(p,a,b) #endif /***************************************************************************** @@ -1014,6 +1042,8 @@ DECLARE_INTERFACE_(IWineD3DVolume,IUnknown) STDMETHOD(UnlockBox)(THIS) PURE; STDMETHOD(AddDirtyBox)(THIS_ CONST D3DBOX* pDirtyBox) PURE; STDMETHOD(CleanDirtyBox)(THIS) PURE; + STDMETHOD(LoadTexture)(THIS_ UINT gl_level) PURE; + STDMETHOD(SetContainer)(THIS_ IUnknown *container) PURE; }; #undef INTERFACE @@ -1034,6 +1064,8 @@ DECLARE_INTERFACE_(IWineD3DVolume,IUnknown) #define IWineD3DVolume_UnlockBox(p) (p)->lpVtbl->UnlockBox(p) #define IWineD3DVolume_AddDirtyBox(p,a) (p)->lpVtbl->AddDirtyBox(p,a) #define IWineD3DVolume_CleanDirtyBox(p) (p)->lpVtbl->CleanDirtyBox(p) +#define IWineD3DVolume_LoadTexture(p,a) (p)->lpVtbl->LoadTexture(p,a) +#define IWineD3DVolume_SetContainer(p,a) (p)->lpVtbl->SetContainer(p,a) #endif /*****************************************************************************