2 * Copyright (c) 1998-2004 Lionel Ulmer
3 * Copyright (c) 2002-2005 Christian Costa
4 * Copyright (c) 2006 Stefan Dösinger
5 * Copyright (c) 2008 Alexander Dorofeyev
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
21 * IDirect3DDevice implementation, version 1, 2, 3 and 7. Rendering is relayed
22 * to WineD3D, some minimal DirectDraw specific management is handled here.
23 * The Direct3DDevice is NOT the parent of the WineD3DDevice, because d3d
24 * is initialized when DirectDraw creates the primary surface.
25 * Some type management is necessary, because some D3D types changed between
31 #include "wine/port.h"
39 #define NONAMELESSUNION
45 #include "wine/exception.h"
50 #include "ddraw_private.h"
51 #include "wine/debug.h"
53 WINE_DEFAULT_DEBUG_CHANNEL(d3d7);
54 WINE_DECLARE_DEBUG_CHANNEL(ddraw_thunk);
57 const GUID IID_D3DDEVICE_WineD3D = {
61 { 0xb7,0x98,0xc6,0x8a,0x77,0x2d,0x72,0x2a }
64 static inline void set_fpu_control_word(WORD fpucw)
66 #if defined(__i386__) && defined(__GNUC__)
67 __asm__ volatile ("fldcw %0" : : "m" (fpucw));
68 #elif defined(__i386__) && defined(_MSC_VER)
73 static inline WORD d3d_fpu_setup(void)
77 #if defined(__i386__) && defined(__GNUC__)
78 __asm__ volatile ("fnstcw %0" : "=m" (oldcw));
79 #elif defined(__i386__) && defined(_MSC_VER)
82 static BOOL warned = FALSE;
85 FIXME("FPUPRESERVE not implemented for this platform / compiler\n");
91 set_fpu_control_word(0x37f);
96 /*****************************************************************************
97 * IUnknown Methods. Common for Version 1, 2, 3 and 7
98 *****************************************************************************/
100 /*****************************************************************************
101 * IDirect3DDevice7::QueryInterface
103 * Used to query other interfaces from a Direct3DDevice interface.
104 * It can return interface pointers to all Direct3DDevice versions as well
105 * as IDirectDraw and IDirect3D. For a link to QueryInterface
106 * rules see ddraw.c, IDirectDraw7::QueryInterface
108 * Exists in Version 1, 2, 3 and 7
111 * refiid: Interface ID queried for
112 * obj: Used to return the interface pointer
115 * D3D_OK or E_NOINTERFACE
117 *****************************************************************************/
118 static HRESULT WINAPI
119 IDirect3DDeviceImpl_7_QueryInterface(IDirect3DDevice7 *iface,
123 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
124 TRACE("(%p)->(%s,%p)\n", This, debugstr_guid(refiid), obj);
126 /* According to COM docs, if the QueryInterface fails, obj should be set to NULL */
130 return DDERR_INVALIDPARAMS;
132 if ( IsEqualGUID( &IID_IUnknown, refiid ) )
134 *obj = ICOM_INTERFACE(This, IDirect3DDevice7);
137 /* Check DirectDraw Interfac
\ 1s */
138 else if( IsEqualGUID( &IID_IDirectDraw7, refiid ) )
140 *obj = ICOM_INTERFACE(This->ddraw, IDirectDraw7);
141 TRACE("(%p) Returning IDirectDraw7 interface at %p\n", This, *obj);
143 else if ( IsEqualGUID( &IID_IDirectDraw4, refiid ) )
145 *obj = ICOM_INTERFACE(This->ddraw, IDirectDraw4);
146 TRACE("(%p) Returning IDirectDraw4 interface at %p\n", This, *obj);
148 else if ( IsEqualGUID( &IID_IDirectDraw2, refiid ) )
150 *obj = ICOM_INTERFACE(This->ddraw, IDirectDraw2);
151 TRACE("(%p) Returning IDirectDraw2 interface at %p\n", This, *obj);
153 else if( IsEqualGUID( &IID_IDirectDraw, refiid ) )
155 *obj = ICOM_INTERFACE(This->ddraw, IDirectDraw);
156 TRACE("(%p) Returning IDirectDraw interface at %p\n", This, *obj);
160 else if ( IsEqualGUID( &IID_IDirect3D , refiid ) )
162 *obj = ICOM_INTERFACE(This->ddraw, IDirect3D);
163 TRACE("(%p) Returning IDirect3D interface at %p\n", This, *obj);
165 else if ( IsEqualGUID( &IID_IDirect3D2 , refiid ) )
167 *obj = ICOM_INTERFACE(This->ddraw, IDirect3D2);
168 TRACE("(%p) Returning IDirect3D2 interface at %p\n", This, *obj);
170 else if ( IsEqualGUID( &IID_IDirect3D3 , refiid ) )
172 *obj = ICOM_INTERFACE(This->ddraw, IDirect3D3);
173 TRACE("(%p) Returning IDirect3D3 interface at %p\n", This, *obj);
175 else if ( IsEqualGUID( &IID_IDirect3D7 , refiid ) )
177 *obj = ICOM_INTERFACE(This->ddraw, IDirect3D7);
178 TRACE("(%p) Returning IDirect3D7 interface at %p\n", This, *obj);
182 else if ( IsEqualGUID( &IID_IDirect3DDevice , refiid ) )
184 *obj = ICOM_INTERFACE(This, IDirect3DDevice);
185 TRACE("(%p) Returning IDirect3DDevice interface at %p\n", This, *obj);
187 else if ( IsEqualGUID( &IID_IDirect3DDevice2 , refiid ) ) {
188 *obj = ICOM_INTERFACE(This, IDirect3DDevice2);
189 TRACE("(%p) Returning IDirect3DDevice2 interface at %p\n", This, *obj);
191 else if ( IsEqualGUID( &IID_IDirect3DDevice3 , refiid ) ) {
192 *obj = ICOM_INTERFACE(This, IDirect3DDevice3);
193 TRACE("(%p) Returning IDirect3DDevice3 interface at %p\n", This, *obj);
195 else if ( IsEqualGUID( &IID_IDirect3DDevice7 , refiid ) ) {
196 *obj = ICOM_INTERFACE(This, IDirect3DDevice7);
197 TRACE("(%p) Returning IDirect3DDevice7 interface at %p\n", This, *obj);
200 /* Unknown interface */
203 ERR("(%p)->(%s, %p): No interface found\n", This, debugstr_guid(refiid), obj);
204 return E_NOINTERFACE;
207 /* AddRef the returned interface */
208 IUnknown_AddRef( (IUnknown *) *obj);
212 static HRESULT WINAPI
213 Thunk_IDirect3DDeviceImpl_3_QueryInterface(IDirect3DDevice3 *iface,
217 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
218 TRACE_(ddraw_thunk)("(%p)->(%s,%p) thunking to IDirect3DDevice7 interface.\n", This, debugstr_guid(riid), obj);
219 return IDirect3DDevice7_QueryInterface(ICOM_INTERFACE(This, IDirect3DDevice7),
224 static HRESULT WINAPI
225 Thunk_IDirect3DDeviceImpl_2_QueryInterface(IDirect3DDevice2 *iface,
229 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
230 TRACE_(ddraw_thunk)("(%p)->(%s,%p) thunking to IDirect3DDevice7 interface.\n", This, debugstr_guid(riid), obj);
231 return IDirect3DDevice7_QueryInterface(ICOM_INTERFACE(This, IDirect3DDevice7),
236 static HRESULT WINAPI
237 Thunk_IDirect3DDeviceImpl_1_QueryInterface(IDirect3DDevice *iface,
241 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
242 TRACE_(ddraw_thunk)("(%p)->(%s,%p) thunking to IDirect3DDevice7 interface.\n", This, debugstr_guid(riid), obp);
243 return IDirect3DDevice7_QueryInterface(ICOM_INTERFACE(This, IDirect3DDevice7),
248 /*****************************************************************************
249 * IDirect3DDevice7::AddRef
251 * Increases the refcount....
252 * The most exciting Method, definitely
254 * Exists in Version 1, 2, 3 and 7
259 *****************************************************************************/
261 IDirect3DDeviceImpl_7_AddRef(IDirect3DDevice7 *iface)
263 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
264 ULONG ref = InterlockedIncrement(&This->ref);
266 TRACE("(%p) : incrementing from %u.\n", This, ref -1);
272 Thunk_IDirect3DDeviceImpl_3_AddRef(IDirect3DDevice3 *iface)
274 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
275 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
276 return IDirect3DDevice7_AddRef(ICOM_INTERFACE(This, IDirect3DDevice7));
280 Thunk_IDirect3DDeviceImpl_2_AddRef(IDirect3DDevice2 *iface)
282 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
283 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
284 return IDirect3DDevice7_AddRef(ICOM_INTERFACE(This, IDirect3DDevice7));
288 Thunk_IDirect3DDeviceImpl_1_AddRef(IDirect3DDevice *iface)
290 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", iface);
291 return IDirect3DDevice7_AddRef(COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice, IDirect3DDevice7, iface));
294 /*****************************************************************************
295 * IDirect3DDevice7::Release
297 * Decreases the refcount of the interface
298 * When the refcount is reduced to 0, the object is destroyed.
300 * Exists in Version 1, 2, 3 and 7
305 *****************************************************************************/
307 IDirect3DDeviceImpl_7_Release(IDirect3DDevice7 *iface)
309 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
310 ULONG ref = InterlockedDecrement(&This->ref);
312 TRACE("(%p)->() decrementing from %u.\n", This, ref +1);
314 /* This method doesn't destroy the WineD3DDevice, because it's still in use for
315 * 2D rendering. IDirectDrawSurface7::Release will destroy the WineD3DDevice
316 * when the render target is released
320 IParent *IndexBufferParent;
323 EnterCriticalSection(&ddraw_cs);
324 /* Free the index buffer. */
325 IWineD3DDevice_SetIndices(This->wineD3DDevice, NULL);
326 IWineD3DIndexBuffer_GetParent(This->indexbuffer,
327 (IUnknown **) &IndexBufferParent);
328 IParent_Release(IndexBufferParent); /* Once for the getParent */
329 if( IParent_Release(IndexBufferParent) != 0) /* And now to destroy it */
331 ERR(" (%p) Something is still holding the index buffer parent %p\n", This, IndexBufferParent);
334 /* There is no need to unset the vertex buffer here, IWineD3DDevice_Uninit3D will do that when
335 * destroying the primary stateblock. If a vertex buffer is destroyed while it is bound
336 * IDirect3DVertexBuffer::Release will unset it.
339 /* Restore the render targets */
340 if(This->OffScreenTarget)
346 vp.Width = This->ddraw->d3d_target->surface_desc.dwWidth;
347 vp.Height = This->ddraw->d3d_target->surface_desc.dwHeight;
350 IWineD3DDevice_SetViewport(This->wineD3DDevice,
353 /* Set the device up to render to the front buffer since the back buffer will
356 IWineD3DDevice_SetRenderTarget(This->wineD3DDevice, 0,
357 This->ddraw->d3d_target->WineD3DSurface);
358 /* This->target is the offscreen target.
359 * This->ddraw->d3d_target is the target used by DDraw
361 TRACE("(%p) Release: Using %p as front buffer, %p as back buffer\n", This, This->ddraw->d3d_target, NULL);
362 IWineD3DDevice_SetFrontBackBuffers(This->wineD3DDevice,
363 This->ddraw->d3d_target->WineD3DSurface,
367 /* Release the WineD3DDevice. This won't destroy it */
368 if(IWineD3DDevice_Release(This->wineD3DDevice) <= 0)
370 ERR(" (%p) The wineD3D device %p was destroyed unexpectedly. Prepare for trouble\n", This, This->wineD3DDevice);
373 /* The texture handles should be unset by now, but there might be some bits
374 * missing in our reference counting(needs test). Do a sanity check
376 for(i = 0; i < This->numHandles; i++)
378 if(This->Handles[i].ptr)
380 switch(This->Handles[i].type)
382 case DDrawHandle_Texture:
384 IDirectDrawSurfaceImpl *surf = This->Handles[i].ptr;
385 FIXME("Texture Handle %d not unset properly\n", i + 1);
390 case DDrawHandle_Material:
392 IDirect3DMaterialImpl *mat = This->Handles[i].ptr;
393 FIXME("Material handle %d not unset properly\n", i + 1);
398 case DDrawHandle_Matrix:
400 /* No fixme here because this might happen because of sloppy apps */
401 WARN("Leftover matrix handle %d, deleting\n", i + 1);
402 IDirect3DDevice_DeleteMatrix(ICOM_INTERFACE(This, IDirect3DDevice),
407 case DDrawHandle_StateBlock:
409 /* No fixme here because this might happen because of sloppy apps */
410 WARN("Leftover stateblock handle %d, deleting\n", i + 1);
411 IDirect3DDevice7_DeleteStateBlock(ICOM_INTERFACE(This, IDirect3DDevice7),
417 FIXME("Unknown handle %d not unset properly\n", i + 1);
422 HeapFree(GetProcessHeap(), 0, This->Handles);
424 TRACE("Releasing target %p %p\n", This->target, This->ddraw->d3d_target);
425 /* Release the render target and the WineD3D render target
426 * (See IDirect3D7::CreateDevice for more comments on this)
428 IDirectDrawSurface7_Release(ICOM_INTERFACE(This->target, IDirectDrawSurface7));
429 IDirectDrawSurface7_Release(ICOM_INTERFACE(This->ddraw->d3d_target,IDirectDrawSurface7));
430 TRACE("Target release done\n");
432 This->ddraw->d3ddevice = NULL;
434 /* Now free the structure */
435 HeapFree(GetProcessHeap(), 0, This);
436 LeaveCriticalSection(&ddraw_cs);
444 Thunk_IDirect3DDeviceImpl_3_Release(IDirect3DDevice3 *iface)
446 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
447 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
448 return IDirect3DDevice7_Release(ICOM_INTERFACE(This, IDirect3DDevice7));
452 Thunk_IDirect3DDeviceImpl_2_Release(IDirect3DDevice2 *iface)
454 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
455 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
456 return IDirect3DDevice7_Release(ICOM_INTERFACE(This, IDirect3DDevice7));
460 Thunk_IDirect3DDeviceImpl_1_Release(IDirect3DDevice *iface)
462 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
463 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
464 return IDirect3DDevice7_Release(ICOM_INTERFACE(This, IDirect3DDevice7));
467 /*****************************************************************************
468 * IDirect3DDevice Methods
469 *****************************************************************************/
471 /*****************************************************************************
472 * IDirect3DDevice::Initialize
474 * Initializes a Direct3DDevice. This implementation is a no-op, as all
475 * initialization is done at create time.
477 * Exists in Version 1
480 * No idea what they mean, as the MSDN page is gone
484 *****************************************************************************/
485 static HRESULT WINAPI
486 IDirect3DDeviceImpl_1_Initialize(IDirect3DDevice *iface,
487 IDirect3D *Direct3D, GUID *guid,
490 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
492 /* It shouldn't be crucial, but print a FIXME, I'm interested if
493 * any game calls it and when
495 FIXME("(%p)->(%p,%p,%p): No-op!\n", This, Direct3D, guid, Desc);
500 /*****************************************************************************
501 * IDirect3DDevice7::GetCaps
503 * Retrieves the device's capabilities
505 * This implementation is used for Version 7 only, the older versions have
506 * their own implementation.
509 * Desc: Pointer to a D3DDEVICEDESC7 structure to fill
513 * D3DERR_* if a problem occurs. See WineD3D
515 *****************************************************************************/
517 IDirect3DDeviceImpl_7_GetCaps(IDirect3DDevice7 *iface,
518 D3DDEVICEDESC7 *Desc)
520 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
521 D3DDEVICEDESC OldDesc;
522 TRACE("(%p)->(%p)\n", This, Desc);
524 /* Call the same function used by IDirect3D, this saves code */
525 return IDirect3DImpl_GetCaps(This->ddraw->wineD3D, &OldDesc, Desc);
528 static HRESULT WINAPI
529 IDirect3DDeviceImpl_7_GetCaps_FPUSetup(IDirect3DDevice7 *iface,
530 D3DDEVICEDESC7 *Desc)
532 return IDirect3DDeviceImpl_7_GetCaps(iface, Desc);
535 static HRESULT WINAPI
536 IDirect3DDeviceImpl_7_GetCaps_FPUPreserve(IDirect3DDevice7 *iface,
537 D3DDEVICEDESC7 *Desc)
542 old_fpucw = d3d_fpu_setup();
543 hr = IDirect3DDeviceImpl_7_GetCaps(iface, Desc);
544 set_fpu_control_word(old_fpucw);
548 /*****************************************************************************
549 * IDirect3DDevice3::GetCaps
551 * Retrieves the capabilities of the hardware device and the emulation
552 * device. For Wine, hardware and emulation are the same (it's all HW).
554 * This implementation is used for Version 1, 2, and 3. Version 7 has its own
557 * HWDesc: Structure to fill with the HW caps
558 * HelDesc: Structure to fill with the hardware emulation caps
562 * D3DERR_* if a problem occurs. See WineD3D
564 *****************************************************************************/
565 static HRESULT WINAPI
566 IDirect3DDeviceImpl_3_GetCaps(IDirect3DDevice3 *iface,
567 D3DDEVICEDESC *HWDesc,
568 D3DDEVICEDESC *HelDesc)
570 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
571 D3DDEVICEDESC7 newDesc;
573 TRACE("(%p)->(%p,%p)\n", iface, HWDesc, HelDesc);
575 hr = IDirect3DImpl_GetCaps(This->ddraw->wineD3D, HWDesc, &newDesc);
576 if(hr != D3D_OK) return hr;
582 static HRESULT WINAPI
583 Thunk_IDirect3DDeviceImpl_2_GetCaps(IDirect3DDevice2 *iface,
584 D3DDEVICEDESC *D3DHWDevDesc,
585 D3DDEVICEDESC *D3DHELDevDesc)
587 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
588 TRACE_(ddraw_thunk)("(%p)->(%p,%p) thunking to IDirect3DDevice3 interface.\n", This, D3DHWDevDesc, D3DHELDevDesc);
589 return IDirect3DDevice3_GetCaps(ICOM_INTERFACE(This, IDirect3DDevice3),
594 static HRESULT WINAPI
595 Thunk_IDirect3DDeviceImpl_1_GetCaps(IDirect3DDevice *iface,
596 D3DDEVICEDESC *D3DHWDevDesc,
597 D3DDEVICEDESC *D3DHELDevDesc)
599 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
600 TRACE_(ddraw_thunk)("(%p)->(%p,%p) thunking to IDirect3DDevice3 interface.\n", This, D3DHWDevDesc, D3DHELDevDesc);
601 return IDirect3DDevice3_GetCaps(ICOM_INTERFACE(This, IDirect3DDevice3),
606 /*****************************************************************************
607 * IDirect3DDevice2::SwapTextureHandles
609 * Swaps the texture handles of 2 Texture interfaces. Version 1 and 2
612 * Tex1, Tex2: The 2 Textures to swap
617 *****************************************************************************/
618 static HRESULT WINAPI
619 IDirect3DDeviceImpl_2_SwapTextureHandles(IDirect3DDevice2 *iface,
620 IDirect3DTexture2 *Tex1,
621 IDirect3DTexture2 *Tex2)
623 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
625 IDirectDrawSurfaceImpl *surf1 = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirect3DTexture2, Tex1);
626 IDirectDrawSurfaceImpl *surf2 = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirect3DTexture2, Tex2);
627 TRACE("(%p)->(%p,%p)\n", This, surf1, surf2);
629 EnterCriticalSection(&ddraw_cs);
630 This->Handles[surf1->Handle - 1].ptr = surf2;
631 This->Handles[surf2->Handle - 1].ptr = surf1;
633 swap = surf2->Handle;
634 surf2->Handle = surf1->Handle;
635 surf1->Handle = swap;
636 LeaveCriticalSection(&ddraw_cs);
641 static HRESULT WINAPI
642 Thunk_IDirect3DDeviceImpl_1_SwapTextureHandles(IDirect3DDevice *iface,
643 IDirect3DTexture *D3DTex1,
644 IDirect3DTexture *D3DTex2)
646 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
647 IDirectDrawSurfaceImpl *surf1 = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirect3DTexture, D3DTex1);
648 IDirectDrawSurfaceImpl *surf2 = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirect3DTexture, D3DTex2);
649 TRACE_(ddraw_thunk)("(%p)->(%p,%p) thunking to IDirect3DDevice2 interface.\n", This, surf1, surf2);
650 return IDirect3DDevice2_SwapTextureHandles(ICOM_INTERFACE(This, IDirect3DDevice2),
651 ICOM_INTERFACE(surf1, IDirect3DTexture2),
652 ICOM_INTERFACE(surf2, IDirect3DTexture2));
655 /*****************************************************************************
656 * IDirect3DDevice3::GetStats
658 * This method seems to retrieve some stats from the device.
659 * The MSDN documentation doesn't exist any more, but the D3DSTATS
660 * structure suggests that the amount of drawn primitives and processed
661 * vertices is returned.
663 * Exists in Version 1, 2 and 3
666 * Stats: Pointer to a D3DSTATS structure to be filled
670 * DDERR_INVALIDPARAMS if Stats == NULL
672 *****************************************************************************/
673 static HRESULT WINAPI
674 IDirect3DDeviceImpl_3_GetStats(IDirect3DDevice3 *iface,
677 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
678 FIXME("(%p)->(%p): Stub!\n", This, Stats);
681 return DDERR_INVALIDPARAMS;
683 /* Fill the Stats with 0 */
684 Stats->dwTrianglesDrawn = 0;
685 Stats->dwLinesDrawn = 0;
686 Stats->dwPointsDrawn = 0;
687 Stats->dwSpansDrawn = 0;
688 Stats->dwVerticesProcessed = 0;
693 static HRESULT WINAPI
694 Thunk_IDirect3DDeviceImpl_2_GetStats(IDirect3DDevice2 *iface,
697 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
698 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, Stats);
699 return IDirect3DDevice3_GetStats(ICOM_INTERFACE(This, IDirect3DDevice3),
703 static HRESULT WINAPI
704 Thunk_IDirect3DDeviceImpl_1_GetStats(IDirect3DDevice *iface,
707 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
708 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, Stats);
709 return IDirect3DDevice3_GetStats(ICOM_INTERFACE(This, IDirect3DDevice3),
713 /*****************************************************************************
714 * IDirect3DDevice::CreateExecuteBuffer
716 * Creates an IDirect3DExecuteBuffer, used for rendering with a
722 * Desc: Buffer description
723 * ExecuteBuffer: Address to return the Interface pointer at
724 * UnkOuter: Must be NULL. Basically for aggregation, which ddraw doesn't
728 * CLASS_E_NOAGGREGATION if UnkOuter != NULL
729 * DDERR_OUTOFMEMORY if we ran out of memory
732 *****************************************************************************/
733 static HRESULT WINAPI
734 IDirect3DDeviceImpl_1_CreateExecuteBuffer(IDirect3DDevice *iface,
735 D3DEXECUTEBUFFERDESC *Desc,
736 IDirect3DExecuteBuffer **ExecuteBuffer,
739 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
740 IDirect3DExecuteBufferImpl* object;
741 TRACE("(%p)->(%p,%p,%p)!\n", This, Desc, ExecuteBuffer, UnkOuter);
744 return CLASS_E_NOAGGREGATION;
746 /* Allocate the new Execute Buffer */
747 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DExecuteBufferImpl));
750 ERR("Out of memory when allocating a IDirect3DExecuteBufferImpl structure\n");
751 return DDERR_OUTOFMEMORY;
754 ICOM_INIT_INTERFACE(object, IDirect3DExecuteBuffer, IDirect3DExecuteBuffer_Vtbl);
757 object->d3ddev = This;
759 /* Initializes memory */
760 memcpy(&object->desc, Desc, Desc->dwSize);
762 /* No buffer given */
763 if ((object->desc.dwFlags & D3DDEB_LPDATA) == 0)
764 object->desc.lpData = NULL;
766 /* No buffer size given */
767 if ((object->desc.dwFlags & D3DDEB_BUFSIZE) == 0)
768 object->desc.dwBufferSize = 0;
770 /* Create buffer if asked */
771 if ((object->desc.lpData == NULL) && (object->desc.dwBufferSize > 0))
773 object->need_free = TRUE;
774 object->desc.lpData = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,object->desc.dwBufferSize);
775 if(!object->desc.lpData)
777 ERR("Out of memory when allocating the execute buffer data\n");
778 HeapFree(GetProcessHeap(), 0, object);
779 return DDERR_OUTOFMEMORY;
784 object->need_free = FALSE;
787 /* No vertices for the moment */
788 object->vertex_data = NULL;
790 object->desc.dwFlags |= D3DDEB_LPDATA;
792 object->indices = NULL;
793 object->nb_indices = 0;
795 *ExecuteBuffer = ICOM_INTERFACE(object, IDirect3DExecuteBuffer);
797 TRACE(" Returning IDirect3DExecuteBuffer at %p, implementation is at %p\n", *ExecuteBuffer, object);
802 /*****************************************************************************
803 * IDirect3DDevice::Execute
805 * Executes all the stuff in an execute buffer.
808 * ExecuteBuffer: The buffer to execute
809 * Viewport: The viewport used for rendering
813 * DDERR_INVALIDPARAMS if ExecuteBuffer == NULL
816 *****************************************************************************/
817 static HRESULT WINAPI
818 IDirect3DDeviceImpl_1_Execute(IDirect3DDevice *iface,
819 IDirect3DExecuteBuffer *ExecuteBuffer,
820 IDirect3DViewport *Viewport,
823 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
824 IDirect3DExecuteBufferImpl *Direct3DExecuteBufferImpl = ICOM_OBJECT(IDirect3DExecuteBufferImpl, IDirect3DExecuteBuffer, ExecuteBuffer);
825 IDirect3DViewportImpl *Direct3DViewportImpl = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Viewport);
827 TRACE("(%p)->(%p,%p,%08x)\n", This, Direct3DExecuteBufferImpl, Direct3DViewportImpl, Flags);
829 if(!Direct3DExecuteBufferImpl)
830 return DDERR_INVALIDPARAMS;
833 EnterCriticalSection(&ddraw_cs);
834 IDirect3DExecuteBufferImpl_Execute(Direct3DExecuteBufferImpl, This, Direct3DViewportImpl);
835 LeaveCriticalSection(&ddraw_cs);
840 /*****************************************************************************
841 * IDirect3DDevice3::AddViewport
843 * Add a Direct3DViewport to the device's viewport list. These viewports
844 * are wrapped to IDirect3DDevice7 viewports in viewport.c
846 * Exists in Version 1, 2 and 3. Note that IDirect3DViewport 1, 2 and 3
847 * are the same interfaces.
850 * Viewport: The viewport to add
853 * DDERR_INVALIDPARAMS if Viewport == NULL
856 *****************************************************************************/
857 static HRESULT WINAPI
858 IDirect3DDeviceImpl_3_AddViewport(IDirect3DDevice3 *iface,
859 IDirect3DViewport3 *Viewport)
861 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
862 IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Viewport);
864 TRACE("(%p)->(%p)\n", This, vp);
868 return DDERR_INVALIDPARAMS;
870 EnterCriticalSection(&ddraw_cs);
871 vp->next = This->viewport_list;
872 This->viewport_list = vp;
873 vp->active_device = This; /* Viewport must be usable for Clear() after AddViewport,
874 so set active_device here. */
875 LeaveCriticalSection(&ddraw_cs);
880 static HRESULT WINAPI
881 Thunk_IDirect3DDeviceImpl_2_AddViewport(IDirect3DDevice2 *iface,
882 IDirect3DViewport2 *Direct3DViewport2)
884 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
885 IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Direct3DViewport2);
886 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, vp);
887 return IDirect3DDevice3_AddViewport(ICOM_INTERFACE(This, IDirect3DDevice3),
888 ICOM_INTERFACE(vp, IDirect3DViewport3));
891 static HRESULT WINAPI
892 Thunk_IDirect3DDeviceImpl_1_AddViewport(IDirect3DDevice *iface,
893 IDirect3DViewport *Direct3DViewport)
895 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
896 IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Direct3DViewport);
897 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, vp);
898 return IDirect3DDevice3_AddViewport(ICOM_INTERFACE(This, IDirect3DDevice3),
899 ICOM_INTERFACE(vp, IDirect3DViewport3));
902 /*****************************************************************************
903 * IDirect3DDevice3::DeleteViewport
905 * Deletes a Direct3DViewport from the device's viewport list.
907 * Exists in Version 1, 2 and 3. Note that all Viewport interface versions
911 * Viewport: The viewport to delete
915 * DDERR_INVALIDPARAMS if the viewport wasn't found in the list
917 *****************************************************************************/
918 static HRESULT WINAPI
919 IDirect3DDeviceImpl_3_DeleteViewport(IDirect3DDevice3 *iface,
920 IDirect3DViewport3 *Viewport)
922 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
923 IDirect3DViewportImpl *vp = (IDirect3DViewportImpl *) Viewport;
924 IDirect3DViewportImpl *cur_viewport, *prev_viewport = NULL;
926 TRACE("(%p)->(%p)\n", This, vp);
928 EnterCriticalSection(&ddraw_cs);
929 cur_viewport = This->viewport_list;
930 while (cur_viewport != NULL)
932 if (cur_viewport == vp)
934 if (prev_viewport == NULL) This->viewport_list = cur_viewport->next;
935 else prev_viewport->next = cur_viewport->next;
936 /* TODO : add desactivate of the viewport and all associated lights... */
937 LeaveCriticalSection(&ddraw_cs);
940 prev_viewport = cur_viewport;
941 cur_viewport = cur_viewport->next;
944 LeaveCriticalSection(&ddraw_cs);
945 return DDERR_INVALIDPARAMS;
948 static HRESULT WINAPI
949 Thunk_IDirect3DDeviceImpl_2_DeleteViewport(IDirect3DDevice2 *iface,
950 IDirect3DViewport2 *Direct3DViewport2)
952 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
953 IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Direct3DViewport2);
954 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, vp);
955 return IDirect3DDevice3_DeleteViewport(ICOM_INTERFACE(This, IDirect3DDevice3),
956 ICOM_INTERFACE(vp, IDirect3DViewport3));
959 static HRESULT WINAPI
960 Thunk_IDirect3DDeviceImpl_1_DeleteViewport(IDirect3DDevice *iface,
961 IDirect3DViewport *Direct3DViewport)
963 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
964 IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Direct3DViewport);
965 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, vp);
966 return IDirect3DDevice3_DeleteViewport(ICOM_INTERFACE(This, IDirect3DDevice3),
967 ICOM_INTERFACE(vp, IDirect3DViewport3));
970 /*****************************************************************************
971 * IDirect3DDevice3::NextViewport
973 * Returns a viewport from the viewport list, depending on the
974 * passed viewport and the flags.
976 * Exists in Version 1, 2 and 3. Note that all Viewport interface versions
980 * Viewport: Viewport to use for beginning the search
981 * Flags: D3DNEXT_NEXT, D3DNEXT_HEAD or D3DNEXT_TAIL
985 * DDERR_INVALIDPARAMS if the flags were wrong, or Viewport was NULL
987 *****************************************************************************/
988 static HRESULT WINAPI
989 IDirect3DDeviceImpl_3_NextViewport(IDirect3DDevice3 *iface,
990 IDirect3DViewport3 *Viewport3,
991 IDirect3DViewport3 **lplpDirect3DViewport3,
994 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
995 IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Viewport3);
996 IDirect3DViewportImpl *res = NULL;
998 TRACE("(%p)->(%p,%p,%08x)\n", This, vp, lplpDirect3DViewport3, Flags);
1002 *lplpDirect3DViewport3 = NULL;
1003 return DDERR_INVALIDPARAMS;
1007 EnterCriticalSection(&ddraw_cs);
1017 res = This->viewport_list;
1022 IDirect3DViewportImpl *cur_viewport = This->viewport_list;
1023 if (cur_viewport != NULL)
1025 while (cur_viewport->next != NULL) cur_viewport = cur_viewport->next;
1031 *lplpDirect3DViewport3 = NULL;
1032 LeaveCriticalSection(&ddraw_cs);
1033 return DDERR_INVALIDPARAMS;
1036 *lplpDirect3DViewport3 = ICOM_INTERFACE(res, IDirect3DViewport3);
1037 LeaveCriticalSection(&ddraw_cs);
1041 static HRESULT WINAPI
1042 Thunk_IDirect3DDeviceImpl_2_NextViewport(IDirect3DDevice2 *iface,
1043 IDirect3DViewport2 *Viewport2,
1044 IDirect3DViewport2 **lplpDirect3DViewport2,
1047 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
1048 IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Viewport2);
1049 IDirect3DViewport3 *res;
1051 TRACE_(ddraw_thunk)("(%p)->(%p,%p,%08x) thunking to IDirect3DDevice3 interface.\n", This, vp, lplpDirect3DViewport2, Flags);
1052 hr = IDirect3DDevice3_NextViewport(ICOM_INTERFACE(This, IDirect3DDevice3),
1053 ICOM_INTERFACE(vp, IDirect3DViewport3),
1056 *lplpDirect3DViewport2 = (IDirect3DViewport2 *) COM_INTERFACE_CAST(IDirect3DViewportImpl, IDirect3DViewport3, IDirect3DViewport3, res);
1060 static HRESULT WINAPI
1061 Thunk_IDirect3DDeviceImpl_1_NextViewport(IDirect3DDevice *iface,
1062 IDirect3DViewport *Viewport,
1063 IDirect3DViewport **lplpDirect3DViewport,
1066 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
1067 IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Viewport);
1068 IDirect3DViewport3 *res;
1070 TRACE_(ddraw_thunk)("(%p)->(%p,%p,%08x) thunking to IDirect3DDevice3 interface.\n", This, vp, lplpDirect3DViewport, Flags);
1071 hr = IDirect3DDevice3_NextViewport(ICOM_INTERFACE(This, IDirect3DDevice3),
1072 ICOM_INTERFACE(vp, IDirect3DViewport3),
1075 *lplpDirect3DViewport = (IDirect3DViewport *) COM_INTERFACE_CAST(IDirect3DViewportImpl, IDirect3DViewport3, IDirect3DViewport3, res);
1079 /*****************************************************************************
1080 * IDirect3DDevice::Pick
1082 * Executes an execute buffer without performing rendering. Instead, a
1083 * list of primitives that intersect with (x1,y1) of the passed rectangle
1084 * is created. IDirect3DDevice::GetPickRecords can be used to retrieve
1090 * ExecuteBuffer: Buffer to execute
1091 * Viewport: Viewport to use for execution
1092 * Flags: None are defined, according to the SDK
1093 * Rect: Specifies the coordinates to be picked. Only x1 and y2 are used,
1094 * x2 and y2 are ignored.
1097 * D3D_OK because it's a stub
1099 *****************************************************************************/
1100 static HRESULT WINAPI
1101 IDirect3DDeviceImpl_1_Pick(IDirect3DDevice *iface,
1102 IDirect3DExecuteBuffer *ExecuteBuffer,
1103 IDirect3DViewport *Viewport,
1107 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
1108 IDirect3DExecuteBufferImpl *execbuf = ICOM_OBJECT(IDirect3DExecuteBufferImpl, IDirect3DExecuteBuffer, ExecuteBuffer);
1109 IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Viewport);
1110 FIXME("(%p)->(%p,%p,%08x,%p): stub!\n", This, execbuf, vp, Flags, Rect);
1115 /*****************************************************************************
1116 * IDirect3DDevice::GetPickRecords
1118 * Retrieves the pick records generated by IDirect3DDevice::GetPickRecords
1123 * Count: Pointer to a DWORD containing the numbers of pick records to
1125 * D3DPickRec: Address to store the resulting D3DPICKRECORD array.
1128 * D3D_OK, because it's a stub
1130 *****************************************************************************/
1131 static HRESULT WINAPI
1132 IDirect3DDeviceImpl_1_GetPickRecords(IDirect3DDevice *iface,
1134 D3DPICKRECORD *D3DPickRec)
1136 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
1137 FIXME("(%p)->(%p,%p): stub!\n", This, Count, D3DPickRec);
1142 /*****************************************************************************
1143 * IDirect3DDevice7::EnumTextureformats
1145 * Enumerates the supported texture formats. It has a list of all possible
1146 * formats and calls IWineD3D::CheckDeviceFormat for each format to see if
1147 * WineD3D supports it. If so, then it is passed to the app.
1149 * This is for Version 7 and 3, older versions have a different
1150 * callback function and their own implementation
1153 * Callback: Callback to call for each enumerated format
1154 * Arg: Argument to pass to the callback
1158 * DDERR_INVALIDPARAMS if Callback == NULL
1160 *****************************************************************************/
1162 IDirect3DDeviceImpl_7_EnumTextureFormats(IDirect3DDevice7 *iface,
1163 LPD3DENUMPIXELFORMATSCALLBACK Callback,
1166 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1168 WINED3DDISPLAYMODE mode;
1171 WINED3DFORMAT FormatList[] = {
1173 WINED3DFMT_A8R8G8B8,
1174 WINED3DFMT_X8R8G8B8,
1178 WINED3DFMT_A1R5G5B5,
1179 WINED3DFMT_A4R4G4B4,
1181 WINED3DFMT_X1R5G5B5,
1191 WINED3DFORMAT BumpFormatList[] = {
1194 WINED3DFMT_X8L8V8U8,
1195 WINED3DFMT_Q8W8V8U8,
1197 WINED3DFMT_W11V11U10,
1198 WINED3DFMT_A2W10V10U10
1201 TRACE("(%p)->(%p,%p): Relay\n", This, Callback, Arg);
1204 return DDERR_INVALIDPARAMS;
1206 EnterCriticalSection(&ddraw_cs);
1208 memset(&mode, 0, sizeof(mode));
1209 hr = IWineD3DDevice_GetDisplayMode(This->ddraw->wineD3DDevice,
1213 LeaveCriticalSection(&ddraw_cs);
1214 WARN("Cannot get the current adapter format\n");
1218 for(i = 0; i < sizeof(FormatList) / sizeof(WINED3DFORMAT); i++)
1220 hr = IWineD3D_CheckDeviceFormat(This->ddraw->wineD3D,
1221 WINED3DADAPTER_DEFAULT,
1225 WINED3DRTYPE_TEXTURE,
1230 DDPIXELFORMAT pformat;
1232 memset(&pformat, 0, sizeof(pformat));
1233 pformat.dwSize = sizeof(pformat);
1234 PixelFormat_WineD3DtoDD(&pformat, FormatList[i]);
1236 TRACE("Enumerating WineD3DFormat %d\n", FormatList[i]);
1237 hr = Callback(&pformat, Arg);
1238 if(hr != DDENUMRET_OK)
1240 TRACE("Format enumeration cancelled by application\n");
1241 LeaveCriticalSection(&ddraw_cs);
1247 for(i = 0; i < sizeof(BumpFormatList) / sizeof(WINED3DFORMAT); i++)
1249 hr = IWineD3D_CheckDeviceFormat(This->ddraw->wineD3D,
1250 WINED3DADAPTER_DEFAULT,
1253 WINED3DUSAGE_QUERY_LEGACYBUMPMAP,
1254 WINED3DRTYPE_TEXTURE,
1259 DDPIXELFORMAT pformat;
1261 memset(&pformat, 0, sizeof(pformat));
1262 pformat.dwSize = sizeof(pformat);
1263 PixelFormat_WineD3DtoDD(&pformat, BumpFormatList[i]);
1265 TRACE("Enumerating WineD3DFormat %d\n", BumpFormatList[i]);
1266 hr = Callback(&pformat, Arg);
1267 if(hr != DDENUMRET_OK)
1269 TRACE("Format enumeration cancelled by application\n");
1270 LeaveCriticalSection(&ddraw_cs);
1275 TRACE("End of enumeration\n");
1276 LeaveCriticalSection(&ddraw_cs);
1280 static HRESULT WINAPI
1281 IDirect3DDeviceImpl_7_EnumTextureFormats_FPUSetup(IDirect3DDevice7 *iface,
1282 LPD3DENUMPIXELFORMATSCALLBACK Callback,
1285 return IDirect3DDeviceImpl_7_EnumTextureFormats(iface, Callback, Arg);
1288 static HRESULT WINAPI
1289 IDirect3DDeviceImpl_7_EnumTextureFormats_FPUPreserve(IDirect3DDevice7 *iface,
1290 LPD3DENUMPIXELFORMATSCALLBACK Callback,
1296 old_fpucw = d3d_fpu_setup();
1297 hr = IDirect3DDeviceImpl_7_EnumTextureFormats(iface, Callback, Arg);
1298 set_fpu_control_word(old_fpucw);
1303 static HRESULT WINAPI
1304 Thunk_IDirect3DDeviceImpl_3_EnumTextureFormats(IDirect3DDevice3 *iface,
1305 LPD3DENUMPIXELFORMATSCALLBACK Callback,
1308 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
1309 TRACE_(ddraw_thunk)("(%p)->(%p,%p) thunking to IDirect3DDevice7 interface.\n", This, Callback, Arg);
1310 return IDirect3DDevice7_EnumTextureFormats(ICOM_INTERFACE(This, IDirect3DDevice7),
1315 /*****************************************************************************
1316 * IDirect3DDevice2::EnumTextureformats
1318 * EnumTextureFormats for Version 1 and 2, see
1319 * IDirect3DDevice7::EnumTexureFormats for a more detailed description.
1321 * This version has a different callback and does not enumerate FourCC
1324 *****************************************************************************/
1325 static HRESULT WINAPI
1326 IDirect3DDeviceImpl_2_EnumTextureFormats(IDirect3DDevice2 *iface,
1327 LPD3DENUMTEXTUREFORMATSCALLBACK Callback,
1330 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
1333 WINED3DDISPLAYMODE mode;
1335 WINED3DFORMAT FormatList[] = {
1337 WINED3DFMT_A8R8G8B8,
1338 WINED3DFMT_X8R8G8B8,
1342 WINED3DFMT_A1R5G5B5,
1343 WINED3DFMT_A4R4G4B4,
1345 WINED3DFMT_X1R5G5B5,
1349 /* FOURCC codes - Not in this version*/
1352 TRACE("(%p)->(%p,%p): Relay\n", This, Callback, Arg);
1355 return DDERR_INVALIDPARAMS;
1357 EnterCriticalSection(&ddraw_cs);
1359 memset(&mode, 0, sizeof(mode));
1360 hr = IWineD3DDevice_GetDisplayMode(This->ddraw->wineD3DDevice,
1364 LeaveCriticalSection(&ddraw_cs);
1365 WARN("Cannot get the current adapter format\n");
1369 for(i = 0; i < sizeof(FormatList) / sizeof(WINED3DFORMAT); i++)
1371 hr = IWineD3D_CheckDeviceFormat(This->ddraw->wineD3D,
1376 WINED3DRTYPE_TEXTURE,
1381 DDSURFACEDESC sdesc;
1383 memset(&sdesc, 0, sizeof(sdesc));
1384 sdesc.dwSize = sizeof(sdesc);
1385 sdesc.dwFlags = DDSD_PIXELFORMAT | DDSD_CAPS;
1386 sdesc.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1387 sdesc.ddpfPixelFormat.dwSize = sizeof(sdesc.ddpfPixelFormat);
1388 PixelFormat_WineD3DtoDD(&sdesc.ddpfPixelFormat, FormatList[i]);
1390 TRACE("Enumerating WineD3DFormat %d\n", FormatList[i]);
1391 hr = Callback(&sdesc, Arg);
1392 if(hr != DDENUMRET_OK)
1394 TRACE("Format enumeration cancelled by application\n");
1395 LeaveCriticalSection(&ddraw_cs);
1400 TRACE("End of enumeration\n");
1401 LeaveCriticalSection(&ddraw_cs);
1405 static HRESULT WINAPI
1406 Thunk_IDirect3DDeviceImpl_1_EnumTextureFormats(IDirect3DDevice *iface,
1407 LPD3DENUMTEXTUREFORMATSCALLBACK Callback,
1410 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
1411 TRACE_(ddraw_thunk)("(%p)->(%p,%p) thunking to IDirect3DDevice2 interface.\n", This, Callback, Arg);
1412 return IDirect3DDevice2_EnumTextureFormats(ICOM_INTERFACE(This, IDirect3DDevice2),
1417 /*****************************************************************************
1418 * IDirect3DDevice::CreateMatrix
1420 * Creates a matrix handle. A handle is created and memory for a D3DMATRIX is
1421 * allocated for the handle.
1426 * D3DMatHandle: Address to return the handle at
1430 * DDERR_INVALIDPARAMS if D3DMatHandle = NULL
1432 *****************************************************************************/
1433 static HRESULT WINAPI
1434 IDirect3DDeviceImpl_1_CreateMatrix(IDirect3DDevice *iface, D3DMATRIXHANDLE *D3DMatHandle)
1436 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
1438 TRACE("(%p)->(%p)\n", This, D3DMatHandle);
1441 return DDERR_INVALIDPARAMS;
1443 Matrix = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(D3DMATRIX));
1446 ERR("Out of memory when allocating a D3DMATRIX\n");
1447 return DDERR_OUTOFMEMORY;
1450 EnterCriticalSection(&ddraw_cs);
1451 *D3DMatHandle = IDirect3DDeviceImpl_CreateHandle(This);
1452 if(!(*D3DMatHandle))
1454 ERR("Failed to create a matrix handle\n");
1455 HeapFree(GetProcessHeap(), 0, Matrix);
1456 LeaveCriticalSection(&ddraw_cs);
1457 return DDERR_OUTOFMEMORY;
1459 This->Handles[*D3DMatHandle - 1].ptr = Matrix;
1460 This->Handles[*D3DMatHandle - 1].type = DDrawHandle_Matrix;
1461 TRACE(" returning matrix handle %d\n", *D3DMatHandle);
1463 LeaveCriticalSection(&ddraw_cs);
1467 /*****************************************************************************
1468 * IDirect3DDevice::SetMatrix
1470 * Sets a matrix for a matrix handle. The matrix is copied into the memory
1471 * allocated for the handle
1476 * D3DMatHandle: Handle to set the matrix to
1477 * D3DMatrix: Matrix to set
1481 * DDERR_INVALIDPARAMS if the handle of the matrix is invalid or the matrix
1484 *****************************************************************************/
1485 static HRESULT WINAPI
1486 IDirect3DDeviceImpl_1_SetMatrix(IDirect3DDevice *iface,
1487 D3DMATRIXHANDLE D3DMatHandle,
1488 D3DMATRIX *D3DMatrix)
1490 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
1491 TRACE("(%p)->(%08x,%p)\n", This, D3DMatHandle, D3DMatrix);
1493 if( (!D3DMatHandle) || (!D3DMatrix) )
1494 return DDERR_INVALIDPARAMS;
1496 EnterCriticalSection(&ddraw_cs);
1497 if(D3DMatHandle > This->numHandles)
1499 ERR("Handle %d out of range\n", D3DMatHandle);
1500 LeaveCriticalSection(&ddraw_cs);
1501 return DDERR_INVALIDPARAMS;
1503 else if(This->Handles[D3DMatHandle - 1].type != DDrawHandle_Matrix)
1505 ERR("Handle %d is not a matrix handle\n", D3DMatHandle);
1506 LeaveCriticalSection(&ddraw_cs);
1507 return DDERR_INVALIDPARAMS;
1511 dump_D3DMATRIX(D3DMatrix);
1513 *((D3DMATRIX *) This->Handles[D3DMatHandle - 1].ptr) = *D3DMatrix;
1515 if(This->world == D3DMatHandle)
1517 IWineD3DDevice_SetTransform(This->wineD3DDevice,
1518 WINED3DTS_WORLDMATRIX(0),
1519 (WINED3DMATRIX *) D3DMatrix);
1521 if(This->view == D3DMatHandle)
1523 IWineD3DDevice_SetTransform(This->wineD3DDevice,
1525 (WINED3DMATRIX *) D3DMatrix);
1527 if(This->proj == D3DMatHandle)
1529 IWineD3DDevice_SetTransform(This->wineD3DDevice,
1530 WINED3DTS_PROJECTION,
1531 (WINED3DMATRIX *) D3DMatrix);
1534 LeaveCriticalSection(&ddraw_cs);
1538 /*****************************************************************************
1539 * IDirect3DDevice::SetMatrix
1541 * Returns the content of a D3DMATRIX handle
1546 * D3DMatHandle: Matrix handle to read the content from
1547 * D3DMatrix: Address to store the content at
1551 * DDERR_INVALIDPARAMS if D3DMatHandle is invalid or D3DMatrix is NULL
1553 *****************************************************************************/
1554 static HRESULT WINAPI
1555 IDirect3DDeviceImpl_1_GetMatrix(IDirect3DDevice *iface,
1556 D3DMATRIXHANDLE D3DMatHandle,
1557 D3DMATRIX *D3DMatrix)
1559 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
1560 TRACE("(%p)->(%08x,%p)\n", This, D3DMatHandle, D3DMatrix);
1563 return DDERR_INVALIDPARAMS;
1565 return DDERR_INVALIDPARAMS;
1567 EnterCriticalSection(&ddraw_cs);
1568 if(D3DMatHandle > This->numHandles)
1570 ERR("Handle %d out of range\n", D3DMatHandle);
1571 LeaveCriticalSection(&ddraw_cs);
1572 return DDERR_INVALIDPARAMS;
1574 else if(This->Handles[D3DMatHandle - 1].type != DDrawHandle_Matrix)
1576 ERR("Handle %d is not a matrix handle\n", D3DMatHandle);
1577 LeaveCriticalSection(&ddraw_cs);
1578 return DDERR_INVALIDPARAMS;
1581 /* The handle is simply a pointer to a D3DMATRIX structure */
1582 *D3DMatrix = *((D3DMATRIX *) This->Handles[D3DMatHandle - 1].ptr);
1584 LeaveCriticalSection(&ddraw_cs);
1588 /*****************************************************************************
1589 * IDirect3DDevice::DeleteMatrix
1591 * Destroys a Matrix handle. Frees the memory and unsets the handle data
1596 * D3DMatHandle: Handle to destroy
1600 * DDERR_INVALIDPARAMS if D3DMatHandle is invalid
1602 *****************************************************************************/
1603 static HRESULT WINAPI
1604 IDirect3DDeviceImpl_1_DeleteMatrix(IDirect3DDevice *iface,
1605 D3DMATRIXHANDLE D3DMatHandle)
1607 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
1608 TRACE("(%p)->(%08x)\n", This, D3DMatHandle);
1611 return DDERR_INVALIDPARAMS;
1613 EnterCriticalSection(&ddraw_cs);
1614 if(D3DMatHandle > This->numHandles)
1616 ERR("Handle %d out of range\n", D3DMatHandle);
1617 LeaveCriticalSection(&ddraw_cs);
1618 return DDERR_INVALIDPARAMS;
1620 else if(This->Handles[D3DMatHandle - 1].type != DDrawHandle_Matrix)
1622 ERR("Handle %d is not a matrix handle\n", D3DMatHandle);
1623 LeaveCriticalSection(&ddraw_cs);
1624 return DDERR_INVALIDPARAMS;
1627 HeapFree(GetProcessHeap(), 0, This->Handles[D3DMatHandle - 1].ptr);
1628 This->Handles[D3DMatHandle - 1].ptr = NULL;
1629 This->Handles[D3DMatHandle - 1].type = DDrawHandle_Unknown;
1631 LeaveCriticalSection(&ddraw_cs);
1635 /*****************************************************************************
1636 * IDirect3DDevice7::BeginScene
1638 * This method must be called before any rendering is performed.
1639 * IDirect3DDevice::EndScene has to be called after the scene is complete
1641 * Version 1, 2, 3 and 7
1644 * D3D_OK on success, for details see IWineD3DDevice::BeginScene
1645 * D3DERR_SCENE_IN_SCENE if WineD3D returns an error(Only in case of an already
1648 *****************************************************************************/
1650 IDirect3DDeviceImpl_7_BeginScene(IDirect3DDevice7 *iface)
1652 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1654 TRACE("(%p): Relay\n", This);
1656 EnterCriticalSection(&ddraw_cs);
1657 hr = IWineD3DDevice_BeginScene(This->wineD3DDevice);
1658 LeaveCriticalSection(&ddraw_cs);
1659 if(hr == WINED3D_OK) return D3D_OK;
1660 else return D3DERR_SCENE_IN_SCENE; /* TODO: Other possible causes of failure */
1663 static HRESULT WINAPI
1664 IDirect3DDeviceImpl_7_BeginScene_FPUSetup(IDirect3DDevice7 *iface)
1666 return IDirect3DDeviceImpl_7_BeginScene(iface);
1669 static HRESULT WINAPI
1670 IDirect3DDeviceImpl_7_BeginScene_FPUPreserve(IDirect3DDevice7 *iface)
1675 old_fpucw = d3d_fpu_setup();
1676 hr = IDirect3DDeviceImpl_7_BeginScene(iface);
1677 set_fpu_control_word(old_fpucw);
1682 static HRESULT WINAPI
1683 Thunk_IDirect3DDeviceImpl_3_BeginScene(IDirect3DDevice3 *iface)
1685 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
1686 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
1687 return IDirect3DDevice7_BeginScene(ICOM_INTERFACE(This, IDirect3DDevice7));
1690 static HRESULT WINAPI
1691 Thunk_IDirect3DDeviceImpl_2_BeginScene(IDirect3DDevice2 *iface)
1693 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
1694 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
1695 return IDirect3DDevice7_BeginScene(ICOM_INTERFACE(This, IDirect3DDevice7));
1698 static HRESULT WINAPI
1699 Thunk_IDirect3DDeviceImpl_1_BeginScene(IDirect3DDevice *iface)
1701 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
1702 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
1703 return IDirect3DDevice7_BeginScene(ICOM_INTERFACE(This, IDirect3DDevice7));
1706 /*****************************************************************************
1707 * IDirect3DDevice7::EndScene
1709 * Ends a scene that has been begun with IDirect3DDevice7::BeginScene.
1710 * This method must be called after rendering is finished.
1712 * Version 1, 2, 3 and 7
1715 * D3D_OK on success, for details see IWineD3DDevice::EndScene
1716 * D3DERR_SCENE_NOT_IN_SCENE is returned if WineD3D returns an error. It does
1717 * that only if the scene was already ended.
1719 *****************************************************************************/
1721 IDirect3DDeviceImpl_7_EndScene(IDirect3DDevice7 *iface)
1723 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1725 TRACE("(%p): Relay\n", This);
1727 EnterCriticalSection(&ddraw_cs);
1728 hr = IWineD3DDevice_EndScene(This->wineD3DDevice);
1729 LeaveCriticalSection(&ddraw_cs);
1730 if(hr == WINED3D_OK) return D3D_OK;
1731 else return D3DERR_SCENE_NOT_IN_SCENE;
1734 static HRESULT WINAPI
1735 IDirect3DDeviceImpl_7_EndScene_FPUSetup(IDirect3DDevice7 *iface)
1737 return IDirect3DDeviceImpl_7_EndScene(iface);
1740 static HRESULT WINAPI
1741 IDirect3DDeviceImpl_7_EndScene_FPUPreserve(IDirect3DDevice7 *iface)
1746 old_fpucw = d3d_fpu_setup();
1747 hr = IDirect3DDeviceImpl_7_EndScene(iface);
1748 set_fpu_control_word(old_fpucw);
1753 static HRESULT WINAPI
1754 Thunk_IDirect3DDeviceImpl_3_EndScene(IDirect3DDevice3 *iface)
1756 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
1757 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
1758 return IDirect3DDevice7_EndScene(ICOM_INTERFACE(This, IDirect3DDevice7));
1761 static HRESULT WINAPI
1762 Thunk_IDirect3DDeviceImpl_2_EndScene(IDirect3DDevice2 *iface)
1764 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
1765 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
1766 return IDirect3DDevice7_EndScene(ICOM_INTERFACE(This, IDirect3DDevice7));
1769 static HRESULT WINAPI
1770 Thunk_IDirect3DDeviceImpl_1_EndScene(IDirect3DDevice *iface)
1772 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
1773 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
1774 return IDirect3DDevice7_EndScene(ICOM_INTERFACE(This, IDirect3DDevice7));
1777 /*****************************************************************************
1778 * IDirect3DDevice7::GetDirect3D
1780 * Returns the IDirect3D(= interface to the DirectDraw object) used to create
1784 * Direct3D7: Address to store the interface pointer at
1788 * DDERR_INVALIDPARAMS if Direct3D7 == NULL
1790 *****************************************************************************/
1791 static HRESULT WINAPI
1792 IDirect3DDeviceImpl_7_GetDirect3D(IDirect3DDevice7 *iface,
1793 IDirect3D7 **Direct3D7)
1795 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1796 TRACE("(%p)->(%p)\n", This, Direct3D7);
1799 return DDERR_INVALIDPARAMS;
1801 *Direct3D7 = ICOM_INTERFACE(This->ddraw, IDirect3D7);
1802 IDirect3D7_AddRef(*Direct3D7);
1804 TRACE(" returning interface %p\n", *Direct3D7);
1808 static HRESULT WINAPI
1809 Thunk_IDirect3DDeviceImpl_3_GetDirect3D(IDirect3DDevice3 *iface,
1810 IDirect3D3 **Direct3D3)
1812 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
1814 IDirect3D7 *ret_ptr;
1816 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, Direct3D3);
1817 ret = IDirect3DDevice7_GetDirect3D(ICOM_INTERFACE(This, IDirect3DDevice7),
1821 *Direct3D3 = COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D7, IDirect3D3, ret_ptr);
1822 TRACE(" returning interface %p\n", *Direct3D3);
1826 static HRESULT WINAPI
1827 Thunk_IDirect3DDeviceImpl_2_GetDirect3D(IDirect3DDevice2 *iface,
1828 IDirect3D2 **Direct3D2)
1830 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
1832 IDirect3D7 *ret_ptr;
1834 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, Direct3D2);
1835 ret = IDirect3DDevice7_GetDirect3D(ICOM_INTERFACE(This, IDirect3DDevice7),
1839 *Direct3D2 = COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D7, IDirect3D2, ret_ptr);
1840 TRACE(" returning interface %p\n", *Direct3D2);
1844 static HRESULT WINAPI
1845 Thunk_IDirect3DDeviceImpl_1_GetDirect3D(IDirect3DDevice *iface,
1846 IDirect3D **Direct3D)
1848 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
1850 IDirect3D7 *ret_ptr;
1852 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, Direct3D);
1853 ret = IDirect3DDevice7_GetDirect3D(ICOM_INTERFACE(This, IDirect3DDevice7),
1857 *Direct3D = COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D7, IDirect3D, ret_ptr);
1858 TRACE(" returning interface %p\n", *Direct3D);
1862 /*****************************************************************************
1863 * IDirect3DDevice3::SetCurrentViewport
1865 * Sets a Direct3DViewport as the current viewport.
1866 * For the thunks note that all viewport interface versions are equal
1869 * Direct3DViewport3: The viewport to set
1875 * (Is a NULL viewport valid?)
1877 *****************************************************************************/
1878 static HRESULT WINAPI
1879 IDirect3DDeviceImpl_3_SetCurrentViewport(IDirect3DDevice3 *iface,
1880 IDirect3DViewport3 *Direct3DViewport3)
1882 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
1883 IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Direct3DViewport3);
1884 TRACE("(%p)->(%p)\n", This, Direct3DViewport3);
1886 EnterCriticalSection(&ddraw_cs);
1887 /* Do nothing if the specified viewport is the same as the current one */
1888 if (This->current_viewport == vp )
1890 LeaveCriticalSection(&ddraw_cs);
1894 /* Should check if the viewport was added or not */
1896 /* Release previous viewport and AddRef the new one */
1897 if (This->current_viewport)
1899 TRACE("ViewportImpl is at %p, interface is at %p\n", This->current_viewport, ICOM_INTERFACE(This->current_viewport, IDirect3DViewport3));
1900 IDirect3DViewport3_Release( ICOM_INTERFACE(This->current_viewport, IDirect3DViewport3) );
1902 IDirect3DViewport3_AddRef(Direct3DViewport3);
1904 /* Set this viewport as the current viewport */
1905 This->current_viewport = vp;
1907 /* Activate this viewport */
1908 This->current_viewport->active_device = This;
1909 This->current_viewport->activate(This->current_viewport, FALSE);
1911 LeaveCriticalSection(&ddraw_cs);
1915 static HRESULT WINAPI
1916 Thunk_IDirect3DDeviceImpl_2_SetCurrentViewport(IDirect3DDevice2 *iface,
1917 IDirect3DViewport2 *Direct3DViewport2)
1919 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
1920 IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Direct3DViewport2);
1921 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, vp);
1922 return IDirect3DDevice3_SetCurrentViewport(ICOM_INTERFACE(This, IDirect3DDevice3),
1923 ICOM_INTERFACE(vp, IDirect3DViewport3));
1926 /*****************************************************************************
1927 * IDirect3DDevice3::GetCurrentViewport
1929 * Returns the currently active viewport.
1934 * Direct3DViewport3: Address to return the interface pointer at
1938 * DDERR_INVALIDPARAMS if Direct3DViewport == NULL
1940 *****************************************************************************/
1941 static HRESULT WINAPI
1942 IDirect3DDeviceImpl_3_GetCurrentViewport(IDirect3DDevice3 *iface,
1943 IDirect3DViewport3 **Direct3DViewport3)
1945 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
1946 TRACE("(%p)->(%p)\n", This, Direct3DViewport3);
1948 if(!Direct3DViewport3)
1949 return DDERR_INVALIDPARAMS;
1951 EnterCriticalSection(&ddraw_cs);
1952 *Direct3DViewport3 = ICOM_INTERFACE(This->current_viewport, IDirect3DViewport3);
1954 /* AddRef the returned viewport */
1955 if(*Direct3DViewport3) IDirect3DViewport3_AddRef(*Direct3DViewport3);
1957 TRACE(" returning interface %p\n", *Direct3DViewport3);
1959 LeaveCriticalSection(&ddraw_cs);
1963 static HRESULT WINAPI
1964 Thunk_IDirect3DDeviceImpl_2_GetCurrentViewport(IDirect3DDevice2 *iface,
1965 IDirect3DViewport2 **Direct3DViewport2)
1967 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
1969 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, Direct3DViewport2);
1970 hr = IDirect3DDevice3_GetCurrentViewport(ICOM_INTERFACE(This, IDirect3DDevice3),
1971 (IDirect3DViewport3 **) Direct3DViewport2);
1972 if(hr != D3D_OK) return hr;
1973 *Direct3DViewport2 = (IDirect3DViewport2 *) COM_INTERFACE_CAST(IDirect3DViewportImpl, IDirect3DViewport3, IDirect3DViewport3, *Direct3DViewport2);
1977 /*****************************************************************************
1978 * IDirect3DDevice7::SetRenderTarget
1980 * Sets the render target for the Direct3DDevice.
1981 * For the thunks note that IDirectDrawSurface7 == IDirectDrawSurface4 and
1982 * IDirectDrawSurface3 == IDirectDrawSurface
1984 * Version 2, 3 and 7
1987 * NewTarget: Pointer to an IDirectDrawSurface7 interface to set as the new
1992 * D3D_OK on success, for details see IWineD3DDevice::SetRenderTarget
1994 *****************************************************************************/
1996 IDirect3DDeviceImpl_7_SetRenderTarget(IDirect3DDevice7 *iface,
1997 IDirectDrawSurface7 *NewTarget,
2000 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
2001 IDirectDrawSurfaceImpl *Target = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, NewTarget);
2003 TRACE("(%p)->(%p,%08x): Relay\n", This, NewTarget, Flags);
2005 EnterCriticalSection(&ddraw_cs);
2006 /* Flags: Not used */
2008 if(This->target == Target)
2010 TRACE("No-op SetRenderTarget operation, not doing anything\n");
2011 LeaveCriticalSection(&ddraw_cs);
2015 hr = IWineD3DDevice_SetRenderTarget(This->wineD3DDevice,
2017 Target ? Target->WineD3DSurface : NULL);
2020 LeaveCriticalSection(&ddraw_cs);
2023 IDirectDrawSurface7_AddRef(NewTarget);
2024 IDirectDrawSurface7_Release(ICOM_INTERFACE(This->target, IDirectDrawSurface7));
2025 This->target = Target;
2026 IDirect3DDeviceImpl_UpdateDepthStencil(This);
2027 LeaveCriticalSection(&ddraw_cs);
2031 static HRESULT WINAPI
2032 IDirect3DDeviceImpl_7_SetRenderTarget_FPUSetup(IDirect3DDevice7 *iface,
2033 IDirectDrawSurface7 *NewTarget,
2036 return IDirect3DDeviceImpl_7_SetRenderTarget(iface, NewTarget, Flags);
2039 static HRESULT WINAPI
2040 IDirect3DDeviceImpl_7_SetRenderTarget_FPUPreserve(IDirect3DDevice7 *iface,
2041 IDirectDrawSurface7 *NewTarget,
2047 old_fpucw = d3d_fpu_setup();
2048 hr = IDirect3DDeviceImpl_7_SetRenderTarget(iface, NewTarget, Flags);
2049 set_fpu_control_word(old_fpucw);
2054 static HRESULT WINAPI
2055 Thunk_IDirect3DDeviceImpl_3_SetRenderTarget(IDirect3DDevice3 *iface,
2056 IDirectDrawSurface4 *NewRenderTarget,
2059 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
2060 IDirectDrawSurfaceImpl *Target = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, NewRenderTarget);
2061 TRACE_(ddraw_thunk)("(%p)->(%p,%08x) thunking to IDirect3DDevice7 interface.\n", This, Target, Flags);
2062 return IDirect3DDevice7_SetRenderTarget(ICOM_INTERFACE(This, IDirect3DDevice7),
2063 ICOM_INTERFACE(Target, IDirectDrawSurface7),
2067 static HRESULT WINAPI
2068 Thunk_IDirect3DDeviceImpl_2_SetRenderTarget(IDirect3DDevice2 *iface,
2069 IDirectDrawSurface *NewRenderTarget,
2072 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
2073 IDirectDrawSurfaceImpl *Target = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface3, NewRenderTarget);
2074 TRACE_(ddraw_thunk)("(%p)->(%p,%08x) thunking to IDirect3DDevice7 interface.\n", This, Target, Flags);
2075 return IDirect3DDevice7_SetRenderTarget(ICOM_INTERFACE(This, IDirect3DDevice7),
2076 ICOM_INTERFACE(Target, IDirectDrawSurface7),
2080 /*****************************************************************************
2081 * IDirect3DDevice7::GetRenderTarget
2083 * Returns the current render target.
2084 * This is handled locally, because the WineD3D render target's parent
2087 * Version 2, 3 and 7
2090 * RenderTarget: Address to store the surface interface pointer
2094 * DDERR_INVALIDPARAMS if RenderTarget == NULL
2096 *****************************************************************************/
2097 static HRESULT WINAPI
2098 IDirect3DDeviceImpl_7_GetRenderTarget(IDirect3DDevice7 *iface,
2099 IDirectDrawSurface7 **RenderTarget)
2101 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
2102 TRACE("(%p)->(%p): Relay\n", This, RenderTarget);
2105 return DDERR_INVALIDPARAMS;
2107 EnterCriticalSection(&ddraw_cs);
2108 *RenderTarget = ICOM_INTERFACE(This->target, IDirectDrawSurface7);
2109 IDirectDrawSurface7_AddRef(*RenderTarget);
2111 LeaveCriticalSection(&ddraw_cs);
2115 static HRESULT WINAPI
2116 Thunk_IDirect3DDeviceImpl_3_GetRenderTarget(IDirect3DDevice3 *iface,
2117 IDirectDrawSurface4 **RenderTarget)
2119 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
2121 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, RenderTarget);
2122 hr = IDirect3DDevice7_GetRenderTarget(ICOM_INTERFACE(This, IDirect3DDevice7),
2123 (IDirectDrawSurface7 **) RenderTarget);
2124 if(hr != D3D_OK) return hr;
2125 *RenderTarget = (IDirectDrawSurface4 *) COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirectDrawSurface7, IDirectDrawSurface7, *RenderTarget);
2129 static HRESULT WINAPI
2130 Thunk_IDirect3DDeviceImpl_2_GetRenderTarget(IDirect3DDevice2 *iface,
2131 IDirectDrawSurface **RenderTarget)
2133 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
2135 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, RenderTarget);
2136 hr = IDirect3DDevice7_GetRenderTarget(ICOM_INTERFACE(This, IDirect3DDevice7),
2137 (IDirectDrawSurface7 **) RenderTarget);
2138 if(hr != D3D_OK) return hr;
2139 *RenderTarget = (IDirectDrawSurface *) COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirectDrawSurface7, IDirectDrawSurface3, *RenderTarget);
2143 /*****************************************************************************
2144 * IDirect3DDevice3::Begin
2146 * Begins a description block of vertices. This is similar to glBegin()
2147 * and glEnd(). After a call to IDirect3DDevice3::End, the vertices
2148 * described with IDirect3DDevice::Vertex are drawn.
2153 * PrimitiveType: The type of primitives to draw
2154 * VertexTypeDesc: A flexible vertex format description of the vertices
2155 * Flags: Some flags..
2160 *****************************************************************************/
2161 static HRESULT WINAPI
2162 IDirect3DDeviceImpl_3_Begin(IDirect3DDevice3 *iface,
2163 D3DPRIMITIVETYPE PrimitiveType,
2164 DWORD VertexTypeDesc,
2167 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
2168 TRACE("(%p)->(%d,%d,%08x)\n", This, PrimitiveType, VertexTypeDesc, Flags);
2170 EnterCriticalSection(&ddraw_cs);
2171 This->primitive_type = PrimitiveType;
2172 This->vertex_type = VertexTypeDesc;
2173 This->render_flags = Flags;
2174 This->vertex_size = get_flexible_vertex_size(This->vertex_type);
2175 This->nb_vertices = 0;
2176 LeaveCriticalSection(&ddraw_cs);
2181 static HRESULT WINAPI
2182 Thunk_IDirect3DDeviceImpl_2_Begin(IDirect3DDevice2 *iface,
2183 D3DPRIMITIVETYPE d3dpt,
2184 D3DVERTEXTYPE dwVertexTypeDesc,
2188 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
2189 TRACE_(ddraw_thunk)("(%p/%p)->(%08x,%08x,%08x): Thunking to IDirect3DDevice3\n", This, iface, d3dpt, dwVertexTypeDesc, dwFlags);
2191 switch(dwVertexTypeDesc)
2193 case D3DVT_VERTEX: FVF = D3DFVF_VERTEX; break;
2194 case D3DVT_LVERTEX: FVF = D3DFVF_LVERTEX; break;
2195 case D3DVT_TLVERTEX: FVF = D3DFVF_TLVERTEX; break;
2197 ERR("Unexpected vertex type %d\n", dwVertexTypeDesc);
2198 return DDERR_INVALIDPARAMS; /* Should never happen */
2201 return IDirect3DDevice3_Begin(ICOM_INTERFACE(This, IDirect3DDevice3),
2207 /*****************************************************************************
2208 * IDirect3DDevice3::BeginIndexed
2210 * Draws primitives based on vertices in a vertex array which are specified
2216 * PrimitiveType: Primitive type to draw
2217 * VertexType: A FVF description of the vertex format
2218 * Vertices: pointer to an array containing the vertices
2219 * NumVertices: The number of vertices in the vertex array
2220 * Flags: Some flags ...
2223 * D3D_OK, because it's a stub
2225 *****************************************************************************/
2226 static HRESULT WINAPI
2227 IDirect3DDeviceImpl_3_BeginIndexed(IDirect3DDevice3 *iface,
2228 D3DPRIMITIVETYPE PrimitiveType,
2234 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
2235 FIXME("(%p)->(%08x,%08x,%p,%08x,%08x): stub!\n", This, PrimitiveType, VertexType, Vertices, NumVertices, Flags);
2240 static HRESULT WINAPI
2241 Thunk_IDirect3DDeviceImpl_2_BeginIndexed(IDirect3DDevice2 *iface,
2242 D3DPRIMITIVETYPE d3dptPrimitiveType,
2243 D3DVERTEXTYPE d3dvtVertexType,
2245 DWORD dwNumVertices,
2249 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
2250 TRACE_(ddraw_thunk)("(%p/%p)->(%08x,%08x,%p,%08x,%08x): Thunking to IDirect3DDevice3\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwNumVertices, dwFlags);
2252 switch(d3dvtVertexType)
2254 case D3DVT_VERTEX: FVF = D3DFVF_VERTEX; break;
2255 case D3DVT_LVERTEX: FVF = D3DFVF_LVERTEX; break;
2256 case D3DVT_TLVERTEX: FVF = D3DFVF_TLVERTEX; break;
2258 ERR("Unexpected vertex type %d\n", d3dvtVertexType);
2259 return DDERR_INVALIDPARAMS; /* Should never happen */
2262 return IDirect3DDevice3_BeginIndexed(ICOM_INTERFACE(This,IDirect3DDevice3),
2270 /*****************************************************************************
2271 * IDirect3DDevice3::Vertex
2273 * Draws a vertex as described by IDirect3DDevice3::Begin. It places all
2274 * drawn vertices in a vertex buffer. If the buffer is too small, its
2275 * size is increased.
2280 * Vertex: Pointer to the vertex
2283 * D3D_OK, on success
2284 * DDERR_INVALIDPARAMS if Vertex is NULL
2286 *****************************************************************************/
2287 static HRESULT WINAPI
2288 IDirect3DDeviceImpl_3_Vertex(IDirect3DDevice3 *iface,
2291 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
2292 TRACE("(%p)->(%p)\n", This, Vertex);
2295 return DDERR_INVALIDPARAMS;
2297 EnterCriticalSection(&ddraw_cs);
2298 if ((This->nb_vertices+1)*This->vertex_size > This->buffer_size)
2301 This->buffer_size = This->buffer_size ? This->buffer_size * 2 : This->vertex_size * 3;
2302 old_buffer = This->vertex_buffer;
2303 This->vertex_buffer = HeapAlloc(GetProcessHeap(), 0, This->buffer_size);
2306 CopyMemory(This->vertex_buffer, old_buffer, This->nb_vertices * This->vertex_size);
2307 HeapFree(GetProcessHeap(), 0, old_buffer);
2311 CopyMemory(This->vertex_buffer + This->nb_vertices++ * This->vertex_size, Vertex, This->vertex_size);
2313 LeaveCriticalSection(&ddraw_cs);
2317 static HRESULT WINAPI
2318 Thunk_IDirect3DDeviceImpl_2_Vertex(IDirect3DDevice2 *iface,
2321 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
2322 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, lpVertexType);
2323 return IDirect3DDevice3_Vertex(ICOM_INTERFACE(This, IDirect3DDevice3),
2327 /*****************************************************************************
2328 * IDirect3DDevice3::Index
2330 * Specifies an index to a vertex to be drawn. The vertex array has to
2331 * be specified with BeginIndexed first.
2334 * VertexIndex: The index of the vertex to draw
2337 * D3D_OK because it's a stub
2339 *****************************************************************************/
2340 static HRESULT WINAPI
2341 IDirect3DDeviceImpl_3_Index(IDirect3DDevice3 *iface,
2344 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
2345 FIXME("(%p)->(%04x): stub!\n", This, VertexIndex);
2349 static HRESULT WINAPI
2350 Thunk_IDirect3DDeviceImpl_2_Index(IDirect3DDevice2 *iface,
2353 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
2354 TRACE_(ddraw_thunk)("(%p)->(%04x) thunking to IDirect3DDevice3 interface.\n", This, wVertexIndex);
2355 return IDirect3DDevice3_Index(ICOM_INTERFACE(This, IDirect3DDevice3),
2359 /*****************************************************************************
2360 * IDirect3DDevice3::End
2362 * Ends a draw begun with IDirect3DDevice3::Begin or
2363 * IDirect3DDevice::BeginIndexed. The vertices specified with
2364 * IDirect3DDevice::Vertex or IDirect3DDevice::Index are drawn using
2365 * the IDirect3DDevice7::DrawPrimitive method. So far only
2366 * non-indexed mode is supported
2371 * Flags: Some flags, as usual. Don't know which are defined
2374 * The return value of IDirect3DDevice7::DrawPrimitive
2376 *****************************************************************************/
2377 static HRESULT WINAPI
2378 IDirect3DDeviceImpl_3_End(IDirect3DDevice3 *iface,
2381 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
2382 TRACE("(%p)->(%08x)\n", This, Flags);
2384 return IDirect3DDevice7_DrawPrimitive(ICOM_INTERFACE(This, IDirect3DDevice7),
2385 This->primitive_type, This->vertex_type,
2386 This->vertex_buffer, This->nb_vertices,
2387 This->render_flags);
2390 static HRESULT WINAPI
2391 Thunk_IDirect3DDeviceImpl_2_End(IDirect3DDevice2 *iface,
2394 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
2395 TRACE_(ddraw_thunk)("(%p)->(%08x) thunking to IDirect3DDevice3 interface.\n", This, dwFlags);
2396 return IDirect3DDevice3_End(ICOM_INTERFACE(This, IDirect3DDevice3),
2400 /*****************************************************************************
2401 * IDirect3DDevice7::GetRenderState
2403 * Returns the value of a render state. The possible render states are
2404 * defined in include/d3dtypes.h
2406 * Version 2, 3 and 7
2409 * RenderStateType: Render state to return the current setting of
2410 * Value: Address to store the value at
2413 * D3D_OK on success, for details see IWineD3DDevice::GetRenderState
2414 * DDERR_INVALIDPARAMS if Value == NULL
2416 *****************************************************************************/
2418 IDirect3DDeviceImpl_7_GetRenderState(IDirect3DDevice7 *iface,
2419 D3DRENDERSTATETYPE RenderStateType,
2422 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
2424 TRACE("(%p)->(%08x,%p): Relay\n", This, RenderStateType, Value);
2427 return DDERR_INVALIDPARAMS;
2429 EnterCriticalSection(&ddraw_cs);
2430 switch(RenderStateType)
2432 case D3DRENDERSTATE_TEXTUREMAG:
2434 WINED3DTEXTUREFILTERTYPE tex_mag;
2436 hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice,
2437 0, WINED3DSAMP_MAGFILTER,
2442 case WINED3DTEXF_POINT:
2443 *Value = D3DFILTER_NEAREST;
2445 case WINED3DTEXF_LINEAR:
2446 *Value = D3DFILTER_LINEAR;
2449 ERR("Unhandled texture mag %d !\n",tex_mag);
2455 case D3DRENDERSTATE_TEXTUREMIN:
2457 WINED3DTEXTUREFILTERTYPE tex_min;
2459 hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice,
2460 0, WINED3DSAMP_MINFILTER,
2465 case WINED3DTEXF_POINT:
2466 *Value = D3DFILTER_NEAREST;
2468 case WINED3DTEXF_LINEAR:
2469 *Value = D3DFILTER_LINEAR;
2472 ERR("Unhandled texture mag %d !\n",tex_min);
2478 case D3DRENDERSTATE_TEXTUREADDRESS:
2479 case D3DRENDERSTATE_TEXTUREADDRESSU:
2480 hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice,
2481 0, WINED3DSAMP_ADDRESSU,
2484 case D3DRENDERSTATE_TEXTUREADDRESSV:
2485 hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice,
2486 0, WINED3DSAMP_ADDRESSV,
2491 /* FIXME: Unhandled: D3DRENDERSTATE_STIPPLEPATTERN00 - 31 */
2492 hr = IWineD3DDevice_GetRenderState(This->wineD3DDevice,
2496 LeaveCriticalSection(&ddraw_cs);
2500 static HRESULT WINAPI
2501 IDirect3DDeviceImpl_7_GetRenderState_FPUSetup(IDirect3DDevice7 *iface,
2502 D3DRENDERSTATETYPE RenderStateType,
2505 return IDirect3DDeviceImpl_7_GetRenderState(iface, RenderStateType, Value);
2508 static HRESULT WINAPI
2509 IDirect3DDeviceImpl_7_GetRenderState_FPUPreserve(IDirect3DDevice7 *iface,
2510 D3DRENDERSTATETYPE RenderStateType,
2516 old_fpucw = d3d_fpu_setup();
2517 hr = IDirect3DDeviceImpl_7_GetRenderState(iface, RenderStateType, Value);
2518 set_fpu_control_word(old_fpucw);
2523 static HRESULT WINAPI
2524 IDirect3DDeviceImpl_3_GetRenderState(IDirect3DDevice3 *iface,
2525 D3DRENDERSTATETYPE dwRenderStateType,
2526 DWORD *lpdwRenderState)
2528 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
2530 TRACE("(%p)->(%08x,%p)\n", This, dwRenderStateType, lpdwRenderState);
2532 switch(dwRenderStateType)
2534 case D3DRENDERSTATE_TEXTUREHANDLE:
2536 /* This state is wrapped to SetTexture in SetRenderState, so
2537 * it has to be wrapped to GetTexture here
2539 IWineD3DBaseTexture *tex = NULL;
2540 *lpdwRenderState = 0;
2542 EnterCriticalSection(&ddraw_cs);
2544 hr = IWineD3DDevice_GetTexture(This->wineD3DDevice,
2548 if(hr == WINED3D_OK && tex)
2550 IDirectDrawSurface7 *parent = NULL;
2551 hr = IWineD3DBaseTexture_GetParent(tex,
2552 (IUnknown **) &parent);
2555 /* The parent of the texture is the IDirectDrawSurface7 interface
2556 * of the ddraw surface
2558 IDirectDrawSurfaceImpl *texImpl = ICOM_OBJECT(IDirectDrawSurfaceImpl,
2559 IDirectDrawSurface7,
2561 *lpdwRenderState = texImpl->Handle;
2562 IDirectDrawSurface7_Release(parent);
2564 IWineD3DBaseTexture_Release(tex);
2567 LeaveCriticalSection(&ddraw_cs);
2572 case D3DRENDERSTATE_TEXTUREMAPBLEND:
2574 /* D3DRENDERSTATE_TEXTUREMAPBLEND is mapped to texture state stages in SetRenderState; reverse
2575 the mapping to get the value. */
2576 DWORD colorop, colorarg1, colorarg2;
2577 DWORD alphaop, alphaarg1, alphaarg2;
2579 EnterCriticalSection(&ddraw_cs);
2581 This->legacyTextureBlending = TRUE;
2583 IWineD3DDevice_GetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLOROP, &colorop);
2584 IWineD3DDevice_GetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG1, &colorarg1);
2585 IWineD3DDevice_GetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG2, &colorarg2);
2586 IWineD3DDevice_GetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAOP, &alphaop);
2587 IWineD3DDevice_GetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG1, &alphaarg1);
2588 IWineD3DDevice_GetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG2, &alphaarg2);
2590 if (colorop == WINED3DTOP_SELECTARG1 && colorarg1 == WINED3DTA_TEXTURE &&
2591 alphaop == WINED3DTOP_SELECTARG1 && alphaarg1 == WINED3DTA_TEXTURE)
2593 *lpdwRenderState = D3DTBLEND_DECAL;
2595 else if (colorop == WINED3DTOP_SELECTARG1 && colorarg1 == WINED3DTA_TEXTURE &&
2596 alphaop == WINED3DTOP_MODULATE && alphaarg1 == WINED3DTA_TEXTURE && alphaarg2 == WINED3DTA_CURRENT)
2598 *lpdwRenderState = D3DTBLEND_DECALALPHA;
2600 else if (colorop == WINED3DTOP_MODULATE && colorarg1 == WINED3DTA_TEXTURE && colorarg2 == WINED3DTA_CURRENT &&
2601 alphaop == WINED3DTOP_MODULATE && alphaarg1 == WINED3DTA_TEXTURE && alphaarg2 == WINED3DTA_CURRENT)
2603 *lpdwRenderState = D3DTBLEND_MODULATEALPHA;
2608 BOOL tex_alpha = FALSE;
2609 IWineD3DBaseTexture *tex = NULL;
2610 WINED3DSURFACE_DESC desc;
2612 DDPIXELFORMAT ddfmt;
2614 hr = IWineD3DDevice_GetTexture(This->wineD3DDevice,
2618 if(hr == WINED3D_OK && tex)
2620 memset(&desc, 0, sizeof(desc));
2622 hr = IWineD3DTexture_GetLevelDesc((IWineD3DTexture*) tex, 0, &desc);
2625 ddfmt.dwSize = sizeof(ddfmt);
2626 PixelFormat_WineD3DtoDD(&ddfmt, fmt);
2627 if (ddfmt.u5.dwRGBAlphaBitMask) tex_alpha = TRUE;
2630 IWineD3DBaseTexture_Release(tex);
2633 if (!(colorop == WINED3DTOP_MODULATE && colorarg1 == WINED3DTA_TEXTURE && colorarg2 == WINED3DTA_CURRENT &&
2634 alphaop == WINED3DTOP_SELECTARG1 && alphaarg1 == (tex_alpha ? WINED3DTA_TEXTURE : WINED3DTA_CURRENT)))
2636 ERR("Unexpected texture stage state setup, returning D3DTBLEND_MODULATE - likely erroneous\n");
2639 *lpdwRenderState = D3DTBLEND_MODULATE;
2642 LeaveCriticalSection(&ddraw_cs);
2648 return IDirect3DDevice7_GetRenderState(ICOM_INTERFACE(This, IDirect3DDevice7),
2654 static HRESULT WINAPI
2655 Thunk_IDirect3DDeviceImpl_2_GetRenderState(IDirect3DDevice2 *iface,
2656 D3DRENDERSTATETYPE dwRenderStateType,
2657 DWORD *lpdwRenderState)
2659 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
2660 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice3 interface.\n", This, dwRenderStateType, lpdwRenderState);
2661 return IDirect3DDevice3_GetRenderState(ICOM_INTERFACE(This, IDirect3DDevice3),
2666 /*****************************************************************************
2667 * IDirect3DDevice7::SetRenderState
2669 * Sets a render state. The possible render states are defined in
2670 * include/d3dtypes.h
2672 * Version 2, 3 and 7
2675 * RenderStateType: State to set
2676 * Value: Value to assign to that state
2679 * D3D_OK on success,
2680 * for details see IWineD3DDevice::SetRenderState
2682 *****************************************************************************/
2684 IDirect3DDeviceImpl_7_SetRenderState(IDirect3DDevice7 *iface,
2685 D3DRENDERSTATETYPE RenderStateType,
2688 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
2690 TRACE("(%p)->(%08x,%d): Relay\n", This, RenderStateType, Value);
2692 EnterCriticalSection(&ddraw_cs);
2693 /* Some render states need special care */
2694 switch(RenderStateType)
2696 case D3DRENDERSTATE_TEXTUREMAG:
2698 WINED3DTEXTUREFILTERTYPE tex_mag = WINED3DTEXF_NONE;
2700 switch ((D3DTEXTUREFILTER) Value)
2702 case D3DFILTER_NEAREST:
2703 case D3DFILTER_LINEARMIPNEAREST:
2704 tex_mag = WINED3DTEXF_POINT;
2706 case D3DFILTER_LINEAR:
2707 case D3DFILTER_LINEARMIPLINEAR:
2708 tex_mag = WINED3DTEXF_LINEAR;
2711 ERR("Unhandled texture mag %d !\n",Value);
2714 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
2715 0, WINED3DSAMP_MAGFILTER,
2720 case D3DRENDERSTATE_TEXTUREMIN:
2722 WINED3DTEXTUREFILTERTYPE tex_min = WINED3DTEXF_NONE;
2723 WINED3DTEXTUREFILTERTYPE tex_mip = WINED3DTEXF_NONE;
2725 switch ((D3DTEXTUREFILTER) Value)
2727 case D3DFILTER_NEAREST:
2728 tex_min = WINED3DTEXF_POINT;
2730 case D3DFILTER_LINEAR:
2731 tex_min = WINED3DTEXF_LINEAR;
2733 case D3DFILTER_MIPNEAREST:
2734 tex_min = WINED3DTEXF_NONE;
2735 tex_mip = WINED3DTEXF_POINT;
2737 case D3DFILTER_MIPLINEAR:
2738 tex_min = WINED3DTEXF_NONE;
2739 tex_mip = WINED3DTEXF_LINEAR;
2741 case D3DFILTER_LINEARMIPNEAREST:
2742 tex_min = WINED3DTEXF_POINT;
2743 tex_mip = WINED3DTEXF_LINEAR;
2745 case D3DFILTER_LINEARMIPLINEAR:
2746 tex_min = WINED3DTEXF_LINEAR;
2747 tex_mip = WINED3DTEXF_LINEAR;
2751 ERR("Unhandled texture min %d !\n",Value);
2754 IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
2755 0, WINED3DSAMP_MIPFILTER,
2757 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
2758 0, WINED3DSAMP_MINFILTER,
2763 case D3DRENDERSTATE_TEXTUREADDRESS:
2764 IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
2765 0, WINED3DSAMP_ADDRESSV,
2768 case D3DRENDERSTATE_TEXTUREADDRESSU:
2769 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
2770 0, WINED3DSAMP_ADDRESSU,
2773 case D3DRENDERSTATE_TEXTUREADDRESSV:
2774 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
2775 0, WINED3DSAMP_ADDRESSV,
2781 /* FIXME: Unhandled: D3DRENDERSTATE_STIPPLEPATTERN00 - 31 */
2783 hr = IWineD3DDevice_SetRenderState(This->wineD3DDevice,
2788 LeaveCriticalSection(&ddraw_cs);
2792 static HRESULT WINAPI
2793 IDirect3DDeviceImpl_7_SetRenderState_FPUSetup(IDirect3DDevice7 *iface,
2794 D3DRENDERSTATETYPE RenderStateType,
2797 return IDirect3DDeviceImpl_7_SetRenderState(iface, RenderStateType, Value);
2800 static HRESULT WINAPI
2801 IDirect3DDeviceImpl_7_SetRenderState_FPUPreserve(IDirect3DDevice7 *iface,
2802 D3DRENDERSTATETYPE RenderStateType,
2808 old_fpucw = d3d_fpu_setup();
2809 hr = IDirect3DDeviceImpl_7_SetRenderState(iface, RenderStateType, Value);
2810 set_fpu_control_word(old_fpucw);
2815 static HRESULT WINAPI
2816 IDirect3DDeviceImpl_3_SetRenderState(IDirect3DDevice3 *iface,
2817 D3DRENDERSTATETYPE RenderStateType,
2820 /* Note about D3DRENDERSTATE_TEXTUREMAPBLEND implementation: most of values
2821 for this state can be directly mapped to texture stage colorop and alphaop, but
2822 D3DTBLEND_MODULATE is tricky: it uses alpha from texture when available and alpha
2823 from diffuse otherwise. So changing the texture must be monitored in SetTexture to modify
2824 alphaarg when needed.
2826 Aliens vs Predator 1 depends on accurate D3DTBLEND_MODULATE emulation
2828 Legacy texture blending (TEXTUREMAPBLEND) and texture stage states: directx6 docs state that
2829 TEXTUREMAPBLEND is deprecated, yet can still be used. Games must not use both or results
2830 are undefined. D3DTBLEND_MODULATE mode in particular is dependent on texture pixel format and
2831 requires fixup of stage 0 texture states when texture changes, but this fixup can interfere
2832 with games not using this deprecated state. So a flag 'legacyTextureBlending' has to be kept
2833 in device - TRUE if the app is using TEXTUREMAPBLEND.
2835 Tests show that setting TEXTUREMAPBLEND on native doesn't seem to change values returned by
2836 GetTextureStageState and vice versa. Not so on Wine, but it is 'undefined' anyway so, probably, ok,
2837 unless some broken game will be found that cares. */
2840 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
2841 TRACE("(%p)->(%08x,%d)\n", This, RenderStateType, Value);
2843 EnterCriticalSection(&ddraw_cs);
2845 switch(RenderStateType)
2847 case D3DRENDERSTATE_TEXTUREHANDLE:
2851 hr = IWineD3DDevice_SetTexture(This->wineD3DDevice,
2857 if(Value > This->numHandles)
2859 FIXME("Specified handle %d out of range\n", Value);
2860 hr = DDERR_INVALIDPARAMS;
2863 if(This->Handles[Value - 1].type != DDrawHandle_Texture)
2865 FIXME("Handle %d isn't a texture handle\n", Value);
2866 hr = DDERR_INVALIDPARAMS;
2871 IDirectDrawSurfaceImpl *surf = This->Handles[Value - 1].ptr;
2872 hr = IDirect3DDevice3_SetTexture(iface, 0, ICOM_INTERFACE(surf, IDirect3DTexture2));
2877 case D3DRENDERSTATE_TEXTUREMAPBLEND:
2879 This->legacyTextureBlending = TRUE;
2881 switch ( (D3DTEXTUREBLEND) Value)
2883 case D3DTBLEND_MODULATE:
2885 BOOL tex_alpha = FALSE;
2886 IWineD3DBaseTexture *tex = NULL;
2887 WINED3DSURFACE_DESC desc;
2889 DDPIXELFORMAT ddfmt;
2891 hr = IWineD3DDevice_GetTexture(This->wineD3DDevice,
2895 if(hr == WINED3D_OK && tex)
2897 memset(&desc, 0, sizeof(desc));
2899 hr = IWineD3DTexture_GetLevelDesc((IWineD3DTexture*) tex, 0, &desc);
2902 ddfmt.dwSize = sizeof(ddfmt);
2903 PixelFormat_WineD3DtoDD(&ddfmt, fmt);
2904 if (ddfmt.u5.dwRGBAlphaBitMask) tex_alpha = TRUE;
2907 IWineD3DBaseTexture_Release(tex);
2910 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAOP, WINED3DTOP_SELECTARG1);
2913 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG1, WINED3DTA_TEXTURE);
2917 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG1, WINED3DTA_CURRENT);
2920 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG1, WINED3DTA_TEXTURE);
2921 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG2, WINED3DTA_CURRENT);
2922 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLOROP, WINED3DTOP_MODULATE);
2928 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLOROP, WINED3DTOP_ADD);
2929 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG1, WINED3DTA_TEXTURE);
2930 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG2, WINED3DTA_CURRENT);
2931 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAOP, WINED3DTOP_SELECTARG2);
2932 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG2, WINED3DTA_CURRENT);
2935 case D3DTBLEND_MODULATEALPHA:
2936 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG1, WINED3DTA_TEXTURE);
2937 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG1, WINED3DTA_TEXTURE);
2938 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG2, WINED3DTA_CURRENT);
2939 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG2, WINED3DTA_CURRENT);
2940 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLOROP, WINED3DTOP_MODULATE);
2941 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAOP, WINED3DTOP_MODULATE);
2944 case D3DTBLEND_COPY:
2945 case D3DTBLEND_DECAL:
2946 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG1, WINED3DTA_TEXTURE);
2947 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG1, WINED3DTA_TEXTURE);
2948 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLOROP, WINED3DTOP_SELECTARG1);
2949 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAOP, WINED3DTOP_SELECTARG1);
2952 case D3DTBLEND_DECALALPHA:
2953 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLOROP, WINED3DTOP_BLENDTEXTUREALPHA);
2954 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG1, WINED3DTA_TEXTURE);
2955 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG2, WINED3DTA_CURRENT);
2956 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAOP, WINED3DTOP_SELECTARG2);
2957 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG2, WINED3DTA_CURRENT);
2961 ERR("Unhandled texture environment %d !\n",Value);
2969 hr = IDirect3DDevice7_SetRenderState(ICOM_INTERFACE(This, IDirect3DDevice7),
2975 LeaveCriticalSection(&ddraw_cs);
2980 static HRESULT WINAPI
2981 Thunk_IDirect3DDeviceImpl_2_SetRenderState(IDirect3DDevice2 *iface,
2982 D3DRENDERSTATETYPE RenderStateType,
2985 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
2986 TRACE_(ddraw_thunk)("(%p)->(%08x,%d) thunking to IDirect3DDevice3 interface.\n", This, RenderStateType, Value);
2987 return IDirect3DDevice3_SetRenderState(ICOM_INTERFACE(This, IDirect3DDevice3), RenderStateType, Value);
2990 /*****************************************************************************
2991 * Direct3DDevice3::SetLightState
2993 * Sets a light state for Direct3DDevice3 and Direct3DDevice2. The
2994 * light states are forwarded to Direct3DDevice7 render states
2999 * LightStateType: The light state to change
3000 * Value: The value to assign to that light state
3004 * DDERR_INVALIDPARAMS if the parameters were incorrect
3005 * Also check IDirect3DDevice7::SetRenderState
3007 *****************************************************************************/
3008 static HRESULT WINAPI
3009 IDirect3DDeviceImpl_3_SetLightState(IDirect3DDevice3 *iface,
3010 D3DLIGHTSTATETYPE LightStateType,
3013 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
3016 TRACE("(%p)->(%08x,%08x)\n", This, LightStateType, Value);
3018 if (!LightStateType && (LightStateType > D3DLIGHTSTATE_COLORVERTEX))
3020 TRACE("Unexpected Light State Type\n");
3021 return DDERR_INVALIDPARAMS;
3024 EnterCriticalSection(&ddraw_cs);
3025 if (LightStateType == D3DLIGHTSTATE_MATERIAL /* 1 */)
3027 IDirect3DMaterialImpl *mat;
3029 if(Value == 0) mat = NULL;
3030 else if(Value > This->numHandles)
3032 ERR("Material handle out of range(%d)\n", Value);
3033 LeaveCriticalSection(&ddraw_cs);
3034 return DDERR_INVALIDPARAMS;
3036 else if(This->Handles[Value - 1].type != DDrawHandle_Material)
3038 ERR("Invalid handle %d\n", Value);
3039 LeaveCriticalSection(&ddraw_cs);
3040 return DDERR_INVALIDPARAMS;
3044 mat = This->Handles[Value - 1].ptr;
3049 TRACE(" activating material %p.\n", mat);
3054 FIXME(" D3DLIGHTSTATE_MATERIAL called with NULL material !!!\n");
3056 This->material = Value;
3058 else if (LightStateType == D3DLIGHTSTATE_COLORMODEL /* 3 */)
3063 ERR("DDCOLOR_MONO should not happen!\n");
3066 /* We are already in this mode */
3067 TRACE("Setting color model to RGB (no-op).\n");
3070 ERR("Unknown color model!\n");
3071 LeaveCriticalSection(&ddraw_cs);
3072 return DDERR_INVALIDPARAMS;
3077 D3DRENDERSTATETYPE rs;
3078 switch (LightStateType)
3080 case D3DLIGHTSTATE_AMBIENT: /* 2 */
3081 rs = D3DRENDERSTATE_AMBIENT;
3083 case D3DLIGHTSTATE_FOGMODE: /* 4 */
3084 rs = D3DRENDERSTATE_FOGVERTEXMODE;
3086 case D3DLIGHTSTATE_FOGSTART: /* 5 */
3087 rs = D3DRENDERSTATE_FOGSTART;
3089 case D3DLIGHTSTATE_FOGEND: /* 6 */
3090 rs = D3DRENDERSTATE_FOGEND;
3092 case D3DLIGHTSTATE_FOGDENSITY: /* 7 */
3093 rs = D3DRENDERSTATE_FOGDENSITY;
3095 case D3DLIGHTSTATE_COLORVERTEX: /* 8 */
3096 rs = D3DRENDERSTATE_COLORVERTEX;
3099 ERR("Unknown D3DLIGHTSTATETYPE %d.\n", LightStateType);
3100 LeaveCriticalSection(&ddraw_cs);
3101 return DDERR_INVALIDPARAMS;
3104 hr = IDirect3DDevice7_SetRenderState(ICOM_INTERFACE(This, IDirect3DDevice7),
3107 LeaveCriticalSection(&ddraw_cs);
3111 LeaveCriticalSection(&ddraw_cs);
3115 static HRESULT WINAPI
3116 Thunk_IDirect3DDeviceImpl_2_SetLightState(IDirect3DDevice2 *iface,
3117 D3DLIGHTSTATETYPE LightStateType,
3120 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
3121 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x) thunking to IDirect3DDevice3 interface.\n", This, LightStateType, Value);
3122 return IDirect3DDevice3_SetLightState(ICOM_INTERFACE(This, IDirect3DDevice3),
3127 /*****************************************************************************
3128 * IDirect3DDevice3::GetLightState
3130 * Returns the current setting of a light state. The state is read from
3131 * the Direct3DDevice7 render state.
3136 * LightStateType: The light state to return
3137 * Value: The address to store the light state setting at
3141 * DDDERR_INVALIDPARAMS if the parameters were incorrect
3142 * Also see IDirect3DDevice7::GetRenderState
3144 *****************************************************************************/
3145 static HRESULT WINAPI
3146 IDirect3DDeviceImpl_3_GetLightState(IDirect3DDevice3 *iface,
3147 D3DLIGHTSTATETYPE LightStateType,
3150 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
3153 TRACE("(%p)->(%08x,%p)\n", This, LightStateType, Value);
3155 if (!LightStateType && (LightStateType > D3DLIGHTSTATE_COLORVERTEX))
3157 TRACE("Unexpected Light State Type\n");
3158 return DDERR_INVALIDPARAMS;
3162 return DDERR_INVALIDPARAMS;
3164 EnterCriticalSection(&ddraw_cs);
3165 if (LightStateType == D3DLIGHTSTATE_MATERIAL /* 1 */)
3167 *Value = This->material;
3169 else if (LightStateType == D3DLIGHTSTATE_COLORMODEL /* 3 */)
3171 *Value = D3DCOLOR_RGB;
3175 D3DRENDERSTATETYPE rs;
3176 switch (LightStateType)
3178 case D3DLIGHTSTATE_AMBIENT: /* 2 */
3179 rs = D3DRENDERSTATE_AMBIENT;
3181 case D3DLIGHTSTATE_FOGMODE: /* 4 */
3182 rs = D3DRENDERSTATE_FOGVERTEXMODE;
3184 case D3DLIGHTSTATE_FOGSTART: /* 5 */
3185 rs = D3DRENDERSTATE_FOGSTART;
3187 case D3DLIGHTSTATE_FOGEND: /* 6 */
3188 rs = D3DRENDERSTATE_FOGEND;
3190 case D3DLIGHTSTATE_FOGDENSITY: /* 7 */
3191 rs = D3DRENDERSTATE_FOGDENSITY;
3193 case D3DLIGHTSTATE_COLORVERTEX: /* 8 */
3194 rs = D3DRENDERSTATE_COLORVERTEX;
3197 ERR("Unknown D3DLIGHTSTATETYPE %d.\n", LightStateType);
3198 LeaveCriticalSection(&ddraw_cs);
3199 return DDERR_INVALIDPARAMS;
3202 hr = IDirect3DDevice7_GetRenderState(ICOM_INTERFACE(This, IDirect3DDevice7),
3205 LeaveCriticalSection(&ddraw_cs);
3209 LeaveCriticalSection(&ddraw_cs);
3213 static HRESULT WINAPI
3214 Thunk_IDirect3DDeviceImpl_2_GetLightState(IDirect3DDevice2 *iface,
3215 D3DLIGHTSTATETYPE LightStateType,
3218 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
3219 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice3 interface.\n", This, LightStateType, Value);
3220 return IDirect3DDevice3_GetLightState(ICOM_INTERFACE(This, IDirect3DDevice3),
3225 /*****************************************************************************
3226 * IDirect3DDevice7::SetTransform
3228 * Assigns a D3DMATRIX to a transform type. The transform types are defined
3229 * in include/d3dtypes.h.
3230 * The D3DTRANSFORMSTATE_WORLD (=1) is translated to D3DTS_WORLDMATRIX(0)
3231 * (=255) for wined3d, because the 1 transform state was removed in d3d8
3232 * and WineD3D already understands the replacement D3DTS_WORLDMATRIX(0)
3234 * Version 2, 3 and 7
3237 * TransformStateType: transform state to set
3238 * Matrix: Matrix to assign to the state
3242 * DDERR_INVALIDPARAMS if Matrix == NULL
3243 * For details see IWineD3DDevice::SetTransform
3245 *****************************************************************************/
3247 IDirect3DDeviceImpl_7_SetTransform(IDirect3DDevice7 *iface,
3248 D3DTRANSFORMSTATETYPE TransformStateType,
3251 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
3252 D3DTRANSFORMSTATETYPE type;
3254 TRACE("(%p)->(%08x,%p): Relay\n", This, TransformStateType, Matrix);
3256 switch(TransformStateType)
3258 case D3DTRANSFORMSTATE_WORLD : type = WINED3DTS_WORLDMATRIX(0); break;
3259 case D3DTRANSFORMSTATE_WORLD1: type = WINED3DTS_WORLDMATRIX(1); break;
3260 case D3DTRANSFORMSTATE_WORLD2: type = WINED3DTS_WORLDMATRIX(2); break;
3261 case D3DTRANSFORMSTATE_WORLD3: type = WINED3DTS_WORLDMATRIX(3); break;
3262 default: type = TransformStateType;
3266 return DDERR_INVALIDPARAMS;
3268 /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
3269 EnterCriticalSection(&ddraw_cs);
3270 hr = IWineD3DDevice_SetTransform(This->wineD3DDevice,
3272 (WINED3DMATRIX*) Matrix);
3273 LeaveCriticalSection(&ddraw_cs);
3277 static HRESULT WINAPI
3278 IDirect3DDeviceImpl_7_SetTransform_FPUSetup(IDirect3DDevice7 *iface,
3279 D3DTRANSFORMSTATETYPE TransformStateType,
3282 return IDirect3DDeviceImpl_7_SetTransform(iface, TransformStateType, Matrix);
3285 static HRESULT WINAPI
3286 IDirect3DDeviceImpl_7_SetTransform_FPUPreserve(IDirect3DDevice7 *iface,
3287 D3DTRANSFORMSTATETYPE TransformStateType,
3293 old_fpucw = d3d_fpu_setup();
3294 hr = IDirect3DDeviceImpl_7_SetTransform(iface, TransformStateType, Matrix);
3295 set_fpu_control_word(old_fpucw);
3300 static HRESULT WINAPI
3301 Thunk_IDirect3DDeviceImpl_3_SetTransform(IDirect3DDevice3 *iface,
3302 D3DTRANSFORMSTATETYPE TransformStateType,
3303 D3DMATRIX *D3DMatrix)
3305 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
3306 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, TransformStateType, D3DMatrix);
3307 return IDirect3DDevice7_SetTransform(ICOM_INTERFACE(This, IDirect3DDevice7),
3312 static HRESULT WINAPI
3313 Thunk_IDirect3DDeviceImpl_2_SetTransform(IDirect3DDevice2 *iface,
3314 D3DTRANSFORMSTATETYPE TransformStateType,
3315 D3DMATRIX *D3DMatrix)
3317 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
3318 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, TransformStateType, D3DMatrix);
3319 return IDirect3DDevice7_SetTransform(ICOM_INTERFACE(This, IDirect3DDevice7),
3324 /*****************************************************************************
3325 * IDirect3DDevice7::GetTransform
3327 * Returns the matrix assigned to a transform state
3328 * D3DTRANSFORMSTATE_WORLD is translated to D3DTS_WORLDMATRIX(0), see
3332 * TransformStateType: State to read the matrix from
3333 * Matrix: Address to store the matrix at
3337 * DDERR_INVALIDPARAMS if Matrix == NULL
3338 * For details, see IWineD3DDevice::GetTransform
3340 *****************************************************************************/
3342 IDirect3DDeviceImpl_7_GetTransform(IDirect3DDevice7 *iface,
3343 D3DTRANSFORMSTATETYPE TransformStateType,
3346 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
3347 D3DTRANSFORMSTATETYPE type;
3349 TRACE("(%p)->(%08x,%p): Relay\n", This, TransformStateType, Matrix);
3351 switch(TransformStateType)
3353 case D3DTRANSFORMSTATE_WORLD : type = WINED3DTS_WORLDMATRIX(0); break;
3354 case D3DTRANSFORMSTATE_WORLD1: type = WINED3DTS_WORLDMATRIX(1); break;
3355 case D3DTRANSFORMSTATE_WORLD2: type = WINED3DTS_WORLDMATRIX(2); break;
3356 case D3DTRANSFORMSTATE_WORLD3: type = WINED3DTS_WORLDMATRIX(3); break;
3357 default: type = TransformStateType;
3361 return DDERR_INVALIDPARAMS;
3363 /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
3364 EnterCriticalSection(&ddraw_cs);
3365 hr = IWineD3DDevice_GetTransform(This->wineD3DDevice, type, (WINED3DMATRIX*) Matrix);
3366 LeaveCriticalSection(&ddraw_cs);
3370 static HRESULT WINAPI
3371 IDirect3DDeviceImpl_7_GetTransform_FPUSetup(IDirect3DDevice7 *iface,
3372 D3DTRANSFORMSTATETYPE TransformStateType,
3375 return IDirect3DDeviceImpl_7_GetTransform(iface, TransformStateType, Matrix);
3378 static HRESULT WINAPI
3379 IDirect3DDeviceImpl_7_GetTransform_FPUPreserve(IDirect3DDevice7 *iface,
3380 D3DTRANSFORMSTATETYPE TransformStateType,
3386 old_fpucw = d3d_fpu_setup();
3387 hr = IDirect3DDeviceImpl_7_GetTransform(iface, TransformStateType, Matrix);
3388 set_fpu_control_word(old_fpucw);
3393 static HRESULT WINAPI
3394 Thunk_IDirect3DDeviceImpl_3_GetTransform(IDirect3DDevice3 *iface,
3395 D3DTRANSFORMSTATETYPE TransformStateType,
3396 D3DMATRIX *D3DMatrix)
3398 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
3399 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, TransformStateType, D3DMatrix);
3400 return IDirect3DDevice7_GetTransform(ICOM_INTERFACE(This, IDirect3DDevice7),
3405 static HRESULT WINAPI
3406 Thunk_IDirect3DDeviceImpl_2_GetTransform(IDirect3DDevice2 *iface,
3407 D3DTRANSFORMSTATETYPE TransformStateType,
3408 D3DMATRIX *D3DMatrix)
3410 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
3411 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, TransformStateType, D3DMatrix);
3412 return IDirect3DDevice7_GetTransform(ICOM_INTERFACE(This, IDirect3DDevice7),
3417 /*****************************************************************************
3418 * IDirect3DDevice7::MultiplyTransform
3420 * Multiplies the already-set transform matrix of a transform state
3421 * with another matrix. For the world matrix, see SetTransform
3423 * Version 2, 3 and 7
3426 * TransformStateType: Transform state to multiply
3427 * D3DMatrix Matrix to multiply with.
3431 * DDERR_INVALIDPARAMS if D3DMatrix is NULL
3432 * For details, see IWineD3DDevice::MultiplyTransform
3434 *****************************************************************************/
3436 IDirect3DDeviceImpl_7_MultiplyTransform(IDirect3DDevice7 *iface,
3437 D3DTRANSFORMSTATETYPE TransformStateType,
3438 D3DMATRIX *D3DMatrix)
3440 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
3442 D3DTRANSFORMSTATETYPE type;
3443 TRACE("(%p)->(%08x,%p): Relay\n", This, TransformStateType, D3DMatrix);
3445 switch(TransformStateType)
3447 case D3DTRANSFORMSTATE_WORLD : type = WINED3DTS_WORLDMATRIX(0); break;
3448 case D3DTRANSFORMSTATE_WORLD1: type = WINED3DTS_WORLDMATRIX(1); break;
3449 case D3DTRANSFORMSTATE_WORLD2: type = WINED3DTS_WORLDMATRIX(2); break;
3450 case D3DTRANSFORMSTATE_WORLD3: type = WINED3DTS_WORLDMATRIX(3); break;
3451 default: type = TransformStateType;
3454 /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
3455 EnterCriticalSection(&ddraw_cs);
3456 hr = IWineD3DDevice_MultiplyTransform(This->wineD3DDevice,
3458 (WINED3DMATRIX*) D3DMatrix);
3459 LeaveCriticalSection(&ddraw_cs);
3463 static HRESULT WINAPI
3464 IDirect3DDeviceImpl_7_MultiplyTransform_FPUSetup(IDirect3DDevice7 *iface,
3465 D3DTRANSFORMSTATETYPE TransformStateType,
3466 D3DMATRIX *D3DMatrix)
3468 return IDirect3DDeviceImpl_7_MultiplyTransform(iface, TransformStateType, D3DMatrix);
3471 static HRESULT WINAPI
3472 IDirect3DDeviceImpl_7_MultiplyTransform_FPUPreserve(IDirect3DDevice7 *iface,
3473 D3DTRANSFORMSTATETYPE TransformStateType,
3474 D3DMATRIX *D3DMatrix)
3479 old_fpucw = d3d_fpu_setup();
3480 hr = IDirect3DDeviceImpl_7_MultiplyTransform(iface, TransformStateType, D3DMatrix);
3481 set_fpu_control_word(old_fpucw);
3486 static HRESULT WINAPI
3487 Thunk_IDirect3DDeviceImpl_3_MultiplyTransform(IDirect3DDevice3 *iface,
3488 D3DTRANSFORMSTATETYPE TransformStateType,
3489 D3DMATRIX *D3DMatrix)
3491 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
3492 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, TransformStateType, D3DMatrix);
3493 return IDirect3DDevice7_MultiplyTransform(ICOM_INTERFACE(This, IDirect3DDevice7),
3498 static HRESULT WINAPI
3499 Thunk_IDirect3DDeviceImpl_2_MultiplyTransform(IDirect3DDevice2 *iface,
3500 D3DTRANSFORMSTATETYPE TransformStateType,
3501 D3DMATRIX *D3DMatrix)
3503 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
3504 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, TransformStateType, D3DMatrix);
3505 return IDirect3DDevice7_MultiplyTransform(ICOM_INTERFACE(This, IDirect3DDevice7),
3510 /*****************************************************************************
3511 * IDirect3DDevice7::DrawPrimitive
3513 * Draws primitives based on vertices in an application-provided pointer
3515 * Version 2, 3 and 7. The IDirect3DDevice2 thunk converts the fixed vertex type into
3516 * an FVF format for D3D7
3519 * PrimitiveType: The type of the primitives to draw
3520 * Vertex type: Flexible vertex format vertex description
3521 * Vertices: Pointer to the vertex array
3522 * VertexCount: The number of vertices to draw
3523 * Flags: As usual a few flags
3527 * DDERR_INVALIDPARAMS if Vertices is NULL
3528 * For details, see IWineD3DDevice::DrawPrimitiveUP
3530 *****************************************************************************/
3532 IDirect3DDeviceImpl_7_DrawPrimitive(IDirect3DDevice7 *iface,
3533 D3DPRIMITIVETYPE PrimitiveType,
3539 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
3540 UINT PrimitiveCount, stride;
3542 TRACE("(%p)->(%08x,%08x,%p,%08x,%08x): Relay!\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Flags);
3545 return DDERR_INVALIDPARAMS;
3547 /* Get the vertex count */
3548 switch(PrimitiveType)
3550 case D3DPT_POINTLIST:
3551 PrimitiveCount = VertexCount;
3554 case D3DPT_LINELIST:
3555 PrimitiveCount = VertexCount / 2;
3558 case D3DPT_LINESTRIP:
3559 PrimitiveCount = VertexCount - 1;
3562 case D3DPT_TRIANGLELIST:
3563 PrimitiveCount = VertexCount / 3;
3566 case D3DPT_TRIANGLESTRIP:
3567 PrimitiveCount = VertexCount - 2;
3570 case D3DPT_TRIANGLEFAN:
3571 PrimitiveCount = VertexCount - 2;
3575 return DDERR_INVALIDPARAMS;
3578 /* Get the stride */
3579 stride = get_flexible_vertex_size(VertexType);
3582 EnterCriticalSection(&ddraw_cs);
3583 hr = IWineD3DDevice_SetVertexDeclaration(This->wineD3DDevice,
3584 IDirectDrawImpl_FindDecl(This->ddraw, VertexType));
3587 LeaveCriticalSection(&ddraw_cs);
3591 /* This method translates to the user pointer draw of WineD3D */
3592 hr = IWineD3DDevice_DrawPrimitiveUP(This->wineD3DDevice,
3597 LeaveCriticalSection(&ddraw_cs);
3601 static HRESULT WINAPI
3602 IDirect3DDeviceImpl_7_DrawPrimitive_FPUSetup(IDirect3DDevice7 *iface,
3603 D3DPRIMITIVETYPE PrimitiveType,
3609 return IDirect3DDeviceImpl_7_DrawPrimitive(iface, PrimitiveType, VertexType, Vertices, VertexCount, Flags);
3612 static HRESULT WINAPI
3613 IDirect3DDeviceImpl_7_DrawPrimitive_FPUPreserve(IDirect3DDevice7 *iface,
3614 D3DPRIMITIVETYPE PrimitiveType,
3623 old_fpucw = d3d_fpu_setup();
3624 hr = IDirect3DDeviceImpl_7_DrawPrimitive(iface, PrimitiveType, VertexType, Vertices, VertexCount, Flags);
3625 set_fpu_control_word(old_fpucw);
3630 static HRESULT WINAPI
3631 Thunk_IDirect3DDeviceImpl_3_DrawPrimitive(IDirect3DDevice3 *iface,
3632 D3DPRIMITIVETYPE PrimitiveType,
3638 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
3639 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Flags);
3640 return IDirect3DDevice7_DrawPrimitive(ICOM_INTERFACE(This, IDirect3DDevice7),
3648 static HRESULT WINAPI
3649 Thunk_IDirect3DDeviceImpl_2_DrawPrimitive(IDirect3DDevice2 *iface,
3650 D3DPRIMITIVETYPE PrimitiveType,
3651 D3DVERTEXTYPE VertexType,
3656 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
3658 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Flags);
3662 case D3DVT_VERTEX: FVF = D3DFVF_VERTEX; break;
3663 case D3DVT_LVERTEX: FVF = D3DFVF_LVERTEX; break;
3664 case D3DVT_TLVERTEX: FVF = D3DFVF_TLVERTEX; break;
3666 ERR("Unexpected vertex type %d\n", VertexType);
3667 return DDERR_INVALIDPARAMS; /* Should never happen */
3670 return IDirect3DDevice7_DrawPrimitive(ICOM_INTERFACE(This, IDirect3DDevice7),
3678 /*****************************************************************************
3679 * IDirect3DDevice7::DrawIndexedPrimitive
3681 * Draws vertices from an application-provided pointer, based on the index
3682 * numbers in a WORD array.
3684 * Version 2, 3 and 7. The version 7 thunk translates the vertex type into
3685 * an FVF format for D3D7
3688 * PrimitiveType: The primitive type to draw
3689 * VertexType: The FVF vertex description
3690 * Vertices: Pointer to the vertex array
3692 * Indices: Pointer to the index array
3693 * IndexCount: Number of indices = Number of vertices to draw
3694 * Flags: As usual, some flags
3698 * DDERR_INVALIDPARAMS if Vertices or Indices is NULL
3699 * For details, see IWineD3DDevice::DrawIndexedPrimitiveUP
3701 *****************************************************************************/
3703 IDirect3DDeviceImpl_7_DrawIndexedPrimitive(IDirect3DDevice7 *iface,
3704 D3DPRIMITIVETYPE PrimitiveType,
3712 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
3713 UINT PrimitiveCount = 0;
3715 TRACE("(%p)->(%08x,%08x,%p,%08x,%p,%08x,%08x): Relay!\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Indices, IndexCount, Flags);
3717 /* Get the primitive number */
3718 switch(PrimitiveType)
3720 case D3DPT_POINTLIST:
3721 PrimitiveCount = IndexCount;
3724 case D3DPT_LINELIST:
3725 PrimitiveCount = IndexCount / 2;
3728 case D3DPT_LINESTRIP:
3729 PrimitiveCount = IndexCount - 1;
3732 case D3DPT_TRIANGLELIST:
3733 PrimitiveCount = IndexCount / 3;
3736 case D3DPT_TRIANGLESTRIP:
3737 PrimitiveCount = IndexCount - 2;
3740 case D3DPT_TRIANGLEFAN:
3741 PrimitiveCount = IndexCount - 2;
3745 return DDERR_INVALIDPARAMS;
3748 /* Set the D3DDevice's FVF */
3749 EnterCriticalSection(&ddraw_cs);
3750 hr = IWineD3DDevice_SetVertexDeclaration(This->wineD3DDevice,
3751 IDirectDrawImpl_FindDecl(This->ddraw, VertexType));
3754 ERR(" (%p) Setting the FVF failed, hr = %x!\n", This, hr);
3755 LeaveCriticalSection(&ddraw_cs);
3759 hr = IWineD3DDevice_DrawIndexedPrimitiveUP(This->wineD3DDevice,
3761 0 /* MinVertexIndex */,
3762 VertexCount /* UINT NumVertexIndex */,
3767 get_flexible_vertex_size(VertexType));
3768 LeaveCriticalSection(&ddraw_cs);
3772 static HRESULT WINAPI
3773 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUSetup(IDirect3DDevice7 *iface,
3774 D3DPRIMITIVETYPE PrimitiveType,
3782 return IDirect3DDeviceImpl_7_DrawIndexedPrimitive(iface, PrimitiveType, VertexType, Vertices, VertexCount, Indices, IndexCount, Flags);
3785 static HRESULT WINAPI
3786 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUPreserve(IDirect3DDevice7 *iface,
3787 D3DPRIMITIVETYPE PrimitiveType,
3798 old_fpucw = d3d_fpu_setup();
3799 hr = IDirect3DDeviceImpl_7_DrawIndexedPrimitive(iface, PrimitiveType, VertexType, Vertices, VertexCount, Indices, IndexCount, Flags);
3800 set_fpu_control_word(old_fpucw);
3805 static HRESULT WINAPI
3806 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitive(IDirect3DDevice3 *iface,
3807 D3DPRIMITIVETYPE PrimitiveType,
3815 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
3816 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Indices, IndexCount, Flags);
3817 return IDirect3DDevice7_DrawIndexedPrimitive(ICOM_INTERFACE(This, IDirect3DDevice7),
3827 static HRESULT WINAPI
3828 Thunk_IDirect3DDeviceImpl_2_DrawIndexedPrimitive(IDirect3DDevice2 *iface,
3829 D3DPRIMITIVETYPE PrimitiveType,
3830 D3DVERTEXTYPE VertexType,
3838 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
3839 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Indices, IndexCount, Flags);
3843 case D3DVT_VERTEX: FVF = D3DFVF_VERTEX; break;
3844 case D3DVT_LVERTEX: FVF = D3DFVF_LVERTEX; break;
3845 case D3DVT_TLVERTEX: FVF = D3DFVF_TLVERTEX; break;
3847 ERR("Unexpected vertex type %d\n", VertexType);
3848 return DDERR_INVALIDPARAMS; /* Should never happen */
3851 return IDirect3DDevice7_DrawIndexedPrimitive(ICOM_INTERFACE(This, IDirect3DDevice7),
3861 /*****************************************************************************
3862 * IDirect3DDevice7::SetClipStatus
3864 * Sets the clip status. This defines things as clipping conditions and
3865 * the extents of the clipping region.
3867 * Version 2, 3 and 7
3873 * D3D_OK because it's a stub
3874 * (DDERR_INVALIDPARAMS if ClipStatus == NULL)
3876 *****************************************************************************/
3877 static HRESULT WINAPI
3878 IDirect3DDeviceImpl_7_SetClipStatus(IDirect3DDevice7 *iface,
3879 D3DCLIPSTATUS *ClipStatus)
3881 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
3882 FIXME("(%p)->(%p): Stub!\n", This, ClipStatus);
3884 /* D3DCLIPSTATUS and WINED3DCLIPSTATUS are different. I don't know how to convert them
3885 * Perhaps this needs a new data type and an additional IWineD3DDevice method
3887 /* return IWineD3DDevice_SetClipStatus(This->wineD3DDevice, ClipStatus);*/
3891 static HRESULT WINAPI
3892 Thunk_IDirect3DDeviceImpl_3_SetClipStatus(IDirect3DDevice3 *iface,
3893 D3DCLIPSTATUS *ClipStatus)
3895 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
3896 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, ClipStatus);
3897 return IDirect3DDevice7_SetClipStatus(ICOM_INTERFACE(This, IDirect3DDevice7),
3901 static HRESULT WINAPI
3902 Thunk_IDirect3DDeviceImpl_2_SetClipStatus(IDirect3DDevice2 *iface,
3903 D3DCLIPSTATUS *ClipStatus)
3905 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
3906 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, ClipStatus);
3907 return IDirect3DDevice7_SetClipStatus(ICOM_INTERFACE(This, IDirect3DDevice7),
3911 /*****************************************************************************
3912 * IDirect3DDevice7::GetClipStatus
3914 * Returns the clip status
3917 * ClipStatus: Address to write the clip status to
3920 * D3D_OK because it's a stub
3922 *****************************************************************************/
3923 static HRESULT WINAPI
3924 IDirect3DDeviceImpl_7_GetClipStatus(IDirect3DDevice7 *iface,
3925 D3DCLIPSTATUS *ClipStatus)
3927 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
3928 FIXME("(%p)->(%p): Stub!\n", This, ClipStatus);
3930 /* D3DCLIPSTATUS and WINED3DCLIPSTATUS are different. I don't know how to convert them */
3931 /* return IWineD3DDevice_GetClipStatus(This->wineD3DDevice, ClipStatus);*/
3935 static HRESULT WINAPI
3936 Thunk_IDirect3DDeviceImpl_3_GetClipStatus(IDirect3DDevice3 *iface,
3937 D3DCLIPSTATUS *ClipStatus)
3939 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
3940 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, ClipStatus);
3941 return IDirect3DDevice7_GetClipStatus(ICOM_INTERFACE(This, IDirect3DDevice7),
3945 static HRESULT WINAPI
3946 Thunk_IDirect3DDeviceImpl_2_GetClipStatus(IDirect3DDevice2 *iface,
3947 D3DCLIPSTATUS *ClipStatus)
3949 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
3950 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, ClipStatus);
3951 return IDirect3DDevice7_GetClipStatus(ICOM_INTERFACE(This, IDirect3DDevice7),
3955 /*****************************************************************************
3956 * IDirect3DDevice::DrawPrimitiveStrided
3958 * Draws vertices described by a D3DDRAWPRIMITIVESTRIDEDDATA structure.
3963 * PrimitiveType: The primitive type to draw
3964 * VertexType: The FVF description of the vertices to draw (for the stride??)
3965 * D3DDrawPrimStrideData: A D3DDRAWPRIMITIVESTRIDEDDATA structure describing
3966 * the vertex data locations
3967 * VertexCount: The number of vertices to draw
3971 * D3D_OK, because it's a stub
3972 * (DDERR_INVALIDPARAMS if D3DDrawPrimStrideData is NULL)
3973 * (For details, see IWineD3DDevice::DrawPrimitiveStrided)
3975 *****************************************************************************/
3977 IDirect3DDeviceImpl_7_DrawPrimitiveStrided(IDirect3DDevice7 *iface,
3978 D3DPRIMITIVETYPE PrimitiveType,
3980 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
3984 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
3985 WineDirect3DVertexStridedData WineD3DStrided;
3987 UINT PrimitiveCount;
3990 TRACE("(%p)->(%08x,%08x,%p,%08x,%08x): stub!\n", This, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Flags);
3992 memset(&WineD3DStrided, 0, sizeof(WineD3DStrided));
3993 /* Get the strided data right. the wined3d structure is a bit bigger
3994 * Watch out: The contents of the strided data are determined by the fvf,
3995 * not by the members set in D3DDrawPrimStrideData. So it's valid
3996 * to have diffuse.lpvData set to 0xdeadbeef if the diffuse flag is
3997 * not set in the fvf.
3999 if(VertexType & D3DFVF_POSITION_MASK)
4001 WineD3DStrided.u.s.position.lpData = D3DDrawPrimStrideData->position.lpvData;
4002 WineD3DStrided.u.s.position.dwStride = D3DDrawPrimStrideData->position.dwStride;
4003 WineD3DStrided.u.s.position.dwType = WINED3DDECLTYPE_FLOAT3;
4004 if (VertexType & D3DFVF_XYZRHW)
4006 WineD3DStrided.u.s.position.dwType = WINED3DDECLTYPE_FLOAT4;
4007 WineD3DStrided.position_transformed = TRUE;
4009 WineD3DStrided.position_transformed = FALSE;
4012 if(VertexType & D3DFVF_NORMAL)
4014 WineD3DStrided.u.s.normal.lpData = D3DDrawPrimStrideData->normal.lpvData;
4015 WineD3DStrided.u.s.normal.dwStride = D3DDrawPrimStrideData->normal.dwStride;
4016 WineD3DStrided.u.s.normal.dwType = WINED3DDECLTYPE_FLOAT3;
4019 if(VertexType & D3DFVF_DIFFUSE)
4021 WineD3DStrided.u.s.diffuse.lpData = D3DDrawPrimStrideData->diffuse.lpvData;
4022 WineD3DStrided.u.s.diffuse.dwStride = D3DDrawPrimStrideData->diffuse.dwStride;
4023 WineD3DStrided.u.s.diffuse.dwType = WINED3DDECLTYPE_D3DCOLOR;
4026 if(VertexType & D3DFVF_SPECULAR)
4028 WineD3DStrided.u.s.specular.lpData = D3DDrawPrimStrideData->specular.lpvData;
4029 WineD3DStrided.u.s.specular.dwStride = D3DDrawPrimStrideData->specular.dwStride;
4030 WineD3DStrided.u.s.specular.dwType = WINED3DDECLTYPE_D3DCOLOR;
4033 for( i = 0; i < GET_TEXCOUNT_FROM_FVF(VertexType); i++)
4035 WineD3DStrided.u.s.texCoords[i].lpData = D3DDrawPrimStrideData->textureCoords[i].lpvData;
4036 WineD3DStrided.u.s.texCoords[i].dwStride = D3DDrawPrimStrideData->textureCoords[i].dwStride;
4037 switch(GET_TEXCOORD_SIZE_FROM_FVF(VertexType, i))
4039 case 1: WineD3DStrided.u.s.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT1; break;
4040 case 2: WineD3DStrided.u.s.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT2; break;
4041 case 3: WineD3DStrided.u.s.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT3; break;
4042 case 4: WineD3DStrided.u.s.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT4; break;
4043 default: ERR("Unexpected texture coordinate size %d\n",
4044 GET_TEXCOORD_SIZE_FROM_FVF(VertexType, i));
4048 /* Get the primitive count */
4049 switch(PrimitiveType)
4051 case D3DPT_POINTLIST:
4052 PrimitiveCount = VertexCount;
4055 case D3DPT_LINELIST:
4056 PrimitiveCount = VertexCount / 2;
4059 case D3DPT_LINESTRIP:
4060 PrimitiveCount = VertexCount - 1;
4063 case D3DPT_TRIANGLELIST:
4064 PrimitiveCount = VertexCount / 3;
4067 case D3DPT_TRIANGLESTRIP:
4068 PrimitiveCount = VertexCount - 2;
4071 case D3DPT_TRIANGLEFAN:
4072 PrimitiveCount = VertexCount - 2;
4075 default: return DDERR_INVALIDPARAMS;
4078 /* WineD3D doesn't need the FVF here */
4079 EnterCriticalSection(&ddraw_cs);
4080 hr = IWineD3DDevice_DrawPrimitiveStrided(This->wineD3DDevice,
4084 LeaveCriticalSection(&ddraw_cs);
4088 static HRESULT WINAPI
4089 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUSetup(IDirect3DDevice7 *iface,
4090 D3DPRIMITIVETYPE PrimitiveType,
4092 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
4096 return IDirect3DDeviceImpl_7_DrawPrimitiveStrided(iface, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Flags);
4099 static HRESULT WINAPI
4100 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUPreserve(IDirect3DDevice7 *iface,
4101 D3DPRIMITIVETYPE PrimitiveType,
4103 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
4110 old_fpucw = d3d_fpu_setup();
4111 hr = IDirect3DDeviceImpl_7_DrawPrimitiveStrided(iface, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Flags);
4112 set_fpu_control_word(old_fpucw);
4117 static HRESULT WINAPI
4118 Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveStrided(IDirect3DDevice3 *iface,
4119 D3DPRIMITIVETYPE PrimitiveType,
4121 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
4125 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
4126 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Flags);
4127 return IDirect3DDevice7_DrawPrimitiveStrided(ICOM_INTERFACE(This, IDirect3DDevice7),
4130 D3DDrawPrimStrideData,
4135 /*****************************************************************************
4136 * IDirect3DDevice7::DrawIndexedPrimitiveStrided
4138 * Draws primitives specified by strided data locations based on indices
4146 * D3D_OK, because it's a stub
4147 * (DDERR_INVALIDPARAMS if D3DDrawPrimStrideData is NULL)
4148 * (DDERR_INVALIDPARAMS if Indices is NULL)
4149 * (For more details, see IWineD3DDevice::DrawIndexedPrimitiveStrided)
4151 *****************************************************************************/
4153 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided(IDirect3DDevice7 *iface,
4154 D3DPRIMITIVETYPE PrimitiveType,
4156 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
4162 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4163 WineDirect3DVertexStridedData WineD3DStrided;
4165 UINT PrimitiveCount;
4168 TRACE("(%p)->(%08x,%08x,%p,%08x,%p,%08x,%08x)\n", This, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Indices, IndexCount, Flags);
4170 memset(&WineD3DStrided, 0, sizeof(WineD3DStrided));
4171 /* Get the strided data right. the wined3d structure is a bit bigger
4172 * Watch out: The contents of the strided data are determined by the fvf,
4173 * not by the members set in D3DDrawPrimStrideData. So it's valid
4174 * to have diffuse.lpvData set to 0xdeadbeef if the diffuse flag is
4175 * not set in the fvf.
4177 if(VertexType & D3DFVF_POSITION_MASK)
4179 WineD3DStrided.u.s.position.lpData = D3DDrawPrimStrideData->position.lpvData;
4180 WineD3DStrided.u.s.position.dwStride = D3DDrawPrimStrideData->position.dwStride;
4181 WineD3DStrided.u.s.position.dwType = WINED3DDECLTYPE_FLOAT3;
4182 if (VertexType & D3DFVF_XYZRHW)
4184 WineD3DStrided.u.s.position.dwType = WINED3DDECLTYPE_FLOAT4;
4185 WineD3DStrided.position_transformed = TRUE;
4187 WineD3DStrided.position_transformed = FALSE;
4190 if(VertexType & D3DFVF_NORMAL)
4192 WineD3DStrided.u.s.normal.lpData = D3DDrawPrimStrideData->normal.lpvData;
4193 WineD3DStrided.u.s.normal.dwStride = D3DDrawPrimStrideData->normal.dwStride;
4194 WineD3DStrided.u.s.normal.dwType = WINED3DDECLTYPE_FLOAT3;
4197 if(VertexType & D3DFVF_DIFFUSE)
4199 WineD3DStrided.u.s.diffuse.lpData = D3DDrawPrimStrideData->diffuse.lpvData;
4200 WineD3DStrided.u.s.diffuse.dwStride = D3DDrawPrimStrideData->diffuse.dwStride;
4201 WineD3DStrided.u.s.diffuse.dwType = WINED3DDECLTYPE_D3DCOLOR;
4204 if(VertexType & D3DFVF_SPECULAR)
4206 WineD3DStrided.u.s.specular.lpData = D3DDrawPrimStrideData->specular.lpvData;
4207 WineD3DStrided.u.s.specular.dwStride = D3DDrawPrimStrideData->specular.dwStride;
4208 WineD3DStrided.u.s.specular.dwType = WINED3DDECLTYPE_D3DCOLOR;
4211 for( i = 0; i < GET_TEXCOUNT_FROM_FVF(VertexType); i++)
4213 WineD3DStrided.u.s.texCoords[i].lpData = D3DDrawPrimStrideData->textureCoords[i].lpvData;
4214 WineD3DStrided.u.s.texCoords[i].dwStride = D3DDrawPrimStrideData->textureCoords[i].dwStride;
4215 switch(GET_TEXCOORD_SIZE_FROM_FVF(VertexType, i))
4217 case 1: WineD3DStrided.u.s.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT1; break;
4218 case 2: WineD3DStrided.u.s.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT2; break;
4219 case 3: WineD3DStrided.u.s.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT3; break;
4220 case 4: WineD3DStrided.u.s.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT4; break;
4221 default: ERR("Unexpected texture coordinate size %d\n",
4222 GET_TEXCOORD_SIZE_FROM_FVF(VertexType, i));
4226 /* Get the primitive count */
4227 switch(PrimitiveType)
4229 case D3DPT_POINTLIST:
4230 PrimitiveCount = IndexCount;
4233 case D3DPT_LINELIST:
4234 PrimitiveCount = IndexCount / 2;
4237 case D3DPT_LINESTRIP:
4238 PrimitiveCount = IndexCount - 1;
4241 case D3DPT_TRIANGLELIST:
4242 PrimitiveCount = IndexCount / 3;
4245 case D3DPT_TRIANGLESTRIP:
4246 PrimitiveCount = IndexCount - 2;
4249 case D3DPT_TRIANGLEFAN:
4250 PrimitiveCount = IndexCount - 2;
4253 default: return DDERR_INVALIDPARAMS;
4256 /* WineD3D doesn't need the FVF here */
4257 EnterCriticalSection(&ddraw_cs);
4258 hr = IWineD3DDevice_DrawIndexedPrimitiveStrided(This->wineD3DDevice,
4264 WINED3DFMT_INDEX16);
4265 LeaveCriticalSection(&ddraw_cs);
4269 static HRESULT WINAPI
4270 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUSetup(IDirect3DDevice7 *iface,
4271 D3DPRIMITIVETYPE PrimitiveType,
4273 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
4279 return IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided(iface, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Indices, IndexCount, Flags);
4282 static HRESULT WINAPI
4283 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUPreserve(IDirect3DDevice7 *iface,
4284 D3DPRIMITIVETYPE PrimitiveType,
4286 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
4295 old_fpucw = d3d_fpu_setup();
4296 hr = IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided(iface, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Indices, IndexCount, Flags);
4297 set_fpu_control_word(old_fpucw);
4302 static HRESULT WINAPI
4303 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveStrided(IDirect3DDevice3 *iface,
4304 D3DPRIMITIVETYPE PrimitiveType,
4306 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
4312 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
4313 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", iface, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Indices, IndexCount, Flags);
4314 return IDirect3DDevice7_DrawIndexedPrimitiveStrided(ICOM_INTERFACE(This, IDirect3DDevice7),
4317 D3DDrawPrimStrideData,
4324 /*****************************************************************************
4325 * IDirect3DDevice7::DrawPrimitiveVB
4327 * Draws primitives from a vertex buffer to the screen.
4332 * PrimitiveType: Type of primitive to be rendered.
4333 * D3DVertexBuf: Source Vertex Buffer
4334 * StartVertex: Index of the first vertex from the buffer to be rendered
4335 * NumVertices: Number of vertices to be rendered
4336 * Flags: Can be D3DDP_WAIT to wait until rendering has finished
4340 * DDERR_INVALIDPARAMS if D3DVertexBuf is NULL
4342 *****************************************************************************/
4344 IDirect3DDeviceImpl_7_DrawPrimitiveVB(IDirect3DDevice7 *iface,
4345 D3DPRIMITIVETYPE PrimitiveType,
4346 IDirect3DVertexBuffer7 *D3DVertexBuf,
4351 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4352 IDirect3DVertexBufferImpl *vb = ICOM_OBJECT(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, D3DVertexBuf);
4353 UINT PrimitiveCount;
4356 WINED3DVERTEXBUFFER_DESC Desc;
4358 TRACE("(%p)->(%08x,%p,%08x,%08x,%08x)\n", This, PrimitiveType, D3DVertexBuf, StartVertex, NumVertices, Flags);
4363 ERR("(%p) No Vertex buffer specified\n", This);
4364 return DDERR_INVALIDPARAMS;
4367 /* Get the primitive count */
4368 switch(PrimitiveType)
4370 case D3DPT_POINTLIST:
4371 PrimitiveCount = NumVertices;
4374 case D3DPT_LINELIST:
4375 PrimitiveCount = NumVertices / 2;
4378 case D3DPT_LINESTRIP:
4379 PrimitiveCount = NumVertices - 1;
4382 case D3DPT_TRIANGLELIST:
4383 PrimitiveCount = NumVertices / 3;
4386 case D3DPT_TRIANGLESTRIP:
4387 PrimitiveCount = NumVertices - 2;
4390 case D3DPT_TRIANGLEFAN:
4391 PrimitiveCount = NumVertices - 2;
4395 return DDERR_INVALIDPARAMS;
4398 /* Get the FVF of the vertex buffer, and its stride */
4399 EnterCriticalSection(&ddraw_cs);
4400 hr = IWineD3DVertexBuffer_GetDesc(vb->wineD3DVertexBuffer,
4404 ERR("(%p) IWineD3DVertexBuffer::GetDesc failed with hr = %08x\n", This, hr);
4405 LeaveCriticalSection(&ddraw_cs);
4408 stride = get_flexible_vertex_size(Desc.FVF);
4410 hr = IWineD3DDevice_SetVertexDeclaration(This->wineD3DDevice,
4411 vb->wineD3DVertexDeclaration);
4414 ERR(" (%p) Setting the FVF failed, hr = %x!\n", This, hr);
4415 LeaveCriticalSection(&ddraw_cs);
4419 /* Set the vertex stream source */
4420 hr = IWineD3DDevice_SetStreamSource(This->wineD3DDevice,
4421 0 /* StreamNumber */,
4422 vb->wineD3DVertexBuffer,
4423 0 /* StartVertex - we pass this to DrawPrimitive */,
4427 ERR("(%p) IDirect3DDevice::SetStreamSource failed with hr = %08x\n", This, hr);
4428 LeaveCriticalSection(&ddraw_cs);
4432 /* Now draw the primitives */
4433 hr = IWineD3DDevice_DrawPrimitive(This->wineD3DDevice,
4437 LeaveCriticalSection(&ddraw_cs);
4441 static HRESULT WINAPI
4442 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUSetup(IDirect3DDevice7 *iface,
4443 D3DPRIMITIVETYPE PrimitiveType,
4444 IDirect3DVertexBuffer7 *D3DVertexBuf,
4449 return IDirect3DDeviceImpl_7_DrawPrimitiveVB(iface, PrimitiveType, D3DVertexBuf, StartVertex, NumVertices, Flags);
4452 static HRESULT WINAPI
4453 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUPreserve(IDirect3DDevice7 *iface,
4454 D3DPRIMITIVETYPE PrimitiveType,
4455 IDirect3DVertexBuffer7 *D3DVertexBuf,
4463 old_fpucw = d3d_fpu_setup();
4464 hr = IDirect3DDeviceImpl_7_DrawPrimitiveVB(iface, PrimitiveType, D3DVertexBuf, StartVertex, NumVertices, Flags);
4465 set_fpu_control_word(old_fpucw);
4470 static HRESULT WINAPI
4471 Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveVB(IDirect3DDevice3 *iface,
4472 D3DPRIMITIVETYPE PrimitiveType,
4473 IDirect3DVertexBuffer *D3DVertexBuf,
4478 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
4479 IDirect3DVertexBufferImpl *vb = ICOM_OBJECT(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, D3DVertexBuf);
4480 TRACE_(ddraw_thunk)("(%p)->(%08x,%p,%08x,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, vb, StartVertex, NumVertices, Flags);
4481 return IDirect3DDevice7_DrawPrimitiveVB(ICOM_INTERFACE(This, IDirect3DDevice7),
4483 ICOM_INTERFACE(vb, IDirect3DVertexBuffer7),
4490 /*****************************************************************************
4491 * IDirect3DDevice7::DrawIndexedPrimitiveVB
4493 * Draws primitives from a vertex buffer to the screen
4496 * PrimitiveType: Type of primitive to be rendered.
4497 * D3DVertexBuf: Source Vertex Buffer
4498 * StartVertex: Index of the first vertex from the buffer to be rendered
4499 * NumVertices: Number of vertices to be rendered
4500 * Indices: Array of DWORDs used to index into the Vertices
4501 * IndexCount: Number of indices in Indices
4502 * Flags: Can be D3DDP_WAIT to wait until rendering has finished
4506 *****************************************************************************/
4508 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB(IDirect3DDevice7 *iface,
4509 D3DPRIMITIVETYPE PrimitiveType,
4510 IDirect3DVertexBuffer7 *D3DVertexBuf,
4517 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4518 IDirect3DVertexBufferImpl *vb = ICOM_OBJECT(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, D3DVertexBuf);
4520 UINT PrimitiveCount;
4521 WORD *LockedIndices;
4523 WINED3DVERTEXBUFFER_DESC Desc;
4525 TRACE("(%p)->(%08x,%p,%d,%d,%p,%d,%08x)\n", This, PrimitiveType, vb, StartVertex, NumVertices, Indices, IndexCount, Flags);
4528 * 1) Calculate some things: Vertex count -> Primitive count, stride, ...
4529 * 2) Upload the Indices to the index buffer
4530 * 3) Set the index source
4531 * 4) Set the Vertex Buffer as the Stream source
4532 * 5) Call IWineD3DDevice::DrawIndexedPrimitive
4535 /* Get the primitive count */
4536 switch(PrimitiveType)
4538 case D3DPT_POINTLIST:
4539 PrimitiveCount = IndexCount;
4542 case D3DPT_LINELIST:
4543 PrimitiveCount = IndexCount / 2;
4546 case D3DPT_LINESTRIP:
4547 PrimitiveCount = IndexCount - 1;
4550 case D3DPT_TRIANGLELIST:
4551 PrimitiveCount = IndexCount / 3;
4554 case D3DPT_TRIANGLESTRIP:
4555 PrimitiveCount = IndexCount - 2;
4558 case D3DPT_TRIANGLEFAN:
4559 PrimitiveCount = IndexCount - 2;
4562 default: return DDERR_INVALIDPARAMS;
4565 EnterCriticalSection(&ddraw_cs);
4566 /* Get the FVF of the vertex buffer, and its stride */
4567 hr = IWineD3DVertexBuffer_GetDesc(vb->wineD3DVertexBuffer,
4571 ERR("(%p) IWineD3DVertexBuffer::GetDesc failed with hr = %08x\n", This, hr);
4572 LeaveCriticalSection(&ddraw_cs);
4575 stride = get_flexible_vertex_size(Desc.FVF);
4576 TRACE("Vertex buffer FVF = %08x, stride=%d\n", Desc.FVF, stride);
4578 hr = IWineD3DDevice_SetVertexDeclaration(This->wineD3DDevice,
4579 vb->wineD3DVertexDeclaration);
4582 ERR(" (%p) Setting the FVF failed, hr = %x!\n", This, hr);
4583 LeaveCriticalSection(&ddraw_cs);
4587 /* copy the index stream into the index buffer.
4588 * A new IWineD3DDevice method could be created
4589 * which takes an user pointer containing the indices
4590 * or a SetData-Method for the index buffer, which
4591 * overrides the index buffer data with our pointer.
4593 hr = IWineD3DIndexBuffer_Lock(This->indexbuffer,
4594 0 /* OffSetToLock */,
4595 IndexCount * sizeof(WORD),
4596 (BYTE **) &LockedIndices,
4598 assert(IndexCount < 0x100000);
4601 ERR("(%p) IWineD3DIndexBuffer::Lock failed with hr = %08x\n", This, hr);
4602 LeaveCriticalSection(&ddraw_cs);
4605 memcpy(LockedIndices, Indices, IndexCount * sizeof(WORD));
4606 hr = IWineD3DIndexBuffer_Unlock(This->indexbuffer);
4609 ERR("(%p) IWineD3DIndexBuffer::Unlock failed with hr = %08x\n", This, hr);
4610 LeaveCriticalSection(&ddraw_cs);
4614 /* Set the index stream */
4615 IWineD3DDevice_SetBaseVertexIndex(This->wineD3DDevice, StartVertex);
4616 hr = IWineD3DDevice_SetIndices(This->wineD3DDevice, This->indexbuffer);
4618 /* Set the vertex stream source */
4619 hr = IWineD3DDevice_SetStreamSource(This->wineD3DDevice,
4620 0 /* StreamNumber */,
4621 vb->wineD3DVertexBuffer,
4622 0 /* offset, we pass this to DrawIndexedPrimitive */,
4626 ERR("(%p) IDirect3DDevice::SetStreamSource failed with hr = %08x\n", This, hr);
4627 LeaveCriticalSection(&ddraw_cs);
4632 hr = IWineD3DDevice_DrawIndexedPrimitive(This->wineD3DDevice,
4639 LeaveCriticalSection(&ddraw_cs);
4643 static HRESULT WINAPI
4644 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUSetup(IDirect3DDevice7 *iface,
4645 D3DPRIMITIVETYPE PrimitiveType,
4646 IDirect3DVertexBuffer7 *D3DVertexBuf,
4653 return IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB(iface, PrimitiveType, D3DVertexBuf, StartVertex, NumVertices, Indices, IndexCount, Flags);
4656 static HRESULT WINAPI
4657 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUPreserve(IDirect3DDevice7 *iface,
4658 D3DPRIMITIVETYPE PrimitiveType,
4659 IDirect3DVertexBuffer7 *D3DVertexBuf,
4669 old_fpucw = d3d_fpu_setup();
4670 hr = IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB(iface, PrimitiveType, D3DVertexBuf, StartVertex, NumVertices, Indices, IndexCount, Flags);
4671 set_fpu_control_word(old_fpucw);
4676 static HRESULT WINAPI
4677 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveVB(IDirect3DDevice3 *iface,
4678 D3DPRIMITIVETYPE PrimitiveType,
4679 IDirect3DVertexBuffer *D3DVertexBuf,
4684 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
4685 IDirect3DVertexBufferImpl *VB = ICOM_OBJECT(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, D3DVertexBuf);
4686 TRACE_(ddraw_thunk)("(%p)->(%08x,%p,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, VB, Indices, IndexCount, Flags);
4688 return IDirect3DDevice7_DrawIndexedPrimitiveVB(ICOM_INTERFACE(This, IDirect3DDevice7),
4690 ICOM_INTERFACE(VB, IDirect3DVertexBuffer7),
4698 /*****************************************************************************
4699 * IDirect3DDevice7::ComputeSphereVisibility
4701 * Calculates the visibility of spheres in the current viewport. The spheres
4702 * are passed in the Centers and Radii arrays, the results are passed back
4703 * in the ReturnValues array. Return values are either completely visible,
4704 * partially visible or completely invisible.
4705 * The return value consist of a combination of D3DCLIP_* flags, or it's
4706 * 0 if the sphere is completely visible(according to the SDK, not checked)
4708 * Sounds like an overdose of math ;)
4713 * Centers: Array containing the sphere centers
4714 * Radii: Array containing the sphere radii
4715 * NumSpheres: The number of centers and radii in the arrays
4717 * ReturnValues: Array to write the results to
4720 * D3D_OK because it's a stub
4721 * (DDERR_INVALIDPARAMS if Centers, Radii or ReturnValues are NULL)
4722 * (D3DERR_INVALIDMATRIX if the combined world, view and proj matrix
4725 *****************************************************************************/
4726 static HRESULT WINAPI
4727 IDirect3DDeviceImpl_7_ComputeSphereVisibility(IDirect3DDevice7 *iface,
4732 DWORD *ReturnValues)
4734 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4735 FIXME("(%p)->(%p,%p,%08x,%08x,%p): stub!\n", This, Centers, Radii, NumSpheres, Flags, ReturnValues);
4737 /* the DirectX 7 sdk says that the visibility is computed by
4738 * back-transforming the viewing frustum to model space
4739 * using the inverse of the combined world, view and projection
4740 * matrix. If the matrix can't be reversed, D3DERR_INVALIDMATRIX
4743 * Basic implementation idea:
4744 * 1) Check if the center is in the viewing frustum
4745 * 2) Cut the sphere with the planes of the viewing
4748 * ->Center inside the frustum, no intersections:
4750 * ->Center outside the frustum, no intersections:
4752 * ->Some intersections: Partially visible
4754 * Implement this call in WineD3D. Either implement the
4755 * matrix and vector stuff in WineD3D, or use some external
4762 static HRESULT WINAPI
4763 Thunk_IDirect3DDeviceImpl_3_ComputeSphereVisibility(IDirect3DDevice3 *iface,
4768 DWORD *ReturnValues)
4770 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
4771 TRACE_(ddraw_thunk)("(%p)->(%p,%p,%08x,%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, Centers, Radii, NumSpheres, Flags, ReturnValues);
4772 return IDirect3DDevice7_ComputeSphereVisibility(ICOM_INTERFACE(This, IDirect3DDevice7),
4780 /*****************************************************************************
4781 * IDirect3DDevice7::GetTexture
4783 * Returns the texture interface handle assigned to a texture stage.
4784 * The returned texture is AddRefed. This is taken from old ddraw,
4785 * not checked in Windows.
4790 * Stage: Texture stage to read the texture from
4791 * Texture: Address to store the interface pointer at
4795 * DDERR_INVALIDPARAMS if Texture is NULL
4796 * For details, see IWineD3DDevice::GetTexture
4798 *****************************************************************************/
4800 IDirect3DDeviceImpl_7_GetTexture(IDirect3DDevice7 *iface,
4802 IDirectDrawSurface7 **Texture)
4804 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4805 IWineD3DBaseTexture *Surf;
4807 TRACE("(%p)->(%d,%p): Relay\n", This, Stage, Texture);
4811 TRACE("Texture == NULL, failing with DDERR_INVALIDPARAMS\n");
4812 return DDERR_INVALIDPARAMS;
4815 EnterCriticalSection(&ddraw_cs);
4816 hr = IWineD3DDevice_GetTexture(This->wineD3DDevice, Stage, &Surf);
4817 if( (hr != D3D_OK) || (!Surf) )
4820 LeaveCriticalSection(&ddraw_cs);
4824 /* GetParent AddRef()s, which is perfectly OK.
4825 * We have passed the IDirectDrawSurface7 interface to WineD3D, so that's OK too.
4827 hr = IWineD3DBaseTexture_GetParent(Surf,
4828 (IUnknown **) Texture);
4829 LeaveCriticalSection(&ddraw_cs);
4833 static HRESULT WINAPI
4834 IDirect3DDeviceImpl_7_GetTexture_FPUSetup(IDirect3DDevice7 *iface,
4836 IDirectDrawSurface7 **Texture)
4838 return IDirect3DDeviceImpl_7_GetTexture(iface, Stage, Texture);
4841 static HRESULT WINAPI
4842 IDirect3DDeviceImpl_7_GetTexture_FPUPreserve(IDirect3DDevice7 *iface,
4844 IDirectDrawSurface7 **Texture)
4849 old_fpucw = d3d_fpu_setup();
4850 hr = IDirect3DDeviceImpl_7_GetTexture(iface, Stage, Texture);
4851 set_fpu_control_word(old_fpucw);
4856 static HRESULT WINAPI
4857 Thunk_IDirect3DDeviceImpl_3_GetTexture(IDirect3DDevice3 *iface,
4859 IDirect3DTexture2 **Texture2)
4861 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
4863 IDirectDrawSurface7 *ret_val;
4865 TRACE_(ddraw_thunk)("(%p)->(%d,%p) thunking to IDirect3DDevice7 interface.\n", This, Stage, Texture2);
4866 ret = IDirect3DDevice7_GetTexture(ICOM_INTERFACE(This, IDirect3DDevice7),
4870 *Texture2 = COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirectDrawSurface7, IDirect3DTexture2, ret_val);
4872 TRACE_(ddraw_thunk)(" returning interface %p.\n", *Texture2);
4877 /*****************************************************************************
4878 * IDirect3DDevice7::SetTexture
4880 * Assigns a texture to a texture stage. Is the texture AddRef-ed?
4885 * Stage: The stage to assign the texture to
4886 * Texture: Interface pointer to the texture surface
4890 * For details, see IWineD3DDevice::SetTexture
4892 *****************************************************************************/
4894 IDirect3DDeviceImpl_7_SetTexture(IDirect3DDevice7 *iface,
4896 IDirectDrawSurface7 *Texture)
4898 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4899 IDirectDrawSurfaceImpl *surf = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, Texture);
4901 TRACE("(%p)->(%08x,%p): Relay!\n", This, Stage, surf);
4903 /* Texture may be NULL here */
4904 EnterCriticalSection(&ddraw_cs);
4905 hr = IWineD3DDevice_SetTexture(This->wineD3DDevice,
4907 surf ? surf->wineD3DTexture : NULL);
4908 LeaveCriticalSection(&ddraw_cs);
4912 static HRESULT WINAPI
4913 IDirect3DDeviceImpl_7_SetTexture_FPUSetup(IDirect3DDevice7 *iface,
4915 IDirectDrawSurface7 *Texture)
4917 return IDirect3DDeviceImpl_7_SetTexture(iface, Stage, Texture);
4920 static HRESULT WINAPI
4921 IDirect3DDeviceImpl_7_SetTexture_FPUPreserve(IDirect3DDevice7 *iface,
4923 IDirectDrawSurface7 *Texture)
4928 old_fpucw = d3d_fpu_setup();
4929 hr = IDirect3DDeviceImpl_7_SetTexture(iface, Stage, Texture);
4930 set_fpu_control_word(old_fpucw);
4935 static HRESULT WINAPI
4936 IDirect3DDeviceImpl_3_SetTexture(IDirect3DDevice3 *iface,
4938 IDirect3DTexture2 *Texture2)
4940 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
4941 IDirectDrawSurfaceImpl *tex = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirect3DTexture2, Texture2);
4944 TRACE("(%p)->(%d,%p)\n", This, Stage, tex);
4946 EnterCriticalSection(&ddraw_cs);
4948 if (This->legacyTextureBlending)
4949 IDirect3DDevice3_GetRenderState(iface, D3DRENDERSTATE_TEXTUREMAPBLEND, &texmapblend);
4951 hr = IDirect3DDevice7_SetTexture(ICOM_INTERFACE(This, IDirect3DDevice7),
4953 ICOM_INTERFACE(tex, IDirectDrawSurface7));
4955 if (This->legacyTextureBlending && texmapblend == D3DTBLEND_MODULATE)
4957 /* This fixup is required by the way D3DTBLEND_MODULATE maps to texture stage states.
4958 See IDirect3DDeviceImpl_3_SetRenderState for details. */
4959 BOOL tex_alpha = FALSE;
4960 IWineD3DBaseTexture *tex = NULL;
4961 WINED3DSURFACE_DESC desc;
4963 DDPIXELFORMAT ddfmt;
4966 result = IWineD3DDevice_GetTexture(This->wineD3DDevice,
4970 if(result == WINED3D_OK && tex)
4972 memset(&desc, 0, sizeof(desc));
4974 result = IWineD3DTexture_GetLevelDesc((IWineD3DTexture*) tex, 0, &desc);
4975 if (SUCCEEDED(result))
4977 ddfmt.dwSize = sizeof(ddfmt);
4978 PixelFormat_WineD3DtoDD(&ddfmt, fmt);
4979 if (ddfmt.u5.dwRGBAlphaBitMask) tex_alpha = TRUE;
4982 IWineD3DBaseTexture_Release(tex);
4985 /* alphaop is WINED3DTOP_SELECTARG1 if it's D3DTBLEND_MODULATE, so only modify alphaarg1 */
4988 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG1, WINED3DTA_TEXTURE);
4992 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG1, WINED3DTA_CURRENT);
4996 LeaveCriticalSection(&ddraw_cs);
5001 static const struct tss_lookup
5008 {FALSE, WINED3DTSS_FORCE_DWORD}, /* 0, unused */
5009 {FALSE, WINED3DTSS_COLOROP}, /* 1, D3DTSS_COLOROP */
5010 {FALSE, WINED3DTSS_COLORARG1}, /* 2, D3DTSS_COLORARG1 */
5011 {FALSE, WINED3DTSS_COLORARG2}, /* 3, D3DTSS_COLORARG2 */
5012 {FALSE, WINED3DTSS_ALPHAOP}, /* 4, D3DTSS_ALPHAOP */
5013 {FALSE, WINED3DTSS_ALPHAARG1}, /* 5, D3DTSS_ALPHAARG1 */
5014 {FALSE, WINED3DTSS_ALPHAARG2}, /* 6, D3DTSS_ALPHAARG2 */
5015 {FALSE, WINED3DTSS_BUMPENVMAT00}, /* 7, D3DTSS_BUMPENVMAT00 */
5016 {FALSE, WINED3DTSS_BUMPENVMAT01}, /* 8, D3DTSS_BUMPENVMAT01 */
5017 {FALSE, WINED3DTSS_BUMPENVMAT10}, /* 9, D3DTSS_BUMPENVMAT10 */
5018 {FALSE, WINED3DTSS_BUMPENVMAT11}, /* 10, D3DTSS_BUMPENVMAT11 */
5019 {FALSE, WINED3DTSS_TEXCOORDINDEX}, /* 11, D3DTSS_TEXCOORDINDEX */
5020 {TRUE, WINED3DSAMP_ADDRESSU}, /* 12, D3DTSS_ADDRESS */
5021 {TRUE, WINED3DSAMP_ADDRESSU}, /* 13, D3DTSS_ADDRESSU */
5022 {TRUE, WINED3DSAMP_ADDRESSV}, /* 14, D3DTSS_ADDRESSV */
5023 {TRUE, WINED3DSAMP_BORDERCOLOR}, /* 15, D3DTSS_BORDERCOLOR */
5024 {TRUE, WINED3DSAMP_MAGFILTER}, /* 16, D3DTSS_MAGFILTER */
5025 {TRUE, WINED3DSAMP_MINFILTER}, /* 17, D3DTSS_MINFILTER */
5026 {TRUE, WINED3DSAMP_MIPFILTER}, /* 18, D3DTSS_MIPFILTER */
5027 {TRUE, WINED3DSAMP_MIPMAPLODBIAS}, /* 19, D3DTSS_MIPMAPLODBIAS */
5028 {TRUE, WINED3DSAMP_MAXMIPLEVEL}, /* 20, D3DTSS_MAXMIPLEVEL */
5029 {TRUE, WINED3DSAMP_MAXANISOTROPY}, /* 21, D3DTSS_MAXANISOTROPY */
5030 {FALSE, WINED3DTSS_BUMPENVLSCALE}, /* 22, D3DTSS_BUMPENVLSCALE */
5031 {FALSE, WINED3DTSS_BUMPENVLOFFSET}, /* 23, D3DTSS_BUMPENVLOFFSET */
5032 {FALSE, WINED3DTSS_TEXTURETRANSFORMFLAGS}, /* 24, D3DTSS_TEXTURETRANSFORMFLAGS */
5035 /*****************************************************************************
5036 * IDirect3DDevice7::GetTextureStageState
5038 * Retrieves a state from a texture stage.
5043 * Stage: The stage to retrieve the state from
5044 * TexStageStateType: The state type to retrieve
5045 * State: Address to store the state's value at
5049 * DDERR_INVALIDPARAMS if State is NULL
5050 * For details, see IWineD3DDevice::GetTextureStageState
5052 *****************************************************************************/
5054 IDirect3DDeviceImpl_7_GetTextureStageState(IDirect3DDevice7 *iface,
5056 D3DTEXTURESTAGESTATETYPE TexStageStateType,
5059 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5061 const struct tss_lookup *l = &tss_lookup[TexStageStateType];
5062 TRACE("(%p)->(%08x,%08x,%p): Relay!\n", This, Stage, TexStageStateType, State);
5065 return DDERR_INVALIDPARAMS;
5067 EnterCriticalSection(&ddraw_cs);
5069 if (l->sampler_state)
5071 hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice, Stage, l->state, State);
5073 switch(TexStageStateType)
5075 /* Mipfilter is a sampler state with different values */
5076 case D3DTSS_MIPFILTER:
5080 case WINED3DTEXF_NONE: *State = D3DTFP_NONE; break;
5081 case WINED3DTEXF_POINT: *State = D3DTFP_POINT; break;
5082 case WINED3DTEXF_LINEAR: *State = D3DTFP_LINEAR; break;
5084 ERR("Unexpected mipfilter value %#x\n", *State);
5085 *State = D3DTFP_NONE;
5091 /* Magfilter has slightly different values */
5092 case D3DTSS_MAGFILTER:
5096 case WINED3DTEXF_POINT: *State = D3DTFG_POINT; break;
5097 case WINED3DTEXF_LINEAR: *State = D3DTFG_LINEAR; break;
5098 case WINED3DTEXF_ANISOTROPIC: *State = D3DTFG_ANISOTROPIC; break;
5099 case WINED3DTEXF_FLATCUBIC: *State = D3DTFG_FLATCUBIC; break;
5100 case WINED3DTEXF_GAUSSIANCUBIC: *State = D3DTFG_GAUSSIANCUBIC; break;
5102 ERR("Unexpected wined3d mag filter value %#x\n", *State);
5103 *State = D3DTFG_POINT;
5115 hr = IWineD3DDevice_GetTextureStageState(This->wineD3DDevice, Stage, l->state, State);
5118 LeaveCriticalSection(&ddraw_cs);
5122 static HRESULT WINAPI
5123 IDirect3DDeviceImpl_7_GetTextureStageState_FPUSetup(IDirect3DDevice7 *iface,
5125 D3DTEXTURESTAGESTATETYPE TexStageStateType,
5128 return IDirect3DDeviceImpl_7_GetTextureStageState(iface, Stage, TexStageStateType, State);
5131 static HRESULT WINAPI
5132 IDirect3DDeviceImpl_7_GetTextureStageState_FPUPreserve(IDirect3DDevice7 *iface,
5134 D3DTEXTURESTAGESTATETYPE TexStageStateType,
5140 old_fpucw = d3d_fpu_setup();
5141 hr = IDirect3DDeviceImpl_7_GetTextureStageState(iface, Stage, TexStageStateType, State);
5142 set_fpu_control_word(old_fpucw);
5147 static HRESULT WINAPI
5148 Thunk_IDirect3DDeviceImpl_3_GetTextureStageState(IDirect3DDevice3 *iface,
5150 D3DTEXTURESTAGESTATETYPE TexStageStateType,
5153 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
5154 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, Stage, TexStageStateType, State);
5155 return IDirect3DDevice7_GetTextureStageState(ICOM_INTERFACE(This, IDirect3DDevice7),
5161 /*****************************************************************************
5162 * IDirect3DDevice7::SetTextureStageState
5164 * Sets a texture stage state. Some stage types need to be handled specially,
5165 * because they do not exist in WineD3D and were moved to another place
5170 * Stage: The stage to modify
5171 * TexStageStateType: The state to change
5172 * State: The new value for the state
5176 * For details, see IWineD3DDevice::SetTextureStageState
5178 *****************************************************************************/
5180 IDirect3DDeviceImpl_7_SetTextureStageState(IDirect3DDevice7 *iface,
5182 D3DTEXTURESTAGESTATETYPE TexStageStateType,
5185 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5186 const struct tss_lookup *l = &tss_lookup[TexStageStateType];
5188 TRACE("(%p)->(%08x,%08x,%08x): Relay!\n", This, Stage, TexStageStateType, State);
5190 EnterCriticalSection(&ddraw_cs);
5192 if (l->sampler_state)
5194 switch(TexStageStateType)
5196 /* Mipfilter is a sampler state with different values */
5197 case D3DTSS_MIPFILTER:
5201 case D3DTFP_NONE: State = WINED3DTEXF_NONE; break;
5202 case D3DTFP_POINT: State = WINED3DTEXF_POINT; break;
5203 case 0: /* Unchecked */
5204 case D3DTFP_LINEAR: State = WINED3DTEXF_LINEAR; break;
5206 ERR("Unexpected mipfilter value %d\n", State);
5207 State = WINED3DTEXF_NONE;
5213 /* Magfilter has slightly different values */
5214 case D3DTSS_MAGFILTER:
5218 case D3DTFG_POINT: State = WINED3DTEXF_POINT; break;
5219 case D3DTFG_LINEAR: State = WINED3DTEXF_LINEAR; break;
5220 case D3DTFG_FLATCUBIC: State = WINED3DTEXF_FLATCUBIC; break;
5221 case D3DTFG_GAUSSIANCUBIC: State = WINED3DTEXF_GAUSSIANCUBIC; break;
5222 case D3DTFG_ANISOTROPIC: State = WINED3DTEXF_ANISOTROPIC; break;
5224 ERR("Unexpected d3d7 mag filter type %d\n", State);
5225 State = WINED3DTEXF_POINT;
5231 case D3DTSS_ADDRESS:
5232 IWineD3DDevice_SetSamplerState(This->wineD3DDevice, Stage, WINED3DSAMP_ADDRESSV, State);
5239 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice, Stage, l->state, State);
5243 hr = IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, Stage, l->state, State);
5246 LeaveCriticalSection(&ddraw_cs);
5250 static HRESULT WINAPI
5251 IDirect3DDeviceImpl_7_SetTextureStageState_FPUSetup(IDirect3DDevice7 *iface,
5253 D3DTEXTURESTAGESTATETYPE TexStageStateType,
5256 return IDirect3DDeviceImpl_7_SetTextureStageState(iface, Stage, TexStageStateType, State);
5259 static HRESULT WINAPI
5260 IDirect3DDeviceImpl_7_SetTextureStageState_FPUPreserve(IDirect3DDevice7 *iface,
5262 D3DTEXTURESTAGESTATETYPE TexStageStateType,
5268 old_fpucw = d3d_fpu_setup();
5269 hr = IDirect3DDeviceImpl_7_SetTextureStageState(iface, Stage, TexStageStateType, State);
5270 set_fpu_control_word(old_fpucw);
5275 static HRESULT WINAPI
5276 Thunk_IDirect3DDeviceImpl_3_SetTextureStageState(IDirect3DDevice3 *iface,
5278 D3DTEXTURESTAGESTATETYPE TexStageStateType,
5281 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
5282 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, Stage, TexStageStateType, State);
5283 return IDirect3DDevice7_SetTextureStageState(ICOM_INTERFACE(This, IDirect3DDevice7),
5289 /*****************************************************************************
5290 * IDirect3DDevice7::ValidateDevice
5292 * SDK: "Reports the device's ability to render the currently set
5293 * texture-blending operations in a single pass". Whatever that means
5299 * NumPasses: Address to write the number of necessary passes for the
5300 * desired effect to.
5304 * See IWineD3DDevice::ValidateDevice for more details
5306 *****************************************************************************/
5308 IDirect3DDeviceImpl_7_ValidateDevice(IDirect3DDevice7 *iface,
5311 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5313 TRACE("(%p)->(%p): Relay\n", This, NumPasses);
5315 EnterCriticalSection(&ddraw_cs);
5316 hr = IWineD3DDevice_ValidateDevice(This->wineD3DDevice, NumPasses);
5317 LeaveCriticalSection(&ddraw_cs);
5321 static HRESULT WINAPI
5322 IDirect3DDeviceImpl_7_ValidateDevice_FPUSetup(IDirect3DDevice7 *iface,
5325 return IDirect3DDeviceImpl_7_ValidateDevice(iface, NumPasses);
5328 static HRESULT WINAPI
5329 IDirect3DDeviceImpl_7_ValidateDevice_FPUPreserve(IDirect3DDevice7 *iface,
5335 old_fpucw = d3d_fpu_setup();
5336 hr = IDirect3DDeviceImpl_7_ValidateDevice(iface, NumPasses);
5337 set_fpu_control_word(old_fpucw);
5342 static HRESULT WINAPI
5343 Thunk_IDirect3DDeviceImpl_3_ValidateDevice(IDirect3DDevice3 *iface,
5346 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
5347 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, Passes);
5348 return IDirect3DDevice7_ValidateDevice(ICOM_INTERFACE(This, IDirect3DDevice7),
5352 /*****************************************************************************
5353 * IDirect3DDevice7::Clear
5355 * Fills the render target, the z buffer and the stencil buffer with a
5356 * clear color / value
5361 * Count: Number of rectangles in Rects must be 0 if Rects is NULL
5362 * Rects: Rectangles to clear. If NULL, the whole surface is cleared
5363 * Flags: Some flags, as usual
5364 * Color: Clear color for the render target
5365 * Z: Clear value for the Z buffer
5366 * Stencil: Clear value to store in each stencil buffer entry
5370 * For details, see IWineD3DDevice::Clear
5372 *****************************************************************************/
5374 IDirect3DDeviceImpl_7_Clear(IDirect3DDevice7 *iface,
5382 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5384 TRACE("(%p)->(%08x,%p,%08x,%08x,%f,%08x): Relay\n", This, Count, Rects, Flags, Color, Z, Stencil);
5386 /* Note; D3DRECT is compatible with WINED3DRECT */
5387 EnterCriticalSection(&ddraw_cs);
5388 hr = IWineD3DDevice_Clear(This->wineD3DDevice, Count, (WINED3DRECT*) Rects, Flags, Color, Z, Stencil);
5389 LeaveCriticalSection(&ddraw_cs);
5393 static HRESULT WINAPI
5394 IDirect3DDeviceImpl_7_Clear_FPUSetup(IDirect3DDevice7 *iface,
5402 return IDirect3DDeviceImpl_7_Clear(iface, Count, Rects, Flags, Color, Z, Stencil);
5405 static HRESULT WINAPI
5406 IDirect3DDeviceImpl_7_Clear_FPUPreserve(IDirect3DDevice7 *iface,
5417 old_fpucw = d3d_fpu_setup();
5418 hr = IDirect3DDeviceImpl_7_Clear(iface, Count, Rects, Flags, Color, Z, Stencil);
5419 set_fpu_control_word(old_fpucw);
5424 /*****************************************************************************
5425 * IDirect3DDevice7::SetViewport
5427 * Sets the current viewport.
5429 * Version 7 only, but IDirect3DViewport uses this call for older
5433 * Data: The new viewport to set
5437 * DDERR_INVALIDPARAMS if Data is NULL
5438 * For more details, see IWineDDDevice::SetViewport
5440 *****************************************************************************/
5442 IDirect3DDeviceImpl_7_SetViewport(IDirect3DDevice7 *iface,
5445 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5447 TRACE("(%p)->(%p) Relay!\n", This, Data);
5450 return DDERR_INVALIDPARAMS;
5452 /* Note: D3DVIEWPORT7 is compatible with WINED3DVIEWPORT */
5453 EnterCriticalSection(&ddraw_cs);
5454 hr = IWineD3DDevice_SetViewport(This->wineD3DDevice,
5455 (WINED3DVIEWPORT*) Data);
5456 LeaveCriticalSection(&ddraw_cs);
5460 static HRESULT WINAPI
5461 IDirect3DDeviceImpl_7_SetViewport_FPUSetup(IDirect3DDevice7 *iface,
5464 return IDirect3DDeviceImpl_7_SetViewport(iface, Data);
5467 static HRESULT WINAPI
5468 IDirect3DDeviceImpl_7_SetViewport_FPUPreserve(IDirect3DDevice7 *iface,
5474 old_fpucw = d3d_fpu_setup();
5475 hr = IDirect3DDeviceImpl_7_SetViewport(iface, Data);
5476 set_fpu_control_word(old_fpucw);
5481 /*****************************************************************************
5482 * IDirect3DDevice::GetViewport
5484 * Returns the current viewport
5489 * Data: D3D7Viewport structure to write the viewport information to
5493 * DDERR_INVALIDPARAMS if Data is NULL
5494 * For more details, see IWineD3DDevice::GetViewport
5496 *****************************************************************************/
5498 IDirect3DDeviceImpl_7_GetViewport(IDirect3DDevice7 *iface,
5501 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5503 TRACE("(%p)->(%p) Relay!\n", This, Data);
5506 return DDERR_INVALIDPARAMS;
5508 /* Note: D3DVIEWPORT7 is compatible with WINED3DVIEWPORT */
5509 EnterCriticalSection(&ddraw_cs);
5510 hr = IWineD3DDevice_GetViewport(This->wineD3DDevice,
5511 (WINED3DVIEWPORT*) Data);
5513 LeaveCriticalSection(&ddraw_cs);
5514 return hr_ddraw_from_wined3d(hr);
5517 static HRESULT WINAPI
5518 IDirect3DDeviceImpl_7_GetViewport_FPUSetup(IDirect3DDevice7 *iface,
5521 return IDirect3DDeviceImpl_7_GetViewport(iface, Data);
5524 static HRESULT WINAPI
5525 IDirect3DDeviceImpl_7_GetViewport_FPUPreserve(IDirect3DDevice7 *iface,
5531 old_fpucw = d3d_fpu_setup();
5532 hr = IDirect3DDeviceImpl_7_GetViewport(iface, Data);
5533 set_fpu_control_word(old_fpucw);
5538 /*****************************************************************************
5539 * IDirect3DDevice7::SetMaterial
5546 * Mat: The material to set
5550 * DDERR_INVALIDPARAMS if Mat is NULL.
5551 * For more details, see IWineD3DDevice::SetMaterial
5553 *****************************************************************************/
5555 IDirect3DDeviceImpl_7_SetMaterial(IDirect3DDevice7 *iface,
5558 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5560 TRACE("(%p)->(%p): Relay!\n", This, Mat);
5562 if (!Mat) return DDERR_INVALIDPARAMS;
5563 /* Note: D3DMATERIAL7 is compatible with WINED3DMATERIAL */
5564 EnterCriticalSection(&ddraw_cs);
5565 hr = IWineD3DDevice_SetMaterial(This->wineD3DDevice,
5566 (WINED3DMATERIAL*) Mat);
5567 LeaveCriticalSection(&ddraw_cs);
5568 return hr_ddraw_from_wined3d(hr);
5571 static HRESULT WINAPI
5572 IDirect3DDeviceImpl_7_SetMaterial_FPUSetup(IDirect3DDevice7 *iface,
5575 return IDirect3DDeviceImpl_7_SetMaterial(iface, Mat);
5578 static HRESULT WINAPI
5579 IDirect3DDeviceImpl_7_SetMaterial_FPUPreserve(IDirect3DDevice7 *iface,
5585 old_fpucw = d3d_fpu_setup();
5586 hr = IDirect3DDeviceImpl_7_SetMaterial(iface, Mat);
5587 set_fpu_control_word(old_fpucw);
5592 /*****************************************************************************
5593 * IDirect3DDevice7::GetMaterial
5595 * Returns the current material
5600 * Mat: D3DMATERIAL7 structure to write the material parameters to
5604 * DDERR_INVALIDPARAMS if Mat is NULL
5605 * For more details, see IWineD3DDevice::GetMaterial
5607 *****************************************************************************/
5609 IDirect3DDeviceImpl_7_GetMaterial(IDirect3DDevice7 *iface,
5612 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5614 TRACE("(%p)->(%p): Relay!\n", This, Mat);
5616 EnterCriticalSection(&ddraw_cs);
5617 /* Note: D3DMATERIAL7 is compatible with WINED3DMATERIAL */
5618 hr = IWineD3DDevice_GetMaterial(This->wineD3DDevice,
5619 (WINED3DMATERIAL*) Mat);
5620 LeaveCriticalSection(&ddraw_cs);
5621 return hr_ddraw_from_wined3d(hr);
5624 static HRESULT WINAPI
5625 IDirect3DDeviceImpl_7_GetMaterial_FPUSetup(IDirect3DDevice7 *iface,
5628 return IDirect3DDeviceImpl_7_GetMaterial(iface, Mat);
5631 static HRESULT WINAPI
5632 IDirect3DDeviceImpl_7_GetMaterial_FPUPreserve(IDirect3DDevice7 *iface,
5638 old_fpucw = d3d_fpu_setup();
5639 hr = IDirect3DDeviceImpl_7_GetMaterial(iface, Mat);
5640 set_fpu_control_word(old_fpucw);
5645 /*****************************************************************************
5646 * IDirect3DDevice7::SetLight
5648 * Assigns a light to a light index, but doesn't activate it yet.
5650 * Version 7, IDirect3DLight uses this method for older versions
5653 * LightIndex: The index of the new light
5654 * Light: A D3DLIGHT7 structure describing the light
5658 * For more details, see IWineD3DDevice::SetLight
5660 *****************************************************************************/
5662 IDirect3DDeviceImpl_7_SetLight(IDirect3DDevice7 *iface,
5666 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5668 TRACE("(%p)->(%08x,%p): Relay!\n", This, LightIndex, Light);
5670 EnterCriticalSection(&ddraw_cs);
5671 /* Note: D3DLIGHT7 is compatible with WINED3DLIGHT */
5672 hr = IWineD3DDevice_SetLight(This->wineD3DDevice,
5674 (WINED3DLIGHT*) Light);
5675 LeaveCriticalSection(&ddraw_cs);
5676 return hr_ddraw_from_wined3d(hr);
5679 static HRESULT WINAPI
5680 IDirect3DDeviceImpl_7_SetLight_FPUSetup(IDirect3DDevice7 *iface,
5684 return IDirect3DDeviceImpl_7_SetLight(iface, LightIndex, Light);
5687 static HRESULT WINAPI
5688 IDirect3DDeviceImpl_7_SetLight_FPUPreserve(IDirect3DDevice7 *iface,
5695 old_fpucw = d3d_fpu_setup();
5696 hr = IDirect3DDeviceImpl_7_SetLight(iface, LightIndex, Light);
5697 set_fpu_control_word(old_fpucw);
5702 /*****************************************************************************
5703 * IDirect3DDevice7::GetLight
5705 * Returns the light assigned to a light index
5708 * Light: Structure to write the light information to
5712 * DDERR_INVALIDPARAMS if Light is NULL
5713 * For details, see IWineD3DDevice::GetLight
5715 *****************************************************************************/
5717 IDirect3DDeviceImpl_7_GetLight(IDirect3DDevice7 *iface,
5721 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5723 TRACE("(%p)->(%08x,%p): Relay!\n", This, LightIndex, Light);
5725 EnterCriticalSection(&ddraw_cs);
5726 /* Note: D3DLIGHT7 is compatible with WINED3DLIGHT */
5727 rc = IWineD3DDevice_GetLight(This->wineD3DDevice,
5729 (WINED3DLIGHT*) Light);
5731 /* Translate the result. WineD3D returns other values than D3D7 */
5732 LeaveCriticalSection(&ddraw_cs);
5733 return hr_ddraw_from_wined3d(rc);
5736 static HRESULT WINAPI
5737 IDirect3DDeviceImpl_7_GetLight_FPUSetup(IDirect3DDevice7 *iface,
5741 return IDirect3DDeviceImpl_7_GetLight(iface, LightIndex, Light);
5744 static HRESULT WINAPI
5745 IDirect3DDeviceImpl_7_GetLight_FPUPreserve(IDirect3DDevice7 *iface,
5752 old_fpucw = d3d_fpu_setup();
5753 hr = IDirect3DDeviceImpl_7_GetLight(iface, LightIndex, Light);
5754 set_fpu_control_word(old_fpucw);
5759 /*****************************************************************************
5760 * IDirect3DDevice7::BeginStateBlock
5762 * Begins recording to a stateblock
5768 * For details see IWineD3DDevice::BeginStateBlock
5770 *****************************************************************************/
5772 IDirect3DDeviceImpl_7_BeginStateBlock(IDirect3DDevice7 *iface)
5774 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5776 TRACE("(%p)->(): Relay!\n", This);
5778 EnterCriticalSection(&ddraw_cs);
5779 hr = IWineD3DDevice_BeginStateBlock(This->wineD3DDevice);
5780 LeaveCriticalSection(&ddraw_cs);
5781 return hr_ddraw_from_wined3d(hr);
5784 static HRESULT WINAPI
5785 IDirect3DDeviceImpl_7_BeginStateBlock_FPUSetup(IDirect3DDevice7 *iface)
5787 return IDirect3DDeviceImpl_7_BeginStateBlock(iface);
5790 static HRESULT WINAPI
5791 IDirect3DDeviceImpl_7_BeginStateBlock_FPUPreserve(IDirect3DDevice7 *iface)
5796 old_fpucw = d3d_fpu_setup();
5797 hr = IDirect3DDeviceImpl_7_BeginStateBlock(iface);
5798 set_fpu_control_word(old_fpucw);
5803 /*****************************************************************************
5804 * IDirect3DDevice7::EndStateBlock
5806 * Stops recording to a state block and returns the created stateblock
5812 * BlockHandle: Address to store the stateblock's handle to
5816 * DDERR_INVALIDPARAMS if BlockHandle is NULL
5817 * See IWineD3DDevice::EndStateBlock for more details
5819 *****************************************************************************/
5821 IDirect3DDeviceImpl_7_EndStateBlock(IDirect3DDevice7 *iface,
5824 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5826 TRACE("(%p)->(%p): Relay!\n", This, BlockHandle);
5830 WARN("BlockHandle == NULL, returning DDERR_INVALIDPARAMS\n");
5831 return DDERR_INVALIDPARAMS;
5834 EnterCriticalSection(&ddraw_cs);
5835 *BlockHandle = IDirect3DDeviceImpl_CreateHandle(This);
5838 ERR("Cannot get a handle number for the stateblock\n");
5839 LeaveCriticalSection(&ddraw_cs);
5840 return DDERR_OUTOFMEMORY;
5842 This->Handles[*BlockHandle - 1].type = DDrawHandle_StateBlock;
5843 hr = IWineD3DDevice_EndStateBlock(This->wineD3DDevice,
5844 (IWineD3DStateBlock **) &This->Handles[*BlockHandle - 1].ptr);
5845 LeaveCriticalSection(&ddraw_cs);
5846 return hr_ddraw_from_wined3d(hr);
5849 static HRESULT WINAPI
5850 IDirect3DDeviceImpl_7_EndStateBlock_FPUSetup(IDirect3DDevice7 *iface,
5853 return IDirect3DDeviceImpl_7_EndStateBlock(iface, BlockHandle);
5856 static HRESULT WINAPI
5857 IDirect3DDeviceImpl_7_EndStateBlock_FPUPreserve(IDirect3DDevice7 *iface,
5863 old_fpucw = d3d_fpu_setup();
5864 hr = IDirect3DDeviceImpl_7_EndStateBlock(iface, BlockHandle);
5865 set_fpu_control_word(old_fpucw);
5870 /*****************************************************************************
5871 * IDirect3DDevice7::PreLoad
5873 * Allows the app to signal that a texture will be used soon, to allow
5874 * the Direct3DDevice to load it to the video card in the meantime.
5879 * Texture: The texture to preload
5883 * DDERR_INVALIDPARAMS if Texture is NULL
5884 * See IWineD3DSurface::PreLoad for details
5886 *****************************************************************************/
5888 IDirect3DDeviceImpl_7_PreLoad(IDirect3DDevice7 *iface,
5889 IDirectDrawSurface7 *Texture)
5891 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5892 IDirectDrawSurfaceImpl *surf = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, Texture);
5894 TRACE("(%p)->(%p): Relay!\n", This, surf);
5897 return DDERR_INVALIDPARAMS;
5899 EnterCriticalSection(&ddraw_cs);
5900 IWineD3DSurface_PreLoad(surf->WineD3DSurface);
5901 LeaveCriticalSection(&ddraw_cs);
5905 static HRESULT WINAPI
5906 IDirect3DDeviceImpl_7_PreLoad_FPUSetup(IDirect3DDevice7 *iface,
5907 IDirectDrawSurface7 *Texture)
5909 return IDirect3DDeviceImpl_7_PreLoad(iface, Texture);
5912 static HRESULT WINAPI
5913 IDirect3DDeviceImpl_7_PreLoad_FPUPreserve(IDirect3DDevice7 *iface,
5914 IDirectDrawSurface7 *Texture)
5919 old_fpucw = d3d_fpu_setup();
5920 hr = IDirect3DDeviceImpl_7_PreLoad(iface, Texture);
5921 set_fpu_control_word(old_fpucw);
5926 /*****************************************************************************
5927 * IDirect3DDevice7::ApplyStateBlock
5929 * Activates the state stored in a state block handle.
5932 * BlockHandle: The stateblock handle to activate
5936 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is NULL
5938 *****************************************************************************/
5940 IDirect3DDeviceImpl_7_ApplyStateBlock(IDirect3DDevice7 *iface,
5943 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5945 TRACE("(%p)->(%08x): Relay!\n", This, BlockHandle);
5947 EnterCriticalSection(&ddraw_cs);
5948 if(!BlockHandle || BlockHandle > This->numHandles)
5950 WARN("Out of range handle %d, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle);
5951 LeaveCriticalSection(&ddraw_cs);
5952 return D3DERR_INVALIDSTATEBLOCK;
5954 if(This->Handles[BlockHandle - 1].type != DDrawHandle_StateBlock)
5956 WARN("Handle %d is not a stateblock, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle);
5957 LeaveCriticalSection(&ddraw_cs);
5958 return D3DERR_INVALIDSTATEBLOCK;
5961 hr = IWineD3DStateBlock_Apply((IWineD3DStateBlock *) This->Handles[BlockHandle - 1].ptr);
5962 LeaveCriticalSection(&ddraw_cs);
5963 return hr_ddraw_from_wined3d(hr);
5966 static HRESULT WINAPI
5967 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUSetup(IDirect3DDevice7 *iface,
5970 return IDirect3DDeviceImpl_7_ApplyStateBlock(iface, BlockHandle);
5973 static HRESULT WINAPI
5974 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUPreserve(IDirect3DDevice7 *iface,
5980 old_fpucw = d3d_fpu_setup();
5981 hr = IDirect3DDeviceImpl_7_ApplyStateBlock(iface, BlockHandle);
5982 set_fpu_control_word(old_fpucw);
5987 /*****************************************************************************
5988 * IDirect3DDevice7::CaptureStateBlock
5990 * Updates a stateblock's values to the values currently set for the device
5995 * BlockHandle: Stateblock to update
5999 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is NULL
6000 * See IWineD3DDevice::CaptureStateBlock for more details
6002 *****************************************************************************/
6004 IDirect3DDeviceImpl_7_CaptureStateBlock(IDirect3DDevice7 *iface,
6007 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
6009 TRACE("(%p)->(%08x): Relay!\n", This, BlockHandle);
6011 EnterCriticalSection(&ddraw_cs);
6012 if(BlockHandle == 0 || BlockHandle > This->numHandles)
6014 WARN("Out of range handle %d, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle);
6015 LeaveCriticalSection(&ddraw_cs);
6016 return D3DERR_INVALIDSTATEBLOCK;
6018 if(This->Handles[BlockHandle - 1].type != DDrawHandle_StateBlock)
6020 WARN("Handle %d is not a stateblock, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle);
6021 LeaveCriticalSection(&ddraw_cs);
6022 return D3DERR_INVALIDSTATEBLOCK;
6025 hr = IWineD3DStateBlock_Capture((IWineD3DStateBlock *) This->Handles[BlockHandle - 1].ptr);
6026 LeaveCriticalSection(&ddraw_cs);
6027 return hr_ddraw_from_wined3d(hr);
6030 static HRESULT WINAPI
6031 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUSetup(IDirect3DDevice7 *iface,
6034 return IDirect3DDeviceImpl_7_CaptureStateBlock(iface, BlockHandle);
6037 static HRESULT WINAPI
6038 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUPreserve(IDirect3DDevice7 *iface,
6044 old_fpucw = d3d_fpu_setup();
6045 hr = IDirect3DDeviceImpl_7_CaptureStateBlock(iface, BlockHandle);
6046 set_fpu_control_word(old_fpucw);
6051 /*****************************************************************************
6052 * IDirect3DDevice7::DeleteStateBlock
6054 * Deletes a stateblock handle. This means releasing the WineD3DStateBlock
6059 * BlockHandle: Stateblock handle to delete
6063 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is 0
6065 *****************************************************************************/
6067 IDirect3DDeviceImpl_7_DeleteStateBlock(IDirect3DDevice7 *iface,
6070 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
6072 TRACE("(%p)->(%08x): Relay!\n", This, BlockHandle);
6074 EnterCriticalSection(&ddraw_cs);
6075 if(BlockHandle == 0 || BlockHandle > This->numHandles)
6077 WARN("Out of range handle %d, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle);
6078 LeaveCriticalSection(&ddraw_cs);
6079 return D3DERR_INVALIDSTATEBLOCK;
6081 if(This->Handles[BlockHandle - 1].type != DDrawHandle_StateBlock)
6083 WARN("Handle %d is not a stateblock, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle);
6084 LeaveCriticalSection(&ddraw_cs);
6085 return D3DERR_INVALIDSTATEBLOCK;
6088 ref = IWineD3DStateBlock_Release((IWineD3DStateBlock *) This->Handles[BlockHandle - 1].ptr);
6091 ERR("Something is still holding the stateblock %p(Handle %d). Ref = %d\n", This->Handles[BlockHandle - 1].ptr, BlockHandle, ref);
6093 This->Handles[BlockHandle - 1].ptr = NULL;
6094 This->Handles[BlockHandle - 1].type = DDrawHandle_Unknown;
6096 LeaveCriticalSection(&ddraw_cs);
6100 static HRESULT WINAPI
6101 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUSetup(IDirect3DDevice7 *iface,
6104 return IDirect3DDeviceImpl_7_DeleteStateBlock(iface, BlockHandle);
6107 static HRESULT WINAPI
6108 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUPreserve(IDirect3DDevice7 *iface,
6114 old_fpucw = d3d_fpu_setup();
6115 hr = IDirect3DDeviceImpl_7_DeleteStateBlock(iface, BlockHandle);
6116 set_fpu_control_word(old_fpucw);
6121 /*****************************************************************************
6122 * IDirect3DDevice7::CreateStateBlock
6124 * Creates a new state block handle.
6129 * Type: The state block type
6130 * BlockHandle: Address to write the created handle to
6134 * DDERR_INVALIDPARAMS if BlockHandle is NULL
6136 *****************************************************************************/
6138 IDirect3DDeviceImpl_7_CreateStateBlock(IDirect3DDevice7 *iface,
6139 D3DSTATEBLOCKTYPE Type,
6142 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
6144 TRACE("(%p)->(%08x,%p)!\n", This, Type, BlockHandle);
6148 WARN("BlockHandle == NULL, returning DDERR_INVALIDPARAMS\n");
6149 return DDERR_INVALIDPARAMS;
6151 if(Type != D3DSBT_ALL && Type != D3DSBT_PIXELSTATE &&
6152 Type != D3DSBT_VERTEXSTATE ) {
6153 WARN("Unexpected stateblock type, returning DDERR_INVALIDPARAMS\n");
6154 return DDERR_INVALIDPARAMS;
6157 EnterCriticalSection(&ddraw_cs);
6158 *BlockHandle = IDirect3DDeviceImpl_CreateHandle(This);
6161 ERR("Cannot get a handle number for the stateblock\n");
6162 LeaveCriticalSection(&ddraw_cs);
6163 return DDERR_OUTOFMEMORY;
6165 This->Handles[*BlockHandle - 1].type = DDrawHandle_StateBlock;
6167 /* The D3DSTATEBLOCKTYPE enum is fine here */
6168 hr = IWineD3DDevice_CreateStateBlock(This->wineD3DDevice,
6170 (IWineD3DStateBlock **) &This->Handles[*BlockHandle - 1].ptr,
6171 NULL /* Parent, hope that works */);
6172 LeaveCriticalSection(&ddraw_cs);
6173 return hr_ddraw_from_wined3d(hr);
6176 static HRESULT WINAPI
6177 IDirect3DDeviceImpl_7_CreateStateBlock_FPUSetup(IDirect3DDevice7 *iface,
6178 D3DSTATEBLOCKTYPE Type,
6181 return IDirect3DDeviceImpl_7_CreateStateBlock(iface, Type, BlockHandle);
6184 static HRESULT WINAPI
6185 IDirect3DDeviceImpl_7_CreateStateBlock_FPUPreserve(IDirect3DDevice7 *iface,
6186 D3DSTATEBLOCKTYPE Type,
6192 old_fpucw = d3d_fpu_setup();
6193 hr =IDirect3DDeviceImpl_7_CreateStateBlock(iface, Type, BlockHandle);
6194 set_fpu_control_word(old_fpucw);
6199 /* Helper function for IDirect3DDeviceImpl_7_Load. */
6200 static BOOL is_mip_level_subset(IDirectDrawSurfaceImpl *dest,
6201 IDirectDrawSurfaceImpl *src)
6203 IDirectDrawSurfaceImpl *src_level, *dest_level;
6204 IDirectDrawSurface7 *temp;
6205 DDSURFACEDESC2 ddsd;
6206 BOOL levelFound; /* at least one suitable sublevel in dest found */
6208 /* To satisfy "destination is mip level subset of source" criteria (regular texture counts as 1 level),
6209 * 1) there must be at least one mip level in destination that matched dimensions of some mip level in source and
6210 * 2) there must be no destination levels that don't match any levels in source. Otherwise it's INVALIDPARAMS.
6217 for (;src_level && dest_level;)
6219 if (src_level->surface_desc.dwWidth == dest_level->surface_desc.dwWidth &&
6220 src_level->surface_desc.dwHeight == dest_level->surface_desc.dwHeight)
6224 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
6225 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_MIPMAPSUBLEVEL;
6226 IDirectDrawSurface7_GetAttachedSurface(ICOM_INTERFACE(dest_level, IDirectDrawSurface7), &ddsd.ddsCaps, &temp);
6228 if (dest_level != dest) IDirectDrawSurface7_Release(ICOM_INTERFACE(dest_level, IDirectDrawSurface7));
6230 dest_level = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, temp);
6233 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
6234 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_MIPMAPSUBLEVEL;
6235 IDirectDrawSurface7_GetAttachedSurface(ICOM_INTERFACE(src_level, IDirectDrawSurface7), &ddsd.ddsCaps, &temp);
6237 if (src_level != src) IDirectDrawSurface7_Release(ICOM_INTERFACE(src_level, IDirectDrawSurface7));
6239 src_level = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, temp);
6242 if (src_level && src_level != src) IDirectDrawSurface7_Release(ICOM_INTERFACE(src_level, IDirectDrawSurface7));
6243 if (dest_level && dest_level != dest) IDirectDrawSurface7_Release(ICOM_INTERFACE(dest_level, IDirectDrawSurface7));
6245 return !dest_level && levelFound;
6248 /* Helper function for IDirect3DDeviceImpl_7_Load. */
6249 static void copy_mipmap_chain(IDirect3DDeviceImpl *device,
6250 IDirectDrawSurfaceImpl *dest,
6251 IDirectDrawSurfaceImpl *src,
6255 IDirectDrawSurfaceImpl *src_level, *dest_level;
6256 IDirectDrawSurface7 *temp;
6257 DDSURFACEDESC2 ddsd;
6261 IDirectDrawPalette *pal = NULL, *pal_src = NULL;
6264 BOOL palette_missing = FALSE;
6266 /* Copy palette, if possible. */
6267 IDirectDrawSurface7_GetPalette(ICOM_INTERFACE(src, IDirectDrawSurface7), &pal_src);
6268 IDirectDrawSurface7_GetPalette(ICOM_INTERFACE(dest, IDirectDrawSurface7), &pal);
6270 if (pal_src != NULL && pal != NULL)
6272 PALETTEENTRY palent[256];
6274 IDirectDrawPalette_GetEntries(pal_src, 0, 0, 256, palent);
6275 IDirectDrawPalette_SetEntries(pal, 0, 0, 256, palent);
6278 if (dest->surface_desc.u4.ddpfPixelFormat.dwFlags & (DDPF_PALETTEINDEXED1 | DDPF_PALETTEINDEXED2 |
6279 DDPF_PALETTEINDEXED4 | DDPF_PALETTEINDEXED8 | DDPF_PALETTEINDEXEDTO8) && !pal)
6281 palette_missing = TRUE;
6284 if (pal) IDirectDrawPalette_Release(pal);
6285 if (pal_src) IDirectDrawPalette_Release(pal_src);
6287 /* Copy colorkeys, if present. */
6288 for (ckeyflag = DDCKEY_DESTBLT; ckeyflag <= DDCKEY_SRCOVERLAY; ckeyflag <<= 1)
6290 hr = IDirectDrawSurface7_GetColorKey(ICOM_INTERFACE(src, IDirectDrawSurface7), ckeyflag, &ddckey);
6294 IDirectDrawSurface7_SetColorKey(ICOM_INTERFACE(dest, IDirectDrawSurface7), ckeyflag, &ddckey);
6304 for (;src_level && dest_level;)
6306 if (src_level->surface_desc.dwWidth == dest_level->surface_desc.dwWidth &&
6307 src_level->surface_desc.dwHeight == dest_level->surface_desc.dwHeight)
6309 /* Try UpdateSurface that may perform a more direct opengl loading. But skip this if destination is paletted texture and has no palette.
6310 * Some games like Sacrifice set palette after Load, and it is a waste of effort to try to load texture without palette and generates
6311 * warnings in wined3d. */
6312 if (!palette_missing)
6313 hr = IWineD3DDevice_UpdateSurface(device->wineD3DDevice, src_level->WineD3DSurface, &rect, dest_level->WineD3DSurface,
6316 if (palette_missing || FAILED(hr))
6318 /* UpdateSurface may fail e.g. if dest is in system memory. Fall back to BltFast that is less strict. */
6319 IWineD3DSurface_BltFast(dest_level->WineD3DSurface,
6321 src_level->WineD3DSurface, &rect, 0);
6324 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
6325 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_MIPMAPSUBLEVEL;
6326 IDirectDrawSurface7_GetAttachedSurface(ICOM_INTERFACE(dest_level, IDirectDrawSurface7), &ddsd.ddsCaps, &temp);
6328 if (dest_level != dest) IDirectDrawSurface7_Release(ICOM_INTERFACE(dest_level, IDirectDrawSurface7));
6330 dest_level = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, temp);
6333 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
6334 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_MIPMAPSUBLEVEL;
6335 IDirectDrawSurface7_GetAttachedSurface(ICOM_INTERFACE(src_level, IDirectDrawSurface7), &ddsd.ddsCaps, &temp);
6337 if (src_level != src) IDirectDrawSurface7_Release(ICOM_INTERFACE(src_level, IDirectDrawSurface7));
6339 src_level = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, temp);
6346 rect.right = (rect.right + 1) / 2;
6347 rect.bottom = (rect.bottom + 1) / 2;
6350 if (src_level && src_level != src) IDirectDrawSurface7_Release(ICOM_INTERFACE(src_level, IDirectDrawSurface7));
6351 if (dest_level && dest_level != dest) IDirectDrawSurface7_Release(ICOM_INTERFACE(dest_level, IDirectDrawSurface7));
6354 /*****************************************************************************
6355 * IDirect3DDevice7::Load
6357 * Loads a rectangular area from the source into the destination texture.
6358 * It can also copy the source to the faces of a cubic environment map
6363 * DestTex: Destination texture
6364 * DestPoint: Point in the destination where the source image should be
6366 * SrcTex: Source texture
6367 * SrcRect: Source rectangle
6368 * Flags: Cubemap faces to load (DDSCAPS2_CUBEMAP_ALLFACES, DDSCAPS2_CUBEMAP_POSITIVEX,
6369 * DDSCAPS2_CUBEMAP_NEGATIVEX, DDSCAPS2_CUBEMAP_POSITIVEY, DDSCAPS2_CUBEMAP_NEGATIVEY,
6370 * DDSCAPS2_CUBEMAP_POSITIVEZ, DDSCAPS2_CUBEMAP_NEGATIVEZ)
6374 * DDERR_INVALIDPARAMS if DestTex or SrcTex are NULL, broken coordinates or anything unexpected.
6377 *****************************************************************************/
6380 IDirect3DDeviceImpl_7_Load(IDirect3DDevice7 *iface,
6381 IDirectDrawSurface7 *DestTex,
6383 IDirectDrawSurface7 *SrcTex,
6387 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
6388 IDirectDrawSurfaceImpl *dest = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, DestTex);
6389 IDirectDrawSurfaceImpl *src = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, SrcTex);
6392 TRACE("(%p)->(%p,%p,%p,%p,%08x)\n", This, dest, DestPoint, src, SrcRect, Flags);
6394 if( (!src) || (!dest) )
6395 return DDERR_INVALIDPARAMS;
6397 EnterCriticalSection(&ddraw_cs);
6399 if (SrcRect) srcrect = *SrcRect;
6402 srcrect.left = srcrect.top = 0;
6403 srcrect.right = src->surface_desc.dwWidth;
6404 srcrect.bottom = src->surface_desc.dwHeight;
6407 if (DestPoint) destpoint = *DestPoint;
6410 destpoint.x = destpoint.y = 0;
6412 /* Check bad dimensions. DestPoint is validated against src, not dest, because
6413 * destination can be a subset of mip levels, in which case actual coordinates used
6414 * for it may be divided. If any dimension of dest is larger than source, it can't be
6415 * mip level subset, so an error can be returned early.
6417 if (srcrect.left >= srcrect.right || srcrect.top >= srcrect.bottom ||
6418 srcrect.right > src->surface_desc.dwWidth ||
6419 srcrect.bottom > src->surface_desc.dwHeight ||
6420 destpoint.x + srcrect.right - srcrect.left > src->surface_desc.dwWidth ||
6421 destpoint.y + srcrect.bottom - srcrect.top > src->surface_desc.dwHeight ||
6422 dest->surface_desc.dwWidth > src->surface_desc.dwWidth ||
6423 dest->surface_desc.dwHeight > src->surface_desc.dwHeight)
6425 LeaveCriticalSection(&ddraw_cs);
6426 return DDERR_INVALIDPARAMS;
6429 /* Must be top level surfaces. */
6430 if (src->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_MIPMAPSUBLEVEL ||
6431 dest->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_MIPMAPSUBLEVEL)
6433 LeaveCriticalSection(&ddraw_cs);
6434 return DDERR_INVALIDPARAMS;
6437 if (src->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP)
6439 DWORD src_face_flag, dest_face_flag;
6440 IDirectDrawSurfaceImpl *src_face, *dest_face;
6441 IDirectDrawSurface7 *temp;
6442 DDSURFACEDESC2 ddsd;
6445 if (!(dest->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP))
6447 LeaveCriticalSection(&ddraw_cs);
6448 return DDERR_INVALIDPARAMS;
6451 /* Iterate through cube faces 2 times. First time is just to check INVALIDPARAMS conditions, second
6452 * time it's actual surface loading. */
6453 for (i = 0; i < 2; i++)
6458 for (;dest_face && src_face;)
6460 src_face_flag = src_face->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP_ALLFACES;
6461 dest_face_flag = dest_face->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP_ALLFACES;
6463 if (src_face_flag == dest_face_flag)
6467 /* Destination mip levels must be subset of source mip levels. */
6468 if (!is_mip_level_subset(dest_face, src_face))
6470 LeaveCriticalSection(&ddraw_cs);
6471 return DDERR_INVALIDPARAMS;
6474 else if (Flags & dest_face_flag)
6476 copy_mipmap_chain(This, dest_face, src_face, &destpoint, &srcrect);
6479 if (src_face_flag < DDSCAPS2_CUBEMAP_NEGATIVEZ)
6481 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
6482 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | (src_face_flag << 1);
6483 IDirectDrawSurface7_GetAttachedSurface(ICOM_INTERFACE(src, IDirectDrawSurface7), &ddsd.ddsCaps, &temp);
6485 if (src_face != src) IDirectDrawSurface7_Release(ICOM_INTERFACE(src_face, IDirectDrawSurface7));
6487 src_face = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, temp);
6491 if (src_face != src) IDirectDrawSurface7_Release(ICOM_INTERFACE(src_face, IDirectDrawSurface7));
6497 if (dest_face_flag < DDSCAPS2_CUBEMAP_NEGATIVEZ)
6499 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
6500 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | (dest_face_flag << 1);
6501 IDirectDrawSurface7_GetAttachedSurface(ICOM_INTERFACE(dest, IDirectDrawSurface7), &ddsd.ddsCaps, &temp);
6503 if (dest_face != dest) IDirectDrawSurface7_Release(ICOM_INTERFACE(dest_face, IDirectDrawSurface7));
6505 dest_face = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, temp);
6509 if (dest_face != dest) IDirectDrawSurface7_Release(ICOM_INTERFACE(dest_face, IDirectDrawSurface7));
6517 /* Native returns error if src faces are not subset of dest faces. */
6520 LeaveCriticalSection(&ddraw_cs);
6521 return DDERR_INVALIDPARAMS;
6526 LeaveCriticalSection(&ddraw_cs);
6529 else if (dest->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP)
6531 LeaveCriticalSection(&ddraw_cs);
6532 return DDERR_INVALIDPARAMS;
6535 /* Handle non cube map textures. */
6537 /* Destination mip levels must be subset of source mip levels. */
6538 if (!is_mip_level_subset(dest, src))
6540 LeaveCriticalSection(&ddraw_cs);
6541 return DDERR_INVALIDPARAMS;
6544 copy_mipmap_chain(This, dest, src, &destpoint, &srcrect);
6546 LeaveCriticalSection(&ddraw_cs);
6550 static HRESULT WINAPI
6551 IDirect3DDeviceImpl_7_Load_FPUSetup(IDirect3DDevice7 *iface,
6552 IDirectDrawSurface7 *DestTex,
6554 IDirectDrawSurface7 *SrcTex,
6558 return IDirect3DDeviceImpl_7_Load(iface, DestTex, DestPoint, SrcTex, SrcRect, Flags);
6561 static HRESULT WINAPI
6562 IDirect3DDeviceImpl_7_Load_FPUPreserve(IDirect3DDevice7 *iface,
6563 IDirectDrawSurface7 *DestTex,
6565 IDirectDrawSurface7 *SrcTex,
6572 old_fpucw = d3d_fpu_setup();
6573 hr = IDirect3DDeviceImpl_7_Load(iface, DestTex, DestPoint, SrcTex, SrcRect, Flags);
6574 set_fpu_control_word(old_fpucw);
6579 /*****************************************************************************
6580 * IDirect3DDevice7::LightEnable
6582 * Enables or disables a light
6584 * Version 7, IDirect3DLight uses this method too.
6587 * LightIndex: The index of the light to enable / disable
6588 * Enable: Enable or disable the light
6592 * For more details, see IWineD3DDevice::SetLightEnable
6594 *****************************************************************************/
6596 IDirect3DDeviceImpl_7_LightEnable(IDirect3DDevice7 *iface,
6600 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
6602 TRACE("(%p)->(%08x,%d): Relay!\n", This, LightIndex, Enable);
6604 EnterCriticalSection(&ddraw_cs);
6605 hr = IWineD3DDevice_SetLightEnable(This->wineD3DDevice, LightIndex, Enable);
6606 LeaveCriticalSection(&ddraw_cs);
6607 return hr_ddraw_from_wined3d(hr);
6610 static HRESULT WINAPI
6611 IDirect3DDeviceImpl_7_LightEnable_FPUSetup(IDirect3DDevice7 *iface,
6615 return IDirect3DDeviceImpl_7_LightEnable(iface, LightIndex, Enable);
6618 static HRESULT WINAPI
6619 IDirect3DDeviceImpl_7_LightEnable_FPUPreserve(IDirect3DDevice7 *iface,
6626 old_fpucw = d3d_fpu_setup();
6627 hr = IDirect3DDeviceImpl_7_LightEnable(iface, LightIndex, Enable);
6628 set_fpu_control_word(old_fpucw);
6633 /*****************************************************************************
6634 * IDirect3DDevice7::GetLightEnable
6636 * Retrieves if the light with the given index is enabled or not
6641 * LightIndex: Index of desired light
6642 * Enable: Pointer to a BOOL which contains the result
6646 * DDERR_INVALIDPARAMS if Enable is NULL
6647 * See IWineD3DDevice::GetLightEnable for more details
6649 *****************************************************************************/
6651 IDirect3DDeviceImpl_7_GetLightEnable(IDirect3DDevice7 *iface,
6655 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
6657 TRACE("(%p)->(%08x,%p): Relay\n", This, LightIndex, Enable);
6660 return DDERR_INVALIDPARAMS;
6662 EnterCriticalSection(&ddraw_cs);
6663 hr = IWineD3DDevice_GetLightEnable(This->wineD3DDevice, LightIndex, Enable);
6664 LeaveCriticalSection(&ddraw_cs);
6665 return hr_ddraw_from_wined3d(hr);
6668 static HRESULT WINAPI
6669 IDirect3DDeviceImpl_7_GetLightEnable_FPUSetup(IDirect3DDevice7 *iface,
6673 return IDirect3DDeviceImpl_7_GetLightEnable(iface, LightIndex, Enable);
6676 static HRESULT WINAPI
6677 IDirect3DDeviceImpl_7_GetLightEnable_FPUPreserve(IDirect3DDevice7 *iface,
6684 old_fpucw = d3d_fpu_setup();
6685 hr = IDirect3DDeviceImpl_7_GetLightEnable(iface, LightIndex, Enable);
6686 set_fpu_control_word(old_fpucw);
6691 /*****************************************************************************
6692 * IDirect3DDevice7::SetClipPlane
6694 * Sets custom clipping plane
6699 * Index: The index of the clipping plane
6700 * PlaneEquation: An equation defining the clipping plane
6704 * DDERR_INVALIDPARAMS if PlaneEquation is NULL
6705 * See IWineD3DDevice::SetClipPlane for more details
6707 *****************************************************************************/
6709 IDirect3DDeviceImpl_7_SetClipPlane(IDirect3DDevice7 *iface,
6711 D3DVALUE* PlaneEquation)
6713 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
6715 TRACE("(%p)->(%08x,%p): Relay!\n", This, Index, PlaneEquation);
6718 return DDERR_INVALIDPARAMS;
6720 EnterCriticalSection(&ddraw_cs);
6721 hr = IWineD3DDevice_SetClipPlane(This->wineD3DDevice, Index, PlaneEquation);
6722 LeaveCriticalSection(&ddraw_cs);
6726 static HRESULT WINAPI
6727 IDirect3DDeviceImpl_7_SetClipPlane_FPUSetup(IDirect3DDevice7 *iface,
6729 D3DVALUE* PlaneEquation)
6731 return IDirect3DDeviceImpl_7_SetClipPlane(iface, Index, PlaneEquation);
6734 static HRESULT WINAPI
6735 IDirect3DDeviceImpl_7_SetClipPlane_FPUPreserve(IDirect3DDevice7 *iface,
6737 D3DVALUE* PlaneEquation)
6742 old_fpucw = d3d_fpu_setup();
6743 hr = IDirect3DDeviceImpl_7_SetClipPlane(iface, Index, PlaneEquation);
6744 set_fpu_control_word(old_fpucw);
6749 /*****************************************************************************
6750 * IDirect3DDevice7::GetClipPlane
6752 * Returns the clipping plane with a specific index
6755 * Index: The index of the desired plane
6756 * PlaneEquation: Address to store the plane equation to
6760 * DDERR_INVALIDPARAMS if PlaneEquation is NULL
6761 * See IWineD3DDevice::GetClipPlane for more details
6763 *****************************************************************************/
6765 IDirect3DDeviceImpl_7_GetClipPlane(IDirect3DDevice7 *iface,
6767 D3DVALUE* PlaneEquation)
6769 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
6771 TRACE("(%p)->(%d,%p): Relay!\n", This, Index, PlaneEquation);
6774 return DDERR_INVALIDPARAMS;
6776 EnterCriticalSection(&ddraw_cs);
6777 hr = IWineD3DDevice_GetClipPlane(This->wineD3DDevice, Index, PlaneEquation);
6778 LeaveCriticalSection(&ddraw_cs);
6782 static HRESULT WINAPI
6783 IDirect3DDeviceImpl_7_GetClipPlane_FPUSetup(IDirect3DDevice7 *iface,
6785 D3DVALUE* PlaneEquation)
6787 return IDirect3DDeviceImpl_7_GetClipPlane(iface, Index, PlaneEquation);
6790 static HRESULT WINAPI
6791 IDirect3DDeviceImpl_7_GetClipPlane_FPUPreserve(IDirect3DDevice7 *iface,
6793 D3DVALUE* PlaneEquation)
6798 old_fpucw = d3d_fpu_setup();
6799 hr = IDirect3DDeviceImpl_7_GetClipPlane(iface, Index, PlaneEquation);
6800 set_fpu_control_word(old_fpucw);
6805 /*****************************************************************************
6806 * IDirect3DDevice7::GetInfo
6808 * Retrieves some information about the device. The DirectX sdk says that
6809 * this version returns S_FALSE for all retail builds of DirectX, that's what
6810 * this implementation does.
6813 * DevInfoID: Information type requested
6814 * DevInfoStruct: Pointer to a structure to store the info to
6815 * Size: Size of the structure
6818 * S_FALSE, because it's a non-debug driver
6820 *****************************************************************************/
6821 static HRESULT WINAPI
6822 IDirect3DDeviceImpl_7_GetInfo(IDirect3DDevice7 *iface,
6824 void *DevInfoStruct,
6827 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
6828 TRACE("(%p)->(%08x,%p,%08x)\n", This, DevInfoID, DevInfoStruct, Size);
6832 TRACE(" info requested : ");
6835 case D3DDEVINFOID_TEXTUREMANAGER: TRACE("D3DDEVINFOID_TEXTUREMANAGER\n"); break;
6836 case D3DDEVINFOID_D3DTEXTUREMANAGER: TRACE("D3DDEVINFOID_D3DTEXTUREMANAGER\n"); break;
6837 case D3DDEVINFOID_TEXTURING: TRACE("D3DDEVINFOID_TEXTURING\n"); break;
6838 default: ERR(" invalid flag !!!\n"); return DDERR_INVALIDPARAMS;
6842 return S_FALSE; /* According to MSDN, this is valid for a non-debug driver */
6845 /* For performance optimization, devices created in FPUSETUP and FPUPRESERVE modes
6846 * have separate vtables. Simple functions where this doesn't matter like GetDirect3D
6847 * are not duplicated.
6849 * Device created with DDSCL_FPUSETUP (d3d7 default) - device methods assume that FPU
6850 * has already been setup for optimal d3d operation.
6852 * Device created with DDSCL_FPUPRESERVE - resets and restores FPU mode when necessary in
6853 * d3d calls (FPU may be in a mode non-suitable for d3d when the app calls d3d). Required
6854 * by Sacrifice (game). */
6855 const IDirect3DDevice7Vtbl IDirect3DDevice7_FPUSetup_Vtbl =
6857 /*** IUnknown Methods ***/
6858 IDirect3DDeviceImpl_7_QueryInterface,
6859 IDirect3DDeviceImpl_7_AddRef,
6860 IDirect3DDeviceImpl_7_Release,
6861 /*** IDirect3DDevice7 ***/
6862 IDirect3DDeviceImpl_7_GetCaps_FPUSetup,
6863 IDirect3DDeviceImpl_7_EnumTextureFormats_FPUSetup,
6864 IDirect3DDeviceImpl_7_BeginScene_FPUSetup,
6865 IDirect3DDeviceImpl_7_EndScene_FPUSetup,
6866 IDirect3DDeviceImpl_7_GetDirect3D,
6867 IDirect3DDeviceImpl_7_SetRenderTarget_FPUSetup,
6868 IDirect3DDeviceImpl_7_GetRenderTarget,
6869 IDirect3DDeviceImpl_7_Clear_FPUSetup,
6870 IDirect3DDeviceImpl_7_SetTransform_FPUSetup,
6871 IDirect3DDeviceImpl_7_GetTransform_FPUSetup,
6872 IDirect3DDeviceImpl_7_SetViewport_FPUSetup,
6873 IDirect3DDeviceImpl_7_MultiplyTransform_FPUSetup,
6874 IDirect3DDeviceImpl_7_GetViewport_FPUSetup,
6875 IDirect3DDeviceImpl_7_SetMaterial_FPUSetup,
6876 IDirect3DDeviceImpl_7_GetMaterial_FPUSetup,
6877 IDirect3DDeviceImpl_7_SetLight_FPUSetup,
6878 IDirect3DDeviceImpl_7_GetLight_FPUSetup,
6879 IDirect3DDeviceImpl_7_SetRenderState_FPUSetup,
6880 IDirect3DDeviceImpl_7_GetRenderState_FPUSetup,
6881 IDirect3DDeviceImpl_7_BeginStateBlock_FPUSetup,
6882 IDirect3DDeviceImpl_7_EndStateBlock_FPUSetup,
6883 IDirect3DDeviceImpl_7_PreLoad_FPUSetup,
6884 IDirect3DDeviceImpl_7_DrawPrimitive_FPUSetup,
6885 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUSetup,
6886 IDirect3DDeviceImpl_7_SetClipStatus,
6887 IDirect3DDeviceImpl_7_GetClipStatus,
6888 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUSetup,
6889 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUSetup,
6890 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUSetup,
6891 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUSetup,
6892 IDirect3DDeviceImpl_7_ComputeSphereVisibility,
6893 IDirect3DDeviceImpl_7_GetTexture_FPUSetup,
6894 IDirect3DDeviceImpl_7_SetTexture_FPUSetup,
6895 IDirect3DDeviceImpl_7_GetTextureStageState_FPUSetup,
6896 IDirect3DDeviceImpl_7_SetTextureStageState_FPUSetup,
6897 IDirect3DDeviceImpl_7_ValidateDevice_FPUSetup,
6898 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUSetup,
6899 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUSetup,
6900 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUSetup,
6901 IDirect3DDeviceImpl_7_CreateStateBlock_FPUSetup,
6902 IDirect3DDeviceImpl_7_Load_FPUSetup,
6903 IDirect3DDeviceImpl_7_LightEnable_FPUSetup,
6904 IDirect3DDeviceImpl_7_GetLightEnable_FPUSetup,
6905 IDirect3DDeviceImpl_7_SetClipPlane_FPUSetup,
6906 IDirect3DDeviceImpl_7_GetClipPlane_FPUSetup,
6907 IDirect3DDeviceImpl_7_GetInfo
6910 const IDirect3DDevice7Vtbl IDirect3DDevice7_FPUPreserve_Vtbl =
6912 /*** IUnknown Methods ***/
6913 IDirect3DDeviceImpl_7_QueryInterface,
6914 IDirect3DDeviceImpl_7_AddRef,
6915 IDirect3DDeviceImpl_7_Release,
6916 /*** IDirect3DDevice7 ***/
6917 IDirect3DDeviceImpl_7_GetCaps_FPUPreserve,
6918 IDirect3DDeviceImpl_7_EnumTextureFormats_FPUPreserve,
6919 IDirect3DDeviceImpl_7_BeginScene_FPUPreserve,
6920 IDirect3DDeviceImpl_7_EndScene_FPUPreserve,
6921 IDirect3DDeviceImpl_7_GetDirect3D,
6922 IDirect3DDeviceImpl_7_SetRenderTarget_FPUPreserve,
6923 IDirect3DDeviceImpl_7_GetRenderTarget,
6924 IDirect3DDeviceImpl_7_Clear_FPUPreserve,
6925 IDirect3DDeviceImpl_7_SetTransform_FPUPreserve,
6926 IDirect3DDeviceImpl_7_GetTransform_FPUPreserve,
6927 IDirect3DDeviceImpl_7_SetViewport_FPUPreserve,
6928 IDirect3DDeviceImpl_7_MultiplyTransform_FPUPreserve,
6929 IDirect3DDeviceImpl_7_GetViewport_FPUPreserve,
6930 IDirect3DDeviceImpl_7_SetMaterial_FPUPreserve,
6931 IDirect3DDeviceImpl_7_GetMaterial_FPUPreserve,
6932 IDirect3DDeviceImpl_7_SetLight_FPUPreserve,
6933 IDirect3DDeviceImpl_7_GetLight_FPUPreserve,
6934 IDirect3DDeviceImpl_7_SetRenderState_FPUPreserve,
6935 IDirect3DDeviceImpl_7_GetRenderState_FPUPreserve,
6936 IDirect3DDeviceImpl_7_BeginStateBlock_FPUPreserve,
6937 IDirect3DDeviceImpl_7_EndStateBlock_FPUPreserve,
6938 IDirect3DDeviceImpl_7_PreLoad_FPUPreserve,
6939 IDirect3DDeviceImpl_7_DrawPrimitive_FPUPreserve,
6940 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUPreserve,
6941 IDirect3DDeviceImpl_7_SetClipStatus,
6942 IDirect3DDeviceImpl_7_GetClipStatus,
6943 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUPreserve,
6944 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUPreserve,
6945 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUPreserve,
6946 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUPreserve,
6947 IDirect3DDeviceImpl_7_ComputeSphereVisibility,
6948 IDirect3DDeviceImpl_7_GetTexture_FPUPreserve,
6949 IDirect3DDeviceImpl_7_SetTexture_FPUPreserve,
6950 IDirect3DDeviceImpl_7_GetTextureStageState_FPUPreserve,
6951 IDirect3DDeviceImpl_7_SetTextureStageState_FPUPreserve,
6952 IDirect3DDeviceImpl_7_ValidateDevice_FPUPreserve,
6953 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUPreserve,
6954 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUPreserve,
6955 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUPreserve,
6956 IDirect3DDeviceImpl_7_CreateStateBlock_FPUPreserve,
6957 IDirect3DDeviceImpl_7_Load_FPUPreserve,
6958 IDirect3DDeviceImpl_7_LightEnable_FPUPreserve,
6959 IDirect3DDeviceImpl_7_GetLightEnable_FPUPreserve,
6960 IDirect3DDeviceImpl_7_SetClipPlane_FPUPreserve,
6961 IDirect3DDeviceImpl_7_GetClipPlane_FPUPreserve,
6962 IDirect3DDeviceImpl_7_GetInfo
6965 const IDirect3DDevice3Vtbl IDirect3DDevice3_Vtbl =
6967 /*** IUnknown Methods ***/
6968 Thunk_IDirect3DDeviceImpl_3_QueryInterface,
6969 Thunk_IDirect3DDeviceImpl_3_AddRef,
6970 Thunk_IDirect3DDeviceImpl_3_Release,
6971 /*** IDirect3DDevice3 ***/
6972 IDirect3DDeviceImpl_3_GetCaps,
6973 IDirect3DDeviceImpl_3_GetStats,
6974 IDirect3DDeviceImpl_3_AddViewport,
6975 IDirect3DDeviceImpl_3_DeleteViewport,
6976 IDirect3DDeviceImpl_3_NextViewport,
6977 Thunk_IDirect3DDeviceImpl_3_EnumTextureFormats,
6978 Thunk_IDirect3DDeviceImpl_3_BeginScene,
6979 Thunk_IDirect3DDeviceImpl_3_EndScene,
6980 Thunk_IDirect3DDeviceImpl_3_GetDirect3D,
6981 IDirect3DDeviceImpl_3_SetCurrentViewport,
6982 IDirect3DDeviceImpl_3_GetCurrentViewport,
6983 Thunk_IDirect3DDeviceImpl_3_SetRenderTarget,
6984 Thunk_IDirect3DDeviceImpl_3_GetRenderTarget,
6985 IDirect3DDeviceImpl_3_Begin,
6986 IDirect3DDeviceImpl_3_BeginIndexed,
6987 IDirect3DDeviceImpl_3_Vertex,
6988 IDirect3DDeviceImpl_3_Index,
6989 IDirect3DDeviceImpl_3_End,
6990 IDirect3DDeviceImpl_3_GetRenderState,
6991 IDirect3DDeviceImpl_3_SetRenderState,
6992 IDirect3DDeviceImpl_3_GetLightState,
6993 IDirect3DDeviceImpl_3_SetLightState,
6994 Thunk_IDirect3DDeviceImpl_3_SetTransform,
6995 Thunk_IDirect3DDeviceImpl_3_GetTransform,
6996 Thunk_IDirect3DDeviceImpl_3_MultiplyTransform,
6997 Thunk_IDirect3DDeviceImpl_3_DrawPrimitive,
6998 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitive,
6999 Thunk_IDirect3DDeviceImpl_3_SetClipStatus,
7000 Thunk_IDirect3DDeviceImpl_3_GetClipStatus,
7001 Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveStrided,
7002 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveStrided,
7003 Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveVB,
7004 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveVB,
7005 Thunk_IDirect3DDeviceImpl_3_ComputeSphereVisibility,
7006 Thunk_IDirect3DDeviceImpl_3_GetTexture,
7007 IDirect3DDeviceImpl_3_SetTexture,
7008 Thunk_IDirect3DDeviceImpl_3_GetTextureStageState,
7009 Thunk_IDirect3DDeviceImpl_3_SetTextureStageState,
7010 Thunk_IDirect3DDeviceImpl_3_ValidateDevice
7013 const IDirect3DDevice2Vtbl IDirect3DDevice2_Vtbl =
7015 /*** IUnknown Methods ***/
7016 Thunk_IDirect3DDeviceImpl_2_QueryInterface,
7017 Thunk_IDirect3DDeviceImpl_2_AddRef,
7018 Thunk_IDirect3DDeviceImpl_2_Release,
7019 /*** IDirect3DDevice2 ***/
7020 Thunk_IDirect3DDeviceImpl_2_GetCaps,
7021 IDirect3DDeviceImpl_2_SwapTextureHandles,
7022 Thunk_IDirect3DDeviceImpl_2_GetStats,
7023 Thunk_IDirect3DDeviceImpl_2_AddViewport,
7024 Thunk_IDirect3DDeviceImpl_2_DeleteViewport,
7025 Thunk_IDirect3DDeviceImpl_2_NextViewport,
7026 IDirect3DDeviceImpl_2_EnumTextureFormats,
7027 Thunk_IDirect3DDeviceImpl_2_BeginScene,
7028 Thunk_IDirect3DDeviceImpl_2_EndScene,
7029 Thunk_IDirect3DDeviceImpl_2_GetDirect3D,
7030 Thunk_IDirect3DDeviceImpl_2_SetCurrentViewport,
7031 Thunk_IDirect3DDeviceImpl_2_GetCurrentViewport,
7032 Thunk_IDirect3DDeviceImpl_2_SetRenderTarget,
7033 Thunk_IDirect3DDeviceImpl_2_GetRenderTarget,
7034 Thunk_IDirect3DDeviceImpl_2_Begin,
7035 Thunk_IDirect3DDeviceImpl_2_BeginIndexed,
7036 Thunk_IDirect3DDeviceImpl_2_Vertex,
7037 Thunk_IDirect3DDeviceImpl_2_Index,
7038 Thunk_IDirect3DDeviceImpl_2_End,
7039 Thunk_IDirect3DDeviceImpl_2_GetRenderState,
7040 Thunk_IDirect3DDeviceImpl_2_SetRenderState,
7041 Thunk_IDirect3DDeviceImpl_2_GetLightState,
7042 Thunk_IDirect3DDeviceImpl_2_SetLightState,
7043 Thunk_IDirect3DDeviceImpl_2_SetTransform,
7044 Thunk_IDirect3DDeviceImpl_2_GetTransform,
7045 Thunk_IDirect3DDeviceImpl_2_MultiplyTransform,
7046 Thunk_IDirect3DDeviceImpl_2_DrawPrimitive,
7047 Thunk_IDirect3DDeviceImpl_2_DrawIndexedPrimitive,
7048 Thunk_IDirect3DDeviceImpl_2_SetClipStatus,
7049 Thunk_IDirect3DDeviceImpl_2_GetClipStatus
7052 const IDirect3DDeviceVtbl IDirect3DDevice1_Vtbl =
7054 /*** IUnknown Methods ***/
7055 Thunk_IDirect3DDeviceImpl_1_QueryInterface,
7056 Thunk_IDirect3DDeviceImpl_1_AddRef,
7057 Thunk_IDirect3DDeviceImpl_1_Release,
7058 /*** IDirect3DDevice1 ***/
7059 IDirect3DDeviceImpl_1_Initialize,
7060 Thunk_IDirect3DDeviceImpl_1_GetCaps,
7061 Thunk_IDirect3DDeviceImpl_1_SwapTextureHandles,
7062 IDirect3DDeviceImpl_1_CreateExecuteBuffer,
7063 Thunk_IDirect3DDeviceImpl_1_GetStats,
7064 IDirect3DDeviceImpl_1_Execute,
7065 Thunk_IDirect3DDeviceImpl_1_AddViewport,
7066 Thunk_IDirect3DDeviceImpl_1_DeleteViewport,
7067 Thunk_IDirect3DDeviceImpl_1_NextViewport,
7068 IDirect3DDeviceImpl_1_Pick,
7069 IDirect3DDeviceImpl_1_GetPickRecords,
7070 Thunk_IDirect3DDeviceImpl_1_EnumTextureFormats,
7071 IDirect3DDeviceImpl_1_CreateMatrix,
7072 IDirect3DDeviceImpl_1_SetMatrix,
7073 IDirect3DDeviceImpl_1_GetMatrix,
7074 IDirect3DDeviceImpl_1_DeleteMatrix,
7075 Thunk_IDirect3DDeviceImpl_1_BeginScene,
7076 Thunk_IDirect3DDeviceImpl_1_EndScene,
7077 Thunk_IDirect3DDeviceImpl_1_GetDirect3D
7080 /*****************************************************************************
7081 * IDirect3DDeviceImpl_CreateHandle
7083 * Not called from the VTable
7085 * Some older interface versions operate with handles, which are basically
7086 * DWORDs which identify an interface, for example
7087 * IDirect3DDevice::SetRenderState with DIRECT3DRENDERSTATE_TEXTUREHANDLE
7089 * Those handle could be just casts to the interface pointers or vice versa,
7090 * but that is not 64 bit safe and would mean blindly derefering a DWORD
7091 * passed by the app. Instead there is a dynamic array in the device which
7092 * keeps a DWORD to pointer information and a type for the handle.
7094 * Basically this array only grows, when a handle is freed its pointer is
7095 * just set to NULL. There will be much more reads from the array than
7096 * insertion operations, so a dynamic array is fine.
7099 * This: D3DDevice implementation for which this handle should be created
7102 * A free handle on success
7105 *****************************************************************************/
7107 IDirect3DDeviceImpl_CreateHandle(IDirect3DDeviceImpl *This)
7110 struct HandleEntry *oldHandles = This->Handles;
7112 TRACE("(%p)\n", This);
7114 for(i = 0; i < This->numHandles; i++)
7116 if(This->Handles[i].ptr == NULL &&
7117 This->Handles[i].type == DDrawHandle_Unknown)
7119 TRACE("Reusing freed handle %d\n", i + 1);
7124 TRACE("Growing the handle array\n");
7127 This->Handles = HeapAlloc(GetProcessHeap(), 0, sizeof(struct HandleEntry) * This->numHandles);
7130 ERR("Out of memory\n");
7131 This->Handles = oldHandles;
7137 memcpy(This->Handles, oldHandles, (This->numHandles - 1) * sizeof(struct HandleEntry));
7138 HeapFree(GetProcessHeap(), 0, oldHandles);
7141 TRACE("Returning %d\n", This->numHandles);
7142 return This->numHandles;
7145 /*****************************************************************************
7146 * IDirect3DDeviceImpl_UpdateDepthStencil
7148 * Checks the current render target for attached depth stencils and sets the
7149 * WineD3D depth stencil accordingly.
7152 * The depth stencil state to set if creating the device
7154 *****************************************************************************/
7156 IDirect3DDeviceImpl_UpdateDepthStencil(IDirect3DDeviceImpl *This)
7158 IDirectDrawSurface7 *depthStencil = NULL;
7159 IDirectDrawSurfaceImpl *dsi;
7160 static DDSCAPS2 depthcaps = { DDSCAPS_ZBUFFER, 0, 0, 0 };
7162 IDirectDrawSurface7_GetAttachedSurface(ICOM_INTERFACE(This->target, IDirectDrawSurface7),
7167 TRACE("Setting wined3d depth stencil to NULL\n");
7168 IWineD3DDevice_SetDepthStencilSurface(This->wineD3DDevice,
7170 return WINED3DZB_FALSE;
7173 dsi = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, depthStencil);
7174 TRACE("Setting wined3d depth stencil to %p (wined3d %p)\n", dsi, dsi->WineD3DSurface);
7175 IWineD3DDevice_SetDepthStencilSurface(This->wineD3DDevice,
7176 dsi->WineD3DSurface);
7178 IDirectDrawSurface7_Release(depthStencil);
7179 return WINED3DZB_TRUE;