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 /*****************************************************************************