|  | /* Direct3D Texture | 
|  | * Copyright (c) 1998 Lionel ULMER | 
|  | * Copyright (c) 2006 Stefan DÖSINGER | 
|  | * | 
|  | * This file contains the implementation of interface Direct3DTexture2. | 
|  | * | 
|  | * 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 "wine/port.h" | 
|  |  | 
|  | #include <assert.h> | 
|  | #include <stdarg.h> | 
|  | #include <string.h> | 
|  | #include <stdlib.h> | 
|  |  | 
|  | #define COBJMACROS | 
|  | #define NONAMELESSUNION | 
|  |  | 
|  | #include "windef.h" | 
|  | #include "winbase.h" | 
|  | #include "winerror.h" | 
|  | #include "wingdi.h" | 
|  | #include "wine/exception.h" | 
|  |  | 
|  | #include "ddraw.h" | 
|  | #include "d3d.h" | 
|  |  | 
|  | #include "ddraw_private.h" | 
|  | #include "wine/debug.h" | 
|  |  | 
|  | WINE_DEFAULT_DEBUG_CHANNEL(d3d7); | 
|  | WINE_DECLARE_DEBUG_CHANNEL(ddraw_thunk); | 
|  |  | 
|  | /***************************************************************************** | 
|  | * IUnknown interfaces. They are thunks to IDirectDrawSurface7 | 
|  | *****************************************************************************/ | 
|  | static HRESULT WINAPI | 
|  | Thunk_IDirect3DTextureImpl_2_QueryInterface(IDirect3DTexture2 *iface, | 
|  | REFIID riid, | 
|  | void **obj) | 
|  | { | 
|  | IDirectDrawSurfaceImpl *This = surface_from_texture2(iface); | 
|  | TRACE("(%p)->(%s,%p) thunking to IDirectDrawSurface7 interface.\n", This, debugstr_guid(riid), obj); | 
|  | return IDirectDrawSurface7_QueryInterface((IDirectDrawSurface7 *)This, riid, obj); | 
|  | } | 
|  |  | 
|  | static HRESULT WINAPI | 
|  | Thunk_IDirect3DTextureImpl_1_QueryInterface(IDirect3DTexture *iface, | 
|  | REFIID riid, | 
|  | void **obj) | 
|  | { | 
|  | IDirectDrawSurfaceImpl *This = surface_from_texture1(iface); | 
|  | TRACE("(%p)->(%s,%p) thunking to IDirectDrawSurface7 interface.\n", This, debugstr_guid(riid), obj); | 
|  |  | 
|  | return IDirectDrawSurface7_QueryInterface((IDirectDrawSurface7 *)This, riid, obj); | 
|  | } | 
|  |  | 
|  | static ULONG WINAPI | 
|  | Thunk_IDirect3DTextureImpl_2_AddRef(IDirect3DTexture2 *iface) | 
|  | { | 
|  | IDirectDrawSurfaceImpl *This = surface_from_texture2(iface); | 
|  | TRACE("(%p)->() thunking to IDirectDrawSurface7 interface.\n", This); | 
|  |  | 
|  | return IDirectDrawSurface7_AddRef((IDirectDrawSurface7 *)This); | 
|  | } | 
|  |  | 
|  | static ULONG WINAPI | 
|  | Thunk_IDirect3DTextureImpl_1_AddRef(IDirect3DTexture *iface) | 
|  | { | 
|  | IDirectDrawSurfaceImpl *This = surface_from_texture1(iface); | 
|  | TRACE("(%p)->() thunking to IDirectDrawSurface7 interface.\n", This); | 
|  |  | 
|  | return IDirectDrawSurface7_AddRef((IDirectDrawSurface7 *)This); | 
|  | } | 
|  |  | 
|  | static ULONG WINAPI | 
|  | Thunk_IDirect3DTextureImpl_2_Release(IDirect3DTexture2 *iface) | 
|  | { | 
|  | IDirectDrawSurfaceImpl *This = surface_from_texture2(iface); | 
|  | TRACE("(%p)->() thunking to IDirectDrawSurface7 interface.\n", This); | 
|  |  | 
|  | return IDirectDrawSurface7_Release((IDirectDrawSurface7 *)This); | 
|  | } | 
|  |  | 
|  |  | 
|  | static ULONG WINAPI | 
|  | Thunk_IDirect3DTextureImpl_1_Release(IDirect3DTexture *iface) | 
|  | { | 
|  | IDirectDrawSurfaceImpl *This = surface_from_texture1(iface); | 
|  | TRACE("(%p)->() thunking to IDirectDrawSurface7 interface.\n", This); | 
|  |  | 
|  | return IDirectDrawSurface7_Release((IDirectDrawSurface7 *)This); | 
|  | } | 
|  |  | 
|  | /***************************************************************************** | 
|  | * IDirect3DTexture interface | 
|  | *****************************************************************************/ | 
|  |  | 
|  | /***************************************************************************** | 
|  | * IDirect3DTexture1::Initialize | 
|  | * | 
|  | * The sdk says it's not implemented | 
|  | * | 
|  | * Params: | 
|  | *  ? | 
|  | * | 
|  | * Returns | 
|  | *  DDERR_UNSUPPORTED | 
|  | * | 
|  | *****************************************************************************/ | 
|  | static HRESULT WINAPI | 
|  | IDirect3DTextureImpl_1_Initialize(IDirect3DTexture *iface, | 
|  | IDirect3DDevice *Direct3DDevice, | 
|  | IDirectDrawSurface *DDSurface) | 
|  | { | 
|  | TRACE("(%p)->(%p,%p) Not implemented\n", iface, Direct3DDevice, DDSurface); | 
|  | return DDERR_UNSUPPORTED; /* Unchecked */ | 
|  | } | 
|  |  | 
|  | /***************************************************************************** | 
|  | * IDirect3DTexture2::PaletteChanged | 
|  | * | 
|  | * Informs the texture about a palette change | 
|  | * | 
|  | * Params: | 
|  | *  Start: Start index of the change | 
|  | *  Count: The number of changed entries | 
|  | * | 
|  | * Returns | 
|  | *  D3D_OK, because it's a stub | 
|  | * | 
|  | *****************************************************************************/ | 
|  | static HRESULT WINAPI | 
|  | IDirect3DTextureImpl_PaletteChanged(IDirect3DTexture2 *iface, | 
|  | DWORD Start, | 
|  | DWORD Count) | 
|  | { | 
|  | IDirectDrawSurfaceImpl *This = surface_from_texture2(iface); | 
|  | FIXME("(%p)->(%08x,%08x): stub!\n", This, Start, Count); | 
|  | return D3D_OK; | 
|  | } | 
|  |  | 
|  | static HRESULT WINAPI | 
|  | Thunk_IDirect3DTextureImpl_1_PaletteChanged(IDirect3DTexture *iface, | 
|  | DWORD Start, | 
|  | DWORD Count) | 
|  | { | 
|  | IDirectDrawSurfaceImpl *This = surface_from_texture1(iface); | 
|  | TRACE("(%p)->(%08x,%08x) thunking to IDirect3DTexture2 interface.\n", This, Start, Count); | 
|  |  | 
|  | return IDirect3DTexture2_PaletteChanged((IDirect3DTexture2 *)&This->IDirect3DTexture2_vtbl, Start, Count); | 
|  | } | 
|  |  | 
|  |  | 
|  | /***************************************************************************** | 
|  | * IDirect3DTexture::Unload | 
|  | * | 
|  | * DX5 SDK: "The IDirect3DTexture2::Unload method is not implemented | 
|  | * | 
|  | * | 
|  | * Returns: | 
|  | *  DDERR_UNSUPPORTED | 
|  | * | 
|  | *****************************************************************************/ | 
|  | static HRESULT WINAPI | 
|  | IDirect3DTextureImpl_1_Unload(IDirect3DTexture *iface) | 
|  | { | 
|  | IDirectDrawSurfaceImpl *This = surface_from_texture1(iface); | 
|  | TRACE("(%p)->(): not implemented!\n", This); | 
|  | return DDERR_UNSUPPORTED; | 
|  | } | 
|  |  | 
|  | /***************************************************************************** | 
|  | * IDirect3DTexture2::GetHandle | 
|  | * | 
|  | * Returns handle for the texture. At the moment, the interface | 
|  | * to the IWineD3DTexture is used. | 
|  | * | 
|  | * Params: | 
|  | *  Direct3DDevice2: Device this handle is assigned to | 
|  | *  Handle: Address to store the handle at. | 
|  | * | 
|  | * Returns: | 
|  | *  D3D_OK | 
|  | * | 
|  | *****************************************************************************/ | 
|  | static HRESULT WINAPI | 
|  | IDirect3DTextureImpl_GetHandle(IDirect3DTexture2 *iface, | 
|  | IDirect3DDevice2 *Direct3DDevice2, | 
|  | D3DTEXTUREHANDLE *lpHandle) | 
|  | { | 
|  | IDirectDrawSurfaceImpl *This = surface_from_texture2(iface); | 
|  | IDirect3DDeviceImpl *d3d = device_from_device2(Direct3DDevice2); | 
|  |  | 
|  | TRACE("(%p)->(%p,%p)\n", This, d3d, lpHandle); | 
|  |  | 
|  | EnterCriticalSection(&ddraw_cs); | 
|  | if(!This->Handle) | 
|  | { | 
|  | This->Handle = IDirect3DDeviceImpl_CreateHandle(d3d); | 
|  | if(This->Handle) | 
|  | { | 
|  | d3d->Handles[This->Handle - 1].ptr = This; | 
|  | d3d->Handles[This->Handle - 1].type = DDrawHandle_Texture; | 
|  | } | 
|  | } | 
|  | *lpHandle = This->Handle; | 
|  |  | 
|  | TRACE(" returning handle %08x.\n", *lpHandle); | 
|  |  | 
|  | LeaveCriticalSection(&ddraw_cs); | 
|  | return D3D_OK; | 
|  | } | 
|  |  | 
|  | static HRESULT WINAPI | 
|  | Thunk_IDirect3DTextureImpl_1_GetHandle(IDirect3DTexture *iface, | 
|  | LPDIRECT3DDEVICE lpDirect3DDevice, | 
|  | LPD3DTEXTUREHANDLE lpHandle) | 
|  | { | 
|  | IDirectDrawSurfaceImpl *This = surface_from_texture1(iface); | 
|  | IDirect3DDeviceImpl *d3d = device_from_device1(lpDirect3DDevice); | 
|  | IDirect3DTexture2 *d3d_texture2 = (IDirect3DTexture2 *)&This->IDirect3DTexture2_vtbl; | 
|  | IDirect3DDevice2 *d3d_device2 = (IDirect3DDevice2 *)&d3d->IDirect3DDevice2_vtbl; | 
|  |  | 
|  | TRACE_(ddraw_thunk)("(%p)->(%p,%p) thunking to IDirect3DTexture2 interface.\n", This, d3d, lpHandle); | 
|  |  | 
|  | return IDirect3DTexture2_GetHandle(d3d_texture2, d3d_device2, lpHandle); | 
|  | } | 
|  |  | 
|  |  | 
|  | /***************************************************************************** | 
|  | * get_sub_mimaplevel | 
|  | * | 
|  | * Helper function that returns the next mipmap level | 
|  | * | 
|  | * tex_ptr: Surface of which to return the next level | 
|  | * | 
|  | *****************************************************************************/ | 
|  | static IDirectDrawSurfaceImpl * | 
|  | get_sub_mimaplevel(IDirectDrawSurfaceImpl *tex_ptr) | 
|  | { | 
|  | /* Now go down the mipmap chain to the next surface */ | 
|  | static DDSCAPS2 mipmap_caps = { DDSCAPS_MIPMAP | DDSCAPS_TEXTURE, 0, 0, 0 }; | 
|  | LPDIRECTDRAWSURFACE7 next_level; | 
|  | IDirectDrawSurfaceImpl *surf_ptr; | 
|  | HRESULT hr; | 
|  |  | 
|  | hr = IDirectDrawSurface7_GetAttachedSurface((IDirectDrawSurface7 *)tex_ptr, &mipmap_caps, &next_level); | 
|  | if (FAILED(hr)) return NULL; | 
|  |  | 
|  | surf_ptr = (IDirectDrawSurfaceImpl *)next_level; | 
|  | IDirectDrawSurface7_Release(next_level); | 
|  |  | 
|  | return surf_ptr; | 
|  | } | 
|  |  | 
|  | /***************************************************************************** | 
|  | * IDirect3DTexture2::Load | 
|  | * | 
|  | * Loads a texture created with the DDSCAPS_ALLOCONLOAD | 
|  | * | 
|  | * This function isn't relayed to WineD3D because the whole interface is | 
|  | * implemented in DDraw only. For speed improvements a implementation which | 
|  | * takes OpenGL more into account could be placed into WineD3D. | 
|  | * | 
|  | * Params: | 
|  | *  D3DTexture2: Address of the texture to load | 
|  | * | 
|  | * Returns: | 
|  | *  D3D_OK on success | 
|  | *  D3DERR_TEXTURE_LOAD_FAILED. | 
|  | * | 
|  | *****************************************************************************/ | 
|  | static HRESULT WINAPI | 
|  | IDirect3DTextureImpl_Load(IDirect3DTexture2 *iface, | 
|  | IDirect3DTexture2 *D3DTexture2) | 
|  | { | 
|  | IDirectDrawSurfaceImpl *This = surface_from_texture2(iface); | 
|  | IDirectDrawSurfaceImpl *src_ptr = surface_from_texture2(D3DTexture2); | 
|  | HRESULT ret_value = D3D_OK; | 
|  | if(src_ptr == This) | 
|  | { | 
|  | TRACE("copying surface %p to surface %p, why?\n", src_ptr, This); | 
|  | return ret_value; | 
|  | } | 
|  |  | 
|  | TRACE("(%p)->(%p)\n", This, src_ptr); | 
|  | EnterCriticalSection(&ddraw_cs); | 
|  |  | 
|  | if (((src_ptr->surface_desc.ddsCaps.dwCaps & DDSCAPS_MIPMAP) != (This->surface_desc.ddsCaps.dwCaps & DDSCAPS_MIPMAP)) || | 
|  | (src_ptr->surface_desc.u2.dwMipMapCount != This->surface_desc.u2.dwMipMapCount)) | 
|  | { | 
|  | ERR("Trying to load surfaces with different mip-map counts !\n"); | 
|  | } | 
|  |  | 
|  | while(1) | 
|  | { | 
|  | IWineD3DPalette *wine_pal, *wine_pal_src; | 
|  | IDirectDrawPalette *pal = NULL, *pal_src = NULL; | 
|  | DDSURFACEDESC *src_d, *dst_d; | 
|  |  | 
|  | TRACE(" copying surface %p to surface %p (mipmap level %d)\n", src_ptr, This, src_ptr->mipmap_level); | 
|  |  | 
|  | /* Suppress the ALLOCONLOAD flag */ | 
|  | This->surface_desc.ddsCaps.dwCaps &= ~DDSCAPS_ALLOCONLOAD; | 
|  |  | 
|  | /* Get the palettes */ | 
|  | ret_value = IWineD3DSurface_GetPalette(This->WineD3DSurface, &wine_pal); | 
|  | if( ret_value != D3D_OK) | 
|  | { | 
|  | ERR("IWineD3DSurface::GetPalette failed! This is unexpected\n"); | 
|  | LeaveCriticalSection(&ddraw_cs); | 
|  | return D3DERR_TEXTURE_LOAD_FAILED; | 
|  | } | 
|  | if(wine_pal) | 
|  | { | 
|  | ret_value = IWineD3DPalette_GetParent(wine_pal, (IUnknown **) &pal); | 
|  | if(ret_value != D3D_OK) | 
|  | { | 
|  | ERR("IWineD3DPalette::GetParent failed! This is unexpected\n"); | 
|  | LeaveCriticalSection(&ddraw_cs); | 
|  | return D3DERR_TEXTURE_LOAD_FAILED; | 
|  | } | 
|  | } | 
|  |  | 
|  | ret_value = IWineD3DSurface_GetPalette(src_ptr->WineD3DSurface, &wine_pal_src); | 
|  | if( ret_value != D3D_OK) | 
|  | { | 
|  | ERR("IWineD3DSurface::GetPalette failed! This is unexpected\n"); | 
|  | LeaveCriticalSection(&ddraw_cs); | 
|  | return D3DERR_TEXTURE_LOAD_FAILED; | 
|  | } | 
|  | if(wine_pal_src) | 
|  | { | 
|  | ret_value = IWineD3DPalette_GetParent(wine_pal_src, (IUnknown **) &pal_src); | 
|  | if(ret_value != D3D_OK) | 
|  | { | 
|  | ERR("IWineD3DPalette::GetParent failed! This is unexpected\n"); | 
|  | if (pal) IDirectDrawPalette_Release(pal); | 
|  | LeaveCriticalSection(&ddraw_cs); | 
|  | return D3DERR_TEXTURE_LOAD_FAILED; | 
|  | } | 
|  | } | 
|  |  | 
|  | if (pal_src != NULL) | 
|  | { | 
|  | PALETTEENTRY palent[256]; | 
|  |  | 
|  | if (pal == NULL) | 
|  | { | 
|  | IDirectDrawPalette_Release(pal_src); | 
|  | LeaveCriticalSection(&ddraw_cs); | 
|  | return DDERR_NOPALETTEATTACHED; | 
|  | } | 
|  | IDirectDrawPalette_GetEntries(pal_src, 0, 0, 256, palent); | 
|  | IDirectDrawPalette_SetEntries(pal, 0, 0, 256, palent); | 
|  | } | 
|  |  | 
|  | if (pal) IDirectDrawPalette_Release(pal); | 
|  | if (pal_src) IDirectDrawPalette_Release(pal_src); | 
|  |  | 
|  | /* Copy one surface on the other */ | 
|  | dst_d = (DDSURFACEDESC *)&(This->surface_desc); | 
|  | src_d = (DDSURFACEDESC *)&(src_ptr->surface_desc); | 
|  |  | 
|  | if ((src_d->dwWidth != dst_d->dwWidth) || (src_d->dwHeight != dst_d->dwHeight)) | 
|  | { | 
|  | /* Should also check for same pixel format, u1.lPitch, ... */ | 
|  | ERR("Error in surface sizes\n"); | 
|  | LeaveCriticalSection(&ddraw_cs); | 
|  | return D3DERR_TEXTURE_LOAD_FAILED; | 
|  | } | 
|  | else | 
|  | { | 
|  | WINED3DLOCKED_RECT pSrcRect, pDstRect; | 
|  |  | 
|  | /* LPDIRECT3DDEVICE2 d3dd = (LPDIRECT3DDEVICE2) This->D3Ddevice; */ | 
|  | /* I should put a macro for the calculus of bpp */ | 
|  |  | 
|  | /* Copy also the ColorKeying stuff */ | 
|  | if (src_d->dwFlags & DDSD_CKSRCBLT) | 
|  | { | 
|  | dst_d->dwFlags |= DDSD_CKSRCBLT; | 
|  | dst_d->ddckCKSrcBlt.dwColorSpaceLowValue = src_d->ddckCKSrcBlt.dwColorSpaceLowValue; | 
|  | dst_d->ddckCKSrcBlt.dwColorSpaceHighValue = src_d->ddckCKSrcBlt.dwColorSpaceHighValue; | 
|  | } | 
|  |  | 
|  | /* Copy the main memory texture into the surface that corresponds to the OpenGL | 
|  | texture object. */ | 
|  |  | 
|  | ret_value = IWineD3DSurface_LockRect(src_ptr->WineD3DSurface, &pSrcRect, NULL, 0); | 
|  | if(ret_value != D3D_OK) | 
|  | { | 
|  | ERR(" (%p) Locking the source surface failed\n", This); | 
|  | LeaveCriticalSection(&ddraw_cs); | 
|  | return D3DERR_TEXTURE_LOAD_FAILED; | 
|  | } | 
|  |  | 
|  | ret_value = IWineD3DSurface_LockRect(This->WineD3DSurface, &pDstRect, NULL, 0); | 
|  | if(ret_value != D3D_OK) | 
|  | { | 
|  | ERR(" (%p) Locking the destination surface failed\n", This); | 
|  | IWineD3DSurface_UnlockRect(src_ptr->WineD3DSurface); | 
|  | LeaveCriticalSection(&ddraw_cs); | 
|  | return D3DERR_TEXTURE_LOAD_FAILED; | 
|  | } | 
|  |  | 
|  | if (This->surface_desc.u4.ddpfPixelFormat.dwFlags & DDPF_FOURCC) | 
|  | memcpy(pDstRect.pBits, pSrcRect.pBits, src_ptr->surface_desc.u1.dwLinearSize); | 
|  | else | 
|  | memcpy(pDstRect.pBits, pSrcRect.pBits, pSrcRect.Pitch * src_d->dwHeight); | 
|  |  | 
|  | IWineD3DSurface_UnlockRect(src_ptr->WineD3DSurface); | 
|  | IWineD3DSurface_UnlockRect(This->WineD3DSurface); | 
|  | } | 
|  |  | 
|  | if (src_ptr->surface_desc.ddsCaps.dwCaps & DDSCAPS_MIPMAP) | 
|  | { | 
|  | src_ptr = get_sub_mimaplevel(src_ptr); | 
|  | } | 
|  | else | 
|  | { | 
|  | src_ptr = NULL; | 
|  | } | 
|  | if (This->surface_desc.ddsCaps.dwCaps & DDSCAPS_MIPMAP) | 
|  | { | 
|  | This = get_sub_mimaplevel(This); | 
|  | } | 
|  | else | 
|  | { | 
|  | This = NULL; | 
|  | } | 
|  |  | 
|  | if ((src_ptr == NULL) || (This == NULL)) | 
|  | { | 
|  | if (src_ptr != This) | 
|  | { | 
|  | ERR(" Loading surface with different mipmap structure !!!\n"); | 
|  | } | 
|  | break; | 
|  | } | 
|  | } | 
|  |  | 
|  | LeaveCriticalSection(&ddraw_cs); | 
|  | return ret_value; | 
|  | } | 
|  |  | 
|  | static HRESULT WINAPI | 
|  | Thunk_IDirect3DTextureImpl_1_Load(IDirect3DTexture *iface, | 
|  | IDirect3DTexture *D3DTexture) | 
|  | { | 
|  | IDirectDrawSurfaceImpl *This = surface_from_texture1(iface); | 
|  | IDirectDrawSurfaceImpl *Texture = surface_from_texture1(D3DTexture); | 
|  | TRACE("(%p)->(%p) thunking to IDirect3DTexture2 interface.\n", This, Texture); | 
|  |  | 
|  | return IDirect3DTexture2_Load((IDirect3DTexture2 *)&This->IDirect3DTexture2_vtbl, | 
|  | D3DTexture ? (IDirect3DTexture2 *)&surface_from_texture1(D3DTexture)->IDirect3DTexture2_vtbl : NULL); | 
|  | } | 
|  |  | 
|  | /***************************************************************************** | 
|  | * The VTables | 
|  | *****************************************************************************/ | 
|  | const IDirect3DTexture2Vtbl IDirect3DTexture2_Vtbl = | 
|  | { | 
|  | Thunk_IDirect3DTextureImpl_2_QueryInterface, | 
|  | Thunk_IDirect3DTextureImpl_2_AddRef, | 
|  | Thunk_IDirect3DTextureImpl_2_Release, | 
|  | IDirect3DTextureImpl_GetHandle, | 
|  | IDirect3DTextureImpl_PaletteChanged, | 
|  | IDirect3DTextureImpl_Load, | 
|  | }; | 
|  |  | 
|  |  | 
|  | const IDirect3DTextureVtbl IDirect3DTexture1_Vtbl = | 
|  | { | 
|  | Thunk_IDirect3DTextureImpl_1_QueryInterface, | 
|  | Thunk_IDirect3DTextureImpl_1_AddRef, | 
|  | Thunk_IDirect3DTextureImpl_1_Release, | 
|  | IDirect3DTextureImpl_1_Initialize, | 
|  | Thunk_IDirect3DTextureImpl_1_GetHandle, | 
|  | Thunk_IDirect3DTextureImpl_1_PaletteChanged, | 
|  | Thunk_IDirect3DTextureImpl_1_Load, | 
|  | IDirect3DTextureImpl_1_Unload, | 
|  | }; |