2 * Copyright (c) 1998 Lionel ULMER
3 * Copyright (c) 2006 Stefan DÖSINGER
5 * This file contains the implementation of interface Direct3DTexture2.
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 #include "wine/port.h"
31 #define NONAMELESSUNION
37 #include "wine/exception.h"
42 #include "ddraw_private.h"
43 #include "wine/debug.h"
45 WINE_DEFAULT_DEBUG_CHANNEL(d3d7);
46 WINE_DECLARE_DEBUG_CHANNEL(ddraw_thunk);
48 /*****************************************************************************
49 * IUnknown interfaces. They are thunks to IDirectDrawSurface7
50 *****************************************************************************/
52 Thunk_IDirect3DTextureImpl_2_QueryInterface(IDirect3DTexture2 *iface,
56 ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirect3DTexture2, iface);
57 TRACE("(%p)->(%s,%p) thunking to IDirectDrawSurface7 interface.\n", This, debugstr_guid(riid), obj);
58 return IDirectDrawSurface7_QueryInterface((IDirectDrawSurface7 *)This, riid, obj);
62 Thunk_IDirect3DTextureImpl_1_QueryInterface(IDirect3DTexture *iface,
66 ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirect3DTexture, iface);
67 TRACE("(%p)->(%s,%p) thunking to IDirectDrawSurface7 interface.\n", This, debugstr_guid(riid), obj);
69 return IDirectDrawSurface7_QueryInterface((IDirectDrawSurface7 *)This, riid, obj);
73 Thunk_IDirect3DTextureImpl_2_AddRef(IDirect3DTexture2 *iface)
75 ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirect3DTexture2, iface);
76 TRACE("(%p)->() thunking to IDirectDrawSurface7 interface.\n", This);
78 return IDirectDrawSurface7_AddRef((IDirectDrawSurface7 *)This);
82 Thunk_IDirect3DTextureImpl_1_AddRef(IDirect3DTexture *iface)
84 ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirect3DTexture, iface);
85 TRACE("(%p)->() thunking to IDirectDrawSurface7 interface.\n", This);
87 return IDirectDrawSurface7_AddRef(COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirect3DTexture, IDirectDrawSurface7, iface));
91 Thunk_IDirect3DTextureImpl_2_Release(IDirect3DTexture2 *iface)
93 ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirect3DTexture2, iface);
94 TRACE("(%p)->() thunking to IDirectDrawSurface7 interface.\n", This);
96 return IDirectDrawSurface7_Release((IDirectDrawSurface7 *)This);
101 Thunk_IDirect3DTextureImpl_1_Release(IDirect3DTexture *iface)
103 ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirect3DTexture, iface);
104 TRACE("(%p)->() thunking to IDirectDrawSurface7 interface.\n", This);
106 return IDirectDrawSurface7_Release(COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirect3DTexture, IDirectDrawSurface7, iface));
109 /*****************************************************************************
110 * IDirect3DTexture interface
111 *****************************************************************************/
113 /*****************************************************************************
114 * IDirect3DTexture1::Initialize
116 * The sdk says it's not implemented
124 *****************************************************************************/
125 static HRESULT WINAPI
126 IDirect3DTextureImpl_1_Initialize(IDirect3DTexture *iface,
127 IDirect3DDevice *Direct3DDevice,
128 IDirectDrawSurface *DDSurface)
130 ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirect3DTexture, iface);
131 IDirect3DDeviceImpl *d3d = ICOM_OBJECT(IDirect3DDeviceImpl, IDirect3DDevice, Direct3DDevice);
132 IDirectDrawSurfaceImpl *surf = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface3, DDSurface);
133 TRACE("(%p)->(%p,%p) Not implemented\n", This, d3d, surf);
134 return DDERR_UNSUPPORTED; /* Unchecked */
137 /*****************************************************************************
138 * IDirect3DTexture2::PaletteChanged
140 * Informs the texture about a palette change
143 * Start: Start index of the change
144 * Count: The number of changed entries
147 * D3D_OK, because it's a stub
149 *****************************************************************************/
150 static HRESULT WINAPI
151 IDirect3DTextureImpl_PaletteChanged(IDirect3DTexture2 *iface,
155 ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirect3DTexture2, iface);
156 FIXME("(%p)->(%08x,%08x): stub!\n", This, Start, Count);
160 static HRESULT WINAPI
161 Thunk_IDirect3DTextureImpl_1_PaletteChanged(IDirect3DTexture *iface,
165 ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirect3DTexture, iface);
166 TRACE("(%p)->(%08x,%08x) thunking to IDirect3DTexture2 interface.\n", This, Start, Count);
168 return IDirect3DTexture2_PaletteChanged(COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirect3DTexture, IDirect3DTexture2, iface),
174 /*****************************************************************************
175 * IDirect3DTexture::Unload
177 * DX5 SDK: "The IDirect3DTexture2::Unload method is not implemented
183 *****************************************************************************/
184 static HRESULT WINAPI
185 IDirect3DTextureImpl_1_Unload(IDirect3DTexture *iface)
187 ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirect3DTexture, iface);
188 TRACE("(%p)->(): not implemented!\n", This);
189 return DDERR_UNSUPPORTED;
192 /*****************************************************************************
193 * IDirect3DTexture2::GetHandle
195 * Returns handle for the texture. At the moment, the interface
196 * to the IWineD3DTexture is used.
199 * Direct3DDevice2: Device this handle is assigned to
200 * Handle: Address to store the handle at.
205 *****************************************************************************/
206 static HRESULT WINAPI
207 IDirect3DTextureImpl_GetHandle(IDirect3DTexture2 *iface,
208 IDirect3DDevice2 *Direct3DDevice2,
209 D3DTEXTUREHANDLE *lpHandle)
211 ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirect3DTexture2, iface);
212 IDirect3DDeviceImpl *d3d = ICOM_OBJECT(IDirect3DDeviceImpl, IDirect3DDevice2, Direct3DDevice2);
214 TRACE("(%p)->(%p,%p)\n", This, d3d, lpHandle);
216 EnterCriticalSection(&ddraw_cs);
219 This->Handle = IDirect3DDeviceImpl_CreateHandle(d3d);
222 d3d->Handles[This->Handle - 1].ptr = This;
223 d3d->Handles[This->Handle - 1].type = DDrawHandle_Texture;
226 *lpHandle = This->Handle;
228 TRACE(" returning handle %08x.\n", *lpHandle);
230 LeaveCriticalSection(&ddraw_cs);
234 static HRESULT WINAPI
235 Thunk_IDirect3DTextureImpl_1_GetHandle(IDirect3DTexture *iface,
236 LPDIRECT3DDEVICE lpDirect3DDevice,
237 LPD3DTEXTUREHANDLE lpHandle)
239 ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirect3DTexture, iface);
240 IDirect3DDeviceImpl *d3d = ICOM_OBJECT(IDirect3DDeviceImpl, IDirect3DDevice, lpDirect3DDevice);
241 IDirect3DTexture2 *d3d_texture2 = (IDirect3DTexture2 *)&This->IDirect3DTexture2_vtbl;
242 IDirect3DDevice2 *d3d_device2 = (IDirect3DDevice2 *)&d3d->IDirect3DDevice2_vtbl;
244 TRACE_(ddraw_thunk)("(%p)->(%p,%p) thunking to IDirect3DTexture2 interface.\n", This, d3d, lpHandle);
246 return IDirect3DTexture2_GetHandle(d3d_texture2, d3d_device2, lpHandle);
250 /*****************************************************************************
253 * Helper function that returns the next mipmap level
255 * tex_ptr: Surface of which to return the next level
257 *****************************************************************************/
258 static IDirectDrawSurfaceImpl *
259 get_sub_mimaplevel(IDirectDrawSurfaceImpl *tex_ptr)
261 /* Now go down the mipmap chain to the next surface */
262 static DDSCAPS2 mipmap_caps = { DDSCAPS_MIPMAP | DDSCAPS_TEXTURE, 0, 0, 0 };
263 LPDIRECTDRAWSURFACE7 next_level;
264 IDirectDrawSurfaceImpl *surf_ptr;
267 hr = IDirectDrawSurface7_GetAttachedSurface((IDirectDrawSurface7 *)tex_ptr, &mipmap_caps, &next_level);
268 if (FAILED(hr)) return NULL;
270 surf_ptr = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, next_level);
271 IDirectDrawSurface7_Release(next_level);
276 /*****************************************************************************
277 * IDirect3DTexture2::Load
279 * Loads a texture created with the DDSCAPS_ALLOCONLOAD
281 * This function isn't relayed to WineD3D because the whole interface is
282 * implemented in DDraw only. For speed improvements a implementation which
283 * takes OpenGL more into account could be placed into WineD3D.
286 * D3DTexture2: Address of the texture to load
290 * D3DERR_TEXTURE_LOAD_FAILED.
292 *****************************************************************************/
293 static HRESULT WINAPI
294 IDirect3DTextureImpl_Load(IDirect3DTexture2 *iface,
295 IDirect3DTexture2 *D3DTexture2)
297 ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirect3DTexture2, iface);
298 IDirectDrawSurfaceImpl *src_ptr = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirect3DTexture2, D3DTexture2);
299 HRESULT ret_value = D3D_OK;
302 TRACE("copying surface %p to surface %p, why?\n", src_ptr, This);
306 TRACE("(%p)->(%p)\n", This, src_ptr);
307 EnterCriticalSection(&ddraw_cs);
309 if (((src_ptr->surface_desc.ddsCaps.dwCaps & DDSCAPS_MIPMAP) != (This->surface_desc.ddsCaps.dwCaps & DDSCAPS_MIPMAP)) ||
310 (src_ptr->surface_desc.u2.dwMipMapCount != This->surface_desc.u2.dwMipMapCount))
312 ERR("Trying to load surfaces with different mip-map counts !\n");
317 IWineD3DPalette *wine_pal, *wine_pal_src;
318 IDirectDrawPalette *pal = NULL, *pal_src = NULL;
319 DDSURFACEDESC *src_d, *dst_d;
321 TRACE(" copying surface %p to surface %p (mipmap level %d)\n", src_ptr, This, src_ptr->mipmap_level);
323 /* Suppress the ALLOCONLOAD flag */
324 This->surface_desc.ddsCaps.dwCaps &= ~DDSCAPS_ALLOCONLOAD;
326 /* Get the palettes */
327 ret_value = IWineD3DSurface_GetPalette(This->WineD3DSurface, &wine_pal);
328 if( ret_value != D3D_OK)
330 ERR("IWineD3DSurface::GetPalette failed! This is unexpected\n");
331 LeaveCriticalSection(&ddraw_cs);
332 return D3DERR_TEXTURE_LOAD_FAILED;
336 ret_value = IWineD3DPalette_GetParent(wine_pal, (IUnknown **) &pal);
337 if(ret_value != D3D_OK)
339 ERR("IWineD3DPalette::GetParent failed! This is unexpected\n");
340 LeaveCriticalSection(&ddraw_cs);
341 return D3DERR_TEXTURE_LOAD_FAILED;
345 ret_value = IWineD3DSurface_GetPalette(src_ptr->WineD3DSurface, &wine_pal_src);
346 if( ret_value != D3D_OK)
348 ERR("IWineD3DSurface::GetPalette failed! This is unexpected\n");
349 LeaveCriticalSection(&ddraw_cs);
350 return D3DERR_TEXTURE_LOAD_FAILED;
354 ret_value = IWineD3DPalette_GetParent(wine_pal_src, (IUnknown **) &pal_src);
355 if(ret_value != D3D_OK)
357 ERR("IWineD3DPalette::GetParent failed! This is unexpected\n");
358 if (pal) IDirectDrawPalette_Release(pal);
359 LeaveCriticalSection(&ddraw_cs);
360 return D3DERR_TEXTURE_LOAD_FAILED;
366 PALETTEENTRY palent[256];
370 IDirectDrawPalette_Release(pal_src);
371 LeaveCriticalSection(&ddraw_cs);
372 return DDERR_NOPALETTEATTACHED;
374 IDirectDrawPalette_GetEntries(pal_src, 0, 0, 256, palent);
375 IDirectDrawPalette_SetEntries(pal, 0, 0, 256, palent);
378 if (pal) IDirectDrawPalette_Release(pal);
379 if (pal_src) IDirectDrawPalette_Release(pal_src);
381 /* Copy one surface on the other */
382 dst_d = (DDSURFACEDESC *)&(This->surface_desc);
383 src_d = (DDSURFACEDESC *)&(src_ptr->surface_desc);
385 if ((src_d->dwWidth != dst_d->dwWidth) || (src_d->dwHeight != dst_d->dwHeight))
387 /* Should also check for same pixel format, u1.lPitch, ... */
388 ERR("Error in surface sizes\n");
389 LeaveCriticalSection(&ddraw_cs);
390 return D3DERR_TEXTURE_LOAD_FAILED;
394 WINED3DLOCKED_RECT pSrcRect, pDstRect;
396 /* LPDIRECT3DDEVICE2 d3dd = (LPDIRECT3DDEVICE2) This->D3Ddevice; */
397 /* I should put a macro for the calculus of bpp */
399 /* Copy also the ColorKeying stuff */
400 if (src_d->dwFlags & DDSD_CKSRCBLT)
402 dst_d->dwFlags |= DDSD_CKSRCBLT;
403 dst_d->ddckCKSrcBlt.dwColorSpaceLowValue = src_d->ddckCKSrcBlt.dwColorSpaceLowValue;
404 dst_d->ddckCKSrcBlt.dwColorSpaceHighValue = src_d->ddckCKSrcBlt.dwColorSpaceHighValue;
407 /* Copy the main memory texture into the surface that corresponds to the OpenGL
410 ret_value = IWineD3DSurface_LockRect(src_ptr->WineD3DSurface, &pSrcRect, NULL, 0);
411 if(ret_value != D3D_OK)
413 ERR(" (%p) Locking the source surface failed\n", This);
414 LeaveCriticalSection(&ddraw_cs);
415 return D3DERR_TEXTURE_LOAD_FAILED;
418 ret_value = IWineD3DSurface_LockRect(This->WineD3DSurface, &pDstRect, NULL, 0);
419 if(ret_value != D3D_OK)
421 ERR(" (%p) Locking the destination surface failed\n", This);
422 IWineD3DSurface_UnlockRect(src_ptr->WineD3DSurface);
423 LeaveCriticalSection(&ddraw_cs);
424 return D3DERR_TEXTURE_LOAD_FAILED;
427 if (This->surface_desc.u4.ddpfPixelFormat.dwFlags & DDPF_FOURCC)
428 memcpy(pDstRect.pBits, pSrcRect.pBits, src_ptr->surface_desc.u1.dwLinearSize);
430 memcpy(pDstRect.pBits, pSrcRect.pBits, pSrcRect.Pitch * src_d->dwHeight);
432 IWineD3DSurface_UnlockRect(src_ptr->WineD3DSurface);
433 IWineD3DSurface_UnlockRect(This->WineD3DSurface);
436 if (src_ptr->surface_desc.ddsCaps.dwCaps & DDSCAPS_MIPMAP)
438 src_ptr = get_sub_mimaplevel(src_ptr);
444 if (This->surface_desc.ddsCaps.dwCaps & DDSCAPS_MIPMAP)
446 This = get_sub_mimaplevel(This);
453 if ((src_ptr == NULL) || (This == NULL))
457 ERR(" Loading surface with different mipmap structure !!!\n");
463 LeaveCriticalSection(&ddraw_cs);
467 static HRESULT WINAPI
468 Thunk_IDirect3DTextureImpl_1_Load(IDirect3DTexture *iface,
469 IDirect3DTexture *D3DTexture)
471 ICOM_THIS_FROM(IDirectDrawSurfaceImpl, IDirect3DTexture, iface);
472 IDirectDrawSurfaceImpl *Texture = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirect3DTexture, D3DTexture);
473 TRACE("(%p)->(%p) thunking to IDirect3DTexture2 interface.\n", This, Texture);
475 return IDirect3DTexture2_Load(COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirect3DTexture, IDirect3DTexture2, iface),
476 COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirect3DTexture, IDirect3DTexture2, D3DTexture));
479 /*****************************************************************************
481 *****************************************************************************/
482 const IDirect3DTexture2Vtbl IDirect3DTexture2_Vtbl =
484 Thunk_IDirect3DTextureImpl_2_QueryInterface,
485 Thunk_IDirect3DTextureImpl_2_AddRef,
486 Thunk_IDirect3DTextureImpl_2_Release,
487 IDirect3DTextureImpl_GetHandle,
488 IDirect3DTextureImpl_PaletteChanged,
489 IDirect3DTextureImpl_Load,
493 const IDirect3DTextureVtbl IDirect3DTexture1_Vtbl =
495 Thunk_IDirect3DTextureImpl_1_QueryInterface,
496 Thunk_IDirect3DTextureImpl_1_AddRef,
497 Thunk_IDirect3DTextureImpl_1_Release,
498 IDirect3DTextureImpl_1_Initialize,
499 Thunk_IDirect3DTextureImpl_1_GetHandle,
500 Thunk_IDirect3DTextureImpl_1_PaletteChanged,
501 Thunk_IDirect3DTextureImpl_1_Load,
502 IDirect3DTextureImpl_1_Unload,