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 IDirectDrawSurfaceImpl
*This
= surface_from_texture2(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 IDirectDrawSurfaceImpl
*This
= surface_from_texture1(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 IDirectDrawSurfaceImpl
*This
= surface_from_texture2(iface
);
76 TRACE("(%p)->() thunking to IDirectDrawSurface7 interface.\n", This
);
78 return IDirectDrawSurface7_AddRef((IDirectDrawSurface7
*)This
);
82 Thunk_IDirect3DTextureImpl_1_AddRef(IDirect3DTexture
*iface
)
84 IDirectDrawSurfaceImpl
*This
= surface_from_texture1(iface
);
85 TRACE("(%p)->() thunking to IDirectDrawSurface7 interface.\n", This
);
87 return IDirectDrawSurface7_AddRef((IDirectDrawSurface7
*)This
);
91 Thunk_IDirect3DTextureImpl_2_Release(IDirect3DTexture2
*iface
)
93 IDirectDrawSurfaceImpl
*This
= surface_from_texture2(iface
);
94 TRACE("(%p)->() thunking to IDirectDrawSurface7 interface.\n", This
);
96 return IDirectDrawSurface7_Release((IDirectDrawSurface7
*)This
);
101 Thunk_IDirect3DTextureImpl_1_Release(IDirect3DTexture
*iface
)
103 IDirectDrawSurfaceImpl
*This
= surface_from_texture1(iface
);
104 TRACE("(%p)->() thunking to IDirectDrawSurface7 interface.\n", This
);
106 return IDirectDrawSurface7_Release((IDirectDrawSurface7
*)This
);
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 TRACE("(%p)->(%p,%p) Not implemented\n", iface
, Direct3DDevice
, DDSurface
);
131 return DDERR_UNSUPPORTED
; /* Unchecked */
134 /*****************************************************************************
135 * IDirect3DTexture2::PaletteChanged
137 * Informs the texture about a palette change
140 * Start: Start index of the change
141 * Count: The number of changed entries
144 * D3D_OK, because it's a stub
146 *****************************************************************************/
147 static HRESULT WINAPI
148 IDirect3DTextureImpl_PaletteChanged(IDirect3DTexture2
*iface
,
152 IDirectDrawSurfaceImpl
*This
= surface_from_texture2(iface
);
153 FIXME("(%p)->(%08x,%08x): stub!\n", This
, Start
, Count
);
157 static HRESULT WINAPI
158 Thunk_IDirect3DTextureImpl_1_PaletteChanged(IDirect3DTexture
*iface
,
162 IDirectDrawSurfaceImpl
*This
= surface_from_texture1(iface
);
163 TRACE("(%p)->(%08x,%08x) thunking to IDirect3DTexture2 interface.\n", This
, Start
, Count
);
165 return IDirect3DTexture2_PaletteChanged((IDirect3DTexture2
*)&This
->IDirect3DTexture2_vtbl
, Start
, Count
);
169 /*****************************************************************************
170 * IDirect3DTexture::Unload
172 * DX5 SDK: "The IDirect3DTexture2::Unload method is not implemented
178 *****************************************************************************/
179 static HRESULT WINAPI
180 IDirect3DTextureImpl_1_Unload(IDirect3DTexture
*iface
)
182 IDirectDrawSurfaceImpl
*This
= surface_from_texture1(iface
);
183 TRACE("(%p)->(): not implemented!\n", This
);
184 return DDERR_UNSUPPORTED
;
187 /*****************************************************************************
188 * IDirect3DTexture2::GetHandle
190 * Returns handle for the texture. At the moment, the interface
191 * to the IWineD3DTexture is used.
194 * Direct3DDevice2: Device this handle is assigned to
195 * Handle: Address to store the handle at.
200 *****************************************************************************/
201 static HRESULT WINAPI
202 IDirect3DTextureImpl_GetHandle(IDirect3DTexture2
*iface
,
203 IDirect3DDevice2
*Direct3DDevice2
,
204 D3DTEXTUREHANDLE
*lpHandle
)
206 IDirectDrawSurfaceImpl
*This
= surface_from_texture2(iface
);
207 IDirect3DDeviceImpl
*d3d
= device_from_device2(Direct3DDevice2
);
209 TRACE("(%p)->(%p,%p)\n", This
, d3d
, lpHandle
);
211 EnterCriticalSection(&ddraw_cs
);
214 DWORD h
= ddraw_allocate_handle(&d3d
->handle_table
, This
, DDRAW_HANDLE_SURFACE
);
215 if (h
== DDRAW_INVALID_HANDLE
)
217 ERR("Failed to allocate a texture handle.\n");
218 LeaveCriticalSection(&ddraw_cs
);
219 return DDERR_OUTOFMEMORY
;
222 This
->Handle
= h
+ 1;
224 *lpHandle
= This
->Handle
;
226 TRACE(" returning handle %08x.\n", *lpHandle
);
228 LeaveCriticalSection(&ddraw_cs
);
232 static HRESULT WINAPI
233 Thunk_IDirect3DTextureImpl_1_GetHandle(IDirect3DTexture
*iface
,
234 LPDIRECT3DDEVICE lpDirect3DDevice
,
235 LPD3DTEXTUREHANDLE lpHandle
)
237 IDirectDrawSurfaceImpl
*This
= surface_from_texture1(iface
);
238 IDirect3DDeviceImpl
*d3d
= device_from_device1(lpDirect3DDevice
);
239 IDirect3DTexture2
*d3d_texture2
= (IDirect3DTexture2
*)&This
->IDirect3DTexture2_vtbl
;
240 IDirect3DDevice2
*d3d_device2
= (IDirect3DDevice2
*)&d3d
->IDirect3DDevice2_vtbl
;
242 TRACE_(ddraw_thunk
)("(%p)->(%p,%p) thunking to IDirect3DTexture2 interface.\n", This
, d3d
, lpHandle
);
244 return IDirect3DTexture2_GetHandle(d3d_texture2
, d3d_device2
, lpHandle
);
248 /*****************************************************************************
251 * Helper function that returns the next mipmap level
253 * tex_ptr: Surface of which to return the next level
255 *****************************************************************************/
256 static IDirectDrawSurfaceImpl
*
257 get_sub_mimaplevel(IDirectDrawSurfaceImpl
*tex_ptr
)
259 /* Now go down the mipmap chain to the next surface */
260 static DDSCAPS2 mipmap_caps
= { DDSCAPS_MIPMAP
| DDSCAPS_TEXTURE
, 0, 0, 0 };
261 LPDIRECTDRAWSURFACE7 next_level
;
262 IDirectDrawSurfaceImpl
*surf_ptr
;
265 hr
= IDirectDrawSurface7_GetAttachedSurface((IDirectDrawSurface7
*)tex_ptr
, &mipmap_caps
, &next_level
);
266 if (FAILED(hr
)) return NULL
;
268 surf_ptr
= (IDirectDrawSurfaceImpl
*)next_level
;
269 IDirectDrawSurface7_Release(next_level
);
274 /*****************************************************************************
275 * IDirect3DTexture2::Load
277 * Loads a texture created with the DDSCAPS_ALLOCONLOAD
279 * This function isn't relayed to WineD3D because the whole interface is
280 * implemented in DDraw only. For speed improvements a implementation which
281 * takes OpenGL more into account could be placed into WineD3D.
284 * D3DTexture2: Address of the texture to load
288 * D3DERR_TEXTURE_LOAD_FAILED.
290 *****************************************************************************/
291 static HRESULT WINAPI
292 IDirect3DTextureImpl_Load(IDirect3DTexture2
*iface
,
293 IDirect3DTexture2
*D3DTexture2
)
295 IDirectDrawSurfaceImpl
*This
= surface_from_texture2(iface
);
296 IDirectDrawSurfaceImpl
*src_ptr
= surface_from_texture2(D3DTexture2
);
297 HRESULT ret_value
= D3D_OK
;
300 TRACE("copying surface %p to surface %p, why?\n", src_ptr
, This
);
304 TRACE("(%p)->(%p)\n", This
, src_ptr
);
305 EnterCriticalSection(&ddraw_cs
);
307 if (((src_ptr
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_MIPMAP
) != (This
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_MIPMAP
)) ||
308 (src_ptr
->surface_desc
.u2
.dwMipMapCount
!= This
->surface_desc
.u2
.dwMipMapCount
))
310 ERR("Trying to load surfaces with different mip-map counts !\n");
315 IWineD3DPalette
*wine_pal
, *wine_pal_src
;
316 IDirectDrawPalette
*pal
= NULL
, *pal_src
= NULL
;
317 DDSURFACEDESC
*src_d
, *dst_d
;
319 TRACE(" copying surface %p to surface %p (mipmap level %d)\n", src_ptr
, This
, src_ptr
->mipmap_level
);
321 /* Suppress the ALLOCONLOAD flag */
322 This
->surface_desc
.ddsCaps
.dwCaps
&= ~DDSCAPS_ALLOCONLOAD
;
324 /* Get the palettes */
325 ret_value
= IWineD3DSurface_GetPalette(This
->WineD3DSurface
, &wine_pal
);
326 if( ret_value
!= D3D_OK
)
328 ERR("IWineD3DSurface::GetPalette failed! This is unexpected\n");
329 LeaveCriticalSection(&ddraw_cs
);
330 return D3DERR_TEXTURE_LOAD_FAILED
;
334 ret_value
= IWineD3DPalette_GetParent(wine_pal
, (IUnknown
**) &pal
);
335 if(ret_value
!= D3D_OK
)
337 ERR("IWineD3DPalette::GetParent failed! This is unexpected\n");
338 LeaveCriticalSection(&ddraw_cs
);
339 return D3DERR_TEXTURE_LOAD_FAILED
;
343 ret_value
= IWineD3DSurface_GetPalette(src_ptr
->WineD3DSurface
, &wine_pal_src
);
344 if( ret_value
!= D3D_OK
)
346 ERR("IWineD3DSurface::GetPalette failed! This is unexpected\n");
347 LeaveCriticalSection(&ddraw_cs
);
348 return D3DERR_TEXTURE_LOAD_FAILED
;
352 ret_value
= IWineD3DPalette_GetParent(wine_pal_src
, (IUnknown
**) &pal_src
);
353 if(ret_value
!= D3D_OK
)
355 ERR("IWineD3DPalette::GetParent failed! This is unexpected\n");
356 if (pal
) IDirectDrawPalette_Release(pal
);
357 LeaveCriticalSection(&ddraw_cs
);
358 return D3DERR_TEXTURE_LOAD_FAILED
;
364 PALETTEENTRY palent
[256];
368 IDirectDrawPalette_Release(pal_src
);
369 LeaveCriticalSection(&ddraw_cs
);
370 return DDERR_NOPALETTEATTACHED
;
372 IDirectDrawPalette_GetEntries(pal_src
, 0, 0, 256, palent
);
373 IDirectDrawPalette_SetEntries(pal
, 0, 0, 256, palent
);
376 if (pal
) IDirectDrawPalette_Release(pal
);
377 if (pal_src
) IDirectDrawPalette_Release(pal_src
);
379 /* Copy one surface on the other */
380 dst_d
= (DDSURFACEDESC
*)&(This
->surface_desc
);
381 src_d
= (DDSURFACEDESC
*)&(src_ptr
->surface_desc
);
383 if ((src_d
->dwWidth
!= dst_d
->dwWidth
) || (src_d
->dwHeight
!= dst_d
->dwHeight
))
385 /* Should also check for same pixel format, u1.lPitch, ... */
386 ERR("Error in surface sizes\n");
387 LeaveCriticalSection(&ddraw_cs
);
388 return D3DERR_TEXTURE_LOAD_FAILED
;
392 WINED3DLOCKED_RECT pSrcRect
, pDstRect
;
394 /* LPDIRECT3DDEVICE2 d3dd = (LPDIRECT3DDEVICE2) This->D3Ddevice; */
395 /* I should put a macro for the calculus of bpp */
397 /* Copy also the ColorKeying stuff */
398 if (src_d
->dwFlags
& DDSD_CKSRCBLT
)
400 dst_d
->dwFlags
|= DDSD_CKSRCBLT
;
401 dst_d
->ddckCKSrcBlt
.dwColorSpaceLowValue
= src_d
->ddckCKSrcBlt
.dwColorSpaceLowValue
;
402 dst_d
->ddckCKSrcBlt
.dwColorSpaceHighValue
= src_d
->ddckCKSrcBlt
.dwColorSpaceHighValue
;
405 /* Copy the main memory texture into the surface that corresponds to the OpenGL
408 ret_value
= IWineD3DSurface_LockRect(src_ptr
->WineD3DSurface
, &pSrcRect
, NULL
, 0);
409 if(ret_value
!= D3D_OK
)
411 ERR(" (%p) Locking the source surface failed\n", This
);
412 LeaveCriticalSection(&ddraw_cs
);
413 return D3DERR_TEXTURE_LOAD_FAILED
;
416 ret_value
= IWineD3DSurface_LockRect(This
->WineD3DSurface
, &pDstRect
, NULL
, 0);
417 if(ret_value
!= D3D_OK
)
419 ERR(" (%p) Locking the destination surface failed\n", This
);
420 IWineD3DSurface_UnlockRect(src_ptr
->WineD3DSurface
);
421 LeaveCriticalSection(&ddraw_cs
);
422 return D3DERR_TEXTURE_LOAD_FAILED
;
425 if (This
->surface_desc
.u4
.ddpfPixelFormat
.dwFlags
& DDPF_FOURCC
)
426 memcpy(pDstRect
.pBits
, pSrcRect
.pBits
, src_ptr
->surface_desc
.u1
.dwLinearSize
);
428 memcpy(pDstRect
.pBits
, pSrcRect
.pBits
, pSrcRect
.Pitch
* src_d
->dwHeight
);
430 IWineD3DSurface_UnlockRect(src_ptr
->WineD3DSurface
);
431 IWineD3DSurface_UnlockRect(This
->WineD3DSurface
);
434 if (src_ptr
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_MIPMAP
)
436 src_ptr
= get_sub_mimaplevel(src_ptr
);
442 if (This
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_MIPMAP
)
444 This
= get_sub_mimaplevel(This
);
451 if ((src_ptr
== NULL
) || (This
== NULL
))
455 ERR(" Loading surface with different mipmap structure !!!\n");
461 LeaveCriticalSection(&ddraw_cs
);
465 static HRESULT WINAPI
466 Thunk_IDirect3DTextureImpl_1_Load(IDirect3DTexture
*iface
,
467 IDirect3DTexture
*D3DTexture
)
469 IDirectDrawSurfaceImpl
*This
= surface_from_texture1(iface
);
470 IDirectDrawSurfaceImpl
*Texture
= surface_from_texture1(D3DTexture
);
471 TRACE("(%p)->(%p) thunking to IDirect3DTexture2 interface.\n", This
, Texture
);
473 return IDirect3DTexture2_Load((IDirect3DTexture2
*)&This
->IDirect3DTexture2_vtbl
,
474 D3DTexture
? (IDirect3DTexture2
*)&surface_from_texture1(D3DTexture
)->IDirect3DTexture2_vtbl
: NULL
);
477 /*****************************************************************************
479 *****************************************************************************/
480 const IDirect3DTexture2Vtbl IDirect3DTexture2_Vtbl
=
482 Thunk_IDirect3DTextureImpl_2_QueryInterface
,
483 Thunk_IDirect3DTextureImpl_2_AddRef
,
484 Thunk_IDirect3DTextureImpl_2_Release
,
485 IDirect3DTextureImpl_GetHandle
,
486 IDirect3DTextureImpl_PaletteChanged
,
487 IDirect3DTextureImpl_Load
,
491 const IDirect3DTextureVtbl IDirect3DTexture1_Vtbl
=
493 Thunk_IDirect3DTextureImpl_1_QueryInterface
,
494 Thunk_IDirect3DTextureImpl_1_AddRef
,
495 Thunk_IDirect3DTextureImpl_1_Release
,
496 IDirect3DTextureImpl_1_Initialize
,
497 Thunk_IDirect3DTextureImpl_1_GetHandle
,
498 Thunk_IDirect3DTextureImpl_1_PaletteChanged
,
499 Thunk_IDirect3DTextureImpl_1_Load
,
500 IDirect3DTextureImpl_1_Unload
,