| /* | 
 |  * IWineD3DVolumeTexture implementation | 
 |  * | 
 |  * Copyright 2002-2005 Jason Edmeades | 
 |  * 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 | 
 |  * License as published by the Free Software Foundation; either | 
 |  * version 2.1 of the License, or (at your option) any later version. | 
 |  * | 
 |  * This library is distributed in the hope that it will be useful, | 
 |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
 |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | 
 |  * Lesser General Public License for more details. | 
 |  * | 
 |  * You should have received a copy of the GNU Lesser General Public | 
 |  * License along with this library; if not, write to the Free Software | 
 |  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA | 
 |  */ | 
 |  | 
 | #include "config.h" | 
 | #include "wined3d_private.h" | 
 |  | 
 | WINE_DEFAULT_DEBUG_CHANNEL(d3d); | 
 | #define GLINFO_LOCATION ((IWineD3DImpl *)(((IWineD3DDeviceImpl *)This->resource.wineD3DDevice)->wineD3D))->gl_info | 
 |  | 
 | /* ******************************************* | 
 |    IWineD3DTexture IUnknown parts follow | 
 |    ******************************************* */ | 
 | static HRESULT WINAPI IWineD3DVolumeTextureImpl_QueryInterface(IWineD3DVolumeTexture *iface, REFIID riid, LPVOID *ppobj) | 
 | { | 
 |     IWineD3DVolumeTextureImpl *This = (IWineD3DVolumeTextureImpl *)iface; | 
 |     TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(riid),ppobj); | 
 |     if (IsEqualGUID(riid, &IID_IUnknown) | 
 |         || IsEqualGUID(riid, &IID_IWineD3DBase) | 
 |         || IsEqualGUID(riid, &IID_IWineD3DResource) | 
 |         || IsEqualGUID(riid, &IID_IWineD3DBaseTexture) | 
 |         || IsEqualGUID(riid, &IID_IWineD3DVolumeTexture)) { | 
 |         IUnknown_AddRef(iface); | 
 |         *ppobj = This; | 
 |         return S_OK; | 
 |     } | 
 |     *ppobj = NULL; | 
 |     return E_NOINTERFACE; | 
 | } | 
 |  | 
 | static ULONG WINAPI IWineD3DVolumeTextureImpl_AddRef(IWineD3DVolumeTexture *iface) { | 
 |     IWineD3DVolumeTextureImpl *This = (IWineD3DVolumeTextureImpl *)iface; | 
 |     TRACE("(%p) : AddRef increasing from %d\n", This, This->resource.ref); | 
 |     return InterlockedIncrement(&This->resource.ref); | 
 | } | 
 |  | 
 | static ULONG WINAPI IWineD3DVolumeTextureImpl_Release(IWineD3DVolumeTexture *iface) { | 
 |     IWineD3DVolumeTextureImpl *This = (IWineD3DVolumeTextureImpl *)iface; | 
 |     ULONG ref; | 
 |     TRACE("(%p) : Releasing from %d\n", This, This->resource.ref); | 
 |     ref = InterlockedDecrement(&This->resource.ref); | 
 |     if (ref == 0) { | 
 |         IWineD3DVolumeTexture_Destroy(iface, D3DCB_DefaultDestroyVolume); | 
 |     } | 
 |     return ref; | 
 | } | 
 |  | 
 | /* **************************************************** | 
 |    IWineD3DVolumeTexture IWineD3DResource parts follow | 
 |    **************************************************** */ | 
 | static HRESULT WINAPI IWineD3DVolumeTextureImpl_GetDevice(IWineD3DVolumeTexture *iface, IWineD3DDevice** ppDevice) { | 
 |     return IWineD3DResourceImpl_GetDevice((IWineD3DResource *)iface, ppDevice); | 
 | } | 
 |  | 
 | static HRESULT WINAPI IWineD3DVolumeTextureImpl_SetPrivateData(IWineD3DVolumeTexture *iface, REFGUID refguid, CONST void* pData, DWORD SizeOfData, DWORD Flags) { | 
 |     return IWineD3DResourceImpl_SetPrivateData((IWineD3DResource *)iface, refguid, pData, SizeOfData, Flags); | 
 | } | 
 |  | 
 | static HRESULT WINAPI IWineD3DVolumeTextureImpl_GetPrivateData(IWineD3DVolumeTexture *iface, REFGUID refguid, void* pData, DWORD* pSizeOfData) { | 
 |     return IWineD3DResourceImpl_GetPrivateData((IWineD3DResource *)iface, refguid, pData, pSizeOfData); | 
 | } | 
 |  | 
 | static HRESULT WINAPI IWineD3DVolumeTextureImpl_FreePrivateData(IWineD3DVolumeTexture *iface, REFGUID refguid) { | 
 |     return IWineD3DResourceImpl_FreePrivateData((IWineD3DResource *)iface, refguid); | 
 | } | 
 |  | 
 | static DWORD WINAPI IWineD3DVolumeTextureImpl_SetPriority(IWineD3DVolumeTexture *iface, DWORD PriorityNew) { | 
 |     return IWineD3DResourceImpl_SetPriority((IWineD3DResource *)iface, PriorityNew); | 
 | } | 
 |  | 
 | static DWORD WINAPI IWineD3DVolumeTextureImpl_GetPriority(IWineD3DVolumeTexture *iface) { | 
 |     return IWineD3DResourceImpl_GetPriority((IWineD3DResource *)iface); | 
 | } | 
 |  | 
 | static void WINAPI IWineD3DVolumeTextureImpl_PreLoad(IWineD3DVolumeTexture *iface) { | 
 |     /* Overrider the IWineD3DResource Preload method */ | 
 |     UINT i; | 
 |     IWineD3DVolumeTextureImpl *This = (IWineD3DVolumeTextureImpl *)iface; | 
 |  | 
 |     TRACE("(%p) : About to load texture\n", This); | 
 |  | 
 |     IWineD3DVolumeTexture_BindTexture(iface); | 
 |  | 
 |     ENTER_GL(); | 
 |     /* If were dirty then reload the volumes */ | 
 |     if(This->baseTexture.dirty) { | 
 |         for (i = 0; i < This->baseTexture.levels; i++) { | 
 |             IWineD3DVolume_LoadTexture(This->volumes[i], i); | 
 |         } | 
 |  | 
 |         /* No longer dirty */ | 
 |         This->baseTexture.dirty = FALSE; | 
 |     } | 
 |     LEAVE_GL(); | 
 |  | 
 |     return ; | 
 | } | 
 |  | 
 | static WINED3DRESOURCETYPE WINAPI IWineD3DVolumeTextureImpl_GetType(IWineD3DVolumeTexture *iface) { | 
 |     return IWineD3DResourceImpl_GetType((IWineD3DResource *)iface); | 
 | } | 
 |  | 
 | static HRESULT WINAPI IWineD3DVolumeTextureImpl_GetParent(IWineD3DVolumeTexture *iface, IUnknown **pParent) { | 
 |     return IWineD3DResourceImpl_GetParent((IWineD3DResource *)iface, pParent); | 
 | } | 
 |  | 
 | /* ****************************************************** | 
 |    IWineD3DVolumeTexture IWineD3DBaseTexture parts follow | 
 |    ****************************************************** */ | 
 | static DWORD WINAPI IWineD3DVolumeTextureImpl_SetLOD(IWineD3DVolumeTexture *iface, DWORD LODNew) { | 
 |     return IWineD3DBaseTextureImpl_SetLOD((IWineD3DBaseTexture *)iface, LODNew); | 
 | } | 
 |  | 
 | static DWORD WINAPI IWineD3DVolumeTextureImpl_GetLOD(IWineD3DVolumeTexture *iface) { | 
 |     return IWineD3DBaseTextureImpl_GetLOD((IWineD3DBaseTexture *)iface); | 
 | } | 
 |  | 
 | static DWORD WINAPI IWineD3DVolumeTextureImpl_GetLevelCount(IWineD3DVolumeTexture *iface) { | 
 |     return IWineD3DBaseTextureImpl_GetLevelCount((IWineD3DBaseTexture *)iface); | 
 | } | 
 |  | 
 | static HRESULT WINAPI IWineD3DVolumeTextureImpl_SetAutoGenFilterType(IWineD3DVolumeTexture *iface, WINED3DTEXTUREFILTERTYPE FilterType) { | 
 |   return IWineD3DBaseTextureImpl_SetAutoGenFilterType((IWineD3DBaseTexture *)iface, FilterType); | 
 | } | 
 |  | 
 | static WINED3DTEXTUREFILTERTYPE WINAPI IWineD3DVolumeTextureImpl_GetAutoGenFilterType(IWineD3DVolumeTexture *iface) { | 
 |   return IWineD3DBaseTextureImpl_GetAutoGenFilterType((IWineD3DBaseTexture *)iface); | 
 | } | 
 |  | 
 | static void WINAPI IWineD3DVolumeTextureImpl_GenerateMipSubLevels(IWineD3DVolumeTexture *iface) { | 
 |   return IWineD3DBaseTextureImpl_GenerateMipSubLevels((IWineD3DBaseTexture *)iface); | 
 | } | 
 |  | 
 | /* Internal function, No d3d mapping */ | 
 | static BOOL WINAPI IWineD3DVolumeTextureImpl_SetDirty(IWineD3DVolumeTexture *iface, BOOL dirty) { | 
 |     return IWineD3DBaseTextureImpl_SetDirty((IWineD3DBaseTexture *)iface, dirty); | 
 | } | 
 |  | 
 | static BOOL WINAPI IWineD3DVolumeTextureImpl_GetDirty(IWineD3DVolumeTexture *iface) { | 
 |     return IWineD3DBaseTextureImpl_GetDirty((IWineD3DBaseTexture *)iface); | 
 | } | 
 |  | 
 | static HRESULT WINAPI IWineD3DVolumeTextureImpl_BindTexture(IWineD3DVolumeTexture *iface) { | 
 |     IWineD3DVolumeTextureImpl *This = (IWineD3DVolumeTextureImpl *)iface; | 
 |     TRACE("(%p) : relay to BaseTexture\n", This); | 
 |     return IWineD3DBaseTextureImpl_BindTexture((IWineD3DBaseTexture *)iface); | 
 | } | 
 |  | 
 | static HRESULT WINAPI IWineD3DVolumeTextureImpl_UnBindTexture(IWineD3DVolumeTexture *iface) { | 
 |     IWineD3DVolumeTextureImpl *This = (IWineD3DVolumeTextureImpl *)iface; | 
 |     TRACE("(%p) : relay to BaseTexture\n", This); | 
 |     return IWineD3DBaseTextureImpl_UnBindTexture((IWineD3DBaseTexture *)iface); | 
 | } | 
 |  | 
 | static UINT WINAPI IWineD3DVolumeTextureImpl_GetTextureDimensions(IWineD3DVolumeTexture *iface) { | 
 |     IWineD3DVolumeTextureImpl *This = (IWineD3DVolumeTextureImpl *)iface; | 
 |     TRACE("(%p)\n", This); | 
 |     return GL_TEXTURE_3D; | 
 | } | 
 |  | 
 | static void WINAPI IWineD3DVolumeTextureImpl_ApplyStateChanges(IWineD3DVolumeTexture *iface, | 
 |                                                         const DWORD textureStates[WINED3D_HIGHEST_TEXTURE_STATE + 1], | 
 |                                                         const DWORD samplerStates[WINED3D_HIGHEST_SAMPLER_STATE + 1]) { | 
 |     IWineD3DVolumeTextureImpl *This = (IWineD3DVolumeTextureImpl *)iface; | 
 |     TRACE("(%p) : nothing to do, passing to base texture\n", This); | 
 |     IWineD3DBaseTextureImpl_ApplyStateChanges((IWineD3DBaseTexture *)iface, textureStates, samplerStates); | 
 | } | 
 |  | 
 |  | 
 | /* ******************************************* | 
 |    IWineD3DVolumeTexture IWineD3DVolumeTexture parts follow | 
 |    ******************************************* */ | 
 | static void WINAPI IWineD3DVolumeTextureImpl_Destroy(IWineD3DVolumeTexture *iface, D3DCB_DESTROYVOLUMEFN D3DCB_DestroyVolume) { | 
 |     IWineD3DVolumeTextureImpl *This = (IWineD3DVolumeTextureImpl *)iface; | 
 |     int i; | 
 |     TRACE("(%p) : Cleaning up\n",This); | 
 |     for (i = 0; i < This->baseTexture.levels; i++) { | 
 |         if (This->volumes[i] != NULL) { | 
 |             /* Cleanup the container */ | 
 |             IWineD3DVolume_SetContainer(This->volumes[i], 0); | 
 |             D3DCB_DestroyVolume(This->volumes[i]); | 
 |         } | 
 |     } | 
 |     IWineD3DBaseTextureImpl_CleanUp((IWineD3DBaseTexture *) iface); | 
 |     HeapFree(GetProcessHeap(), 0, This); | 
 | } | 
 |  | 
 | static HRESULT WINAPI IWineD3DVolumeTextureImpl_GetLevelDesc(IWineD3DVolumeTexture *iface, UINT Level,WINED3DVOLUME_DESC *pDesc) { | 
 |     IWineD3DVolumeTextureImpl *This = (IWineD3DVolumeTextureImpl *)iface; | 
 |     if (Level < This->baseTexture.levels) { | 
 |         TRACE("(%p) Level (%d)\n", This, Level); | 
 |         return IWineD3DVolume_GetDesc((IWineD3DVolume *) This->volumes[Level], pDesc); | 
 |     } else { | 
 |         FIXME("(%p) Level (%d)\n", This, Level); | 
 |     } | 
 |     return WINED3D_OK; | 
 | } | 
 | static HRESULT WINAPI IWineD3DVolumeTextureImpl_GetVolumeLevel(IWineD3DVolumeTexture *iface, UINT Level, IWineD3DVolume** ppVolumeLevel) { | 
 |     IWineD3DVolumeTextureImpl *This = (IWineD3DVolumeTextureImpl *)iface; | 
 |     if (Level < This->baseTexture.levels) { | 
 |       *ppVolumeLevel = (IWineD3DVolume *)This->volumes[Level]; | 
 |       IWineD3DVolume_AddRef((IWineD3DVolume *) *ppVolumeLevel); | 
 |       TRACE("(%p) -> level(%d) returning volume@%p\n", This, Level, *ppVolumeLevel); | 
 |     } else { | 
 |       FIXME("(%p) Level(%d) overflow Levels(%d)\n", This, Level, This->baseTexture.levels); | 
 |       return WINED3DERR_INVALIDCALL; | 
 |     } | 
 |     return WINED3D_OK; | 
 |  | 
 | } | 
 | static HRESULT WINAPI IWineD3DVolumeTextureImpl_LockBox(IWineD3DVolumeTexture *iface, UINT Level, WINED3DLOCKED_BOX* pLockedVolume, CONST WINED3DBOX* pBox, DWORD Flags) { | 
 |     HRESULT hr; | 
 |     IWineD3DVolumeTextureImpl *This = (IWineD3DVolumeTextureImpl *)iface; | 
 |  | 
 |     if (Level < This->baseTexture.levels) { | 
 |       hr = IWineD3DVolume_LockBox((IWineD3DVolume *)This->volumes[Level], pLockedVolume, pBox, Flags); | 
 |       TRACE("(%p) Level (%d) success(%u)\n", This, Level, hr); | 
 |  | 
 |     } else { | 
 |       FIXME("(%p) level(%d) overflow Levels(%d)\n", This, Level, This->baseTexture.levels); | 
 |       return WINED3DERR_INVALIDCALL; | 
 |     } | 
 |     return hr; | 
 | } | 
 |  | 
 | static HRESULT WINAPI IWineD3DVolumeTextureImpl_UnlockBox(IWineD3DVolumeTexture *iface, UINT Level) { | 
 |     HRESULT hr; | 
 |     IWineD3DVolumeTextureImpl *This = (IWineD3DVolumeTextureImpl *)iface; | 
 |  | 
 |     if (Level < This->baseTexture.levels) { | 
 |       hr = IWineD3DVolume_UnlockBox((IWineD3DVolume*) This->volumes[Level]); | 
 |       TRACE("(%p) -> level(%d) success(%u)\n", This, Level, hr); | 
 |  | 
 |     } else { | 
 |       FIXME("(%p) level(%d) overflow Levels(%d)\n", This, Level, This->baseTexture.levels); | 
 |       return WINED3DERR_INVALIDCALL; | 
 |     } | 
 |     return hr; | 
 | } | 
 |  | 
 | static HRESULT WINAPI IWineD3DVolumeTextureImpl_AddDirtyBox(IWineD3DVolumeTexture *iface, CONST WINED3DBOX* pDirtyBox) { | 
 |     IWineD3DVolumeTextureImpl *This = (IWineD3DVolumeTextureImpl *)iface; | 
 |     This->baseTexture.dirty = TRUE; | 
 |     TRACE("(%p) : dirtyfication of volume Level (0)\n", This); | 
 |     return IWineD3DVolume_AddDirtyBox((IWineD3DVolume *) This->volumes[0], pDirtyBox); | 
 | } | 
 |  | 
 | const IWineD3DVolumeTextureVtbl IWineD3DVolumeTexture_Vtbl = | 
 | { | 
 |     /* IUnknown */ | 
 |     IWineD3DVolumeTextureImpl_QueryInterface, | 
 |     IWineD3DVolumeTextureImpl_AddRef, | 
 |     IWineD3DVolumeTextureImpl_Release, | 
 |     /* resource */ | 
 |     IWineD3DVolumeTextureImpl_GetParent, | 
 |     IWineD3DVolumeTextureImpl_GetDevice, | 
 |     IWineD3DVolumeTextureImpl_SetPrivateData, | 
 |     IWineD3DVolumeTextureImpl_GetPrivateData, | 
 |     IWineD3DVolumeTextureImpl_FreePrivateData, | 
 |     IWineD3DVolumeTextureImpl_SetPriority, | 
 |     IWineD3DVolumeTextureImpl_GetPriority, | 
 |     IWineD3DVolumeTextureImpl_PreLoad, | 
 |     IWineD3DVolumeTextureImpl_GetType, | 
 |     /* BaseTexture */ | 
 |     IWineD3DVolumeTextureImpl_SetLOD, | 
 |     IWineD3DVolumeTextureImpl_GetLOD, | 
 |     IWineD3DVolumeTextureImpl_GetLevelCount, | 
 |     IWineD3DVolumeTextureImpl_SetAutoGenFilterType, | 
 |     IWineD3DVolumeTextureImpl_GetAutoGenFilterType, | 
 |     IWineD3DVolumeTextureImpl_GenerateMipSubLevels, | 
 |     IWineD3DVolumeTextureImpl_SetDirty, | 
 |     IWineD3DVolumeTextureImpl_GetDirty, | 
 |     /* not in d3d */ | 
 |     IWineD3DVolumeTextureImpl_BindTexture, | 
 |     IWineD3DVolumeTextureImpl_UnBindTexture, | 
 |     IWineD3DVolumeTextureImpl_GetTextureDimensions, | 
 |     IWineD3DVolumeTextureImpl_ApplyStateChanges, | 
 |     /* volume texture */ | 
 |     IWineD3DVolumeTextureImpl_Destroy, | 
 |     IWineD3DVolumeTextureImpl_GetLevelDesc, | 
 |     IWineD3DVolumeTextureImpl_GetVolumeLevel, | 
 |     IWineD3DVolumeTextureImpl_LockBox, | 
 |     IWineD3DVolumeTextureImpl_UnlockBox, | 
 |     IWineD3DVolumeTextureImpl_AddDirtyBox | 
 | }; |