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(ICOM_INTERFACE(This
, IDirectDrawSurface7
),
64 Thunk_IDirect3DTextureImpl_1_QueryInterface(IDirect3DTexture
*iface
,
68 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirect3DTexture
, iface
);
69 TRACE("(%p)->(%s,%p) thunking to IDirectDrawSurface7 interface.\n", This
, debugstr_guid(riid
), obj
);
71 return IDirectDrawSurface7_QueryInterface(ICOM_INTERFACE(This
, IDirectDrawSurface7
),
77 Thunk_IDirect3DTextureImpl_2_AddRef(IDirect3DTexture2
*iface
)
79 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirect3DTexture2
, iface
);
80 TRACE("(%p)->() thunking to IDirectDrawSurface7 interface.\n", This
);
82 return IDirectDrawSurface7_AddRef(ICOM_INTERFACE(This
, IDirectDrawSurface7
));
86 Thunk_IDirect3DTextureImpl_1_AddRef(IDirect3DTexture
*iface
)
88 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirect3DTexture
, iface
);
89 TRACE("(%p)->() thunking to IDirectDrawSurface7 interface.\n", This
);
91 return IDirectDrawSurface7_AddRef(COM_INTERFACE_CAST(IDirectDrawSurfaceImpl
, IDirect3DTexture
, IDirectDrawSurface7
, iface
));
95 Thunk_IDirect3DTextureImpl_2_Release(IDirect3DTexture2
*iface
)
97 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirect3DTexture2
, iface
);
98 TRACE("(%p)->() thunking to IDirectDrawSurface7 interface.\n", This
);
100 return IDirectDrawSurface7_Release(ICOM_INTERFACE(This
, IDirectDrawSurface7
));
105 Thunk_IDirect3DTextureImpl_1_Release(IDirect3DTexture
*iface
)
107 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirect3DTexture
, iface
);
108 TRACE("(%p)->() thunking to IDirectDrawSurface7 interface.\n", This
);
110 return IDirectDrawSurface7_Release(COM_INTERFACE_CAST(IDirectDrawSurfaceImpl
, IDirect3DTexture
, IDirectDrawSurface7
, iface
));
113 /*****************************************************************************
114 * IDirect3DTexture interface
115 *****************************************************************************/
117 /*****************************************************************************
118 * IDirect3DTexture1::Initialize
120 * The sdk says it's not implemented
128 *****************************************************************************/
129 static HRESULT WINAPI
130 IDirect3DTextureImpl_1_Initialize(IDirect3DTexture
*iface
,
131 IDirect3DDevice
*Direct3DDevice
,
132 IDirectDrawSurface
*DDSurface
)
134 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirect3DTexture
, iface
);
135 IDirect3DDeviceImpl
*d3d
= ICOM_OBJECT(IDirect3DDeviceImpl
, IDirect3DDevice
, Direct3DDevice
);
136 IDirectDrawSurfaceImpl
*surf
= ICOM_OBJECT(IDirectDrawSurfaceImpl
, IDirectDrawSurface3
, DDSurface
);
137 TRACE("(%p)->(%p,%p) Not implemented\n", This
, d3d
, surf
);
138 return DDERR_UNSUPPORTED
; /* Unchecked */
141 /*****************************************************************************
142 * IDirect3DTexture2::PaletteChanged
144 * Informs the texture about a palette change
147 * Start: Start index of the change
148 * Count: The number of changed entries
151 * D3D_OK, because it's a stub
153 *****************************************************************************/
154 static HRESULT WINAPI
155 IDirect3DTextureImpl_PaletteChanged(IDirect3DTexture2
*iface
,
159 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirect3DTexture2
, iface
);
160 FIXME("(%p)->(%08x,%08x): stub!\n", This
, Start
, Count
);
164 static HRESULT WINAPI
165 Thunk_IDirect3DTextureImpl_1_PaletteChanged(IDirect3DTexture
*iface
,
169 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirect3DTexture
, iface
);
170 TRACE("(%p)->(%08x,%08x) thunking to IDirect3DTexture2 interface.\n", This
, Start
, Count
);
172 return IDirect3DTexture2_PaletteChanged(COM_INTERFACE_CAST(IDirectDrawSurfaceImpl
, IDirect3DTexture
, IDirect3DTexture2
, iface
),
178 /*****************************************************************************
179 * IDirect3DTexture::Unload
181 * DX5 SDK: "The IDirect3DTexture2::Unload method is not implemented
187 *****************************************************************************/
188 static HRESULT WINAPI
189 IDirect3DTextureImpl_1_Unload(IDirect3DTexture
*iface
)
191 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirect3DTexture
, iface
);
192 TRACE("(%p)->(): not implemented!\n", This
);
193 return DDERR_UNSUPPORTED
;
196 /*****************************************************************************
197 * IDirect3DTexture2::GetHandle
199 * Returns handle for the texture. At the moment, the interface
200 * to the IWineD3DTexture is used.
203 * Direct3DDevice2: Device this handle is assigned to
204 * Handle: Address to store the handle at.
209 *****************************************************************************/
210 static HRESULT WINAPI
211 IDirect3DTextureImpl_GetHandle(IDirect3DTexture2
*iface
,
212 IDirect3DDevice2
*Direct3DDevice2
,
213 D3DTEXTUREHANDLE
*lpHandle
)
215 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirect3DTexture2
, iface
);
216 IDirect3DDeviceImpl
*d3d
= ICOM_OBJECT(IDirect3DDeviceImpl
, IDirect3DDevice2
, Direct3DDevice2
);
218 TRACE("(%p)->(%p,%p)\n", This
, d3d
, lpHandle
);
220 EnterCriticalSection(&ddraw_cs
);
223 This
->Handle
= IDirect3DDeviceImpl_CreateHandle(d3d
);
226 d3d
->Handles
[This
->Handle
- 1].ptr
= This
;
227 d3d
->Handles
[This
->Handle
- 1].type
= DDrawHandle_Texture
;
230 *lpHandle
= This
->Handle
;
232 TRACE(" returning handle %08x.\n", *lpHandle
);
234 LeaveCriticalSection(&ddraw_cs
);
238 static HRESULT WINAPI
239 Thunk_IDirect3DTextureImpl_1_GetHandle(IDirect3DTexture
*iface
,
240 LPDIRECT3DDEVICE lpDirect3DDevice
,
241 LPD3DTEXTUREHANDLE lpHandle
)
243 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirect3DTexture
, iface
);
244 IDirect3DDeviceImpl
*d3d
= ICOM_OBJECT(IDirect3DDeviceImpl
, IDirect3DDevice
, lpDirect3DDevice
);
245 TRACE_(ddraw_thunk
)("(%p)->(%p,%p) thunking to IDirect3DTexture2 interface.\n", This
, d3d
, lpHandle
);
247 return IDirect3DTexture2_GetHandle(ICOM_INTERFACE(This
, IDirect3DTexture2
),
248 ICOM_INTERFACE(d3d
, IDirect3DDevice2
),
253 /*****************************************************************************
256 * Helper function that returns the next mipmap level
258 * tex_ptr: Surface of which to return the next level
260 *****************************************************************************/
261 static IDirectDrawSurfaceImpl
*
262 get_sub_mimaplevel(IDirectDrawSurfaceImpl
*tex_ptr
)
264 /* Now go down the mipmap chain to the next surface */
265 static DDSCAPS2 mipmap_caps
= { DDSCAPS_MIPMAP
| DDSCAPS_TEXTURE
, 0, 0, 0 };
266 LPDIRECTDRAWSURFACE7 next_level
;
267 IDirectDrawSurfaceImpl
*surf_ptr
;
270 hr
= IDirectDrawSurface7_GetAttachedSurface(ICOM_INTERFACE(tex_ptr
, IDirectDrawSurface7
),
271 &mipmap_caps
, &next_level
);
272 if (FAILED(hr
)) return NULL
;
274 surf_ptr
= ICOM_OBJECT(IDirectDrawSurfaceImpl
, IDirectDrawSurface7
, next_level
);
275 IDirectDrawSurface7_Release(next_level
);
280 /*****************************************************************************
281 * IDirect3DTexture2::Load
283 * Loads a texture created with the DDSCAPS_ALLOCONLOAD
285 * This function isn't relayed to WineD3D because the whole interface is
286 * implemented in DDraw only. For speed improvements a implementation which
287 * takes OpenGL more into account could be placed into WineD3D.
290 * D3DTexture2: Address of the texture to load
294 * D3DERR_TEXTURE_LOAD_FAILED.
296 *****************************************************************************/
297 static HRESULT WINAPI
298 IDirect3DTextureImpl_Load(IDirect3DTexture2
*iface
,
299 IDirect3DTexture2
*D3DTexture2
)
301 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirect3DTexture2
, iface
);
302 IDirectDrawSurfaceImpl
*src_ptr
= ICOM_OBJECT(IDirectDrawSurfaceImpl
, IDirect3DTexture2
, D3DTexture2
);
303 HRESULT ret_value
= D3D_OK
;
305 TRACE("(%p)->(%p)\n", This
, src_ptr
);
306 EnterCriticalSection(&ddraw_cs
);
308 if (((src_ptr
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_MIPMAP
) != (This
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_MIPMAP
)) ||
309 (src_ptr
->surface_desc
.u2
.dwMipMapCount
!= This
->surface_desc
.u2
.dwMipMapCount
))
311 ERR("Trying to load surfaces with different mip-map counts !\n");
316 IWineD3DPalette
*wine_pal
, *wine_pal_src
;
317 IDirectDrawPalette
*pal
= NULL
, *pal_src
= NULL
;
318 DDSURFACEDESC
*src_d
, *dst_d
;
320 TRACE(" copying surface %p to surface %p (mipmap level %d)\n", src_ptr
, This
, src_ptr
->mipmap_level
);
322 if ( This
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_ALLOCONLOAD
)
323 /* If the surface is not allocated and its location is not yet specified,
324 force it to video memory */
325 if ( !(This
->surface_desc
.ddsCaps
.dwCaps
& (DDSCAPS_SYSTEMMEMORY
|DDSCAPS_VIDEOMEMORY
)) )
326 This
->surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_VIDEOMEMORY
;
328 /* Suppress the ALLOCONLOAD flag */
329 This
->surface_desc
.ddsCaps
.dwCaps
&= ~DDSCAPS_ALLOCONLOAD
;
331 /* Get the palettes */
332 ret_value
= IWineD3DSurface_GetPalette(This
->WineD3DSurface
, &wine_pal
);
333 if( ret_value
!= D3D_OK
)
335 ERR("IWineD3DSurface::GetPalette failed! This is unexpected\n");
336 LeaveCriticalSection(&ddraw_cs
);
337 return D3DERR_TEXTURE_LOAD_FAILED
;
341 ret_value
= IWineD3DPalette_GetParent(wine_pal
, (IUnknown
**) &pal
);
342 if(ret_value
!= D3D_OK
)
344 ERR("IWineD3DPalette::GetParent failed! This is unexpected\n");
345 LeaveCriticalSection(&ddraw_cs
);
346 return D3DERR_TEXTURE_LOAD_FAILED
;
350 ret_value
= IWineD3DSurface_GetPalette(src_ptr
->WineD3DSurface
, &wine_pal_src
);
351 if( ret_value
!= D3D_OK
)
353 ERR("IWineD3DSurface::GetPalette failed! This is unexpected\n");
354 LeaveCriticalSection(&ddraw_cs
);
355 return D3DERR_TEXTURE_LOAD_FAILED
;
359 ret_value
= IWineD3DPalette_GetParent(wine_pal_src
, (IUnknown
**) &pal_src
);
360 if(ret_value
!= D3D_OK
)
362 ERR("IWineD3DPalette::GetParent failed! This is unexpected\n");
363 if (pal
) IDirectDrawPalette_Release(pal
);
364 LeaveCriticalSection(&ddraw_cs
);
365 return D3DERR_TEXTURE_LOAD_FAILED
;
371 PALETTEENTRY palent
[256];
375 IDirectDrawPalette_Release(pal_src
);
376 LeaveCriticalSection(&ddraw_cs
);
377 return DDERR_NOPALETTEATTACHED
;
379 IDirectDrawPalette_GetEntries(pal_src
, 0, 0, 256, palent
);
380 IDirectDrawPalette_SetEntries(pal
, 0, 0, 256, palent
);
383 if (pal
) IDirectDrawPalette_Release(pal
);
384 if (pal_src
) IDirectDrawPalette_Release(pal_src
);
386 /* Copy one surface on the other */
387 dst_d
= (DDSURFACEDESC
*)&(This
->surface_desc
);
388 src_d
= (DDSURFACEDESC
*)&(src_ptr
->surface_desc
);
390 if ((src_d
->dwWidth
!= dst_d
->dwWidth
) || (src_d
->dwHeight
!= dst_d
->dwHeight
))
392 /* Should also check for same pixel format, u1.lPitch, ... */
393 ERR("Error in surface sizes\n");
394 LeaveCriticalSection(&ddraw_cs
);
395 return D3DERR_TEXTURE_LOAD_FAILED
;
399 WINED3DLOCKED_RECT pSrcRect
, pDstRect
;
401 /* LPDIRECT3DDEVICE2 d3dd = (LPDIRECT3DDEVICE2) This->D3Ddevice; */
402 /* I should put a macro for the calculus of bpp */
404 /* Copy also the ColorKeying stuff */
405 if (src_d
->dwFlags
& DDSD_CKSRCBLT
)
407 dst_d
->dwFlags
|= DDSD_CKSRCBLT
;
408 dst_d
->ddckCKSrcBlt
.dwColorSpaceLowValue
= src_d
->ddckCKSrcBlt
.dwColorSpaceLowValue
;
409 dst_d
->ddckCKSrcBlt
.dwColorSpaceHighValue
= src_d
->ddckCKSrcBlt
.dwColorSpaceHighValue
;
412 /* Copy the main memory texture into the surface that corresponds to the OpenGL
415 ret_value
= IWineD3DSurface_LockRect(src_ptr
->WineD3DSurface
, &pSrcRect
, NULL
, 0);
416 if(ret_value
!= D3D_OK
)
418 ERR(" (%p) Locking the source surface failed\n", This
);
419 LeaveCriticalSection(&ddraw_cs
);
420 return D3DERR_TEXTURE_LOAD_FAILED
;
423 ret_value
= IWineD3DSurface_LockRect(This
->WineD3DSurface
, &pDstRect
, NULL
, 0);
424 if(ret_value
!= D3D_OK
)
426 ERR(" (%p) Locking the destination surface failed\n", This
);
427 IWineD3DSurface_UnlockRect(src_ptr
->WineD3DSurface
);
428 LeaveCriticalSection(&ddraw_cs
);
429 return D3DERR_TEXTURE_LOAD_FAILED
;
432 if (This
->surface_desc
.u4
.ddpfPixelFormat
.dwFlags
& DDPF_FOURCC
)
433 memcpy(pDstRect
.pBits
, pSrcRect
.pBits
, src_ptr
->surface_desc
.u1
.dwLinearSize
);
435 memcpy(pDstRect
.pBits
, pSrcRect
.pBits
, pSrcRect
.Pitch
* src_d
->dwHeight
);
437 IWineD3DSurface_UnlockRect(src_ptr
->WineD3DSurface
);
438 IWineD3DSurface_UnlockRect(This
->WineD3DSurface
);
441 if (src_ptr
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_MIPMAP
)
443 src_ptr
= get_sub_mimaplevel(src_ptr
);
449 if (This
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_MIPMAP
)
451 This
= get_sub_mimaplevel(This
);
458 if ((src_ptr
== NULL
) || (This
== NULL
))
462 ERR(" Loading surface with different mipmap structure !!!\n");
468 LeaveCriticalSection(&ddraw_cs
);
472 static HRESULT WINAPI
473 Thunk_IDirect3DTextureImpl_1_Load(IDirect3DTexture
*iface
,
474 IDirect3DTexture
*D3DTexture
)
476 ICOM_THIS_FROM(IDirectDrawSurfaceImpl
, IDirect3DTexture
, iface
);
477 IDirectDrawSurfaceImpl
*Texture
= ICOM_OBJECT(IDirectDrawSurfaceImpl
, IDirect3DTexture
, D3DTexture
);
478 TRACE("(%p)->(%p) thunking to IDirect3DTexture2 interface.\n", This
, Texture
);
480 return IDirect3DTexture2_Load(COM_INTERFACE_CAST(IDirectDrawSurfaceImpl
, IDirect3DTexture
, IDirect3DTexture2
, iface
),
481 COM_INTERFACE_CAST(IDirectDrawSurfaceImpl
, IDirect3DTexture
, IDirect3DTexture2
, D3DTexture
));
484 /*****************************************************************************
486 *****************************************************************************/
487 const IDirect3DTexture2Vtbl IDirect3DTexture2_Vtbl
=
489 Thunk_IDirect3DTextureImpl_2_QueryInterface
,
490 Thunk_IDirect3DTextureImpl_2_AddRef
,
491 Thunk_IDirect3DTextureImpl_2_Release
,
492 IDirect3DTextureImpl_GetHandle
,
493 IDirect3DTextureImpl_PaletteChanged
,
494 IDirect3DTextureImpl_Load
,
498 const IDirect3DTextureVtbl IDirect3DTexture1_Vtbl
=
500 Thunk_IDirect3DTextureImpl_1_QueryInterface
,
501 Thunk_IDirect3DTextureImpl_1_AddRef
,
502 Thunk_IDirect3DTextureImpl_1_Release
,
503 IDirect3DTextureImpl_1_Initialize
,
504 Thunk_IDirect3DTextureImpl_1_GetHandle
,
505 Thunk_IDirect3DTextureImpl_1_PaletteChanged
,
506 Thunk_IDirect3DTextureImpl_1_Load
,
507 IDirect3DTextureImpl_1_Unload
,