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 object->IDirect3DExecuteBuffer_vtbl = &IDirect3DExecuteBuffer_Vtbl;
756 object->d3ddev = This;
758 /* Initializes memory */
759 memcpy(&object->desc, Desc, Desc->dwSize);
761 /* No buffer given */
762 if ((object->desc.dwFlags & D3DDEB_LPDATA) == 0)
763 object->desc.lpData = NULL;
765 /* No buffer size given */
766 if ((object->desc.dwFlags & D3DDEB_BUFSIZE) == 0)
767 object->desc.dwBufferSize = 0;
769 /* Create buffer if asked */
770 if ((object->desc.lpData == NULL) && (object->desc.dwBufferSize > 0))
772 object->need_free = TRUE;
773 object->desc.lpData = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,object->desc.dwBufferSize);
774 if(!object->desc.lpData)
776 ERR("Out of memory when allocating the execute buffer data\n");
777 HeapFree(GetProcessHeap(), 0, object);
778 return DDERR_OUTOFMEMORY;
783 object->need_free = FALSE;
786 /* No vertices for the moment */
787 object->vertex_data = NULL;
789 object->desc.dwFlags |= D3DDEB_LPDATA;
791 object->indices = NULL;
792 object->nb_indices = 0;
794 *ExecuteBuffer = ICOM_INTERFACE(object, IDirect3DExecuteBuffer);
796 TRACE(" Returning IDirect3DExecuteBuffer at %p, implementation is at %p\n", *ExecuteBuffer, object);
801 /*****************************************************************************
802 * IDirect3DDevice::Execute
804 * Executes all the stuff in an execute buffer.
807 * ExecuteBuffer: The buffer to execute
808 * Viewport: The viewport used for rendering
812 * DDERR_INVALIDPARAMS if ExecuteBuffer == NULL
815 *****************************************************************************/
816 static HRESULT WINAPI
817 IDirect3DDeviceImpl_1_Execute(IDirect3DDevice *iface,
818 IDirect3DExecuteBuffer *ExecuteBuffer,
819 IDirect3DViewport *Viewport,
822 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
823 IDirect3DExecuteBufferImpl *Direct3DExecuteBufferImpl = ICOM_OBJECT(IDirect3DExecuteBufferImpl, IDirect3DExecuteBuffer, ExecuteBuffer);
824 IDirect3DViewportImpl *Direct3DViewportImpl = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Viewport);
826 TRACE("(%p)->(%p,%p,%08x)\n", This, Direct3DExecuteBufferImpl, Direct3DViewportImpl, Flags);
828 if(!Direct3DExecuteBufferImpl)
829 return DDERR_INVALIDPARAMS;
832 EnterCriticalSection(&ddraw_cs);
833 IDirect3DExecuteBufferImpl_Execute(Direct3DExecuteBufferImpl, This, Direct3DViewportImpl);
834 LeaveCriticalSection(&ddraw_cs);
839 /*****************************************************************************
840 * IDirect3DDevice3::AddViewport
842 * Add a Direct3DViewport to the device's viewport list. These viewports
843 * are wrapped to IDirect3DDevice7 viewports in viewport.c
845 * Exists in Version 1, 2 and 3. Note that IDirect3DViewport 1, 2 and 3
846 * are the same interfaces.
849 * Viewport: The viewport to add
852 * DDERR_INVALIDPARAMS if Viewport == NULL
855 *****************************************************************************/
856 static HRESULT WINAPI
857 IDirect3DDeviceImpl_3_AddViewport(IDirect3DDevice3 *iface,
858 IDirect3DViewport3 *Viewport)
860 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
861 IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Viewport);
863 TRACE("(%p)->(%p)\n", This, vp);
867 return DDERR_INVALIDPARAMS;
869 EnterCriticalSection(&ddraw_cs);
870 vp->next = This->viewport_list;
871 This->viewport_list = vp;
872 vp->active_device = This; /* Viewport must be usable for Clear() after AddViewport,
873 so set active_device here. */
874 LeaveCriticalSection(&ddraw_cs);
879 static HRESULT WINAPI
880 Thunk_IDirect3DDeviceImpl_2_AddViewport(IDirect3DDevice2 *iface,
881 IDirect3DViewport2 *Direct3DViewport2)
883 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
884 IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Direct3DViewport2);
885 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, vp);
886 return IDirect3DDevice3_AddViewport(ICOM_INTERFACE(This, IDirect3DDevice3),
887 ICOM_INTERFACE(vp, IDirect3DViewport3));
890 static HRESULT WINAPI
891 Thunk_IDirect3DDeviceImpl_1_AddViewport(IDirect3DDevice *iface,
892 IDirect3DViewport *Direct3DViewport)
894 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
895 IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Direct3DViewport);
896 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, vp);
897 return IDirect3DDevice3_AddViewport(ICOM_INTERFACE(This, IDirect3DDevice3),
898 ICOM_INTERFACE(vp, IDirect3DViewport3));
901 /*****************************************************************************
902 * IDirect3DDevice3::DeleteViewport
904 * Deletes a Direct3DViewport from the device's viewport list.
906 * Exists in Version 1, 2 and 3. Note that all Viewport interface versions
910 * Viewport: The viewport to delete
914 * DDERR_INVALIDPARAMS if the viewport wasn't found in the list
916 *****************************************************************************/
917 static HRESULT WINAPI
918 IDirect3DDeviceImpl_3_DeleteViewport(IDirect3DDevice3 *iface,
919 IDirect3DViewport3 *Viewport)
921 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
922 IDirect3DViewportImpl *vp = (IDirect3DViewportImpl *) Viewport;
923 IDirect3DViewportImpl *cur_viewport, *prev_viewport = NULL;
925 TRACE("(%p)->(%p)\n", This, vp);
927 EnterCriticalSection(&ddraw_cs);
928 cur_viewport = This->viewport_list;
929 while (cur_viewport != NULL)
931 if (cur_viewport == vp)
933 if (prev_viewport == NULL) This->viewport_list = cur_viewport->next;
934 else prev_viewport->next = cur_viewport->next;
935 /* TODO : add desactivate of the viewport and all associated lights... */
936 LeaveCriticalSection(&ddraw_cs);
939 prev_viewport = cur_viewport;
940 cur_viewport = cur_viewport->next;
943 LeaveCriticalSection(&ddraw_cs);
944 return DDERR_INVALIDPARAMS;
947 static HRESULT WINAPI
948 Thunk_IDirect3DDeviceImpl_2_DeleteViewport(IDirect3DDevice2 *iface,
949 IDirect3DViewport2 *Direct3DViewport2)
951 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
952 IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Direct3DViewport2);
953 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, vp);
954 return IDirect3DDevice3_DeleteViewport(ICOM_INTERFACE(This, IDirect3DDevice3),
955 ICOM_INTERFACE(vp, IDirect3DViewport3));
958 static HRESULT WINAPI
959 Thunk_IDirect3DDeviceImpl_1_DeleteViewport(IDirect3DDevice *iface,
960 IDirect3DViewport *Direct3DViewport)
962 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
963 IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Direct3DViewport);
964 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, vp);
965 return IDirect3DDevice3_DeleteViewport(ICOM_INTERFACE(This, IDirect3DDevice3),
966 ICOM_INTERFACE(vp, IDirect3DViewport3));
969 /*****************************************************************************
970 * IDirect3DDevice3::NextViewport
972 * Returns a viewport from the viewport list, depending on the
973 * passed viewport and the flags.
975 * Exists in Version 1, 2 and 3. Note that all Viewport interface versions
979 * Viewport: Viewport to use for beginning the search
980 * Flags: D3DNEXT_NEXT, D3DNEXT_HEAD or D3DNEXT_TAIL
984 * DDERR_INVALIDPARAMS if the flags were wrong, or Viewport was NULL
986 *****************************************************************************/
987 static HRESULT WINAPI
988 IDirect3DDeviceImpl_3_NextViewport(IDirect3DDevice3 *iface,
989 IDirect3DViewport3 *Viewport3,
990 IDirect3DViewport3 **lplpDirect3DViewport3,
993 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
994 IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Viewport3);
995 IDirect3DViewportImpl *res = NULL;
997 TRACE("(%p)->(%p,%p,%08x)\n", This, vp, lplpDirect3DViewport3, Flags);
1001 *lplpDirect3DViewport3 = NULL;
1002 return DDERR_INVALIDPARAMS;
1006 EnterCriticalSection(&ddraw_cs);
1016 res = This->viewport_list;
1021 IDirect3DViewportImpl *cur_viewport = This->viewport_list;
1022 if (cur_viewport != NULL)
1024 while (cur_viewport->next != NULL) cur_viewport = cur_viewport->next;
1030 *lplpDirect3DViewport3 = NULL;
1031 LeaveCriticalSection(&ddraw_cs);
1032 return DDERR_INVALIDPARAMS;
1035 *lplpDirect3DViewport3 = ICOM_INTERFACE(res, IDirect3DViewport3);
1036 LeaveCriticalSection(&ddraw_cs);
1040 static HRESULT WINAPI
1041 Thunk_IDirect3DDeviceImpl_2_NextViewport(IDirect3DDevice2 *iface,
1042 IDirect3DViewport2 *Viewport2,
1043 IDirect3DViewport2 **lplpDirect3DViewport2,
1046 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
1047 IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Viewport2);
1048 IDirect3DViewport3 *res;
1050 TRACE_(ddraw_thunk)("(%p)->(%p,%p,%08x) thunking to IDirect3DDevice3 interface.\n", This, vp, lplpDirect3DViewport2, Flags);
1051 hr = IDirect3DDevice3_NextViewport(ICOM_INTERFACE(This, IDirect3DDevice3),
1052 ICOM_INTERFACE(vp, IDirect3DViewport3),
1055 *lplpDirect3DViewport2 = (IDirect3DViewport2 *) COM_INTERFACE_CAST(IDirect3DViewportImpl, IDirect3DViewport3, IDirect3DViewport3, res);
1059 static HRESULT WINAPI
1060 Thunk_IDirect3DDeviceImpl_1_NextViewport(IDirect3DDevice *iface,
1061 IDirect3DViewport *Viewport,
1062 IDirect3DViewport **lplpDirect3DViewport,
1065 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
1066 IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Viewport);
1067 IDirect3DViewport3 *res;
1069 TRACE_(ddraw_thunk)("(%p)->(%p,%p,%08x) thunking to IDirect3DDevice3 interface.\n", This, vp, lplpDirect3DViewport, Flags);
1070 hr = IDirect3DDevice3_NextViewport(ICOM_INTERFACE(This, IDirect3DDevice3),
1071 ICOM_INTERFACE(vp, IDirect3DViewport3),
1074 *lplpDirect3DViewport = (IDirect3DViewport *) COM_INTERFACE_CAST(IDirect3DViewportImpl, IDirect3DViewport3, IDirect3DViewport3, res);
1078 /*****************************************************************************
1079 * IDirect3DDevice::Pick
1081 * Executes an execute buffer without performing rendering. Instead, a
1082 * list of primitives that intersect with (x1,y1) of the passed rectangle
1083 * is created. IDirect3DDevice::GetPickRecords can be used to retrieve
1089 * ExecuteBuffer: Buffer to execute
1090 * Viewport: Viewport to use for execution
1091 * Flags: None are defined, according to the SDK
1092 * Rect: Specifies the coordinates to be picked. Only x1 and y2 are used,
1093 * x2 and y2 are ignored.
1096 * D3D_OK because it's a stub
1098 *****************************************************************************/
1099 static HRESULT WINAPI
1100 IDirect3DDeviceImpl_1_Pick(IDirect3DDevice *iface,
1101 IDirect3DExecuteBuffer *ExecuteBuffer,
1102 IDirect3DViewport *Viewport,
1106 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
1107 IDirect3DExecuteBufferImpl *execbuf = ICOM_OBJECT(IDirect3DExecuteBufferImpl, IDirect3DExecuteBuffer, ExecuteBuffer);
1108 IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Viewport);
1109 FIXME("(%p)->(%p,%p,%08x,%p): stub!\n", This, execbuf, vp, Flags, Rect);
1114 /*****************************************************************************
1115 * IDirect3DDevice::GetPickRecords
1117 * Retrieves the pick records generated by IDirect3DDevice::GetPickRecords
1122 * Count: Pointer to a DWORD containing the numbers of pick records to
1124 * D3DPickRec: Address to store the resulting D3DPICKRECORD array.
1127 * D3D_OK, because it's a stub
1129 *****************************************************************************/
1130 static HRESULT WINAPI
1131 IDirect3DDeviceImpl_1_GetPickRecords(IDirect3DDevice *iface,
1133 D3DPICKRECORD *D3DPickRec)
1135 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
1136 FIXME("(%p)->(%p,%p): stub!\n", This, Count, D3DPickRec);
1141 /*****************************************************************************
1142 * IDirect3DDevice7::EnumTextureformats
1144 * Enumerates the supported texture formats. It has a list of all possible
1145 * formats and calls IWineD3D::CheckDeviceFormat for each format to see if
1146 * WineD3D supports it. If so, then it is passed to the app.
1148 * This is for Version 7 and 3, older versions have a different
1149 * callback function and their own implementation
1152 * Callback: Callback to call for each enumerated format
1153 * Arg: Argument to pass to the callback
1157 * DDERR_INVALIDPARAMS if Callback == NULL
1159 *****************************************************************************/
1161 IDirect3DDeviceImpl_7_EnumTextureFormats(IDirect3DDevice7 *iface,
1162 LPD3DENUMPIXELFORMATSCALLBACK Callback,
1165 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1167 WINED3DDISPLAYMODE mode;
1170 WINED3DFORMAT FormatList[] = {
1172 WINED3DFMT_A8R8G8B8,
1173 WINED3DFMT_X8R8G8B8,
1177 WINED3DFMT_A1R5G5B5,
1178 WINED3DFMT_A4R4G4B4,
1180 WINED3DFMT_X1R5G5B5,
1190 WINED3DFORMAT BumpFormatList[] = {
1193 WINED3DFMT_X8L8V8U8,
1194 WINED3DFMT_Q8W8V8U8,
1196 WINED3DFMT_W11V11U10,
1197 WINED3DFMT_A2W10V10U10
1200 TRACE("(%p)->(%p,%p): Relay\n", This, Callback, Arg);
1203 return DDERR_INVALIDPARAMS;
1205 EnterCriticalSection(&ddraw_cs);
1207 memset(&mode, 0, sizeof(mode));
1208 hr = IWineD3DDevice_GetDisplayMode(This->ddraw->wineD3DDevice,
1212 LeaveCriticalSection(&ddraw_cs);
1213 WARN("Cannot get the current adapter format\n");
1217 for(i = 0; i < sizeof(FormatList) / sizeof(WINED3DFORMAT); i++)
1219 hr = IWineD3D_CheckDeviceFormat(This->ddraw->wineD3D,
1220 WINED3DADAPTER_DEFAULT,
1224 WINED3DRTYPE_TEXTURE,
1229 DDPIXELFORMAT pformat;
1231 memset(&pformat, 0, sizeof(pformat));
1232 pformat.dwSize = sizeof(pformat);
1233 PixelFormat_WineD3DtoDD(&pformat, FormatList[i]);
1235 TRACE("Enumerating WineD3DFormat %d\n", FormatList[i]);
1236 hr = Callback(&pformat, Arg);
1237 if(hr != DDENUMRET_OK)
1239 TRACE("Format enumeration cancelled by application\n");
1240 LeaveCriticalSection(&ddraw_cs);
1246 for(i = 0; i < sizeof(BumpFormatList) / sizeof(WINED3DFORMAT); i++)
1248 hr = IWineD3D_CheckDeviceFormat(This->ddraw->wineD3D,
1249 WINED3DADAPTER_DEFAULT,
1252 WINED3DUSAGE_QUERY_LEGACYBUMPMAP,
1253 WINED3DRTYPE_TEXTURE,
1258 DDPIXELFORMAT pformat;
1260 memset(&pformat, 0, sizeof(pformat));
1261 pformat.dwSize = sizeof(pformat);
1262 PixelFormat_WineD3DtoDD(&pformat, BumpFormatList[i]);
1264 TRACE("Enumerating WineD3DFormat %d\n", BumpFormatList[i]);
1265 hr = Callback(&pformat, Arg);
1266 if(hr != DDENUMRET_OK)
1268 TRACE("Format enumeration cancelled by application\n");
1269 LeaveCriticalSection(&ddraw_cs);
1274 TRACE("End of enumeration\n");
1275 LeaveCriticalSection(&ddraw_cs);
1279 static HRESULT WINAPI
1280 IDirect3DDeviceImpl_7_EnumTextureFormats_FPUSetup(IDirect3DDevice7 *iface,
1281 LPD3DENUMPIXELFORMATSCALLBACK Callback,
1284 return IDirect3DDeviceImpl_7_EnumTextureFormats(iface, Callback, Arg);
1287 static HRESULT WINAPI
1288 IDirect3DDeviceImpl_7_EnumTextureFormats_FPUPreserve(IDirect3DDevice7 *iface,
1289 LPD3DENUMPIXELFORMATSCALLBACK Callback,
1295 old_fpucw = d3d_fpu_setup();
1296 hr = IDirect3DDeviceImpl_7_EnumTextureFormats(iface, Callback, Arg);
1297 set_fpu_control_word(old_fpucw);
1302 static HRESULT WINAPI
1303 Thunk_IDirect3DDeviceImpl_3_EnumTextureFormats(IDirect3DDevice3 *iface,
1304 LPD3DENUMPIXELFORMATSCALLBACK Callback,
1307 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
1308 TRACE_(ddraw_thunk)("(%p)->(%p,%p) thunking to IDirect3DDevice7 interface.\n", This, Callback, Arg);
1309 return IDirect3DDevice7_EnumTextureFormats(ICOM_INTERFACE(This, IDirect3DDevice7),
1314 /*****************************************************************************
1315 * IDirect3DDevice2::EnumTextureformats
1317 * EnumTextureFormats for Version 1 and 2, see
1318 * IDirect3DDevice7::EnumTexureFormats for a more detailed description.
1320 * This version has a different callback and does not enumerate FourCC
1323 *****************************************************************************/
1324 static HRESULT WINAPI
1325 IDirect3DDeviceImpl_2_EnumTextureFormats(IDirect3DDevice2 *iface,
1326 LPD3DENUMTEXTUREFORMATSCALLBACK Callback,
1329 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
1332 WINED3DDISPLAYMODE mode;
1334 WINED3DFORMAT FormatList[] = {
1336 WINED3DFMT_A8R8G8B8,
1337 WINED3DFMT_X8R8G8B8,
1341 WINED3DFMT_A1R5G5B5,
1342 WINED3DFMT_A4R4G4B4,
1344 WINED3DFMT_X1R5G5B5,
1348 /* FOURCC codes - Not in this version*/
1351 TRACE("(%p)->(%p,%p): Relay\n", This, Callback, Arg);
1354 return DDERR_INVALIDPARAMS;
1356 EnterCriticalSection(&ddraw_cs);
1358 memset(&mode, 0, sizeof(mode));
1359 hr = IWineD3DDevice_GetDisplayMode(This->ddraw->wineD3DDevice,
1363 LeaveCriticalSection(&ddraw_cs);
1364 WARN("Cannot get the current adapter format\n");
1368 for(i = 0; i < sizeof(FormatList) / sizeof(WINED3DFORMAT); i++)
1370 hr = IWineD3D_CheckDeviceFormat(This->ddraw->wineD3D,
1375 WINED3DRTYPE_TEXTURE,
1380 DDSURFACEDESC sdesc;
1382 memset(&sdesc, 0, sizeof(sdesc));
1383 sdesc.dwSize = sizeof(sdesc);
1384 sdesc.dwFlags = DDSD_PIXELFORMAT | DDSD_CAPS;
1385 sdesc.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1386 sdesc.ddpfPixelFormat.dwSize = sizeof(sdesc.ddpfPixelFormat);
1387 PixelFormat_WineD3DtoDD(&sdesc.ddpfPixelFormat, FormatList[i]);
1389 TRACE("Enumerating WineD3DFormat %d\n", FormatList[i]);
1390 hr = Callback(&sdesc, Arg);
1391 if(hr != DDENUMRET_OK)
1393 TRACE("Format enumeration cancelled by application\n");
1394 LeaveCriticalSection(&ddraw_cs);
1399 TRACE("End of enumeration\n");
1400 LeaveCriticalSection(&ddraw_cs);
1404 static HRESULT WINAPI
1405 Thunk_IDirect3DDeviceImpl_1_EnumTextureFormats(IDirect3DDevice *iface,
1406 LPD3DENUMTEXTUREFORMATSCALLBACK Callback,
1409 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
1410 TRACE_(ddraw_thunk)("(%p)->(%p,%p) thunking to IDirect3DDevice2 interface.\n", This, Callback, Arg);
1411 return IDirect3DDevice2_EnumTextureFormats(ICOM_INTERFACE(This, IDirect3DDevice2),
1416 /*****************************************************************************
1417 * IDirect3DDevice::CreateMatrix
1419 * Creates a matrix handle. A handle is created and memory for a D3DMATRIX is
1420 * allocated for the handle.
1425 * D3DMatHandle: Address to return the handle at
1429 * DDERR_INVALIDPARAMS if D3DMatHandle = NULL
1431 *****************************************************************************/
1432 static HRESULT WINAPI
1433 IDirect3DDeviceImpl_1_CreateMatrix(IDirect3DDevice *iface, D3DMATRIXHANDLE *D3DMatHandle)
1435 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
1437 TRACE("(%p)->(%p)\n", This, D3DMatHandle);
1440 return DDERR_INVALIDPARAMS;
1442 Matrix = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(D3DMATRIX));
1445 ERR("Out of memory when allocating a D3DMATRIX\n");
1446 return DDERR_OUTOFMEMORY;
1449 EnterCriticalSection(&ddraw_cs);
1450 *D3DMatHandle = IDirect3DDeviceImpl_CreateHandle(This);
1451 if(!(*D3DMatHandle))
1453 ERR("Failed to create a matrix handle\n");
1454 HeapFree(GetProcessHeap(), 0, Matrix);
1455 LeaveCriticalSection(&ddraw_cs);
1456 return DDERR_OUTOFMEMORY;
1458 This->Handles[*D3DMatHandle - 1].ptr = Matrix;
1459 This->Handles[*D3DMatHandle - 1].type = DDrawHandle_Matrix;
1460 TRACE(" returning matrix handle %d\n", *D3DMatHandle);
1462 LeaveCriticalSection(&ddraw_cs);
1466 /*****************************************************************************
1467 * IDirect3DDevice::SetMatrix
1469 * Sets a matrix for a matrix handle. The matrix is copied into the memory
1470 * allocated for the handle
1475 * D3DMatHandle: Handle to set the matrix to
1476 * D3DMatrix: Matrix to set
1480 * DDERR_INVALIDPARAMS if the handle of the matrix is invalid or the matrix
1483 *****************************************************************************/
1484 static HRESULT WINAPI
1485 IDirect3DDeviceImpl_1_SetMatrix(IDirect3DDevice *iface,
1486 D3DMATRIXHANDLE D3DMatHandle,
1487 D3DMATRIX *D3DMatrix)
1489 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
1490 TRACE("(%p)->(%08x,%p)\n", This, D3DMatHandle, D3DMatrix);
1492 if( (!D3DMatHandle) || (!D3DMatrix) )
1493 return DDERR_INVALIDPARAMS;
1495 EnterCriticalSection(&ddraw_cs);
1496 if(D3DMatHandle > This->numHandles)
1498 ERR("Handle %d out of range\n", D3DMatHandle);
1499 LeaveCriticalSection(&ddraw_cs);
1500 return DDERR_INVALIDPARAMS;
1502 else if(This->Handles[D3DMatHandle - 1].type != DDrawHandle_Matrix)
1504 ERR("Handle %d is not a matrix handle\n", D3DMatHandle);
1505 LeaveCriticalSection(&ddraw_cs);
1506 return DDERR_INVALIDPARAMS;
1510 dump_D3DMATRIX(D3DMatrix);
1512 *((D3DMATRIX *) This->Handles[D3DMatHandle - 1].ptr) = *D3DMatrix;
1514 if(This->world == D3DMatHandle)
1516 IWineD3DDevice_SetTransform(This->wineD3DDevice,
1517 WINED3DTS_WORLDMATRIX(0),
1518 (WINED3DMATRIX *) D3DMatrix);
1520 if(This->view == D3DMatHandle)
1522 IWineD3DDevice_SetTransform(This->wineD3DDevice,
1524 (WINED3DMATRIX *) D3DMatrix);
1526 if(This->proj == D3DMatHandle)
1528 IWineD3DDevice_SetTransform(This->wineD3DDevice,
1529 WINED3DTS_PROJECTION,
1530 (WINED3DMATRIX *) D3DMatrix);
1533 LeaveCriticalSection(&ddraw_cs);
1537 /*****************************************************************************
1538 * IDirect3DDevice::SetMatrix
1540 * Returns the content of a D3DMATRIX handle
1545 * D3DMatHandle: Matrix handle to read the content from
1546 * D3DMatrix: Address to store the content at
1550 * DDERR_INVALIDPARAMS if D3DMatHandle is invalid or D3DMatrix is NULL
1552 *****************************************************************************/
1553 static HRESULT WINAPI
1554 IDirect3DDeviceImpl_1_GetMatrix(IDirect3DDevice *iface,
1555 D3DMATRIXHANDLE D3DMatHandle,
1556 D3DMATRIX *D3DMatrix)
1558 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
1559 TRACE("(%p)->(%08x,%p)\n", This, D3DMatHandle, D3DMatrix);
1562 return DDERR_INVALIDPARAMS;
1564 return DDERR_INVALIDPARAMS;
1566 EnterCriticalSection(&ddraw_cs);
1567 if(D3DMatHandle > This->numHandles)
1569 ERR("Handle %d out of range\n", D3DMatHandle);
1570 LeaveCriticalSection(&ddraw_cs);
1571 return DDERR_INVALIDPARAMS;
1573 else if(This->Handles[D3DMatHandle - 1].type != DDrawHandle_Matrix)
1575 ERR("Handle %d is not a matrix handle\n", D3DMatHandle);
1576 LeaveCriticalSection(&ddraw_cs);
1577 return DDERR_INVALIDPARAMS;
1580 /* The handle is simply a pointer to a D3DMATRIX structure */
1581 *D3DMatrix = *((D3DMATRIX *) This->Handles[D3DMatHandle - 1].ptr);
1583 LeaveCriticalSection(&ddraw_cs);
1587 /*****************************************************************************
1588 * IDirect3DDevice::DeleteMatrix
1590 * Destroys a Matrix handle. Frees the memory and unsets the handle data
1595 * D3DMatHandle: Handle to destroy
1599 * DDERR_INVALIDPARAMS if D3DMatHandle is invalid
1601 *****************************************************************************/
1602 static HRESULT WINAPI
1603 IDirect3DDeviceImpl_1_DeleteMatrix(IDirect3DDevice *iface,
1604 D3DMATRIXHANDLE D3DMatHandle)
1606 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
1607 TRACE("(%p)->(%08x)\n", This, D3DMatHandle);
1610 return DDERR_INVALIDPARAMS;
1612 EnterCriticalSection(&ddraw_cs);
1613 if(D3DMatHandle > This->numHandles)
1615 ERR("Handle %d out of range\n", D3DMatHandle);
1616 LeaveCriticalSection(&ddraw_cs);
1617 return DDERR_INVALIDPARAMS;
1619 else if(This->Handles[D3DMatHandle - 1].type != DDrawHandle_Matrix)
1621 ERR("Handle %d is not a matrix handle\n", D3DMatHandle);
1622 LeaveCriticalSection(&ddraw_cs);
1623 return DDERR_INVALIDPARAMS;
1626 HeapFree(GetProcessHeap(), 0, This->Handles[D3DMatHandle - 1].ptr);
1627 This->Handles[D3DMatHandle - 1].ptr = NULL;
1628 This->Handles[D3DMatHandle - 1].type = DDrawHandle_Unknown;
1630 LeaveCriticalSection(&ddraw_cs);
1634 /*****************************************************************************
1635 * IDirect3DDevice7::BeginScene
1637 * This method must be called before any rendering is performed.
1638 * IDirect3DDevice::EndScene has to be called after the scene is complete
1640 * Version 1, 2, 3 and 7
1643 * D3D_OK on success, for details see IWineD3DDevice::BeginScene
1644 * D3DERR_SCENE_IN_SCENE if WineD3D returns an error(Only in case of an already
1647 *****************************************************************************/
1649 IDirect3DDeviceImpl_7_BeginScene(IDirect3DDevice7 *iface)
1651 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1653 TRACE("(%p): Relay\n", This);
1655 EnterCriticalSection(&ddraw_cs);
1656 hr = IWineD3DDevice_BeginScene(This->wineD3DDevice);
1657 LeaveCriticalSection(&ddraw_cs);
1658 if(hr == WINED3D_OK) return D3D_OK;
1659 else return D3DERR_SCENE_IN_SCENE; /* TODO: Other possible causes of failure */
1662 static HRESULT WINAPI
1663 IDirect3DDeviceImpl_7_BeginScene_FPUSetup(IDirect3DDevice7 *iface)
1665 return IDirect3DDeviceImpl_7_BeginScene(iface);
1668 static HRESULT WINAPI
1669 IDirect3DDeviceImpl_7_BeginScene_FPUPreserve(IDirect3DDevice7 *iface)
1674 old_fpucw = d3d_fpu_setup();
1675 hr = IDirect3DDeviceImpl_7_BeginScene(iface);
1676 set_fpu_control_word(old_fpucw);
1681 static HRESULT WINAPI
1682 Thunk_IDirect3DDeviceImpl_3_BeginScene(IDirect3DDevice3 *iface)
1684 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
1685 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
1686 return IDirect3DDevice7_BeginScene(ICOM_INTERFACE(This, IDirect3DDevice7));
1689 static HRESULT WINAPI
1690 Thunk_IDirect3DDeviceImpl_2_BeginScene(IDirect3DDevice2 *iface)
1692 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
1693 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
1694 return IDirect3DDevice7_BeginScene(ICOM_INTERFACE(This, IDirect3DDevice7));
1697 static HRESULT WINAPI
1698 Thunk_IDirect3DDeviceImpl_1_BeginScene(IDirect3DDevice *iface)
1700 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
1701 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
1702 return IDirect3DDevice7_BeginScene(ICOM_INTERFACE(This, IDirect3DDevice7));
1705 /*****************************************************************************
1706 * IDirect3DDevice7::EndScene
1708 * Ends a scene that has been begun with IDirect3DDevice7::BeginScene.
1709 * This method must be called after rendering is finished.
1711 * Version 1, 2, 3 and 7
1714 * D3D_OK on success, for details see IWineD3DDevice::EndScene
1715 * D3DERR_SCENE_NOT_IN_SCENE is returned if WineD3D returns an error. It does
1716 * that only if the scene was already ended.
1718 *****************************************************************************/
1720 IDirect3DDeviceImpl_7_EndScene(IDirect3DDevice7 *iface)
1722 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1724 TRACE("(%p): Relay\n", This);
1726 EnterCriticalSection(&ddraw_cs);
1727 hr = IWineD3DDevice_EndScene(This->wineD3DDevice);
1728 LeaveCriticalSection(&ddraw_cs);
1729 if(hr == WINED3D_OK) return D3D_OK;
1730 else return D3DERR_SCENE_NOT_IN_SCENE;
1733 static HRESULT WINAPI
1734 IDirect3DDeviceImpl_7_EndScene_FPUSetup(IDirect3DDevice7 *iface)
1736 return IDirect3DDeviceImpl_7_EndScene(iface);
1739 static HRESULT WINAPI
1740 IDirect3DDeviceImpl_7_EndScene_FPUPreserve(IDirect3DDevice7 *iface)
1745 old_fpucw = d3d_fpu_setup();
1746 hr = IDirect3DDeviceImpl_7_EndScene(iface);
1747 set_fpu_control_word(old_fpucw);
1752 static HRESULT WINAPI
1753 Thunk_IDirect3DDeviceImpl_3_EndScene(IDirect3DDevice3 *iface)
1755 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
1756 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
1757 return IDirect3DDevice7_EndScene(ICOM_INTERFACE(This, IDirect3DDevice7));
1760 static HRESULT WINAPI
1761 Thunk_IDirect3DDeviceImpl_2_EndScene(IDirect3DDevice2 *iface)
1763 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
1764 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
1765 return IDirect3DDevice7_EndScene(ICOM_INTERFACE(This, IDirect3DDevice7));
1768 static HRESULT WINAPI
1769 Thunk_IDirect3DDeviceImpl_1_EndScene(IDirect3DDevice *iface)
1771 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
1772 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
1773 return IDirect3DDevice7_EndScene(ICOM_INTERFACE(This, IDirect3DDevice7));
1776 /*****************************************************************************
1777 * IDirect3DDevice7::GetDirect3D
1779 * Returns the IDirect3D(= interface to the DirectDraw object) used to create
1783 * Direct3D7: Address to store the interface pointer at
1787 * DDERR_INVALIDPARAMS if Direct3D7 == NULL
1789 *****************************************************************************/
1790 static HRESULT WINAPI
1791 IDirect3DDeviceImpl_7_GetDirect3D(IDirect3DDevice7 *iface,
1792 IDirect3D7 **Direct3D7)
1794 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
1795 TRACE("(%p)->(%p)\n", This, Direct3D7);
1798 return DDERR_INVALIDPARAMS;
1800 *Direct3D7 = ICOM_INTERFACE(This->ddraw, IDirect3D7);
1801 IDirect3D7_AddRef(*Direct3D7);
1803 TRACE(" returning interface %p\n", *Direct3D7);
1807 static HRESULT WINAPI
1808 Thunk_IDirect3DDeviceImpl_3_GetDirect3D(IDirect3DDevice3 *iface,
1809 IDirect3D3 **Direct3D3)
1811 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
1813 IDirect3D7 *ret_ptr;
1815 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, Direct3D3);
1816 ret = IDirect3DDevice7_GetDirect3D(ICOM_INTERFACE(This, IDirect3DDevice7),
1820 *Direct3D3 = COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D7, IDirect3D3, ret_ptr);
1821 TRACE(" returning interface %p\n", *Direct3D3);
1825 static HRESULT WINAPI
1826 Thunk_IDirect3DDeviceImpl_2_GetDirect3D(IDirect3DDevice2 *iface,
1827 IDirect3D2 **Direct3D2)
1829 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
1831 IDirect3D7 *ret_ptr;
1833 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, Direct3D2);
1834 ret = IDirect3DDevice7_GetDirect3D(ICOM_INTERFACE(This, IDirect3DDevice7),
1838 *Direct3D2 = COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D7, IDirect3D2, ret_ptr);
1839 TRACE(" returning interface %p\n", *Direct3D2);
1843 static HRESULT WINAPI
1844 Thunk_IDirect3DDeviceImpl_1_GetDirect3D(IDirect3DDevice *iface,
1845 IDirect3D **Direct3D)
1847 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice, iface);
1849 IDirect3D7 *ret_ptr;
1851 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, Direct3D);
1852 ret = IDirect3DDevice7_GetDirect3D(ICOM_INTERFACE(This, IDirect3DDevice7),
1856 *Direct3D = COM_INTERFACE_CAST(IDirectDrawImpl, IDirect3D7, IDirect3D, ret_ptr);
1857 TRACE(" returning interface %p\n", *Direct3D);
1861 /*****************************************************************************
1862 * IDirect3DDevice3::SetCurrentViewport
1864 * Sets a Direct3DViewport as the current viewport.
1865 * For the thunks note that all viewport interface versions are equal
1868 * Direct3DViewport3: The viewport to set
1874 * (Is a NULL viewport valid?)
1876 *****************************************************************************/
1877 static HRESULT WINAPI
1878 IDirect3DDeviceImpl_3_SetCurrentViewport(IDirect3DDevice3 *iface,
1879 IDirect3DViewport3 *Direct3DViewport3)
1881 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
1882 IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Direct3DViewport3);
1883 TRACE("(%p)->(%p)\n", This, Direct3DViewport3);
1885 EnterCriticalSection(&ddraw_cs);
1886 /* Do nothing if the specified viewport is the same as the current one */
1887 if (This->current_viewport == vp )
1889 LeaveCriticalSection(&ddraw_cs);
1893 /* Should check if the viewport was added or not */
1895 /* Release previous viewport and AddRef the new one */
1896 if (This->current_viewport)
1898 TRACE("ViewportImpl is at %p, interface is at %p\n", This->current_viewport, ICOM_INTERFACE(This->current_viewport, IDirect3DViewport3));
1899 IDirect3DViewport3_Release( ICOM_INTERFACE(This->current_viewport, IDirect3DViewport3) );
1901 IDirect3DViewport3_AddRef(Direct3DViewport3);
1903 /* Set this viewport as the current viewport */
1904 This->current_viewport = vp;
1906 /* Activate this viewport */
1907 This->current_viewport->active_device = This;
1908 This->current_viewport->activate(This->current_viewport, FALSE);
1910 LeaveCriticalSection(&ddraw_cs);
1914 static HRESULT WINAPI
1915 Thunk_IDirect3DDeviceImpl_2_SetCurrentViewport(IDirect3DDevice2 *iface,
1916 IDirect3DViewport2 *Direct3DViewport2)
1918 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
1919 IDirect3DViewportImpl *vp = ICOM_OBJECT(IDirect3DViewportImpl, IDirect3DViewport3, Direct3DViewport2);
1920 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, vp);
1921 return IDirect3DDevice3_SetCurrentViewport(ICOM_INTERFACE(This, IDirect3DDevice3),
1922 ICOM_INTERFACE(vp, IDirect3DViewport3));
1925 /*****************************************************************************
1926 * IDirect3DDevice3::GetCurrentViewport
1928 * Returns the currently active viewport.
1933 * Direct3DViewport3: Address to return the interface pointer at
1937 * DDERR_INVALIDPARAMS if Direct3DViewport == NULL
1939 *****************************************************************************/
1940 static HRESULT WINAPI
1941 IDirect3DDeviceImpl_3_GetCurrentViewport(IDirect3DDevice3 *iface,
1942 IDirect3DViewport3 **Direct3DViewport3)
1944 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
1945 TRACE("(%p)->(%p)\n", This, Direct3DViewport3);
1947 if(!Direct3DViewport3)
1948 return DDERR_INVALIDPARAMS;
1950 EnterCriticalSection(&ddraw_cs);
1951 *Direct3DViewport3 = ICOM_INTERFACE(This->current_viewport, IDirect3DViewport3);
1953 /* AddRef the returned viewport */
1954 if(*Direct3DViewport3) IDirect3DViewport3_AddRef(*Direct3DViewport3);
1956 TRACE(" returning interface %p\n", *Direct3DViewport3);
1958 LeaveCriticalSection(&ddraw_cs);
1962 static HRESULT WINAPI
1963 Thunk_IDirect3DDeviceImpl_2_GetCurrentViewport(IDirect3DDevice2 *iface,
1964 IDirect3DViewport2 **Direct3DViewport2)
1966 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
1968 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, Direct3DViewport2);
1969 hr = IDirect3DDevice3_GetCurrentViewport(ICOM_INTERFACE(This, IDirect3DDevice3),
1970 (IDirect3DViewport3 **) Direct3DViewport2);
1971 if(hr != D3D_OK) return hr;
1972 *Direct3DViewport2 = (IDirect3DViewport2 *) COM_INTERFACE_CAST(IDirect3DViewportImpl, IDirect3DViewport3, IDirect3DViewport3, *Direct3DViewport2);
1976 /*****************************************************************************
1977 * IDirect3DDevice7::SetRenderTarget
1979 * Sets the render target for the Direct3DDevice.
1980 * For the thunks note that IDirectDrawSurface7 == IDirectDrawSurface4 and
1981 * IDirectDrawSurface3 == IDirectDrawSurface
1983 * Version 2, 3 and 7
1986 * NewTarget: Pointer to an IDirectDrawSurface7 interface to set as the new
1991 * D3D_OK on success, for details see IWineD3DDevice::SetRenderTarget
1993 *****************************************************************************/
1995 IDirect3DDeviceImpl_7_SetRenderTarget(IDirect3DDevice7 *iface,
1996 IDirectDrawSurface7 *NewTarget,
1999 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
2000 IDirectDrawSurfaceImpl *Target = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, NewTarget);
2002 TRACE("(%p)->(%p,%08x): Relay\n", This, NewTarget, Flags);
2004 EnterCriticalSection(&ddraw_cs);
2005 /* Flags: Not used */
2007 if(This->target == Target)
2009 TRACE("No-op SetRenderTarget operation, not doing anything\n");
2010 LeaveCriticalSection(&ddraw_cs);
2014 hr = IWineD3DDevice_SetRenderTarget(This->wineD3DDevice,
2016 Target ? Target->WineD3DSurface : NULL);
2019 LeaveCriticalSection(&ddraw_cs);
2022 IDirectDrawSurface7_AddRef(NewTarget);
2023 IDirectDrawSurface7_Release(ICOM_INTERFACE(This->target, IDirectDrawSurface7));
2024 This->target = Target;
2025 IDirect3DDeviceImpl_UpdateDepthStencil(This);
2026 LeaveCriticalSection(&ddraw_cs);
2030 static HRESULT WINAPI
2031 IDirect3DDeviceImpl_7_SetRenderTarget_FPUSetup(IDirect3DDevice7 *iface,
2032 IDirectDrawSurface7 *NewTarget,
2035 return IDirect3DDeviceImpl_7_SetRenderTarget(iface, NewTarget, Flags);
2038 static HRESULT WINAPI
2039 IDirect3DDeviceImpl_7_SetRenderTarget_FPUPreserve(IDirect3DDevice7 *iface,
2040 IDirectDrawSurface7 *NewTarget,
2046 old_fpucw = d3d_fpu_setup();
2047 hr = IDirect3DDeviceImpl_7_SetRenderTarget(iface, NewTarget, Flags);
2048 set_fpu_control_word(old_fpucw);
2053 static HRESULT WINAPI
2054 Thunk_IDirect3DDeviceImpl_3_SetRenderTarget(IDirect3DDevice3 *iface,
2055 IDirectDrawSurface4 *NewRenderTarget,
2058 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
2059 IDirectDrawSurfaceImpl *Target = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, NewRenderTarget);
2060 TRACE_(ddraw_thunk)("(%p)->(%p,%08x) thunking to IDirect3DDevice7 interface.\n", This, Target, Flags);
2061 return IDirect3DDevice7_SetRenderTarget(ICOM_INTERFACE(This, IDirect3DDevice7),
2062 ICOM_INTERFACE(Target, IDirectDrawSurface7),
2066 static HRESULT WINAPI
2067 Thunk_IDirect3DDeviceImpl_2_SetRenderTarget(IDirect3DDevice2 *iface,
2068 IDirectDrawSurface *NewRenderTarget,
2071 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
2072 IDirectDrawSurfaceImpl *Target = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface3, NewRenderTarget);
2073 TRACE_(ddraw_thunk)("(%p)->(%p,%08x) thunking to IDirect3DDevice7 interface.\n", This, Target, Flags);
2074 return IDirect3DDevice7_SetRenderTarget(ICOM_INTERFACE(This, IDirect3DDevice7),
2075 ICOM_INTERFACE(Target, IDirectDrawSurface7),
2079 /*****************************************************************************
2080 * IDirect3DDevice7::GetRenderTarget
2082 * Returns the current render target.
2083 * This is handled locally, because the WineD3D render target's parent
2086 * Version 2, 3 and 7
2089 * RenderTarget: Address to store the surface interface pointer
2093 * DDERR_INVALIDPARAMS if RenderTarget == NULL
2095 *****************************************************************************/
2096 static HRESULT WINAPI
2097 IDirect3DDeviceImpl_7_GetRenderTarget(IDirect3DDevice7 *iface,
2098 IDirectDrawSurface7 **RenderTarget)
2100 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
2101 TRACE("(%p)->(%p): Relay\n", This, RenderTarget);
2104 return DDERR_INVALIDPARAMS;
2106 EnterCriticalSection(&ddraw_cs);
2107 *RenderTarget = ICOM_INTERFACE(This->target, IDirectDrawSurface7);
2108 IDirectDrawSurface7_AddRef(*RenderTarget);
2110 LeaveCriticalSection(&ddraw_cs);
2114 static HRESULT WINAPI
2115 Thunk_IDirect3DDeviceImpl_3_GetRenderTarget(IDirect3DDevice3 *iface,
2116 IDirectDrawSurface4 **RenderTarget)
2118 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
2120 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, RenderTarget);
2121 hr = IDirect3DDevice7_GetRenderTarget(ICOM_INTERFACE(This, IDirect3DDevice7),
2122 (IDirectDrawSurface7 **) RenderTarget);
2123 if(hr != D3D_OK) return hr;
2124 *RenderTarget = (IDirectDrawSurface4 *) COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirectDrawSurface7, IDirectDrawSurface7, *RenderTarget);
2128 static HRESULT WINAPI
2129 Thunk_IDirect3DDeviceImpl_2_GetRenderTarget(IDirect3DDevice2 *iface,
2130 IDirectDrawSurface **RenderTarget)
2132 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
2134 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, RenderTarget);
2135 hr = IDirect3DDevice7_GetRenderTarget(ICOM_INTERFACE(This, IDirect3DDevice7),
2136 (IDirectDrawSurface7 **) RenderTarget);
2137 if(hr != D3D_OK) return hr;
2138 *RenderTarget = (IDirectDrawSurface *) COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirectDrawSurface7, IDirectDrawSurface3, *RenderTarget);
2142 /*****************************************************************************
2143 * IDirect3DDevice3::Begin
2145 * Begins a description block of vertices. This is similar to glBegin()
2146 * and glEnd(). After a call to IDirect3DDevice3::End, the vertices
2147 * described with IDirect3DDevice::Vertex are drawn.
2152 * PrimitiveType: The type of primitives to draw
2153 * VertexTypeDesc: A flexible vertex format description of the vertices
2154 * Flags: Some flags..
2159 *****************************************************************************/
2160 static HRESULT WINAPI
2161 IDirect3DDeviceImpl_3_Begin(IDirect3DDevice3 *iface,
2162 D3DPRIMITIVETYPE PrimitiveType,
2163 DWORD VertexTypeDesc,
2166 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
2167 TRACE("(%p)->(%d,%d,%08x)\n", This, PrimitiveType, VertexTypeDesc, Flags);
2169 EnterCriticalSection(&ddraw_cs);
2170 This->primitive_type = PrimitiveType;
2171 This->vertex_type = VertexTypeDesc;
2172 This->render_flags = Flags;
2173 This->vertex_size = get_flexible_vertex_size(This->vertex_type);
2174 This->nb_vertices = 0;
2175 LeaveCriticalSection(&ddraw_cs);
2180 static HRESULT WINAPI
2181 Thunk_IDirect3DDeviceImpl_2_Begin(IDirect3DDevice2 *iface,
2182 D3DPRIMITIVETYPE d3dpt,
2183 D3DVERTEXTYPE dwVertexTypeDesc,
2187 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
2188 TRACE_(ddraw_thunk)("(%p/%p)->(%08x,%08x,%08x): Thunking to IDirect3DDevice3\n", This, iface, d3dpt, dwVertexTypeDesc, dwFlags);
2190 switch(dwVertexTypeDesc)
2192 case D3DVT_VERTEX: FVF = D3DFVF_VERTEX; break;
2193 case D3DVT_LVERTEX: FVF = D3DFVF_LVERTEX; break;
2194 case D3DVT_TLVERTEX: FVF = D3DFVF_TLVERTEX; break;
2196 ERR("Unexpected vertex type %d\n", dwVertexTypeDesc);
2197 return DDERR_INVALIDPARAMS; /* Should never happen */
2200 return IDirect3DDevice3_Begin(ICOM_INTERFACE(This, IDirect3DDevice3),
2206 /*****************************************************************************
2207 * IDirect3DDevice3::BeginIndexed
2209 * Draws primitives based on vertices in a vertex array which are specified
2215 * PrimitiveType: Primitive type to draw
2216 * VertexType: A FVF description of the vertex format
2217 * Vertices: pointer to an array containing the vertices
2218 * NumVertices: The number of vertices in the vertex array
2219 * Flags: Some flags ...
2222 * D3D_OK, because it's a stub
2224 *****************************************************************************/
2225 static HRESULT WINAPI
2226 IDirect3DDeviceImpl_3_BeginIndexed(IDirect3DDevice3 *iface,
2227 D3DPRIMITIVETYPE PrimitiveType,
2233 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
2234 FIXME("(%p)->(%08x,%08x,%p,%08x,%08x): stub!\n", This, PrimitiveType, VertexType, Vertices, NumVertices, Flags);
2239 static HRESULT WINAPI
2240 Thunk_IDirect3DDeviceImpl_2_BeginIndexed(IDirect3DDevice2 *iface,
2241 D3DPRIMITIVETYPE d3dptPrimitiveType,
2242 D3DVERTEXTYPE d3dvtVertexType,
2244 DWORD dwNumVertices,
2248 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
2249 TRACE_(ddraw_thunk)("(%p/%p)->(%08x,%08x,%p,%08x,%08x): Thunking to IDirect3DDevice3\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwNumVertices, dwFlags);
2251 switch(d3dvtVertexType)
2253 case D3DVT_VERTEX: FVF = D3DFVF_VERTEX; break;
2254 case D3DVT_LVERTEX: FVF = D3DFVF_LVERTEX; break;
2255 case D3DVT_TLVERTEX: FVF = D3DFVF_TLVERTEX; break;
2257 ERR("Unexpected vertex type %d\n", d3dvtVertexType);
2258 return DDERR_INVALIDPARAMS; /* Should never happen */
2261 return IDirect3DDevice3_BeginIndexed(ICOM_INTERFACE(This,IDirect3DDevice3),
2269 /*****************************************************************************
2270 * IDirect3DDevice3::Vertex
2272 * Draws a vertex as described by IDirect3DDevice3::Begin. It places all
2273 * drawn vertices in a vertex buffer. If the buffer is too small, its
2274 * size is increased.
2279 * Vertex: Pointer to the vertex
2282 * D3D_OK, on success
2283 * DDERR_INVALIDPARAMS if Vertex is NULL
2285 *****************************************************************************/
2286 static HRESULT WINAPI
2287 IDirect3DDeviceImpl_3_Vertex(IDirect3DDevice3 *iface,
2290 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
2291 TRACE("(%p)->(%p)\n", This, Vertex);
2294 return DDERR_INVALIDPARAMS;
2296 EnterCriticalSection(&ddraw_cs);
2297 if ((This->nb_vertices+1)*This->vertex_size > This->buffer_size)
2300 This->buffer_size = This->buffer_size ? This->buffer_size * 2 : This->vertex_size * 3;
2301 old_buffer = This->vertex_buffer;
2302 This->vertex_buffer = HeapAlloc(GetProcessHeap(), 0, This->buffer_size);
2305 CopyMemory(This->vertex_buffer, old_buffer, This->nb_vertices * This->vertex_size);
2306 HeapFree(GetProcessHeap(), 0, old_buffer);
2310 CopyMemory(This->vertex_buffer + This->nb_vertices++ * This->vertex_size, Vertex, This->vertex_size);
2312 LeaveCriticalSection(&ddraw_cs);
2316 static HRESULT WINAPI
2317 Thunk_IDirect3DDeviceImpl_2_Vertex(IDirect3DDevice2 *iface,
2320 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
2321 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, lpVertexType);
2322 return IDirect3DDevice3_Vertex(ICOM_INTERFACE(This, IDirect3DDevice3),
2326 /*****************************************************************************
2327 * IDirect3DDevice3::Index
2329 * Specifies an index to a vertex to be drawn. The vertex array has to
2330 * be specified with BeginIndexed first.
2333 * VertexIndex: The index of the vertex to draw
2336 * D3D_OK because it's a stub
2338 *****************************************************************************/
2339 static HRESULT WINAPI
2340 IDirect3DDeviceImpl_3_Index(IDirect3DDevice3 *iface,
2343 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
2344 FIXME("(%p)->(%04x): stub!\n", This, VertexIndex);
2348 static HRESULT WINAPI
2349 Thunk_IDirect3DDeviceImpl_2_Index(IDirect3DDevice2 *iface,
2352 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
2353 TRACE_(ddraw_thunk)("(%p)->(%04x) thunking to IDirect3DDevice3 interface.\n", This, wVertexIndex);
2354 return IDirect3DDevice3_Index(ICOM_INTERFACE(This, IDirect3DDevice3),
2358 /*****************************************************************************
2359 * IDirect3DDevice3::End
2361 * Ends a draw begun with IDirect3DDevice3::Begin or
2362 * IDirect3DDevice::BeginIndexed. The vertices specified with
2363 * IDirect3DDevice::Vertex or IDirect3DDevice::Index are drawn using
2364 * the IDirect3DDevice7::DrawPrimitive method. So far only
2365 * non-indexed mode is supported
2370 * Flags: Some flags, as usual. Don't know which are defined
2373 * The return value of IDirect3DDevice7::DrawPrimitive
2375 *****************************************************************************/
2376 static HRESULT WINAPI
2377 IDirect3DDeviceImpl_3_End(IDirect3DDevice3 *iface,
2380 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
2381 TRACE("(%p)->(%08x)\n", This, Flags);
2383 return IDirect3DDevice7_DrawPrimitive(ICOM_INTERFACE(This, IDirect3DDevice7),
2384 This->primitive_type, This->vertex_type,
2385 This->vertex_buffer, This->nb_vertices,
2386 This->render_flags);
2389 static HRESULT WINAPI
2390 Thunk_IDirect3DDeviceImpl_2_End(IDirect3DDevice2 *iface,
2393 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
2394 TRACE_(ddraw_thunk)("(%p)->(%08x) thunking to IDirect3DDevice3 interface.\n", This, dwFlags);
2395 return IDirect3DDevice3_End(ICOM_INTERFACE(This, IDirect3DDevice3),
2399 /*****************************************************************************
2400 * IDirect3DDevice7::GetRenderState
2402 * Returns the value of a render state. The possible render states are
2403 * defined in include/d3dtypes.h
2405 * Version 2, 3 and 7
2408 * RenderStateType: Render state to return the current setting of
2409 * Value: Address to store the value at
2412 * D3D_OK on success, for details see IWineD3DDevice::GetRenderState
2413 * DDERR_INVALIDPARAMS if Value == NULL
2415 *****************************************************************************/
2417 IDirect3DDeviceImpl_7_GetRenderState(IDirect3DDevice7 *iface,
2418 D3DRENDERSTATETYPE RenderStateType,
2421 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
2423 TRACE("(%p)->(%08x,%p): Relay\n", This, RenderStateType, Value);
2426 return DDERR_INVALIDPARAMS;
2428 EnterCriticalSection(&ddraw_cs);
2429 switch(RenderStateType)
2431 case D3DRENDERSTATE_TEXTUREMAG:
2433 WINED3DTEXTUREFILTERTYPE tex_mag;
2435 hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice,
2436 0, WINED3DSAMP_MAGFILTER,
2441 case WINED3DTEXF_POINT:
2442 *Value = D3DFILTER_NEAREST;
2444 case WINED3DTEXF_LINEAR:
2445 *Value = D3DFILTER_LINEAR;
2448 ERR("Unhandled texture mag %d !\n",tex_mag);
2454 case D3DRENDERSTATE_TEXTUREMIN:
2456 WINED3DTEXTUREFILTERTYPE tex_min;
2458 hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice,
2459 0, WINED3DSAMP_MINFILTER,
2464 case WINED3DTEXF_POINT:
2465 *Value = D3DFILTER_NEAREST;
2467 case WINED3DTEXF_LINEAR:
2468 *Value = D3DFILTER_LINEAR;
2471 ERR("Unhandled texture mag %d !\n",tex_min);
2477 case D3DRENDERSTATE_TEXTUREADDRESS:
2478 case D3DRENDERSTATE_TEXTUREADDRESSU:
2479 hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice,
2480 0, WINED3DSAMP_ADDRESSU,
2483 case D3DRENDERSTATE_TEXTUREADDRESSV:
2484 hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice,
2485 0, WINED3DSAMP_ADDRESSV,
2490 /* FIXME: Unhandled: D3DRENDERSTATE_STIPPLEPATTERN00 - 31 */
2491 hr = IWineD3DDevice_GetRenderState(This->wineD3DDevice,
2495 LeaveCriticalSection(&ddraw_cs);
2499 static HRESULT WINAPI
2500 IDirect3DDeviceImpl_7_GetRenderState_FPUSetup(IDirect3DDevice7 *iface,
2501 D3DRENDERSTATETYPE RenderStateType,
2504 return IDirect3DDeviceImpl_7_GetRenderState(iface, RenderStateType, Value);
2507 static HRESULT WINAPI
2508 IDirect3DDeviceImpl_7_GetRenderState_FPUPreserve(IDirect3DDevice7 *iface,
2509 D3DRENDERSTATETYPE RenderStateType,
2515 old_fpucw = d3d_fpu_setup();
2516 hr = IDirect3DDeviceImpl_7_GetRenderState(iface, RenderStateType, Value);
2517 set_fpu_control_word(old_fpucw);
2522 static HRESULT WINAPI
2523 IDirect3DDeviceImpl_3_GetRenderState(IDirect3DDevice3 *iface,
2524 D3DRENDERSTATETYPE dwRenderStateType,
2525 DWORD *lpdwRenderState)
2527 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
2529 TRACE("(%p)->(%08x,%p)\n", This, dwRenderStateType, lpdwRenderState);
2531 switch(dwRenderStateType)
2533 case D3DRENDERSTATE_TEXTUREHANDLE:
2535 /* This state is wrapped to SetTexture in SetRenderState, so
2536 * it has to be wrapped to GetTexture here
2538 IWineD3DBaseTexture *tex = NULL;
2539 *lpdwRenderState = 0;
2541 EnterCriticalSection(&ddraw_cs);
2543 hr = IWineD3DDevice_GetTexture(This->wineD3DDevice,
2547 if(hr == WINED3D_OK && tex)
2549 IDirectDrawSurface7 *parent = NULL;
2550 hr = IWineD3DBaseTexture_GetParent(tex,
2551 (IUnknown **) &parent);
2554 /* The parent of the texture is the IDirectDrawSurface7 interface
2555 * of the ddraw surface
2557 IDirectDrawSurfaceImpl *texImpl = ICOM_OBJECT(IDirectDrawSurfaceImpl,
2558 IDirectDrawSurface7,
2560 *lpdwRenderState = texImpl->Handle;
2561 IDirectDrawSurface7_Release(parent);
2563 IWineD3DBaseTexture_Release(tex);
2566 LeaveCriticalSection(&ddraw_cs);
2571 case D3DRENDERSTATE_TEXTUREMAPBLEND:
2573 /* D3DRENDERSTATE_TEXTUREMAPBLEND is mapped to texture state stages in SetRenderState; reverse
2574 the mapping to get the value. */
2575 DWORD colorop, colorarg1, colorarg2;
2576 DWORD alphaop, alphaarg1, alphaarg2;
2578 EnterCriticalSection(&ddraw_cs);
2580 This->legacyTextureBlending = TRUE;
2582 IWineD3DDevice_GetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLOROP, &colorop);
2583 IWineD3DDevice_GetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG1, &colorarg1);
2584 IWineD3DDevice_GetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG2, &colorarg2);
2585 IWineD3DDevice_GetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAOP, &alphaop);
2586 IWineD3DDevice_GetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG1, &alphaarg1);
2587 IWineD3DDevice_GetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG2, &alphaarg2);
2589 if (colorop == WINED3DTOP_SELECTARG1 && colorarg1 == WINED3DTA_TEXTURE &&
2590 alphaop == WINED3DTOP_SELECTARG1 && alphaarg1 == WINED3DTA_TEXTURE)
2592 *lpdwRenderState = D3DTBLEND_DECAL;
2594 else if (colorop == WINED3DTOP_SELECTARG1 && colorarg1 == WINED3DTA_TEXTURE &&
2595 alphaop == WINED3DTOP_MODULATE && alphaarg1 == WINED3DTA_TEXTURE && alphaarg2 == WINED3DTA_CURRENT)
2597 *lpdwRenderState = D3DTBLEND_DECALALPHA;
2599 else if (colorop == WINED3DTOP_MODULATE && colorarg1 == WINED3DTA_TEXTURE && colorarg2 == WINED3DTA_CURRENT &&
2600 alphaop == WINED3DTOP_MODULATE && alphaarg1 == WINED3DTA_TEXTURE && alphaarg2 == WINED3DTA_CURRENT)
2602 *lpdwRenderState = D3DTBLEND_MODULATEALPHA;
2607 BOOL tex_alpha = FALSE;
2608 IWineD3DBaseTexture *tex = NULL;
2609 WINED3DSURFACE_DESC desc;
2611 DDPIXELFORMAT ddfmt;
2613 hr = IWineD3DDevice_GetTexture(This->wineD3DDevice,
2617 if(hr == WINED3D_OK && tex)
2619 memset(&desc, 0, sizeof(desc));
2621 hr = IWineD3DTexture_GetLevelDesc((IWineD3DTexture*) tex, 0, &desc);
2624 ddfmt.dwSize = sizeof(ddfmt);
2625 PixelFormat_WineD3DtoDD(&ddfmt, fmt);
2626 if (ddfmt.u5.dwRGBAlphaBitMask) tex_alpha = TRUE;
2629 IWineD3DBaseTexture_Release(tex);
2632 if (!(colorop == WINED3DTOP_MODULATE && colorarg1 == WINED3DTA_TEXTURE && colorarg2 == WINED3DTA_CURRENT &&
2633 alphaop == WINED3DTOP_SELECTARG1 && alphaarg1 == (tex_alpha ? WINED3DTA_TEXTURE : WINED3DTA_CURRENT)))
2635 ERR("Unexpected texture stage state setup, returning D3DTBLEND_MODULATE - likely erroneous\n");
2638 *lpdwRenderState = D3DTBLEND_MODULATE;
2641 LeaveCriticalSection(&ddraw_cs);
2647 return IDirect3DDevice7_GetRenderState(ICOM_INTERFACE(This, IDirect3DDevice7),
2653 static HRESULT WINAPI
2654 Thunk_IDirect3DDeviceImpl_2_GetRenderState(IDirect3DDevice2 *iface,
2655 D3DRENDERSTATETYPE dwRenderStateType,
2656 DWORD *lpdwRenderState)
2658 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
2659 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice3 interface.\n", This, dwRenderStateType, lpdwRenderState);
2660 return IDirect3DDevice3_GetRenderState(ICOM_INTERFACE(This, IDirect3DDevice3),
2665 /*****************************************************************************
2666 * IDirect3DDevice7::SetRenderState
2668 * Sets a render state. The possible render states are defined in
2669 * include/d3dtypes.h
2671 * Version 2, 3 and 7
2674 * RenderStateType: State to set
2675 * Value: Value to assign to that state
2678 * D3D_OK on success,
2679 * for details see IWineD3DDevice::SetRenderState
2681 *****************************************************************************/
2683 IDirect3DDeviceImpl_7_SetRenderState(IDirect3DDevice7 *iface,
2684 D3DRENDERSTATETYPE RenderStateType,
2687 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
2689 TRACE("(%p)->(%08x,%d): Relay\n", This, RenderStateType, Value);
2691 EnterCriticalSection(&ddraw_cs);
2692 /* Some render states need special care */
2693 switch(RenderStateType)
2695 case D3DRENDERSTATE_TEXTUREMAG:
2697 WINED3DTEXTUREFILTERTYPE tex_mag = WINED3DTEXF_NONE;
2699 switch ((D3DTEXTUREFILTER) Value)
2701 case D3DFILTER_NEAREST:
2702 case D3DFILTER_LINEARMIPNEAREST:
2703 tex_mag = WINED3DTEXF_POINT;
2705 case D3DFILTER_LINEAR:
2706 case D3DFILTER_LINEARMIPLINEAR:
2707 tex_mag = WINED3DTEXF_LINEAR;
2710 ERR("Unhandled texture mag %d !\n",Value);
2713 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
2714 0, WINED3DSAMP_MAGFILTER,
2719 case D3DRENDERSTATE_TEXTUREMIN:
2721 WINED3DTEXTUREFILTERTYPE tex_min = WINED3DTEXF_NONE;
2722 WINED3DTEXTUREFILTERTYPE tex_mip = WINED3DTEXF_NONE;
2724 switch ((D3DTEXTUREFILTER) Value)
2726 case D3DFILTER_NEAREST:
2727 tex_min = WINED3DTEXF_POINT;
2729 case D3DFILTER_LINEAR:
2730 tex_min = WINED3DTEXF_LINEAR;
2732 case D3DFILTER_MIPNEAREST:
2733 tex_min = WINED3DTEXF_NONE;
2734 tex_mip = WINED3DTEXF_POINT;
2736 case D3DFILTER_MIPLINEAR:
2737 tex_min = WINED3DTEXF_NONE;
2738 tex_mip = WINED3DTEXF_LINEAR;
2740 case D3DFILTER_LINEARMIPNEAREST:
2741 tex_min = WINED3DTEXF_POINT;
2742 tex_mip = WINED3DTEXF_LINEAR;
2744 case D3DFILTER_LINEARMIPLINEAR:
2745 tex_min = WINED3DTEXF_LINEAR;
2746 tex_mip = WINED3DTEXF_LINEAR;
2750 ERR("Unhandled texture min %d !\n",Value);
2753 IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
2754 0, WINED3DSAMP_MIPFILTER,
2756 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
2757 0, WINED3DSAMP_MINFILTER,
2762 case D3DRENDERSTATE_TEXTUREADDRESS:
2763 IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
2764 0, WINED3DSAMP_ADDRESSV,
2767 case D3DRENDERSTATE_TEXTUREADDRESSU:
2768 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
2769 0, WINED3DSAMP_ADDRESSU,
2772 case D3DRENDERSTATE_TEXTUREADDRESSV:
2773 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
2774 0, WINED3DSAMP_ADDRESSV,
2780 /* FIXME: Unhandled: D3DRENDERSTATE_STIPPLEPATTERN00 - 31 */
2782 hr = IWineD3DDevice_SetRenderState(This->wineD3DDevice,
2787 LeaveCriticalSection(&ddraw_cs);
2791 static HRESULT WINAPI
2792 IDirect3DDeviceImpl_7_SetRenderState_FPUSetup(IDirect3DDevice7 *iface,
2793 D3DRENDERSTATETYPE RenderStateType,
2796 return IDirect3DDeviceImpl_7_SetRenderState(iface, RenderStateType, Value);
2799 static HRESULT WINAPI
2800 IDirect3DDeviceImpl_7_SetRenderState_FPUPreserve(IDirect3DDevice7 *iface,
2801 D3DRENDERSTATETYPE RenderStateType,
2807 old_fpucw = d3d_fpu_setup();
2808 hr = IDirect3DDeviceImpl_7_SetRenderState(iface, RenderStateType, Value);
2809 set_fpu_control_word(old_fpucw);
2814 static HRESULT WINAPI
2815 IDirect3DDeviceImpl_3_SetRenderState(IDirect3DDevice3 *iface,
2816 D3DRENDERSTATETYPE RenderStateType,
2819 /* Note about D3DRENDERSTATE_TEXTUREMAPBLEND implementation: most of values
2820 for this state can be directly mapped to texture stage colorop and alphaop, but
2821 D3DTBLEND_MODULATE is tricky: it uses alpha from texture when available and alpha
2822 from diffuse otherwise. So changing the texture must be monitored in SetTexture to modify
2823 alphaarg when needed.
2825 Aliens vs Predator 1 depends on accurate D3DTBLEND_MODULATE emulation
2827 Legacy texture blending (TEXTUREMAPBLEND) and texture stage states: directx6 docs state that
2828 TEXTUREMAPBLEND is deprecated, yet can still be used. Games must not use both or results
2829 are undefined. D3DTBLEND_MODULATE mode in particular is dependent on texture pixel format and
2830 requires fixup of stage 0 texture states when texture changes, but this fixup can interfere
2831 with games not using this deprecated state. So a flag 'legacyTextureBlending' has to be kept
2832 in device - TRUE if the app is using TEXTUREMAPBLEND.
2834 Tests show that setting TEXTUREMAPBLEND on native doesn't seem to change values returned by
2835 GetTextureStageState and vice versa. Not so on Wine, but it is 'undefined' anyway so, probably, ok,
2836 unless some broken game will be found that cares. */
2839 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
2840 TRACE("(%p)->(%08x,%d)\n", This, RenderStateType, Value);
2842 EnterCriticalSection(&ddraw_cs);
2844 switch(RenderStateType)
2846 case D3DRENDERSTATE_TEXTUREHANDLE:
2850 hr = IWineD3DDevice_SetTexture(This->wineD3DDevice,
2856 if(Value > This->numHandles)
2858 FIXME("Specified handle %d out of range\n", Value);
2859 hr = DDERR_INVALIDPARAMS;
2862 if(This->Handles[Value - 1].type != DDrawHandle_Texture)
2864 FIXME("Handle %d isn't a texture handle\n", Value);
2865 hr = DDERR_INVALIDPARAMS;
2870 IDirectDrawSurfaceImpl *surf = This->Handles[Value - 1].ptr;
2871 hr = IDirect3DDevice3_SetTexture(iface, 0, ICOM_INTERFACE(surf, IDirect3DTexture2));
2876 case D3DRENDERSTATE_TEXTUREMAPBLEND:
2878 This->legacyTextureBlending = TRUE;
2880 switch ( (D3DTEXTUREBLEND) Value)
2882 case D3DTBLEND_MODULATE:
2884 BOOL tex_alpha = FALSE;
2885 IWineD3DBaseTexture *tex = NULL;
2886 WINED3DSURFACE_DESC desc;
2888 DDPIXELFORMAT ddfmt;
2890 hr = IWineD3DDevice_GetTexture(This->wineD3DDevice,
2894 if(hr == WINED3D_OK && tex)
2896 memset(&desc, 0, sizeof(desc));
2898 hr = IWineD3DTexture_GetLevelDesc((IWineD3DTexture*) tex, 0, &desc);
2901 ddfmt.dwSize = sizeof(ddfmt);
2902 PixelFormat_WineD3DtoDD(&ddfmt, fmt);
2903 if (ddfmt.u5.dwRGBAlphaBitMask) tex_alpha = TRUE;
2906 IWineD3DBaseTexture_Release(tex);
2909 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAOP, WINED3DTOP_SELECTARG1);
2912 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG1, WINED3DTA_TEXTURE);
2916 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG1, WINED3DTA_CURRENT);
2919 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG1, WINED3DTA_TEXTURE);
2920 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG2, WINED3DTA_CURRENT);
2921 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLOROP, WINED3DTOP_MODULATE);
2927 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLOROP, WINED3DTOP_ADD);
2928 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG1, WINED3DTA_TEXTURE);
2929 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG2, WINED3DTA_CURRENT);
2930 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAOP, WINED3DTOP_SELECTARG2);
2931 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG2, WINED3DTA_CURRENT);
2934 case D3DTBLEND_MODULATEALPHA:
2935 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG1, WINED3DTA_TEXTURE);
2936 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG1, WINED3DTA_TEXTURE);
2937 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG2, WINED3DTA_CURRENT);
2938 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG2, WINED3DTA_CURRENT);
2939 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLOROP, WINED3DTOP_MODULATE);
2940 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAOP, WINED3DTOP_MODULATE);
2943 case D3DTBLEND_COPY:
2944 case D3DTBLEND_DECAL:
2945 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG1, WINED3DTA_TEXTURE);
2946 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG1, WINED3DTA_TEXTURE);
2947 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLOROP, WINED3DTOP_SELECTARG1);
2948 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAOP, WINED3DTOP_SELECTARG1);
2951 case D3DTBLEND_DECALALPHA:
2952 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLOROP, WINED3DTOP_BLENDTEXTUREALPHA);
2953 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG1, WINED3DTA_TEXTURE);
2954 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG2, WINED3DTA_CURRENT);
2955 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAOP, WINED3DTOP_SELECTARG2);
2956 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG2, WINED3DTA_CURRENT);
2960 ERR("Unhandled texture environment %d !\n",Value);
2968 hr = IDirect3DDevice7_SetRenderState(ICOM_INTERFACE(This, IDirect3DDevice7),
2974 LeaveCriticalSection(&ddraw_cs);
2979 static HRESULT WINAPI
2980 Thunk_IDirect3DDeviceImpl_2_SetRenderState(IDirect3DDevice2 *iface,
2981 D3DRENDERSTATETYPE RenderStateType,
2984 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
2985 TRACE_(ddraw_thunk)("(%p)->(%08x,%d) thunking to IDirect3DDevice3 interface.\n", This, RenderStateType, Value);
2986 return IDirect3DDevice3_SetRenderState(ICOM_INTERFACE(This, IDirect3DDevice3), RenderStateType, Value);
2989 /*****************************************************************************
2990 * Direct3DDevice3::SetLightState
2992 * Sets a light state for Direct3DDevice3 and Direct3DDevice2. The
2993 * light states are forwarded to Direct3DDevice7 render states
2998 * LightStateType: The light state to change
2999 * Value: The value to assign to that light state
3003 * DDERR_INVALIDPARAMS if the parameters were incorrect
3004 * Also check IDirect3DDevice7::SetRenderState
3006 *****************************************************************************/
3007 static HRESULT WINAPI
3008 IDirect3DDeviceImpl_3_SetLightState(IDirect3DDevice3 *iface,
3009 D3DLIGHTSTATETYPE LightStateType,
3012 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
3015 TRACE("(%p)->(%08x,%08x)\n", This, LightStateType, Value);
3017 if (!LightStateType && (LightStateType > D3DLIGHTSTATE_COLORVERTEX))
3019 TRACE("Unexpected Light State Type\n");
3020 return DDERR_INVALIDPARAMS;
3023 EnterCriticalSection(&ddraw_cs);
3024 if (LightStateType == D3DLIGHTSTATE_MATERIAL /* 1 */)
3026 IDirect3DMaterialImpl *mat;
3028 if(Value == 0) mat = NULL;
3029 else if(Value > This->numHandles)
3031 ERR("Material handle out of range(%d)\n", Value);
3032 LeaveCriticalSection(&ddraw_cs);
3033 return DDERR_INVALIDPARAMS;
3035 else if(This->Handles[Value - 1].type != DDrawHandle_Material)
3037 ERR("Invalid handle %d\n", Value);
3038 LeaveCriticalSection(&ddraw_cs);
3039 return DDERR_INVALIDPARAMS;
3043 mat = This->Handles[Value - 1].ptr;
3048 TRACE(" activating material %p.\n", mat);
3053 FIXME(" D3DLIGHTSTATE_MATERIAL called with NULL material !!!\n");
3055 This->material = Value;
3057 else if (LightStateType == D3DLIGHTSTATE_COLORMODEL /* 3 */)
3062 ERR("DDCOLOR_MONO should not happen!\n");
3065 /* We are already in this mode */
3066 TRACE("Setting color model to RGB (no-op).\n");
3069 ERR("Unknown color model!\n");
3070 LeaveCriticalSection(&ddraw_cs);
3071 return DDERR_INVALIDPARAMS;
3076 D3DRENDERSTATETYPE rs;
3077 switch (LightStateType)
3079 case D3DLIGHTSTATE_AMBIENT: /* 2 */
3080 rs = D3DRENDERSTATE_AMBIENT;
3082 case D3DLIGHTSTATE_FOGMODE: /* 4 */
3083 rs = D3DRENDERSTATE_FOGVERTEXMODE;
3085 case D3DLIGHTSTATE_FOGSTART: /* 5 */
3086 rs = D3DRENDERSTATE_FOGSTART;
3088 case D3DLIGHTSTATE_FOGEND: /* 6 */
3089 rs = D3DRENDERSTATE_FOGEND;
3091 case D3DLIGHTSTATE_FOGDENSITY: /* 7 */
3092 rs = D3DRENDERSTATE_FOGDENSITY;
3094 case D3DLIGHTSTATE_COLORVERTEX: /* 8 */
3095 rs = D3DRENDERSTATE_COLORVERTEX;
3098 ERR("Unknown D3DLIGHTSTATETYPE %d.\n", LightStateType);
3099 LeaveCriticalSection(&ddraw_cs);
3100 return DDERR_INVALIDPARAMS;
3103 hr = IDirect3DDevice7_SetRenderState(ICOM_INTERFACE(This, IDirect3DDevice7),
3106 LeaveCriticalSection(&ddraw_cs);
3110 LeaveCriticalSection(&ddraw_cs);
3114 static HRESULT WINAPI
3115 Thunk_IDirect3DDeviceImpl_2_SetLightState(IDirect3DDevice2 *iface,
3116 D3DLIGHTSTATETYPE LightStateType,
3119 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
3120 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x) thunking to IDirect3DDevice3 interface.\n", This, LightStateType, Value);
3121 return IDirect3DDevice3_SetLightState(ICOM_INTERFACE(This, IDirect3DDevice3),
3126 /*****************************************************************************
3127 * IDirect3DDevice3::GetLightState
3129 * Returns the current setting of a light state. The state is read from
3130 * the Direct3DDevice7 render state.
3135 * LightStateType: The light state to return
3136 * Value: The address to store the light state setting at
3140 * DDDERR_INVALIDPARAMS if the parameters were incorrect
3141 * Also see IDirect3DDevice7::GetRenderState
3143 *****************************************************************************/
3144 static HRESULT WINAPI
3145 IDirect3DDeviceImpl_3_GetLightState(IDirect3DDevice3 *iface,
3146 D3DLIGHTSTATETYPE LightStateType,
3149 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
3152 TRACE("(%p)->(%08x,%p)\n", This, LightStateType, Value);
3154 if (!LightStateType && (LightStateType > D3DLIGHTSTATE_COLORVERTEX))
3156 TRACE("Unexpected Light State Type\n");
3157 return DDERR_INVALIDPARAMS;
3161 return DDERR_INVALIDPARAMS;
3163 EnterCriticalSection(&ddraw_cs);
3164 if (LightStateType == D3DLIGHTSTATE_MATERIAL /* 1 */)
3166 *Value = This->material;
3168 else if (LightStateType == D3DLIGHTSTATE_COLORMODEL /* 3 */)
3170 *Value = D3DCOLOR_RGB;
3174 D3DRENDERSTATETYPE rs;
3175 switch (LightStateType)
3177 case D3DLIGHTSTATE_AMBIENT: /* 2 */
3178 rs = D3DRENDERSTATE_AMBIENT;
3180 case D3DLIGHTSTATE_FOGMODE: /* 4 */
3181 rs = D3DRENDERSTATE_FOGVERTEXMODE;
3183 case D3DLIGHTSTATE_FOGSTART: /* 5 */
3184 rs = D3DRENDERSTATE_FOGSTART;
3186 case D3DLIGHTSTATE_FOGEND: /* 6 */
3187 rs = D3DRENDERSTATE_FOGEND;
3189 case D3DLIGHTSTATE_FOGDENSITY: /* 7 */
3190 rs = D3DRENDERSTATE_FOGDENSITY;
3192 case D3DLIGHTSTATE_COLORVERTEX: /* 8 */
3193 rs = D3DRENDERSTATE_COLORVERTEX;
3196 ERR("Unknown D3DLIGHTSTATETYPE %d.\n", LightStateType);
3197 LeaveCriticalSection(&ddraw_cs);
3198 return DDERR_INVALIDPARAMS;
3201 hr = IDirect3DDevice7_GetRenderState(ICOM_INTERFACE(This, IDirect3DDevice7),
3204 LeaveCriticalSection(&ddraw_cs);
3208 LeaveCriticalSection(&ddraw_cs);
3212 static HRESULT WINAPI
3213 Thunk_IDirect3DDeviceImpl_2_GetLightState(IDirect3DDevice2 *iface,
3214 D3DLIGHTSTATETYPE LightStateType,
3217 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
3218 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice3 interface.\n", This, LightStateType, Value);
3219 return IDirect3DDevice3_GetLightState(ICOM_INTERFACE(This, IDirect3DDevice3),
3224 /*****************************************************************************
3225 * IDirect3DDevice7::SetTransform
3227 * Assigns a D3DMATRIX to a transform type. The transform types are defined
3228 * in include/d3dtypes.h.
3229 * The D3DTRANSFORMSTATE_WORLD (=1) is translated to D3DTS_WORLDMATRIX(0)
3230 * (=255) for wined3d, because the 1 transform state was removed in d3d8
3231 * and WineD3D already understands the replacement D3DTS_WORLDMATRIX(0)
3233 * Version 2, 3 and 7
3236 * TransformStateType: transform state to set
3237 * Matrix: Matrix to assign to the state
3241 * DDERR_INVALIDPARAMS if Matrix == NULL
3242 * For details see IWineD3DDevice::SetTransform
3244 *****************************************************************************/
3246 IDirect3DDeviceImpl_7_SetTransform(IDirect3DDevice7 *iface,
3247 D3DTRANSFORMSTATETYPE TransformStateType,
3250 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
3251 D3DTRANSFORMSTATETYPE type;
3253 TRACE("(%p)->(%08x,%p): Relay\n", This, TransformStateType, Matrix);
3255 switch(TransformStateType)
3257 case D3DTRANSFORMSTATE_WORLD : type = WINED3DTS_WORLDMATRIX(0); break;
3258 case D3DTRANSFORMSTATE_WORLD1: type = WINED3DTS_WORLDMATRIX(1); break;
3259 case D3DTRANSFORMSTATE_WORLD2: type = WINED3DTS_WORLDMATRIX(2); break;
3260 case D3DTRANSFORMSTATE_WORLD3: type = WINED3DTS_WORLDMATRIX(3); break;
3261 default: type = TransformStateType;
3265 return DDERR_INVALIDPARAMS;
3267 /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
3268 EnterCriticalSection(&ddraw_cs);
3269 hr = IWineD3DDevice_SetTransform(This->wineD3DDevice,
3271 (WINED3DMATRIX*) Matrix);
3272 LeaveCriticalSection(&ddraw_cs);
3276 static HRESULT WINAPI
3277 IDirect3DDeviceImpl_7_SetTransform_FPUSetup(IDirect3DDevice7 *iface,
3278 D3DTRANSFORMSTATETYPE TransformStateType,
3281 return IDirect3DDeviceImpl_7_SetTransform(iface, TransformStateType, Matrix);
3284 static HRESULT WINAPI
3285 IDirect3DDeviceImpl_7_SetTransform_FPUPreserve(IDirect3DDevice7 *iface,
3286 D3DTRANSFORMSTATETYPE TransformStateType,
3292 old_fpucw = d3d_fpu_setup();
3293 hr = IDirect3DDeviceImpl_7_SetTransform(iface, TransformStateType, Matrix);
3294 set_fpu_control_word(old_fpucw);
3299 static HRESULT WINAPI
3300 Thunk_IDirect3DDeviceImpl_3_SetTransform(IDirect3DDevice3 *iface,
3301 D3DTRANSFORMSTATETYPE TransformStateType,
3302 D3DMATRIX *D3DMatrix)
3304 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
3305 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, TransformStateType, D3DMatrix);
3306 return IDirect3DDevice7_SetTransform(ICOM_INTERFACE(This, IDirect3DDevice7),
3311 static HRESULT WINAPI
3312 Thunk_IDirect3DDeviceImpl_2_SetTransform(IDirect3DDevice2 *iface,
3313 D3DTRANSFORMSTATETYPE TransformStateType,
3314 D3DMATRIX *D3DMatrix)
3316 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
3317 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, TransformStateType, D3DMatrix);
3318 return IDirect3DDevice7_SetTransform(ICOM_INTERFACE(This, IDirect3DDevice7),
3323 /*****************************************************************************
3324 * IDirect3DDevice7::GetTransform
3326 * Returns the matrix assigned to a transform state
3327 * D3DTRANSFORMSTATE_WORLD is translated to D3DTS_WORLDMATRIX(0), see
3331 * TransformStateType: State to read the matrix from
3332 * Matrix: Address to store the matrix at
3336 * DDERR_INVALIDPARAMS if Matrix == NULL
3337 * For details, see IWineD3DDevice::GetTransform
3339 *****************************************************************************/
3341 IDirect3DDeviceImpl_7_GetTransform(IDirect3DDevice7 *iface,
3342 D3DTRANSFORMSTATETYPE TransformStateType,
3345 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
3346 D3DTRANSFORMSTATETYPE type;
3348 TRACE("(%p)->(%08x,%p): Relay\n", This, TransformStateType, Matrix);
3350 switch(TransformStateType)
3352 case D3DTRANSFORMSTATE_WORLD : type = WINED3DTS_WORLDMATRIX(0); break;
3353 case D3DTRANSFORMSTATE_WORLD1: type = WINED3DTS_WORLDMATRIX(1); break;
3354 case D3DTRANSFORMSTATE_WORLD2: type = WINED3DTS_WORLDMATRIX(2); break;
3355 case D3DTRANSFORMSTATE_WORLD3: type = WINED3DTS_WORLDMATRIX(3); break;
3356 default: type = TransformStateType;
3360 return DDERR_INVALIDPARAMS;
3362 /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
3363 EnterCriticalSection(&ddraw_cs);
3364 hr = IWineD3DDevice_GetTransform(This->wineD3DDevice, type, (WINED3DMATRIX*) Matrix);
3365 LeaveCriticalSection(&ddraw_cs);
3369 static HRESULT WINAPI
3370 IDirect3DDeviceImpl_7_GetTransform_FPUSetup(IDirect3DDevice7 *iface,
3371 D3DTRANSFORMSTATETYPE TransformStateType,
3374 return IDirect3DDeviceImpl_7_GetTransform(iface, TransformStateType, Matrix);
3377 static HRESULT WINAPI
3378 IDirect3DDeviceImpl_7_GetTransform_FPUPreserve(IDirect3DDevice7 *iface,
3379 D3DTRANSFORMSTATETYPE TransformStateType,
3385 old_fpucw = d3d_fpu_setup();
3386 hr = IDirect3DDeviceImpl_7_GetTransform(iface, TransformStateType, Matrix);
3387 set_fpu_control_word(old_fpucw);
3392 static HRESULT WINAPI
3393 Thunk_IDirect3DDeviceImpl_3_GetTransform(IDirect3DDevice3 *iface,
3394 D3DTRANSFORMSTATETYPE TransformStateType,
3395 D3DMATRIX *D3DMatrix)
3397 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
3398 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, TransformStateType, D3DMatrix);
3399 return IDirect3DDevice7_GetTransform(ICOM_INTERFACE(This, IDirect3DDevice7),
3404 static HRESULT WINAPI
3405 Thunk_IDirect3DDeviceImpl_2_GetTransform(IDirect3DDevice2 *iface,
3406 D3DTRANSFORMSTATETYPE TransformStateType,
3407 D3DMATRIX *D3DMatrix)
3409 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
3410 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, TransformStateType, D3DMatrix);
3411 return IDirect3DDevice7_GetTransform(ICOM_INTERFACE(This, IDirect3DDevice7),
3416 /*****************************************************************************
3417 * IDirect3DDevice7::MultiplyTransform
3419 * Multiplies the already-set transform matrix of a transform state
3420 * with another matrix. For the world matrix, see SetTransform
3422 * Version 2, 3 and 7
3425 * TransformStateType: Transform state to multiply
3426 * D3DMatrix Matrix to multiply with.
3430 * DDERR_INVALIDPARAMS if D3DMatrix is NULL
3431 * For details, see IWineD3DDevice::MultiplyTransform
3433 *****************************************************************************/
3435 IDirect3DDeviceImpl_7_MultiplyTransform(IDirect3DDevice7 *iface,
3436 D3DTRANSFORMSTATETYPE TransformStateType,
3437 D3DMATRIX *D3DMatrix)
3439 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
3441 D3DTRANSFORMSTATETYPE type;
3442 TRACE("(%p)->(%08x,%p): Relay\n", This, TransformStateType, D3DMatrix);
3444 switch(TransformStateType)
3446 case D3DTRANSFORMSTATE_WORLD : type = WINED3DTS_WORLDMATRIX(0); break;
3447 case D3DTRANSFORMSTATE_WORLD1: type = WINED3DTS_WORLDMATRIX(1); break;
3448 case D3DTRANSFORMSTATE_WORLD2: type = WINED3DTS_WORLDMATRIX(2); break;
3449 case D3DTRANSFORMSTATE_WORLD3: type = WINED3DTS_WORLDMATRIX(3); break;
3450 default: type = TransformStateType;
3453 /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
3454 EnterCriticalSection(&ddraw_cs);
3455 hr = IWineD3DDevice_MultiplyTransform(This->wineD3DDevice,
3457 (WINED3DMATRIX*) D3DMatrix);
3458 LeaveCriticalSection(&ddraw_cs);
3462 static HRESULT WINAPI
3463 IDirect3DDeviceImpl_7_MultiplyTransform_FPUSetup(IDirect3DDevice7 *iface,
3464 D3DTRANSFORMSTATETYPE TransformStateType,
3465 D3DMATRIX *D3DMatrix)
3467 return IDirect3DDeviceImpl_7_MultiplyTransform(iface, TransformStateType, D3DMatrix);
3470 static HRESULT WINAPI
3471 IDirect3DDeviceImpl_7_MultiplyTransform_FPUPreserve(IDirect3DDevice7 *iface,
3472 D3DTRANSFORMSTATETYPE TransformStateType,
3473 D3DMATRIX *D3DMatrix)
3478 old_fpucw = d3d_fpu_setup();
3479 hr = IDirect3DDeviceImpl_7_MultiplyTransform(iface, TransformStateType, D3DMatrix);
3480 set_fpu_control_word(old_fpucw);
3485 static HRESULT WINAPI
3486 Thunk_IDirect3DDeviceImpl_3_MultiplyTransform(IDirect3DDevice3 *iface,
3487 D3DTRANSFORMSTATETYPE TransformStateType,
3488 D3DMATRIX *D3DMatrix)
3490 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
3491 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, TransformStateType, D3DMatrix);
3492 return IDirect3DDevice7_MultiplyTransform(ICOM_INTERFACE(This, IDirect3DDevice7),
3497 static HRESULT WINAPI
3498 Thunk_IDirect3DDeviceImpl_2_MultiplyTransform(IDirect3DDevice2 *iface,
3499 D3DTRANSFORMSTATETYPE TransformStateType,
3500 D3DMATRIX *D3DMatrix)
3502 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
3503 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, TransformStateType, D3DMatrix);
3504 return IDirect3DDevice7_MultiplyTransform(ICOM_INTERFACE(This, IDirect3DDevice7),
3509 /*****************************************************************************
3510 * IDirect3DDevice7::DrawPrimitive
3512 * Draws primitives based on vertices in an application-provided pointer
3514 * Version 2, 3 and 7. The IDirect3DDevice2 thunk converts the fixed vertex type into
3515 * an FVF format for D3D7
3518 * PrimitiveType: The type of the primitives to draw
3519 * Vertex type: Flexible vertex format vertex description
3520 * Vertices: Pointer to the vertex array
3521 * VertexCount: The number of vertices to draw
3522 * Flags: As usual a few flags
3526 * DDERR_INVALIDPARAMS if Vertices is NULL
3527 * For details, see IWineD3DDevice::DrawPrimitiveUP
3529 *****************************************************************************/
3531 IDirect3DDeviceImpl_7_DrawPrimitive(IDirect3DDevice7 *iface,
3532 D3DPRIMITIVETYPE PrimitiveType,
3538 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
3539 UINT PrimitiveCount, stride;
3541 TRACE("(%p)->(%08x,%08x,%p,%08x,%08x): Relay!\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Flags);
3544 return DDERR_INVALIDPARAMS;
3546 /* Get the vertex count */
3547 switch(PrimitiveType)
3549 case D3DPT_POINTLIST:
3550 PrimitiveCount = VertexCount;
3553 case D3DPT_LINELIST:
3554 PrimitiveCount = VertexCount / 2;
3557 case D3DPT_LINESTRIP:
3558 PrimitiveCount = VertexCount - 1;
3561 case D3DPT_TRIANGLELIST:
3562 PrimitiveCount = VertexCount / 3;
3565 case D3DPT_TRIANGLESTRIP:
3566 PrimitiveCount = VertexCount - 2;
3569 case D3DPT_TRIANGLEFAN:
3570 PrimitiveCount = VertexCount - 2;
3574 return DDERR_INVALIDPARAMS;
3577 /* Get the stride */
3578 stride = get_flexible_vertex_size(VertexType);
3581 EnterCriticalSection(&ddraw_cs);
3582 hr = IWineD3DDevice_SetVertexDeclaration(This->wineD3DDevice,
3583 IDirectDrawImpl_FindDecl(This->ddraw, VertexType));
3586 LeaveCriticalSection(&ddraw_cs);
3590 /* This method translates to the user pointer draw of WineD3D */
3591 hr = IWineD3DDevice_DrawPrimitiveUP(This->wineD3DDevice,
3596 LeaveCriticalSection(&ddraw_cs);
3600 static HRESULT WINAPI
3601 IDirect3DDeviceImpl_7_DrawPrimitive_FPUSetup(IDirect3DDevice7 *iface,
3602 D3DPRIMITIVETYPE PrimitiveType,
3608 return IDirect3DDeviceImpl_7_DrawPrimitive(iface, PrimitiveType, VertexType, Vertices, VertexCount, Flags);
3611 static HRESULT WINAPI
3612 IDirect3DDeviceImpl_7_DrawPrimitive_FPUPreserve(IDirect3DDevice7 *iface,
3613 D3DPRIMITIVETYPE PrimitiveType,
3622 old_fpucw = d3d_fpu_setup();
3623 hr = IDirect3DDeviceImpl_7_DrawPrimitive(iface, PrimitiveType, VertexType, Vertices, VertexCount, Flags);
3624 set_fpu_control_word(old_fpucw);
3629 static HRESULT WINAPI
3630 Thunk_IDirect3DDeviceImpl_3_DrawPrimitive(IDirect3DDevice3 *iface,
3631 D3DPRIMITIVETYPE PrimitiveType,
3637 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
3638 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Flags);
3639 return IDirect3DDevice7_DrawPrimitive(ICOM_INTERFACE(This, IDirect3DDevice7),
3647 static HRESULT WINAPI
3648 Thunk_IDirect3DDeviceImpl_2_DrawPrimitive(IDirect3DDevice2 *iface,
3649 D3DPRIMITIVETYPE PrimitiveType,
3650 D3DVERTEXTYPE VertexType,
3655 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
3657 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Flags);
3661 case D3DVT_VERTEX: FVF = D3DFVF_VERTEX; break;
3662 case D3DVT_LVERTEX: FVF = D3DFVF_LVERTEX; break;
3663 case D3DVT_TLVERTEX: FVF = D3DFVF_TLVERTEX; break;
3665 ERR("Unexpected vertex type %d\n", VertexType);
3666 return DDERR_INVALIDPARAMS; /* Should never happen */
3669 return IDirect3DDevice7_DrawPrimitive(ICOM_INTERFACE(This, IDirect3DDevice7),
3677 /*****************************************************************************
3678 * IDirect3DDevice7::DrawIndexedPrimitive
3680 * Draws vertices from an application-provided pointer, based on the index
3681 * numbers in a WORD array.
3683 * Version 2, 3 and 7. The version 7 thunk translates the vertex type into
3684 * an FVF format for D3D7
3687 * PrimitiveType: The primitive type to draw
3688 * VertexType: The FVF vertex description
3689 * Vertices: Pointer to the vertex array
3691 * Indices: Pointer to the index array
3692 * IndexCount: Number of indices = Number of vertices to draw
3693 * Flags: As usual, some flags
3697 * DDERR_INVALIDPARAMS if Vertices or Indices is NULL
3698 * For details, see IWineD3DDevice::DrawIndexedPrimitiveUP
3700 *****************************************************************************/
3702 IDirect3DDeviceImpl_7_DrawIndexedPrimitive(IDirect3DDevice7 *iface,
3703 D3DPRIMITIVETYPE PrimitiveType,
3711 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
3712 UINT PrimitiveCount = 0;
3714 TRACE("(%p)->(%08x,%08x,%p,%08x,%p,%08x,%08x): Relay!\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Indices, IndexCount, Flags);
3716 /* Get the primitive number */
3717 switch(PrimitiveType)
3719 case D3DPT_POINTLIST:
3720 PrimitiveCount = IndexCount;
3723 case D3DPT_LINELIST:
3724 PrimitiveCount = IndexCount / 2;
3727 case D3DPT_LINESTRIP:
3728 PrimitiveCount = IndexCount - 1;
3731 case D3DPT_TRIANGLELIST:
3732 PrimitiveCount = IndexCount / 3;
3735 case D3DPT_TRIANGLESTRIP:
3736 PrimitiveCount = IndexCount - 2;
3739 case D3DPT_TRIANGLEFAN:
3740 PrimitiveCount = IndexCount - 2;
3744 return DDERR_INVALIDPARAMS;
3747 /* Set the D3DDevice's FVF */
3748 EnterCriticalSection(&ddraw_cs);
3749 hr = IWineD3DDevice_SetVertexDeclaration(This->wineD3DDevice,
3750 IDirectDrawImpl_FindDecl(This->ddraw, VertexType));
3753 ERR(" (%p) Setting the FVF failed, hr = %x!\n", This, hr);
3754 LeaveCriticalSection(&ddraw_cs);
3758 hr = IWineD3DDevice_DrawIndexedPrimitiveUP(This->wineD3DDevice,
3760 0 /* MinVertexIndex */,
3761 VertexCount /* UINT NumVertexIndex */,
3766 get_flexible_vertex_size(VertexType));
3767 LeaveCriticalSection(&ddraw_cs);
3771 static HRESULT WINAPI
3772 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUSetup(IDirect3DDevice7 *iface,
3773 D3DPRIMITIVETYPE PrimitiveType,
3781 return IDirect3DDeviceImpl_7_DrawIndexedPrimitive(iface, PrimitiveType, VertexType, Vertices, VertexCount, Indices, IndexCount, Flags);
3784 static HRESULT WINAPI
3785 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUPreserve(IDirect3DDevice7 *iface,
3786 D3DPRIMITIVETYPE PrimitiveType,
3797 old_fpucw = d3d_fpu_setup();
3798 hr = IDirect3DDeviceImpl_7_DrawIndexedPrimitive(iface, PrimitiveType, VertexType, Vertices, VertexCount, Indices, IndexCount, Flags);
3799 set_fpu_control_word(old_fpucw);
3804 static HRESULT WINAPI
3805 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitive(IDirect3DDevice3 *iface,
3806 D3DPRIMITIVETYPE PrimitiveType,
3814 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
3815 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Indices, IndexCount, Flags);
3816 return IDirect3DDevice7_DrawIndexedPrimitive(ICOM_INTERFACE(This, IDirect3DDevice7),
3826 static HRESULT WINAPI
3827 Thunk_IDirect3DDeviceImpl_2_DrawIndexedPrimitive(IDirect3DDevice2 *iface,
3828 D3DPRIMITIVETYPE PrimitiveType,
3829 D3DVERTEXTYPE VertexType,
3837 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
3838 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Indices, IndexCount, Flags);
3842 case D3DVT_VERTEX: FVF = D3DFVF_VERTEX; break;
3843 case D3DVT_LVERTEX: FVF = D3DFVF_LVERTEX; break;
3844 case D3DVT_TLVERTEX: FVF = D3DFVF_TLVERTEX; break;
3846 ERR("Unexpected vertex type %d\n", VertexType);
3847 return DDERR_INVALIDPARAMS; /* Should never happen */
3850 return IDirect3DDevice7_DrawIndexedPrimitive(ICOM_INTERFACE(This, IDirect3DDevice7),
3860 /*****************************************************************************
3861 * IDirect3DDevice7::SetClipStatus
3863 * Sets the clip status. This defines things as clipping conditions and
3864 * the extents of the clipping region.
3866 * Version 2, 3 and 7
3872 * D3D_OK because it's a stub
3873 * (DDERR_INVALIDPARAMS if ClipStatus == NULL)
3875 *****************************************************************************/
3876 static HRESULT WINAPI
3877 IDirect3DDeviceImpl_7_SetClipStatus(IDirect3DDevice7 *iface,
3878 D3DCLIPSTATUS *ClipStatus)
3880 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
3881 FIXME("(%p)->(%p): Stub!\n", This, ClipStatus);
3883 /* D3DCLIPSTATUS and WINED3DCLIPSTATUS are different. I don't know how to convert them
3884 * Perhaps this needs a new data type and an additional IWineD3DDevice method
3886 /* return IWineD3DDevice_SetClipStatus(This->wineD3DDevice, ClipStatus);*/
3890 static HRESULT WINAPI
3891 Thunk_IDirect3DDeviceImpl_3_SetClipStatus(IDirect3DDevice3 *iface,
3892 D3DCLIPSTATUS *ClipStatus)
3894 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
3895 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, ClipStatus);
3896 return IDirect3DDevice7_SetClipStatus(ICOM_INTERFACE(This, IDirect3DDevice7),
3900 static HRESULT WINAPI
3901 Thunk_IDirect3DDeviceImpl_2_SetClipStatus(IDirect3DDevice2 *iface,
3902 D3DCLIPSTATUS *ClipStatus)
3904 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
3905 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, ClipStatus);
3906 return IDirect3DDevice7_SetClipStatus(ICOM_INTERFACE(This, IDirect3DDevice7),
3910 /*****************************************************************************
3911 * IDirect3DDevice7::GetClipStatus
3913 * Returns the clip status
3916 * ClipStatus: Address to write the clip status to
3919 * D3D_OK because it's a stub
3921 *****************************************************************************/
3922 static HRESULT WINAPI
3923 IDirect3DDeviceImpl_7_GetClipStatus(IDirect3DDevice7 *iface,
3924 D3DCLIPSTATUS *ClipStatus)
3926 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
3927 FIXME("(%p)->(%p): Stub!\n", This, ClipStatus);
3929 /* D3DCLIPSTATUS and WINED3DCLIPSTATUS are different. I don't know how to convert them */
3930 /* return IWineD3DDevice_GetClipStatus(This->wineD3DDevice, ClipStatus);*/
3934 static HRESULT WINAPI
3935 Thunk_IDirect3DDeviceImpl_3_GetClipStatus(IDirect3DDevice3 *iface,
3936 D3DCLIPSTATUS *ClipStatus)
3938 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
3939 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, ClipStatus);
3940 return IDirect3DDevice7_GetClipStatus(ICOM_INTERFACE(This, IDirect3DDevice7),
3944 static HRESULT WINAPI
3945 Thunk_IDirect3DDeviceImpl_2_GetClipStatus(IDirect3DDevice2 *iface,
3946 D3DCLIPSTATUS *ClipStatus)
3948 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice2, iface);
3949 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, ClipStatus);
3950 return IDirect3DDevice7_GetClipStatus(ICOM_INTERFACE(This, IDirect3DDevice7),
3954 /*****************************************************************************
3955 * IDirect3DDevice::DrawPrimitiveStrided
3957 * Draws vertices described by a D3DDRAWPRIMITIVESTRIDEDDATA structure.
3962 * PrimitiveType: The primitive type to draw
3963 * VertexType: The FVF description of the vertices to draw (for the stride??)
3964 * D3DDrawPrimStrideData: A D3DDRAWPRIMITIVESTRIDEDDATA structure describing
3965 * the vertex data locations
3966 * VertexCount: The number of vertices to draw
3970 * D3D_OK, because it's a stub
3971 * (DDERR_INVALIDPARAMS if D3DDrawPrimStrideData is NULL)
3972 * (For details, see IWineD3DDevice::DrawPrimitiveStrided)
3974 *****************************************************************************/
3976 IDirect3DDeviceImpl_7_DrawPrimitiveStrided(IDirect3DDevice7 *iface,
3977 D3DPRIMITIVETYPE PrimitiveType,
3979 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
3983 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
3984 WineDirect3DVertexStridedData WineD3DStrided;
3986 UINT PrimitiveCount;
3989 TRACE("(%p)->(%08x,%08x,%p,%08x,%08x): stub!\n", This, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Flags);
3991 memset(&WineD3DStrided, 0, sizeof(WineD3DStrided));
3992 /* Get the strided data right. the wined3d structure is a bit bigger
3993 * Watch out: The contents of the strided data are determined by the fvf,
3994 * not by the members set in D3DDrawPrimStrideData. So it's valid
3995 * to have diffuse.lpvData set to 0xdeadbeef if the diffuse flag is
3996 * not set in the fvf.
3998 if(VertexType & D3DFVF_POSITION_MASK)
4000 WineD3DStrided.u.s.position.lpData = D3DDrawPrimStrideData->position.lpvData;
4001 WineD3DStrided.u.s.position.dwStride = D3DDrawPrimStrideData->position.dwStride;
4002 WineD3DStrided.u.s.position.dwType = WINED3DDECLTYPE_FLOAT3;
4003 if (VertexType & D3DFVF_XYZRHW)
4005 WineD3DStrided.u.s.position.dwType = WINED3DDECLTYPE_FLOAT4;
4006 WineD3DStrided.position_transformed = TRUE;
4008 WineD3DStrided.position_transformed = FALSE;
4011 if(VertexType & D3DFVF_NORMAL)
4013 WineD3DStrided.u.s.normal.lpData = D3DDrawPrimStrideData->normal.lpvData;
4014 WineD3DStrided.u.s.normal.dwStride = D3DDrawPrimStrideData->normal.dwStride;
4015 WineD3DStrided.u.s.normal.dwType = WINED3DDECLTYPE_FLOAT3;
4018 if(VertexType & D3DFVF_DIFFUSE)
4020 WineD3DStrided.u.s.diffuse.lpData = D3DDrawPrimStrideData->diffuse.lpvData;
4021 WineD3DStrided.u.s.diffuse.dwStride = D3DDrawPrimStrideData->diffuse.dwStride;
4022 WineD3DStrided.u.s.diffuse.dwType = WINED3DDECLTYPE_D3DCOLOR;
4025 if(VertexType & D3DFVF_SPECULAR)
4027 WineD3DStrided.u.s.specular.lpData = D3DDrawPrimStrideData->specular.lpvData;
4028 WineD3DStrided.u.s.specular.dwStride = D3DDrawPrimStrideData->specular.dwStride;
4029 WineD3DStrided.u.s.specular.dwType = WINED3DDECLTYPE_D3DCOLOR;
4032 for( i = 0; i < GET_TEXCOUNT_FROM_FVF(VertexType); i++)
4034 WineD3DStrided.u.s.texCoords[i].lpData = D3DDrawPrimStrideData->textureCoords[i].lpvData;
4035 WineD3DStrided.u.s.texCoords[i].dwStride = D3DDrawPrimStrideData->textureCoords[i].dwStride;
4036 switch(GET_TEXCOORD_SIZE_FROM_FVF(VertexType, i))
4038 case 1: WineD3DStrided.u.s.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT1; break;
4039 case 2: WineD3DStrided.u.s.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT2; break;
4040 case 3: WineD3DStrided.u.s.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT3; break;
4041 case 4: WineD3DStrided.u.s.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT4; break;
4042 default: ERR("Unexpected texture coordinate size %d\n",
4043 GET_TEXCOORD_SIZE_FROM_FVF(VertexType, i));
4047 /* Get the primitive count */
4048 switch(PrimitiveType)
4050 case D3DPT_POINTLIST:
4051 PrimitiveCount = VertexCount;
4054 case D3DPT_LINELIST:
4055 PrimitiveCount = VertexCount / 2;
4058 case D3DPT_LINESTRIP:
4059 PrimitiveCount = VertexCount - 1;
4062 case D3DPT_TRIANGLELIST:
4063 PrimitiveCount = VertexCount / 3;
4066 case D3DPT_TRIANGLESTRIP:
4067 PrimitiveCount = VertexCount - 2;
4070 case D3DPT_TRIANGLEFAN:
4071 PrimitiveCount = VertexCount - 2;
4074 default: return DDERR_INVALIDPARAMS;
4077 /* WineD3D doesn't need the FVF here */
4078 EnterCriticalSection(&ddraw_cs);
4079 hr = IWineD3DDevice_DrawPrimitiveStrided(This->wineD3DDevice,
4083 LeaveCriticalSection(&ddraw_cs);
4087 static HRESULT WINAPI
4088 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUSetup(IDirect3DDevice7 *iface,
4089 D3DPRIMITIVETYPE PrimitiveType,
4091 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
4095 return IDirect3DDeviceImpl_7_DrawPrimitiveStrided(iface, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Flags);
4098 static HRESULT WINAPI
4099 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUPreserve(IDirect3DDevice7 *iface,
4100 D3DPRIMITIVETYPE PrimitiveType,
4102 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
4109 old_fpucw = d3d_fpu_setup();
4110 hr = IDirect3DDeviceImpl_7_DrawPrimitiveStrided(iface, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Flags);
4111 set_fpu_control_word(old_fpucw);
4116 static HRESULT WINAPI
4117 Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveStrided(IDirect3DDevice3 *iface,
4118 D3DPRIMITIVETYPE PrimitiveType,
4120 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
4124 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
4125 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Flags);
4126 return IDirect3DDevice7_DrawPrimitiveStrided(ICOM_INTERFACE(This, IDirect3DDevice7),
4129 D3DDrawPrimStrideData,
4134 /*****************************************************************************
4135 * IDirect3DDevice7::DrawIndexedPrimitiveStrided
4137 * Draws primitives specified by strided data locations based on indices
4145 * D3D_OK, because it's a stub
4146 * (DDERR_INVALIDPARAMS if D3DDrawPrimStrideData is NULL)
4147 * (DDERR_INVALIDPARAMS if Indices is NULL)
4148 * (For more details, see IWineD3DDevice::DrawIndexedPrimitiveStrided)
4150 *****************************************************************************/
4152 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided(IDirect3DDevice7 *iface,
4153 D3DPRIMITIVETYPE PrimitiveType,
4155 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
4161 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4162 WineDirect3DVertexStridedData WineD3DStrided;
4164 UINT PrimitiveCount;
4167 TRACE("(%p)->(%08x,%08x,%p,%08x,%p,%08x,%08x)\n", This, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Indices, IndexCount, Flags);
4169 memset(&WineD3DStrided, 0, sizeof(WineD3DStrided));
4170 /* Get the strided data right. the wined3d structure is a bit bigger
4171 * Watch out: The contents of the strided data are determined by the fvf,
4172 * not by the members set in D3DDrawPrimStrideData. So it's valid
4173 * to have diffuse.lpvData set to 0xdeadbeef if the diffuse flag is
4174 * not set in the fvf.
4176 if(VertexType & D3DFVF_POSITION_MASK)
4178 WineD3DStrided.u.s.position.lpData = D3DDrawPrimStrideData->position.lpvData;
4179 WineD3DStrided.u.s.position.dwStride = D3DDrawPrimStrideData->position.dwStride;
4180 WineD3DStrided.u.s.position.dwType = WINED3DDECLTYPE_FLOAT3;
4181 if (VertexType & D3DFVF_XYZRHW)
4183 WineD3DStrided.u.s.position.dwType = WINED3DDECLTYPE_FLOAT4;
4184 WineD3DStrided.position_transformed = TRUE;
4186 WineD3DStrided.position_transformed = FALSE;
4189 if(VertexType & D3DFVF_NORMAL)
4191 WineD3DStrided.u.s.normal.lpData = D3DDrawPrimStrideData->normal.lpvData;
4192 WineD3DStrided.u.s.normal.dwStride = D3DDrawPrimStrideData->normal.dwStride;
4193 WineD3DStrided.u.s.normal.dwType = WINED3DDECLTYPE_FLOAT3;
4196 if(VertexType & D3DFVF_DIFFUSE)
4198 WineD3DStrided.u.s.diffuse.lpData = D3DDrawPrimStrideData->diffuse.lpvData;
4199 WineD3DStrided.u.s.diffuse.dwStride = D3DDrawPrimStrideData->diffuse.dwStride;
4200 WineD3DStrided.u.s.diffuse.dwType = WINED3DDECLTYPE_D3DCOLOR;
4203 if(VertexType & D3DFVF_SPECULAR)
4205 WineD3DStrided.u.s.specular.lpData = D3DDrawPrimStrideData->specular.lpvData;
4206 WineD3DStrided.u.s.specular.dwStride = D3DDrawPrimStrideData->specular.dwStride;
4207 WineD3DStrided.u.s.specular.dwType = WINED3DDECLTYPE_D3DCOLOR;
4210 for( i = 0; i < GET_TEXCOUNT_FROM_FVF(VertexType); i++)
4212 WineD3DStrided.u.s.texCoords[i].lpData = D3DDrawPrimStrideData->textureCoords[i].lpvData;
4213 WineD3DStrided.u.s.texCoords[i].dwStride = D3DDrawPrimStrideData->textureCoords[i].dwStride;
4214 switch(GET_TEXCOORD_SIZE_FROM_FVF(VertexType, i))
4216 case 1: WineD3DStrided.u.s.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT1; break;
4217 case 2: WineD3DStrided.u.s.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT2; break;
4218 case 3: WineD3DStrided.u.s.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT3; break;
4219 case 4: WineD3DStrided.u.s.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT4; break;
4220 default: ERR("Unexpected texture coordinate size %d\n",
4221 GET_TEXCOORD_SIZE_FROM_FVF(VertexType, i));
4225 /* Get the primitive count */
4226 switch(PrimitiveType)
4228 case D3DPT_POINTLIST:
4229 PrimitiveCount = IndexCount;
4232 case D3DPT_LINELIST:
4233 PrimitiveCount = IndexCount / 2;
4236 case D3DPT_LINESTRIP:
4237 PrimitiveCount = IndexCount - 1;
4240 case D3DPT_TRIANGLELIST:
4241 PrimitiveCount = IndexCount / 3;
4244 case D3DPT_TRIANGLESTRIP:
4245 PrimitiveCount = IndexCount - 2;
4248 case D3DPT_TRIANGLEFAN:
4249 PrimitiveCount = IndexCount - 2;
4252 default: return DDERR_INVALIDPARAMS;
4255 /* WineD3D doesn't need the FVF here */
4256 EnterCriticalSection(&ddraw_cs);
4257 hr = IWineD3DDevice_DrawIndexedPrimitiveStrided(This->wineD3DDevice,
4263 WINED3DFMT_INDEX16);
4264 LeaveCriticalSection(&ddraw_cs);
4268 static HRESULT WINAPI
4269 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUSetup(IDirect3DDevice7 *iface,
4270 D3DPRIMITIVETYPE PrimitiveType,
4272 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
4278 return IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided(iface, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Indices, IndexCount, Flags);
4281 static HRESULT WINAPI
4282 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUPreserve(IDirect3DDevice7 *iface,
4283 D3DPRIMITIVETYPE PrimitiveType,
4285 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
4294 old_fpucw = d3d_fpu_setup();
4295 hr = IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided(iface, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Indices, IndexCount, Flags);
4296 set_fpu_control_word(old_fpucw);
4301 static HRESULT WINAPI
4302 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveStrided(IDirect3DDevice3 *iface,
4303 D3DPRIMITIVETYPE PrimitiveType,
4305 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
4311 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
4312 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", iface, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Indices, IndexCount, Flags);
4313 return IDirect3DDevice7_DrawIndexedPrimitiveStrided(ICOM_INTERFACE(This, IDirect3DDevice7),
4316 D3DDrawPrimStrideData,
4323 /*****************************************************************************
4324 * IDirect3DDevice7::DrawPrimitiveVB
4326 * Draws primitives from a vertex buffer to the screen.
4331 * PrimitiveType: Type of primitive to be rendered.
4332 * D3DVertexBuf: Source Vertex Buffer
4333 * StartVertex: Index of the first vertex from the buffer to be rendered
4334 * NumVertices: Number of vertices to be rendered
4335 * Flags: Can be D3DDP_WAIT to wait until rendering has finished
4339 * DDERR_INVALIDPARAMS if D3DVertexBuf is NULL
4341 *****************************************************************************/
4343 IDirect3DDeviceImpl_7_DrawPrimitiveVB(IDirect3DDevice7 *iface,
4344 D3DPRIMITIVETYPE PrimitiveType,
4345 IDirect3DVertexBuffer7 *D3DVertexBuf,
4350 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4351 IDirect3DVertexBufferImpl *vb = ICOM_OBJECT(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, D3DVertexBuf);
4352 UINT PrimitiveCount;
4355 WINED3DVERTEXBUFFER_DESC Desc;
4357 TRACE("(%p)->(%08x,%p,%08x,%08x,%08x)\n", This, PrimitiveType, D3DVertexBuf, StartVertex, NumVertices, Flags);
4362 ERR("(%p) No Vertex buffer specified\n", This);
4363 return DDERR_INVALIDPARAMS;
4366 /* Get the primitive count */
4367 switch(PrimitiveType)
4369 case D3DPT_POINTLIST:
4370 PrimitiveCount = NumVertices;
4373 case D3DPT_LINELIST:
4374 PrimitiveCount = NumVertices / 2;
4377 case D3DPT_LINESTRIP:
4378 PrimitiveCount = NumVertices - 1;
4381 case D3DPT_TRIANGLELIST:
4382 PrimitiveCount = NumVertices / 3;
4385 case D3DPT_TRIANGLESTRIP:
4386 PrimitiveCount = NumVertices - 2;
4389 case D3DPT_TRIANGLEFAN:
4390 PrimitiveCount = NumVertices - 2;
4394 return DDERR_INVALIDPARAMS;
4397 /* Get the FVF of the vertex buffer, and its stride */
4398 EnterCriticalSection(&ddraw_cs);
4399 hr = IWineD3DVertexBuffer_GetDesc(vb->wineD3DVertexBuffer,
4403 ERR("(%p) IWineD3DVertexBuffer::GetDesc failed with hr = %08x\n", This, hr);
4404 LeaveCriticalSection(&ddraw_cs);
4407 stride = get_flexible_vertex_size(Desc.FVF);
4409 hr = IWineD3DDevice_SetVertexDeclaration(This->wineD3DDevice,
4410 vb->wineD3DVertexDeclaration);
4413 ERR(" (%p) Setting the FVF failed, hr = %x!\n", This, hr);
4414 LeaveCriticalSection(&ddraw_cs);
4418 /* Set the vertex stream source */
4419 hr = IWineD3DDevice_SetStreamSource(This->wineD3DDevice,
4420 0 /* StreamNumber */,
4421 vb->wineD3DVertexBuffer,
4422 0 /* StartVertex - we pass this to DrawPrimitive */,
4426 ERR("(%p) IDirect3DDevice::SetStreamSource failed with hr = %08x\n", This, hr);
4427 LeaveCriticalSection(&ddraw_cs);
4431 /* Now draw the primitives */
4432 hr = IWineD3DDevice_DrawPrimitive(This->wineD3DDevice,
4436 LeaveCriticalSection(&ddraw_cs);
4440 static HRESULT WINAPI
4441 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUSetup(IDirect3DDevice7 *iface,
4442 D3DPRIMITIVETYPE PrimitiveType,
4443 IDirect3DVertexBuffer7 *D3DVertexBuf,
4448 return IDirect3DDeviceImpl_7_DrawPrimitiveVB(iface, PrimitiveType, D3DVertexBuf, StartVertex, NumVertices, Flags);
4451 static HRESULT WINAPI
4452 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUPreserve(IDirect3DDevice7 *iface,
4453 D3DPRIMITIVETYPE PrimitiveType,
4454 IDirect3DVertexBuffer7 *D3DVertexBuf,
4462 old_fpucw = d3d_fpu_setup();
4463 hr = IDirect3DDeviceImpl_7_DrawPrimitiveVB(iface, PrimitiveType, D3DVertexBuf, StartVertex, NumVertices, Flags);
4464 set_fpu_control_word(old_fpucw);
4469 static HRESULT WINAPI
4470 Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveVB(IDirect3DDevice3 *iface,
4471 D3DPRIMITIVETYPE PrimitiveType,
4472 IDirect3DVertexBuffer *D3DVertexBuf,
4477 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
4478 IDirect3DVertexBufferImpl *vb = ICOM_OBJECT(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, D3DVertexBuf);
4479 TRACE_(ddraw_thunk)("(%p)->(%08x,%p,%08x,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, vb, StartVertex, NumVertices, Flags);
4480 return IDirect3DDevice7_DrawPrimitiveVB(ICOM_INTERFACE(This, IDirect3DDevice7),
4482 ICOM_INTERFACE(vb, IDirect3DVertexBuffer7),
4489 /*****************************************************************************
4490 * IDirect3DDevice7::DrawIndexedPrimitiveVB
4492 * Draws primitives from a vertex buffer to the screen
4495 * PrimitiveType: Type of primitive to be rendered.
4496 * D3DVertexBuf: Source Vertex Buffer
4497 * StartVertex: Index of the first vertex from the buffer to be rendered
4498 * NumVertices: Number of vertices to be rendered
4499 * Indices: Array of DWORDs used to index into the Vertices
4500 * IndexCount: Number of indices in Indices
4501 * Flags: Can be D3DDP_WAIT to wait until rendering has finished
4505 *****************************************************************************/
4507 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB(IDirect3DDevice7 *iface,
4508 D3DPRIMITIVETYPE PrimitiveType,
4509 IDirect3DVertexBuffer7 *D3DVertexBuf,
4516 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4517 IDirect3DVertexBufferImpl *vb = ICOM_OBJECT(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, D3DVertexBuf);
4519 UINT PrimitiveCount;
4520 WORD *LockedIndices;
4522 WINED3DVERTEXBUFFER_DESC Desc;
4524 TRACE("(%p)->(%08x,%p,%d,%d,%p,%d,%08x)\n", This, PrimitiveType, vb, StartVertex, NumVertices, Indices, IndexCount, Flags);
4527 * 1) Calculate some things: Vertex count -> Primitive count, stride, ...
4528 * 2) Upload the Indices to the index buffer
4529 * 3) Set the index source
4530 * 4) Set the Vertex Buffer as the Stream source
4531 * 5) Call IWineD3DDevice::DrawIndexedPrimitive
4534 /* Get the primitive count */
4535 switch(PrimitiveType)
4537 case D3DPT_POINTLIST:
4538 PrimitiveCount = IndexCount;
4541 case D3DPT_LINELIST:
4542 PrimitiveCount = IndexCount / 2;
4545 case D3DPT_LINESTRIP:
4546 PrimitiveCount = IndexCount - 1;
4549 case D3DPT_TRIANGLELIST:
4550 PrimitiveCount = IndexCount / 3;
4553 case D3DPT_TRIANGLESTRIP:
4554 PrimitiveCount = IndexCount - 2;
4557 case D3DPT_TRIANGLEFAN:
4558 PrimitiveCount = IndexCount - 2;
4561 default: return DDERR_INVALIDPARAMS;
4564 EnterCriticalSection(&ddraw_cs);
4565 /* Get the FVF of the vertex buffer, and its stride */
4566 hr = IWineD3DVertexBuffer_GetDesc(vb->wineD3DVertexBuffer,
4570 ERR("(%p) IWineD3DVertexBuffer::GetDesc failed with hr = %08x\n", This, hr);
4571 LeaveCriticalSection(&ddraw_cs);
4574 stride = get_flexible_vertex_size(Desc.FVF);
4575 TRACE("Vertex buffer FVF = %08x, stride=%d\n", Desc.FVF, stride);
4577 hr = IWineD3DDevice_SetVertexDeclaration(This->wineD3DDevice,
4578 vb->wineD3DVertexDeclaration);
4581 ERR(" (%p) Setting the FVF failed, hr = %x!\n", This, hr);
4582 LeaveCriticalSection(&ddraw_cs);
4586 /* copy the index stream into the index buffer.
4587 * A new IWineD3DDevice method could be created
4588 * which takes an user pointer containing the indices
4589 * or a SetData-Method for the index buffer, which
4590 * overrides the index buffer data with our pointer.
4592 hr = IWineD3DIndexBuffer_Lock(This->indexbuffer,
4593 0 /* OffSetToLock */,
4594 IndexCount * sizeof(WORD),
4595 (BYTE **) &LockedIndices,
4597 assert(IndexCount < 0x100000);
4600 ERR("(%p) IWineD3DIndexBuffer::Lock failed with hr = %08x\n", This, hr);
4601 LeaveCriticalSection(&ddraw_cs);
4604 memcpy(LockedIndices, Indices, IndexCount * sizeof(WORD));
4605 hr = IWineD3DIndexBuffer_Unlock(This->indexbuffer);
4608 ERR("(%p) IWineD3DIndexBuffer::Unlock failed with hr = %08x\n", This, hr);
4609 LeaveCriticalSection(&ddraw_cs);
4613 /* Set the index stream */
4614 IWineD3DDevice_SetBaseVertexIndex(This->wineD3DDevice, StartVertex);
4615 hr = IWineD3DDevice_SetIndices(This->wineD3DDevice, This->indexbuffer);
4617 /* Set the vertex stream source */
4618 hr = IWineD3DDevice_SetStreamSource(This->wineD3DDevice,
4619 0 /* StreamNumber */,
4620 vb->wineD3DVertexBuffer,
4621 0 /* offset, we pass this to DrawIndexedPrimitive */,
4625 ERR("(%p) IDirect3DDevice::SetStreamSource failed with hr = %08x\n", This, hr);
4626 LeaveCriticalSection(&ddraw_cs);
4631 hr = IWineD3DDevice_DrawIndexedPrimitive(This->wineD3DDevice,
4638 LeaveCriticalSection(&ddraw_cs);
4642 static HRESULT WINAPI
4643 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUSetup(IDirect3DDevice7 *iface,
4644 D3DPRIMITIVETYPE PrimitiveType,
4645 IDirect3DVertexBuffer7 *D3DVertexBuf,
4652 return IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB(iface, PrimitiveType, D3DVertexBuf, StartVertex, NumVertices, Indices, IndexCount, Flags);
4655 static HRESULT WINAPI
4656 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUPreserve(IDirect3DDevice7 *iface,
4657 D3DPRIMITIVETYPE PrimitiveType,
4658 IDirect3DVertexBuffer7 *D3DVertexBuf,
4668 old_fpucw = d3d_fpu_setup();
4669 hr = IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB(iface, PrimitiveType, D3DVertexBuf, StartVertex, NumVertices, Indices, IndexCount, Flags);
4670 set_fpu_control_word(old_fpucw);
4675 static HRESULT WINAPI
4676 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveVB(IDirect3DDevice3 *iface,
4677 D3DPRIMITIVETYPE PrimitiveType,
4678 IDirect3DVertexBuffer *D3DVertexBuf,
4683 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
4684 IDirect3DVertexBufferImpl *VB = ICOM_OBJECT(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, D3DVertexBuf);
4685 TRACE_(ddraw_thunk)("(%p)->(%08x,%p,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, VB, Indices, IndexCount, Flags);
4687 return IDirect3DDevice7_DrawIndexedPrimitiveVB(ICOM_INTERFACE(This, IDirect3DDevice7),
4689 ICOM_INTERFACE(VB, IDirect3DVertexBuffer7),
4697 /*****************************************************************************
4698 * IDirect3DDevice7::ComputeSphereVisibility
4700 * Calculates the visibility of spheres in the current viewport. The spheres
4701 * are passed in the Centers and Radii arrays, the results are passed back
4702 * in the ReturnValues array. Return values are either completely visible,
4703 * partially visible or completely invisible.
4704 * The return value consist of a combination of D3DCLIP_* flags, or it's
4705 * 0 if the sphere is completely visible(according to the SDK, not checked)
4707 * Sounds like an overdose of math ;)
4712 * Centers: Array containing the sphere centers
4713 * Radii: Array containing the sphere radii
4714 * NumSpheres: The number of centers and radii in the arrays
4716 * ReturnValues: Array to write the results to
4719 * D3D_OK because it's a stub
4720 * (DDERR_INVALIDPARAMS if Centers, Radii or ReturnValues are NULL)
4721 * (D3DERR_INVALIDMATRIX if the combined world, view and proj matrix
4724 *****************************************************************************/
4725 static HRESULT WINAPI
4726 IDirect3DDeviceImpl_7_ComputeSphereVisibility(IDirect3DDevice7 *iface,
4731 DWORD *ReturnValues)
4733 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4734 FIXME("(%p)->(%p,%p,%08x,%08x,%p): stub!\n", This, Centers, Radii, NumSpheres, Flags, ReturnValues);
4736 /* the DirectX 7 sdk says that the visibility is computed by
4737 * back-transforming the viewing frustum to model space
4738 * using the inverse of the combined world, view and projection
4739 * matrix. If the matrix can't be reversed, D3DERR_INVALIDMATRIX
4742 * Basic implementation idea:
4743 * 1) Check if the center is in the viewing frustum
4744 * 2) Cut the sphere with the planes of the viewing
4747 * ->Center inside the frustum, no intersections:
4749 * ->Center outside the frustum, no intersections:
4751 * ->Some intersections: Partially visible
4753 * Implement this call in WineD3D. Either implement the
4754 * matrix and vector stuff in WineD3D, or use some external
4761 static HRESULT WINAPI
4762 Thunk_IDirect3DDeviceImpl_3_ComputeSphereVisibility(IDirect3DDevice3 *iface,
4767 DWORD *ReturnValues)
4769 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
4770 TRACE_(ddraw_thunk)("(%p)->(%p,%p,%08x,%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, Centers, Radii, NumSpheres, Flags, ReturnValues);
4771 return IDirect3DDevice7_ComputeSphereVisibility(ICOM_INTERFACE(This, IDirect3DDevice7),
4779 /*****************************************************************************
4780 * IDirect3DDevice7::GetTexture
4782 * Returns the texture interface handle assigned to a texture stage.
4783 * The returned texture is AddRefed. This is taken from old ddraw,
4784 * not checked in Windows.
4789 * Stage: Texture stage to read the texture from
4790 * Texture: Address to store the interface pointer at
4794 * DDERR_INVALIDPARAMS if Texture is NULL
4795 * For details, see IWineD3DDevice::GetTexture
4797 *****************************************************************************/
4799 IDirect3DDeviceImpl_7_GetTexture(IDirect3DDevice7 *iface,
4801 IDirectDrawSurface7 **Texture)
4803 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4804 IWineD3DBaseTexture *Surf;
4806 TRACE("(%p)->(%d,%p): Relay\n", This, Stage, Texture);
4810 TRACE("Texture == NULL, failing with DDERR_INVALIDPARAMS\n");
4811 return DDERR_INVALIDPARAMS;
4814 EnterCriticalSection(&ddraw_cs);
4815 hr = IWineD3DDevice_GetTexture(This->wineD3DDevice, Stage, &Surf);
4816 if( (hr != D3D_OK) || (!Surf) )
4819 LeaveCriticalSection(&ddraw_cs);
4823 /* GetParent AddRef()s, which is perfectly OK.
4824 * We have passed the IDirectDrawSurface7 interface to WineD3D, so that's OK too.
4826 hr = IWineD3DBaseTexture_GetParent(Surf,
4827 (IUnknown **) Texture);
4828 LeaveCriticalSection(&ddraw_cs);
4832 static HRESULT WINAPI
4833 IDirect3DDeviceImpl_7_GetTexture_FPUSetup(IDirect3DDevice7 *iface,
4835 IDirectDrawSurface7 **Texture)
4837 return IDirect3DDeviceImpl_7_GetTexture(iface, Stage, Texture);
4840 static HRESULT WINAPI
4841 IDirect3DDeviceImpl_7_GetTexture_FPUPreserve(IDirect3DDevice7 *iface,
4843 IDirectDrawSurface7 **Texture)
4848 old_fpucw = d3d_fpu_setup();
4849 hr = IDirect3DDeviceImpl_7_GetTexture(iface, Stage, Texture);
4850 set_fpu_control_word(old_fpucw);
4855 static HRESULT WINAPI
4856 Thunk_IDirect3DDeviceImpl_3_GetTexture(IDirect3DDevice3 *iface,
4858 IDirect3DTexture2 **Texture2)
4860 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
4862 IDirectDrawSurface7 *ret_val;
4864 TRACE_(ddraw_thunk)("(%p)->(%d,%p) thunking to IDirect3DDevice7 interface.\n", This, Stage, Texture2);
4865 ret = IDirect3DDevice7_GetTexture(ICOM_INTERFACE(This, IDirect3DDevice7),
4869 *Texture2 = COM_INTERFACE_CAST(IDirectDrawSurfaceImpl, IDirectDrawSurface7, IDirect3DTexture2, ret_val);
4871 TRACE_(ddraw_thunk)(" returning interface %p.\n", *Texture2);
4876 /*****************************************************************************
4877 * IDirect3DDevice7::SetTexture
4879 * Assigns a texture to a texture stage. Is the texture AddRef-ed?
4884 * Stage: The stage to assign the texture to
4885 * Texture: Interface pointer to the texture surface
4889 * For details, see IWineD3DDevice::SetTexture
4891 *****************************************************************************/
4893 IDirect3DDeviceImpl_7_SetTexture(IDirect3DDevice7 *iface,
4895 IDirectDrawSurface7 *Texture)
4897 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
4898 IDirectDrawSurfaceImpl *surf = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, Texture);
4900 TRACE("(%p)->(%08x,%p): Relay!\n", This, Stage, surf);
4902 /* Texture may be NULL here */
4903 EnterCriticalSection(&ddraw_cs);
4904 hr = IWineD3DDevice_SetTexture(This->wineD3DDevice,
4906 surf ? surf->wineD3DTexture : NULL);
4907 LeaveCriticalSection(&ddraw_cs);
4911 static HRESULT WINAPI
4912 IDirect3DDeviceImpl_7_SetTexture_FPUSetup(IDirect3DDevice7 *iface,
4914 IDirectDrawSurface7 *Texture)
4916 return IDirect3DDeviceImpl_7_SetTexture(iface, Stage, Texture);
4919 static HRESULT WINAPI
4920 IDirect3DDeviceImpl_7_SetTexture_FPUPreserve(IDirect3DDevice7 *iface,
4922 IDirectDrawSurface7 *Texture)
4927 old_fpucw = d3d_fpu_setup();
4928 hr = IDirect3DDeviceImpl_7_SetTexture(iface, Stage, Texture);
4929 set_fpu_control_word(old_fpucw);
4934 static HRESULT WINAPI
4935 IDirect3DDeviceImpl_3_SetTexture(IDirect3DDevice3 *iface,
4937 IDirect3DTexture2 *Texture2)
4939 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
4940 IDirectDrawSurfaceImpl *tex = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirect3DTexture2, Texture2);
4943 TRACE("(%p)->(%d,%p)\n", This, Stage, tex);
4945 EnterCriticalSection(&ddraw_cs);
4947 if (This->legacyTextureBlending)
4948 IDirect3DDevice3_GetRenderState(iface, D3DRENDERSTATE_TEXTUREMAPBLEND, &texmapblend);
4950 hr = IDirect3DDevice7_SetTexture(ICOM_INTERFACE(This, IDirect3DDevice7),
4952 ICOM_INTERFACE(tex, IDirectDrawSurface7));
4954 if (This->legacyTextureBlending && texmapblend == D3DTBLEND_MODULATE)
4956 /* This fixup is required by the way D3DTBLEND_MODULATE maps to texture stage states.
4957 See IDirect3DDeviceImpl_3_SetRenderState for details. */
4958 BOOL tex_alpha = FALSE;
4959 IWineD3DBaseTexture *tex = NULL;
4960 WINED3DSURFACE_DESC desc;
4962 DDPIXELFORMAT ddfmt;
4965 result = IWineD3DDevice_GetTexture(This->wineD3DDevice,
4969 if(result == WINED3D_OK && tex)
4971 memset(&desc, 0, sizeof(desc));
4973 result = IWineD3DTexture_GetLevelDesc((IWineD3DTexture*) tex, 0, &desc);
4974 if (SUCCEEDED(result))
4976 ddfmt.dwSize = sizeof(ddfmt);
4977 PixelFormat_WineD3DtoDD(&ddfmt, fmt);
4978 if (ddfmt.u5.dwRGBAlphaBitMask) tex_alpha = TRUE;
4981 IWineD3DBaseTexture_Release(tex);
4984 /* alphaop is WINED3DTOP_SELECTARG1 if it's D3DTBLEND_MODULATE, so only modify alphaarg1 */
4987 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG1, WINED3DTA_TEXTURE);
4991 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG1, WINED3DTA_CURRENT);
4995 LeaveCriticalSection(&ddraw_cs);
5000 static const struct tss_lookup
5007 {FALSE, WINED3DTSS_FORCE_DWORD}, /* 0, unused */
5008 {FALSE, WINED3DTSS_COLOROP}, /* 1, D3DTSS_COLOROP */
5009 {FALSE, WINED3DTSS_COLORARG1}, /* 2, D3DTSS_COLORARG1 */
5010 {FALSE, WINED3DTSS_COLORARG2}, /* 3, D3DTSS_COLORARG2 */
5011 {FALSE, WINED3DTSS_ALPHAOP}, /* 4, D3DTSS_ALPHAOP */
5012 {FALSE, WINED3DTSS_ALPHAARG1}, /* 5, D3DTSS_ALPHAARG1 */
5013 {FALSE, WINED3DTSS_ALPHAARG2}, /* 6, D3DTSS_ALPHAARG2 */
5014 {FALSE, WINED3DTSS_BUMPENVMAT00}, /* 7, D3DTSS_BUMPENVMAT00 */
5015 {FALSE, WINED3DTSS_BUMPENVMAT01}, /* 8, D3DTSS_BUMPENVMAT01 */
5016 {FALSE, WINED3DTSS_BUMPENVMAT10}, /* 9, D3DTSS_BUMPENVMAT10 */
5017 {FALSE, WINED3DTSS_BUMPENVMAT11}, /* 10, D3DTSS_BUMPENVMAT11 */
5018 {FALSE, WINED3DTSS_TEXCOORDINDEX}, /* 11, D3DTSS_TEXCOORDINDEX */
5019 {TRUE, WINED3DSAMP_ADDRESSU}, /* 12, D3DTSS_ADDRESS */
5020 {TRUE, WINED3DSAMP_ADDRESSU}, /* 13, D3DTSS_ADDRESSU */
5021 {TRUE, WINED3DSAMP_ADDRESSV}, /* 14, D3DTSS_ADDRESSV */
5022 {TRUE, WINED3DSAMP_BORDERCOLOR}, /* 15, D3DTSS_BORDERCOLOR */
5023 {TRUE, WINED3DSAMP_MAGFILTER}, /* 16, D3DTSS_MAGFILTER */
5024 {TRUE, WINED3DSAMP_MINFILTER}, /* 17, D3DTSS_MINFILTER */
5025 {TRUE, WINED3DSAMP_MIPFILTER}, /* 18, D3DTSS_MIPFILTER */
5026 {TRUE, WINED3DSAMP_MIPMAPLODBIAS}, /* 19, D3DTSS_MIPMAPLODBIAS */
5027 {TRUE, WINED3DSAMP_MAXMIPLEVEL}, /* 20, D3DTSS_MAXMIPLEVEL */
5028 {TRUE, WINED3DSAMP_MAXANISOTROPY}, /* 21, D3DTSS_MAXANISOTROPY */
5029 {FALSE, WINED3DTSS_BUMPENVLSCALE}, /* 22, D3DTSS_BUMPENVLSCALE */
5030 {FALSE, WINED3DTSS_BUMPENVLOFFSET}, /* 23, D3DTSS_BUMPENVLOFFSET */
5031 {FALSE, WINED3DTSS_TEXTURETRANSFORMFLAGS}, /* 24, D3DTSS_TEXTURETRANSFORMFLAGS */
5034 /*****************************************************************************
5035 * IDirect3DDevice7::GetTextureStageState
5037 * Retrieves a state from a texture stage.
5042 * Stage: The stage to retrieve the state from
5043 * TexStageStateType: The state type to retrieve
5044 * State: Address to store the state's value at
5048 * DDERR_INVALIDPARAMS if State is NULL
5049 * For details, see IWineD3DDevice::GetTextureStageState
5051 *****************************************************************************/
5053 IDirect3DDeviceImpl_7_GetTextureStageState(IDirect3DDevice7 *iface,
5055 D3DTEXTURESTAGESTATETYPE TexStageStateType,
5058 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5060 const struct tss_lookup *l = &tss_lookup[TexStageStateType];
5061 TRACE("(%p)->(%08x,%08x,%p): Relay!\n", This, Stage, TexStageStateType, State);
5064 return DDERR_INVALIDPARAMS;
5066 EnterCriticalSection(&ddraw_cs);
5068 if (l->sampler_state)
5070 hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice, Stage, l->state, State);
5072 switch(TexStageStateType)
5074 /* Mipfilter is a sampler state with different values */
5075 case D3DTSS_MIPFILTER:
5079 case WINED3DTEXF_NONE: *State = D3DTFP_NONE; break;
5080 case WINED3DTEXF_POINT: *State = D3DTFP_POINT; break;
5081 case WINED3DTEXF_LINEAR: *State = D3DTFP_LINEAR; break;
5083 ERR("Unexpected mipfilter value %#x\n", *State);
5084 *State = D3DTFP_NONE;
5090 /* Magfilter has slightly different values */
5091 case D3DTSS_MAGFILTER:
5095 case WINED3DTEXF_POINT: *State = D3DTFG_POINT; break;
5096 case WINED3DTEXF_LINEAR: *State = D3DTFG_LINEAR; break;
5097 case WINED3DTEXF_ANISOTROPIC: *State = D3DTFG_ANISOTROPIC; break;
5098 case WINED3DTEXF_FLATCUBIC: *State = D3DTFG_FLATCUBIC; break;
5099 case WINED3DTEXF_GAUSSIANCUBIC: *State = D3DTFG_GAUSSIANCUBIC; break;
5101 ERR("Unexpected wined3d mag filter value %#x\n", *State);
5102 *State = D3DTFG_POINT;
5114 hr = IWineD3DDevice_GetTextureStageState(This->wineD3DDevice, Stage, l->state, State);
5117 LeaveCriticalSection(&ddraw_cs);
5121 static HRESULT WINAPI
5122 IDirect3DDeviceImpl_7_GetTextureStageState_FPUSetup(IDirect3DDevice7 *iface,
5124 D3DTEXTURESTAGESTATETYPE TexStageStateType,
5127 return IDirect3DDeviceImpl_7_GetTextureStageState(iface, Stage, TexStageStateType, State);
5130 static HRESULT WINAPI
5131 IDirect3DDeviceImpl_7_GetTextureStageState_FPUPreserve(IDirect3DDevice7 *iface,
5133 D3DTEXTURESTAGESTATETYPE TexStageStateType,
5139 old_fpucw = d3d_fpu_setup();
5140 hr = IDirect3DDeviceImpl_7_GetTextureStageState(iface, Stage, TexStageStateType, State);
5141 set_fpu_control_word(old_fpucw);
5146 static HRESULT WINAPI
5147 Thunk_IDirect3DDeviceImpl_3_GetTextureStageState(IDirect3DDevice3 *iface,
5149 D3DTEXTURESTAGESTATETYPE TexStageStateType,
5152 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
5153 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, Stage, TexStageStateType, State);
5154 return IDirect3DDevice7_GetTextureStageState(ICOM_INTERFACE(This, IDirect3DDevice7),
5160 /*****************************************************************************
5161 * IDirect3DDevice7::SetTextureStageState
5163 * Sets a texture stage state. Some stage types need to be handled specially,
5164 * because they do not exist in WineD3D and were moved to another place
5169 * Stage: The stage to modify
5170 * TexStageStateType: The state to change
5171 * State: The new value for the state
5175 * For details, see IWineD3DDevice::SetTextureStageState
5177 *****************************************************************************/
5179 IDirect3DDeviceImpl_7_SetTextureStageState(IDirect3DDevice7 *iface,
5181 D3DTEXTURESTAGESTATETYPE TexStageStateType,
5184 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5185 const struct tss_lookup *l = &tss_lookup[TexStageStateType];
5187 TRACE("(%p)->(%08x,%08x,%08x): Relay!\n", This, Stage, TexStageStateType, State);
5189 EnterCriticalSection(&ddraw_cs);
5191 if (l->sampler_state)
5193 switch(TexStageStateType)
5195 /* Mipfilter is a sampler state with different values */
5196 case D3DTSS_MIPFILTER:
5200 case D3DTFP_NONE: State = WINED3DTEXF_NONE; break;
5201 case D3DTFP_POINT: State = WINED3DTEXF_POINT; break;
5202 case 0: /* Unchecked */
5203 case D3DTFP_LINEAR: State = WINED3DTEXF_LINEAR; break;
5205 ERR("Unexpected mipfilter value %d\n", State);
5206 State = WINED3DTEXF_NONE;
5212 /* Magfilter has slightly different values */
5213 case D3DTSS_MAGFILTER:
5217 case D3DTFG_POINT: State = WINED3DTEXF_POINT; break;
5218 case D3DTFG_LINEAR: State = WINED3DTEXF_LINEAR; break;
5219 case D3DTFG_FLATCUBIC: State = WINED3DTEXF_FLATCUBIC; break;
5220 case D3DTFG_GAUSSIANCUBIC: State = WINED3DTEXF_GAUSSIANCUBIC; break;
5221 case D3DTFG_ANISOTROPIC: State = WINED3DTEXF_ANISOTROPIC; break;
5223 ERR("Unexpected d3d7 mag filter type %d\n", State);
5224 State = WINED3DTEXF_POINT;
5230 case D3DTSS_ADDRESS:
5231 IWineD3DDevice_SetSamplerState(This->wineD3DDevice, Stage, WINED3DSAMP_ADDRESSV, State);
5238 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice, Stage, l->state, State);
5242 hr = IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, Stage, l->state, State);
5245 LeaveCriticalSection(&ddraw_cs);
5249 static HRESULT WINAPI
5250 IDirect3DDeviceImpl_7_SetTextureStageState_FPUSetup(IDirect3DDevice7 *iface,
5252 D3DTEXTURESTAGESTATETYPE TexStageStateType,
5255 return IDirect3DDeviceImpl_7_SetTextureStageState(iface, Stage, TexStageStateType, State);
5258 static HRESULT WINAPI
5259 IDirect3DDeviceImpl_7_SetTextureStageState_FPUPreserve(IDirect3DDevice7 *iface,
5261 D3DTEXTURESTAGESTATETYPE TexStageStateType,
5267 old_fpucw = d3d_fpu_setup();
5268 hr = IDirect3DDeviceImpl_7_SetTextureStageState(iface, Stage, TexStageStateType, State);
5269 set_fpu_control_word(old_fpucw);
5274 static HRESULT WINAPI
5275 Thunk_IDirect3DDeviceImpl_3_SetTextureStageState(IDirect3DDevice3 *iface,
5277 D3DTEXTURESTAGESTATETYPE TexStageStateType,
5280 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
5281 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, Stage, TexStageStateType, State);
5282 return IDirect3DDevice7_SetTextureStageState(ICOM_INTERFACE(This, IDirect3DDevice7),
5288 /*****************************************************************************
5289 * IDirect3DDevice7::ValidateDevice
5291 * SDK: "Reports the device's ability to render the currently set
5292 * texture-blending operations in a single pass". Whatever that means
5298 * NumPasses: Address to write the number of necessary passes for the
5299 * desired effect to.
5303 * See IWineD3DDevice::ValidateDevice for more details
5305 *****************************************************************************/
5307 IDirect3DDeviceImpl_7_ValidateDevice(IDirect3DDevice7 *iface,
5310 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5312 TRACE("(%p)->(%p): Relay\n", This, NumPasses);
5314 EnterCriticalSection(&ddraw_cs);
5315 hr = IWineD3DDevice_ValidateDevice(This->wineD3DDevice, NumPasses);
5316 LeaveCriticalSection(&ddraw_cs);
5320 static HRESULT WINAPI
5321 IDirect3DDeviceImpl_7_ValidateDevice_FPUSetup(IDirect3DDevice7 *iface,
5324 return IDirect3DDeviceImpl_7_ValidateDevice(iface, NumPasses);
5327 static HRESULT WINAPI
5328 IDirect3DDeviceImpl_7_ValidateDevice_FPUPreserve(IDirect3DDevice7 *iface,
5334 old_fpucw = d3d_fpu_setup();
5335 hr = IDirect3DDeviceImpl_7_ValidateDevice(iface, NumPasses);
5336 set_fpu_control_word(old_fpucw);
5341 static HRESULT WINAPI
5342 Thunk_IDirect3DDeviceImpl_3_ValidateDevice(IDirect3DDevice3 *iface,
5345 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice3, iface);
5346 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, Passes);
5347 return IDirect3DDevice7_ValidateDevice(ICOM_INTERFACE(This, IDirect3DDevice7),
5351 /*****************************************************************************
5352 * IDirect3DDevice7::Clear
5354 * Fills the render target, the z buffer and the stencil buffer with a
5355 * clear color / value
5360 * Count: Number of rectangles in Rects must be 0 if Rects is NULL
5361 * Rects: Rectangles to clear. If NULL, the whole surface is cleared
5362 * Flags: Some flags, as usual
5363 * Color: Clear color for the render target
5364 * Z: Clear value for the Z buffer
5365 * Stencil: Clear value to store in each stencil buffer entry
5369 * For details, see IWineD3DDevice::Clear
5371 *****************************************************************************/
5373 IDirect3DDeviceImpl_7_Clear(IDirect3DDevice7 *iface,
5381 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5383 TRACE("(%p)->(%08x,%p,%08x,%08x,%f,%08x): Relay\n", This, Count, Rects, Flags, Color, Z, Stencil);
5385 /* Note; D3DRECT is compatible with WINED3DRECT */
5386 EnterCriticalSection(&ddraw_cs);
5387 hr = IWineD3DDevice_Clear(This->wineD3DDevice, Count, (WINED3DRECT*) Rects, Flags, Color, Z, Stencil);
5388 LeaveCriticalSection(&ddraw_cs);
5392 static HRESULT WINAPI
5393 IDirect3DDeviceImpl_7_Clear_FPUSetup(IDirect3DDevice7 *iface,
5401 return IDirect3DDeviceImpl_7_Clear(iface, Count, Rects, Flags, Color, Z, Stencil);
5404 static HRESULT WINAPI
5405 IDirect3DDeviceImpl_7_Clear_FPUPreserve(IDirect3DDevice7 *iface,
5416 old_fpucw = d3d_fpu_setup();
5417 hr = IDirect3DDeviceImpl_7_Clear(iface, Count, Rects, Flags, Color, Z, Stencil);
5418 set_fpu_control_word(old_fpucw);
5423 /*****************************************************************************
5424 * IDirect3DDevice7::SetViewport
5426 * Sets the current viewport.
5428 * Version 7 only, but IDirect3DViewport uses this call for older
5432 * Data: The new viewport to set
5436 * DDERR_INVALIDPARAMS if Data is NULL
5437 * For more details, see IWineDDDevice::SetViewport
5439 *****************************************************************************/
5441 IDirect3DDeviceImpl_7_SetViewport(IDirect3DDevice7 *iface,
5444 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5446 TRACE("(%p)->(%p) Relay!\n", This, Data);
5449 return DDERR_INVALIDPARAMS;
5451 /* Note: D3DVIEWPORT7 is compatible with WINED3DVIEWPORT */
5452 EnterCriticalSection(&ddraw_cs);
5453 hr = IWineD3DDevice_SetViewport(This->wineD3DDevice,
5454 (WINED3DVIEWPORT*) Data);
5455 LeaveCriticalSection(&ddraw_cs);
5459 static HRESULT WINAPI
5460 IDirect3DDeviceImpl_7_SetViewport_FPUSetup(IDirect3DDevice7 *iface,
5463 return IDirect3DDeviceImpl_7_SetViewport(iface, Data);
5466 static HRESULT WINAPI
5467 IDirect3DDeviceImpl_7_SetViewport_FPUPreserve(IDirect3DDevice7 *iface,
5473 old_fpucw = d3d_fpu_setup();
5474 hr = IDirect3DDeviceImpl_7_SetViewport(iface, Data);
5475 set_fpu_control_word(old_fpucw);
5480 /*****************************************************************************
5481 * IDirect3DDevice::GetViewport
5483 * Returns the current viewport
5488 * Data: D3D7Viewport structure to write the viewport information to
5492 * DDERR_INVALIDPARAMS if Data is NULL
5493 * For more details, see IWineD3DDevice::GetViewport
5495 *****************************************************************************/
5497 IDirect3DDeviceImpl_7_GetViewport(IDirect3DDevice7 *iface,
5500 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5502 TRACE("(%p)->(%p) Relay!\n", This, Data);
5505 return DDERR_INVALIDPARAMS;
5507 /* Note: D3DVIEWPORT7 is compatible with WINED3DVIEWPORT */
5508 EnterCriticalSection(&ddraw_cs);
5509 hr = IWineD3DDevice_GetViewport(This->wineD3DDevice,
5510 (WINED3DVIEWPORT*) Data);
5512 LeaveCriticalSection(&ddraw_cs);
5513 return hr_ddraw_from_wined3d(hr);
5516 static HRESULT WINAPI
5517 IDirect3DDeviceImpl_7_GetViewport_FPUSetup(IDirect3DDevice7 *iface,
5520 return IDirect3DDeviceImpl_7_GetViewport(iface, Data);
5523 static HRESULT WINAPI
5524 IDirect3DDeviceImpl_7_GetViewport_FPUPreserve(IDirect3DDevice7 *iface,
5530 old_fpucw = d3d_fpu_setup();
5531 hr = IDirect3DDeviceImpl_7_GetViewport(iface, Data);
5532 set_fpu_control_word(old_fpucw);
5537 /*****************************************************************************
5538 * IDirect3DDevice7::SetMaterial
5545 * Mat: The material to set
5549 * DDERR_INVALIDPARAMS if Mat is NULL.
5550 * For more details, see IWineD3DDevice::SetMaterial
5552 *****************************************************************************/
5554 IDirect3DDeviceImpl_7_SetMaterial(IDirect3DDevice7 *iface,
5557 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5559 TRACE("(%p)->(%p): Relay!\n", This, Mat);
5561 if (!Mat) return DDERR_INVALIDPARAMS;
5562 /* Note: D3DMATERIAL7 is compatible with WINED3DMATERIAL */
5563 EnterCriticalSection(&ddraw_cs);
5564 hr = IWineD3DDevice_SetMaterial(This->wineD3DDevice,
5565 (WINED3DMATERIAL*) Mat);
5566 LeaveCriticalSection(&ddraw_cs);
5567 return hr_ddraw_from_wined3d(hr);
5570 static HRESULT WINAPI
5571 IDirect3DDeviceImpl_7_SetMaterial_FPUSetup(IDirect3DDevice7 *iface,
5574 return IDirect3DDeviceImpl_7_SetMaterial(iface, Mat);
5577 static HRESULT WINAPI
5578 IDirect3DDeviceImpl_7_SetMaterial_FPUPreserve(IDirect3DDevice7 *iface,
5584 old_fpucw = d3d_fpu_setup();
5585 hr = IDirect3DDeviceImpl_7_SetMaterial(iface, Mat);
5586 set_fpu_control_word(old_fpucw);
5591 /*****************************************************************************
5592 * IDirect3DDevice7::GetMaterial
5594 * Returns the current material
5599 * Mat: D3DMATERIAL7 structure to write the material parameters to
5603 * DDERR_INVALIDPARAMS if Mat is NULL
5604 * For more details, see IWineD3DDevice::GetMaterial
5606 *****************************************************************************/
5608 IDirect3DDeviceImpl_7_GetMaterial(IDirect3DDevice7 *iface,
5611 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5613 TRACE("(%p)->(%p): Relay!\n", This, Mat);
5615 EnterCriticalSection(&ddraw_cs);
5616 /* Note: D3DMATERIAL7 is compatible with WINED3DMATERIAL */
5617 hr = IWineD3DDevice_GetMaterial(This->wineD3DDevice,
5618 (WINED3DMATERIAL*) Mat);
5619 LeaveCriticalSection(&ddraw_cs);
5620 return hr_ddraw_from_wined3d(hr);
5623 static HRESULT WINAPI
5624 IDirect3DDeviceImpl_7_GetMaterial_FPUSetup(IDirect3DDevice7 *iface,
5627 return IDirect3DDeviceImpl_7_GetMaterial(iface, Mat);
5630 static HRESULT WINAPI
5631 IDirect3DDeviceImpl_7_GetMaterial_FPUPreserve(IDirect3DDevice7 *iface,
5637 old_fpucw = d3d_fpu_setup();
5638 hr = IDirect3DDeviceImpl_7_GetMaterial(iface, Mat);
5639 set_fpu_control_word(old_fpucw);
5644 /*****************************************************************************
5645 * IDirect3DDevice7::SetLight
5647 * Assigns a light to a light index, but doesn't activate it yet.
5649 * Version 7, IDirect3DLight uses this method for older versions
5652 * LightIndex: The index of the new light
5653 * Light: A D3DLIGHT7 structure describing the light
5657 * For more details, see IWineD3DDevice::SetLight
5659 *****************************************************************************/
5661 IDirect3DDeviceImpl_7_SetLight(IDirect3DDevice7 *iface,
5665 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5667 TRACE("(%p)->(%08x,%p): Relay!\n", This, LightIndex, Light);
5669 EnterCriticalSection(&ddraw_cs);
5670 /* Note: D3DLIGHT7 is compatible with WINED3DLIGHT */
5671 hr = IWineD3DDevice_SetLight(This->wineD3DDevice,
5673 (WINED3DLIGHT*) Light);
5674 LeaveCriticalSection(&ddraw_cs);
5675 return hr_ddraw_from_wined3d(hr);
5678 static HRESULT WINAPI
5679 IDirect3DDeviceImpl_7_SetLight_FPUSetup(IDirect3DDevice7 *iface,
5683 return IDirect3DDeviceImpl_7_SetLight(iface, LightIndex, Light);
5686 static HRESULT WINAPI
5687 IDirect3DDeviceImpl_7_SetLight_FPUPreserve(IDirect3DDevice7 *iface,
5694 old_fpucw = d3d_fpu_setup();
5695 hr = IDirect3DDeviceImpl_7_SetLight(iface, LightIndex, Light);
5696 set_fpu_control_word(old_fpucw);
5701 /*****************************************************************************
5702 * IDirect3DDevice7::GetLight
5704 * Returns the light assigned to a light index
5707 * Light: Structure to write the light information to
5711 * DDERR_INVALIDPARAMS if Light is NULL
5712 * For details, see IWineD3DDevice::GetLight
5714 *****************************************************************************/
5716 IDirect3DDeviceImpl_7_GetLight(IDirect3DDevice7 *iface,
5720 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5722 TRACE("(%p)->(%08x,%p): Relay!\n", This, LightIndex, Light);
5724 EnterCriticalSection(&ddraw_cs);
5725 /* Note: D3DLIGHT7 is compatible with WINED3DLIGHT */
5726 rc = IWineD3DDevice_GetLight(This->wineD3DDevice,
5728 (WINED3DLIGHT*) Light);
5730 /* Translate the result. WineD3D returns other values than D3D7 */
5731 LeaveCriticalSection(&ddraw_cs);
5732 return hr_ddraw_from_wined3d(rc);
5735 static HRESULT WINAPI
5736 IDirect3DDeviceImpl_7_GetLight_FPUSetup(IDirect3DDevice7 *iface,
5740 return IDirect3DDeviceImpl_7_GetLight(iface, LightIndex, Light);
5743 static HRESULT WINAPI
5744 IDirect3DDeviceImpl_7_GetLight_FPUPreserve(IDirect3DDevice7 *iface,
5751 old_fpucw = d3d_fpu_setup();
5752 hr = IDirect3DDeviceImpl_7_GetLight(iface, LightIndex, Light);
5753 set_fpu_control_word(old_fpucw);
5758 /*****************************************************************************
5759 * IDirect3DDevice7::BeginStateBlock
5761 * Begins recording to a stateblock
5767 * For details see IWineD3DDevice::BeginStateBlock
5769 *****************************************************************************/
5771 IDirect3DDeviceImpl_7_BeginStateBlock(IDirect3DDevice7 *iface)
5773 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5775 TRACE("(%p)->(): Relay!\n", This);
5777 EnterCriticalSection(&ddraw_cs);
5778 hr = IWineD3DDevice_BeginStateBlock(This->wineD3DDevice);
5779 LeaveCriticalSection(&ddraw_cs);
5780 return hr_ddraw_from_wined3d(hr);
5783 static HRESULT WINAPI
5784 IDirect3DDeviceImpl_7_BeginStateBlock_FPUSetup(IDirect3DDevice7 *iface)
5786 return IDirect3DDeviceImpl_7_BeginStateBlock(iface);
5789 static HRESULT WINAPI
5790 IDirect3DDeviceImpl_7_BeginStateBlock_FPUPreserve(IDirect3DDevice7 *iface)
5795 old_fpucw = d3d_fpu_setup();
5796 hr = IDirect3DDeviceImpl_7_BeginStateBlock(iface);
5797 set_fpu_control_word(old_fpucw);
5802 /*****************************************************************************
5803 * IDirect3DDevice7::EndStateBlock
5805 * Stops recording to a state block and returns the created stateblock
5811 * BlockHandle: Address to store the stateblock's handle to
5815 * DDERR_INVALIDPARAMS if BlockHandle is NULL
5816 * See IWineD3DDevice::EndStateBlock for more details
5818 *****************************************************************************/
5820 IDirect3DDeviceImpl_7_EndStateBlock(IDirect3DDevice7 *iface,
5823 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5825 TRACE("(%p)->(%p): Relay!\n", This, BlockHandle);
5829 WARN("BlockHandle == NULL, returning DDERR_INVALIDPARAMS\n");
5830 return DDERR_INVALIDPARAMS;
5833 EnterCriticalSection(&ddraw_cs);
5834 *BlockHandle = IDirect3DDeviceImpl_CreateHandle(This);
5837 ERR("Cannot get a handle number for the stateblock\n");
5838 LeaveCriticalSection(&ddraw_cs);
5839 return DDERR_OUTOFMEMORY;
5841 This->Handles[*BlockHandle - 1].type = DDrawHandle_StateBlock;
5842 hr = IWineD3DDevice_EndStateBlock(This->wineD3DDevice,
5843 (IWineD3DStateBlock **) &This->Handles[*BlockHandle - 1].ptr);
5844 LeaveCriticalSection(&ddraw_cs);
5845 return hr_ddraw_from_wined3d(hr);
5848 static HRESULT WINAPI
5849 IDirect3DDeviceImpl_7_EndStateBlock_FPUSetup(IDirect3DDevice7 *iface,
5852 return IDirect3DDeviceImpl_7_EndStateBlock(iface, BlockHandle);
5855 static HRESULT WINAPI
5856 IDirect3DDeviceImpl_7_EndStateBlock_FPUPreserve(IDirect3DDevice7 *iface,
5862 old_fpucw = d3d_fpu_setup();
5863 hr = IDirect3DDeviceImpl_7_EndStateBlock(iface, BlockHandle);
5864 set_fpu_control_word(old_fpucw);
5869 /*****************************************************************************
5870 * IDirect3DDevice7::PreLoad
5872 * Allows the app to signal that a texture will be used soon, to allow
5873 * the Direct3DDevice to load it to the video card in the meantime.
5878 * Texture: The texture to preload
5882 * DDERR_INVALIDPARAMS if Texture is NULL
5883 * See IWineD3DSurface::PreLoad for details
5885 *****************************************************************************/
5887 IDirect3DDeviceImpl_7_PreLoad(IDirect3DDevice7 *iface,
5888 IDirectDrawSurface7 *Texture)
5890 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5891 IDirectDrawSurfaceImpl *surf = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, Texture);
5893 TRACE("(%p)->(%p): Relay!\n", This, surf);
5896 return DDERR_INVALIDPARAMS;
5898 EnterCriticalSection(&ddraw_cs);
5899 IWineD3DSurface_PreLoad(surf->WineD3DSurface);
5900 LeaveCriticalSection(&ddraw_cs);
5904 static HRESULT WINAPI
5905 IDirect3DDeviceImpl_7_PreLoad_FPUSetup(IDirect3DDevice7 *iface,
5906 IDirectDrawSurface7 *Texture)
5908 return IDirect3DDeviceImpl_7_PreLoad(iface, Texture);
5911 static HRESULT WINAPI
5912 IDirect3DDeviceImpl_7_PreLoad_FPUPreserve(IDirect3DDevice7 *iface,
5913 IDirectDrawSurface7 *Texture)
5918 old_fpucw = d3d_fpu_setup();
5919 hr = IDirect3DDeviceImpl_7_PreLoad(iface, Texture);
5920 set_fpu_control_word(old_fpucw);
5925 /*****************************************************************************
5926 * IDirect3DDevice7::ApplyStateBlock
5928 * Activates the state stored in a state block handle.
5931 * BlockHandle: The stateblock handle to activate
5935 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is NULL
5937 *****************************************************************************/
5939 IDirect3DDeviceImpl_7_ApplyStateBlock(IDirect3DDevice7 *iface,
5942 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
5944 TRACE("(%p)->(%08x): Relay!\n", This, BlockHandle);
5946 EnterCriticalSection(&ddraw_cs);
5947 if(!BlockHandle || BlockHandle > This->numHandles)
5949 WARN("Out of range handle %d, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle);
5950 LeaveCriticalSection(&ddraw_cs);
5951 return D3DERR_INVALIDSTATEBLOCK;
5953 if(This->Handles[BlockHandle - 1].type != DDrawHandle_StateBlock)
5955 WARN("Handle %d is not a stateblock, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle);
5956 LeaveCriticalSection(&ddraw_cs);
5957 return D3DERR_INVALIDSTATEBLOCK;
5960 hr = IWineD3DStateBlock_Apply((IWineD3DStateBlock *) This->Handles[BlockHandle - 1].ptr);
5961 LeaveCriticalSection(&ddraw_cs);
5962 return hr_ddraw_from_wined3d(hr);
5965 static HRESULT WINAPI
5966 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUSetup(IDirect3DDevice7 *iface,
5969 return IDirect3DDeviceImpl_7_ApplyStateBlock(iface, BlockHandle);
5972 static HRESULT WINAPI
5973 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUPreserve(IDirect3DDevice7 *iface,
5979 old_fpucw = d3d_fpu_setup();
5980 hr = IDirect3DDeviceImpl_7_ApplyStateBlock(iface, BlockHandle);
5981 set_fpu_control_word(old_fpucw);
5986 /*****************************************************************************
5987 * IDirect3DDevice7::CaptureStateBlock
5989 * Updates a stateblock's values to the values currently set for the device
5994 * BlockHandle: Stateblock to update
5998 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is NULL
5999 * See IWineD3DDevice::CaptureStateBlock for more details
6001 *****************************************************************************/
6003 IDirect3DDeviceImpl_7_CaptureStateBlock(IDirect3DDevice7 *iface,
6006 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
6008 TRACE("(%p)->(%08x): Relay!\n", This, BlockHandle);
6010 EnterCriticalSection(&ddraw_cs);
6011 if(BlockHandle == 0 || BlockHandle > This->numHandles)
6013 WARN("Out of range handle %d, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle);
6014 LeaveCriticalSection(&ddraw_cs);
6015 return D3DERR_INVALIDSTATEBLOCK;
6017 if(This->Handles[BlockHandle - 1].type != DDrawHandle_StateBlock)
6019 WARN("Handle %d is not a stateblock, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle);
6020 LeaveCriticalSection(&ddraw_cs);
6021 return D3DERR_INVALIDSTATEBLOCK;
6024 hr = IWineD3DStateBlock_Capture((IWineD3DStateBlock *) This->Handles[BlockHandle - 1].ptr);
6025 LeaveCriticalSection(&ddraw_cs);
6026 return hr_ddraw_from_wined3d(hr);
6029 static HRESULT WINAPI
6030 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUSetup(IDirect3DDevice7 *iface,
6033 return IDirect3DDeviceImpl_7_CaptureStateBlock(iface, BlockHandle);
6036 static HRESULT WINAPI
6037 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUPreserve(IDirect3DDevice7 *iface,
6043 old_fpucw = d3d_fpu_setup();
6044 hr = IDirect3DDeviceImpl_7_CaptureStateBlock(iface, BlockHandle);
6045 set_fpu_control_word(old_fpucw);
6050 /*****************************************************************************
6051 * IDirect3DDevice7::DeleteStateBlock
6053 * Deletes a stateblock handle. This means releasing the WineD3DStateBlock
6058 * BlockHandle: Stateblock handle to delete
6062 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is 0
6064 *****************************************************************************/
6066 IDirect3DDeviceImpl_7_DeleteStateBlock(IDirect3DDevice7 *iface,
6069 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
6071 TRACE("(%p)->(%08x): Relay!\n", This, BlockHandle);
6073 EnterCriticalSection(&ddraw_cs);
6074 if(BlockHandle == 0 || BlockHandle > This->numHandles)
6076 WARN("Out of range handle %d, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle);
6077 LeaveCriticalSection(&ddraw_cs);
6078 return D3DERR_INVALIDSTATEBLOCK;
6080 if(This->Handles[BlockHandle - 1].type != DDrawHandle_StateBlock)
6082 WARN("Handle %d is not a stateblock, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle);
6083 LeaveCriticalSection(&ddraw_cs);
6084 return D3DERR_INVALIDSTATEBLOCK;
6087 ref = IWineD3DStateBlock_Release((IWineD3DStateBlock *) This->Handles[BlockHandle - 1].ptr);
6090 ERR("Something is still holding the stateblock %p(Handle %d). Ref = %d\n", This->Handles[BlockHandle - 1].ptr, BlockHandle, ref);
6092 This->Handles[BlockHandle - 1].ptr = NULL;
6093 This->Handles[BlockHandle - 1].type = DDrawHandle_Unknown;
6095 LeaveCriticalSection(&ddraw_cs);
6099 static HRESULT WINAPI
6100 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUSetup(IDirect3DDevice7 *iface,
6103 return IDirect3DDeviceImpl_7_DeleteStateBlock(iface, BlockHandle);
6106 static HRESULT WINAPI
6107 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUPreserve(IDirect3DDevice7 *iface,
6113 old_fpucw = d3d_fpu_setup();
6114 hr = IDirect3DDeviceImpl_7_DeleteStateBlock(iface, BlockHandle);
6115 set_fpu_control_word(old_fpucw);
6120 /*****************************************************************************
6121 * IDirect3DDevice7::CreateStateBlock
6123 * Creates a new state block handle.
6128 * Type: The state block type
6129 * BlockHandle: Address to write the created handle to
6133 * DDERR_INVALIDPARAMS if BlockHandle is NULL
6135 *****************************************************************************/
6137 IDirect3DDeviceImpl_7_CreateStateBlock(IDirect3DDevice7 *iface,
6138 D3DSTATEBLOCKTYPE Type,
6141 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
6143 TRACE("(%p)->(%08x,%p)!\n", This, Type, BlockHandle);
6147 WARN("BlockHandle == NULL, returning DDERR_INVALIDPARAMS\n");
6148 return DDERR_INVALIDPARAMS;
6150 if(Type != D3DSBT_ALL && Type != D3DSBT_PIXELSTATE &&
6151 Type != D3DSBT_VERTEXSTATE ) {
6152 WARN("Unexpected stateblock type, returning DDERR_INVALIDPARAMS\n");
6153 return DDERR_INVALIDPARAMS;
6156 EnterCriticalSection(&ddraw_cs);
6157 *BlockHandle = IDirect3DDeviceImpl_CreateHandle(This);
6160 ERR("Cannot get a handle number for the stateblock\n");
6161 LeaveCriticalSection(&ddraw_cs);
6162 return DDERR_OUTOFMEMORY;
6164 This->Handles[*BlockHandle - 1].type = DDrawHandle_StateBlock;
6166 /* The D3DSTATEBLOCKTYPE enum is fine here */
6167 hr = IWineD3DDevice_CreateStateBlock(This->wineD3DDevice,
6169 (IWineD3DStateBlock **) &This->Handles[*BlockHandle - 1].ptr,
6170 NULL /* Parent, hope that works */);
6171 LeaveCriticalSection(&ddraw_cs);
6172 return hr_ddraw_from_wined3d(hr);
6175 static HRESULT WINAPI
6176 IDirect3DDeviceImpl_7_CreateStateBlock_FPUSetup(IDirect3DDevice7 *iface,
6177 D3DSTATEBLOCKTYPE Type,
6180 return IDirect3DDeviceImpl_7_CreateStateBlock(iface, Type, BlockHandle);
6183 static HRESULT WINAPI
6184 IDirect3DDeviceImpl_7_CreateStateBlock_FPUPreserve(IDirect3DDevice7 *iface,
6185 D3DSTATEBLOCKTYPE Type,
6191 old_fpucw = d3d_fpu_setup();
6192 hr =IDirect3DDeviceImpl_7_CreateStateBlock(iface, Type, BlockHandle);
6193 set_fpu_control_word(old_fpucw);
6198 /* Helper function for IDirect3DDeviceImpl_7_Load. */
6199 static BOOL is_mip_level_subset(IDirectDrawSurfaceImpl *dest,
6200 IDirectDrawSurfaceImpl *src)
6202 IDirectDrawSurfaceImpl *src_level, *dest_level;
6203 IDirectDrawSurface7 *temp;
6204 DDSURFACEDESC2 ddsd;
6205 BOOL levelFound; /* at least one suitable sublevel in dest found */
6207 /* To satisfy "destination is mip level subset of source" criteria (regular texture counts as 1 level),
6208 * 1) there must be at least one mip level in destination that matched dimensions of some mip level in source and
6209 * 2) there must be no destination levels that don't match any levels in source. Otherwise it's INVALIDPARAMS.
6216 for (;src_level && dest_level;)
6218 if (src_level->surface_desc.dwWidth == dest_level->surface_desc.dwWidth &&
6219 src_level->surface_desc.dwHeight == dest_level->surface_desc.dwHeight)
6223 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
6224 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_MIPMAPSUBLEVEL;
6225 IDirectDrawSurface7_GetAttachedSurface(ICOM_INTERFACE(dest_level, IDirectDrawSurface7), &ddsd.ddsCaps, &temp);
6227 if (dest_level != dest) IDirectDrawSurface7_Release(ICOM_INTERFACE(dest_level, IDirectDrawSurface7));
6229 dest_level = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, temp);
6232 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
6233 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_MIPMAPSUBLEVEL;
6234 IDirectDrawSurface7_GetAttachedSurface(ICOM_INTERFACE(src_level, IDirectDrawSurface7), &ddsd.ddsCaps, &temp);
6236 if (src_level != src) IDirectDrawSurface7_Release(ICOM_INTERFACE(src_level, IDirectDrawSurface7));
6238 src_level = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, temp);
6241 if (src_level && src_level != src) IDirectDrawSurface7_Release(ICOM_INTERFACE(src_level, IDirectDrawSurface7));
6242 if (dest_level && dest_level != dest) IDirectDrawSurface7_Release(ICOM_INTERFACE(dest_level, IDirectDrawSurface7));
6244 return !dest_level && levelFound;
6247 /* Helper function for IDirect3DDeviceImpl_7_Load. */
6248 static void copy_mipmap_chain(IDirect3DDeviceImpl *device,
6249 IDirectDrawSurfaceImpl *dest,
6250 IDirectDrawSurfaceImpl *src,
6254 IDirectDrawSurfaceImpl *src_level, *dest_level;
6255 IDirectDrawSurface7 *temp;
6256 DDSURFACEDESC2 ddsd;
6260 IDirectDrawPalette *pal = NULL, *pal_src = NULL;
6263 BOOL palette_missing = FALSE;
6265 /* Copy palette, if possible. */
6266 IDirectDrawSurface7_GetPalette(ICOM_INTERFACE(src, IDirectDrawSurface7), &pal_src);
6267 IDirectDrawSurface7_GetPalette(ICOM_INTERFACE(dest, IDirectDrawSurface7), &pal);
6269 if (pal_src != NULL && pal != NULL)
6271 PALETTEENTRY palent[256];
6273 IDirectDrawPalette_GetEntries(pal_src, 0, 0, 256, palent);
6274 IDirectDrawPalette_SetEntries(pal, 0, 0, 256, palent);
6277 if (dest->surface_desc.u4.ddpfPixelFormat.dwFlags & (DDPF_PALETTEINDEXED1 | DDPF_PALETTEINDEXED2 |
6278 DDPF_PALETTEINDEXED4 | DDPF_PALETTEINDEXED8 | DDPF_PALETTEINDEXEDTO8) && !pal)
6280 palette_missing = TRUE;
6283 if (pal) IDirectDrawPalette_Release(pal);
6284 if (pal_src) IDirectDrawPalette_Release(pal_src);
6286 /* Copy colorkeys, if present. */
6287 for (ckeyflag = DDCKEY_DESTBLT; ckeyflag <= DDCKEY_SRCOVERLAY; ckeyflag <<= 1)
6289 hr = IDirectDrawSurface7_GetColorKey(ICOM_INTERFACE(src, IDirectDrawSurface7), ckeyflag, &ddckey);
6293 IDirectDrawSurface7_SetColorKey(ICOM_INTERFACE(dest, IDirectDrawSurface7), ckeyflag, &ddckey);
6303 for (;src_level && dest_level;)
6305 if (src_level->surface_desc.dwWidth == dest_level->surface_desc.dwWidth &&
6306 src_level->surface_desc.dwHeight == dest_level->surface_desc.dwHeight)
6308 /* Try UpdateSurface that may perform a more direct opengl loading. But skip this if destination is paletted texture and has no palette.
6309 * Some games like Sacrifice set palette after Load, and it is a waste of effort to try to load texture without palette and generates
6310 * warnings in wined3d. */
6311 if (!palette_missing)
6312 hr = IWineD3DDevice_UpdateSurface(device->wineD3DDevice, src_level->WineD3DSurface, &rect, dest_level->WineD3DSurface,
6315 if (palette_missing || FAILED(hr))
6317 /* UpdateSurface may fail e.g. if dest is in system memory. Fall back to BltFast that is less strict. */
6318 IWineD3DSurface_BltFast(dest_level->WineD3DSurface,
6320 src_level->WineD3DSurface, &rect, 0);
6323 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
6324 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_MIPMAPSUBLEVEL;
6325 IDirectDrawSurface7_GetAttachedSurface(ICOM_INTERFACE(dest_level, IDirectDrawSurface7), &ddsd.ddsCaps, &temp);
6327 if (dest_level != dest) IDirectDrawSurface7_Release(ICOM_INTERFACE(dest_level, IDirectDrawSurface7));
6329 dest_level = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, temp);
6332 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
6333 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_MIPMAPSUBLEVEL;
6334 IDirectDrawSurface7_GetAttachedSurface(ICOM_INTERFACE(src_level, IDirectDrawSurface7), &ddsd.ddsCaps, &temp);
6336 if (src_level != src) IDirectDrawSurface7_Release(ICOM_INTERFACE(src_level, IDirectDrawSurface7));
6338 src_level = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, temp);
6345 rect.right = (rect.right + 1) / 2;
6346 rect.bottom = (rect.bottom + 1) / 2;
6349 if (src_level && src_level != src) IDirectDrawSurface7_Release(ICOM_INTERFACE(src_level, IDirectDrawSurface7));
6350 if (dest_level && dest_level != dest) IDirectDrawSurface7_Release(ICOM_INTERFACE(dest_level, IDirectDrawSurface7));
6353 /*****************************************************************************
6354 * IDirect3DDevice7::Load
6356 * Loads a rectangular area from the source into the destination texture.
6357 * It can also copy the source to the faces of a cubic environment map
6362 * DestTex: Destination texture
6363 * DestPoint: Point in the destination where the source image should be
6365 * SrcTex: Source texture
6366 * SrcRect: Source rectangle
6367 * Flags: Cubemap faces to load (DDSCAPS2_CUBEMAP_ALLFACES, DDSCAPS2_CUBEMAP_POSITIVEX,
6368 * DDSCAPS2_CUBEMAP_NEGATIVEX, DDSCAPS2_CUBEMAP_POSITIVEY, DDSCAPS2_CUBEMAP_NEGATIVEY,
6369 * DDSCAPS2_CUBEMAP_POSITIVEZ, DDSCAPS2_CUBEMAP_NEGATIVEZ)
6373 * DDERR_INVALIDPARAMS if DestTex or SrcTex are NULL, broken coordinates or anything unexpected.
6376 *****************************************************************************/
6379 IDirect3DDeviceImpl_7_Load(IDirect3DDevice7 *iface,
6380 IDirectDrawSurface7 *DestTex,
6382 IDirectDrawSurface7 *SrcTex,
6386 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
6387 IDirectDrawSurfaceImpl *dest = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, DestTex);
6388 IDirectDrawSurfaceImpl *src = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, SrcTex);
6391 TRACE("(%p)->(%p,%p,%p,%p,%08x)\n", This, dest, DestPoint, src, SrcRect, Flags);
6393 if( (!src) || (!dest) )
6394 return DDERR_INVALIDPARAMS;
6396 EnterCriticalSection(&ddraw_cs);
6398 if (SrcRect) srcrect = *SrcRect;
6401 srcrect.left = srcrect.top = 0;
6402 srcrect.right = src->surface_desc.dwWidth;
6403 srcrect.bottom = src->surface_desc.dwHeight;
6406 if (DestPoint) destpoint = *DestPoint;
6409 destpoint.x = destpoint.y = 0;
6411 /* Check bad dimensions. DestPoint is validated against src, not dest, because
6412 * destination can be a subset of mip levels, in which case actual coordinates used
6413 * for it may be divided. If any dimension of dest is larger than source, it can't be
6414 * mip level subset, so an error can be returned early.
6416 if (srcrect.left >= srcrect.right || srcrect.top >= srcrect.bottom ||
6417 srcrect.right > src->surface_desc.dwWidth ||
6418 srcrect.bottom > src->surface_desc.dwHeight ||
6419 destpoint.x + srcrect.right - srcrect.left > src->surface_desc.dwWidth ||
6420 destpoint.y + srcrect.bottom - srcrect.top > src->surface_desc.dwHeight ||
6421 dest->surface_desc.dwWidth > src->surface_desc.dwWidth ||
6422 dest->surface_desc.dwHeight > src->surface_desc.dwHeight)
6424 LeaveCriticalSection(&ddraw_cs);
6425 return DDERR_INVALIDPARAMS;
6428 /* Must be top level surfaces. */
6429 if (src->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_MIPMAPSUBLEVEL ||
6430 dest->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_MIPMAPSUBLEVEL)
6432 LeaveCriticalSection(&ddraw_cs);
6433 return DDERR_INVALIDPARAMS;
6436 if (src->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP)
6438 DWORD src_face_flag, dest_face_flag;
6439 IDirectDrawSurfaceImpl *src_face, *dest_face;
6440 IDirectDrawSurface7 *temp;
6441 DDSURFACEDESC2 ddsd;
6444 if (!(dest->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP))
6446 LeaveCriticalSection(&ddraw_cs);
6447 return DDERR_INVALIDPARAMS;
6450 /* Iterate through cube faces 2 times. First time is just to check INVALIDPARAMS conditions, second
6451 * time it's actual surface loading. */
6452 for (i = 0; i < 2; i++)
6457 for (;dest_face && src_face;)
6459 src_face_flag = src_face->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP_ALLFACES;
6460 dest_face_flag = dest_face->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP_ALLFACES;
6462 if (src_face_flag == dest_face_flag)
6466 /* Destination mip levels must be subset of source mip levels. */
6467 if (!is_mip_level_subset(dest_face, src_face))
6469 LeaveCriticalSection(&ddraw_cs);
6470 return DDERR_INVALIDPARAMS;
6473 else if (Flags & dest_face_flag)
6475 copy_mipmap_chain(This, dest_face, src_face, &destpoint, &srcrect);
6478 if (src_face_flag < DDSCAPS2_CUBEMAP_NEGATIVEZ)
6480 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
6481 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | (src_face_flag << 1);
6482 IDirectDrawSurface7_GetAttachedSurface(ICOM_INTERFACE(src, IDirectDrawSurface7), &ddsd.ddsCaps, &temp);
6484 if (src_face != src) IDirectDrawSurface7_Release(ICOM_INTERFACE(src_face, IDirectDrawSurface7));
6486 src_face = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, temp);
6490 if (src_face != src) IDirectDrawSurface7_Release(ICOM_INTERFACE(src_face, IDirectDrawSurface7));
6496 if (dest_face_flag < DDSCAPS2_CUBEMAP_NEGATIVEZ)
6498 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
6499 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | (dest_face_flag << 1);
6500 IDirectDrawSurface7_GetAttachedSurface(ICOM_INTERFACE(dest, IDirectDrawSurface7), &ddsd.ddsCaps, &temp);
6502 if (dest_face != dest) IDirectDrawSurface7_Release(ICOM_INTERFACE(dest_face, IDirectDrawSurface7));
6504 dest_face = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, temp);
6508 if (dest_face != dest) IDirectDrawSurface7_Release(ICOM_INTERFACE(dest_face, IDirectDrawSurface7));
6516 /* Native returns error if src faces are not subset of dest faces. */
6519 LeaveCriticalSection(&ddraw_cs);
6520 return DDERR_INVALIDPARAMS;
6525 LeaveCriticalSection(&ddraw_cs);
6528 else if (dest->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP)
6530 LeaveCriticalSection(&ddraw_cs);
6531 return DDERR_INVALIDPARAMS;
6534 /* Handle non cube map textures. */
6536 /* Destination mip levels must be subset of source mip levels. */
6537 if (!is_mip_level_subset(dest, src))
6539 LeaveCriticalSection(&ddraw_cs);
6540 return DDERR_INVALIDPARAMS;
6543 copy_mipmap_chain(This, dest, src, &destpoint, &srcrect);
6545 LeaveCriticalSection(&ddraw_cs);
6549 static HRESULT WINAPI
6550 IDirect3DDeviceImpl_7_Load_FPUSetup(IDirect3DDevice7 *iface,
6551 IDirectDrawSurface7 *DestTex,
6553 IDirectDrawSurface7 *SrcTex,
6557 return IDirect3DDeviceImpl_7_Load(iface, DestTex, DestPoint, SrcTex, SrcRect, Flags);
6560 static HRESULT WINAPI
6561 IDirect3DDeviceImpl_7_Load_FPUPreserve(IDirect3DDevice7 *iface,
6562 IDirectDrawSurface7 *DestTex,
6564 IDirectDrawSurface7 *SrcTex,
6571 old_fpucw = d3d_fpu_setup();
6572 hr = IDirect3DDeviceImpl_7_Load(iface, DestTex, DestPoint, SrcTex, SrcRect, Flags);
6573 set_fpu_control_word(old_fpucw);
6578 /*****************************************************************************
6579 * IDirect3DDevice7::LightEnable
6581 * Enables or disables a light
6583 * Version 7, IDirect3DLight uses this method too.
6586 * LightIndex: The index of the light to enable / disable
6587 * Enable: Enable or disable the light
6591 * For more details, see IWineD3DDevice::SetLightEnable
6593 *****************************************************************************/
6595 IDirect3DDeviceImpl_7_LightEnable(IDirect3DDevice7 *iface,
6599 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
6601 TRACE("(%p)->(%08x,%d): Relay!\n", This, LightIndex, Enable);
6603 EnterCriticalSection(&ddraw_cs);
6604 hr = IWineD3DDevice_SetLightEnable(This->wineD3DDevice, LightIndex, Enable);
6605 LeaveCriticalSection(&ddraw_cs);
6606 return hr_ddraw_from_wined3d(hr);
6609 static HRESULT WINAPI
6610 IDirect3DDeviceImpl_7_LightEnable_FPUSetup(IDirect3DDevice7 *iface,
6614 return IDirect3DDeviceImpl_7_LightEnable(iface, LightIndex, Enable);
6617 static HRESULT WINAPI
6618 IDirect3DDeviceImpl_7_LightEnable_FPUPreserve(IDirect3DDevice7 *iface,
6625 old_fpucw = d3d_fpu_setup();
6626 hr = IDirect3DDeviceImpl_7_LightEnable(iface, LightIndex, Enable);
6627 set_fpu_control_word(old_fpucw);
6632 /*****************************************************************************
6633 * IDirect3DDevice7::GetLightEnable
6635 * Retrieves if the light with the given index is enabled or not
6640 * LightIndex: Index of desired light
6641 * Enable: Pointer to a BOOL which contains the result
6645 * DDERR_INVALIDPARAMS if Enable is NULL
6646 * See IWineD3DDevice::GetLightEnable for more details
6648 *****************************************************************************/
6650 IDirect3DDeviceImpl_7_GetLightEnable(IDirect3DDevice7 *iface,
6654 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
6656 TRACE("(%p)->(%08x,%p): Relay\n", This, LightIndex, Enable);
6659 return DDERR_INVALIDPARAMS;
6661 EnterCriticalSection(&ddraw_cs);
6662 hr = IWineD3DDevice_GetLightEnable(This->wineD3DDevice, LightIndex, Enable);
6663 LeaveCriticalSection(&ddraw_cs);
6664 return hr_ddraw_from_wined3d(hr);
6667 static HRESULT WINAPI
6668 IDirect3DDeviceImpl_7_GetLightEnable_FPUSetup(IDirect3DDevice7 *iface,
6672 return IDirect3DDeviceImpl_7_GetLightEnable(iface, LightIndex, Enable);
6675 static HRESULT WINAPI
6676 IDirect3DDeviceImpl_7_GetLightEnable_FPUPreserve(IDirect3DDevice7 *iface,
6683 old_fpucw = d3d_fpu_setup();
6684 hr = IDirect3DDeviceImpl_7_GetLightEnable(iface, LightIndex, Enable);
6685 set_fpu_control_word(old_fpucw);
6690 /*****************************************************************************
6691 * IDirect3DDevice7::SetClipPlane
6693 * Sets custom clipping plane
6698 * Index: The index of the clipping plane
6699 * PlaneEquation: An equation defining the clipping plane
6703 * DDERR_INVALIDPARAMS if PlaneEquation is NULL
6704 * See IWineD3DDevice::SetClipPlane for more details
6706 *****************************************************************************/
6708 IDirect3DDeviceImpl_7_SetClipPlane(IDirect3DDevice7 *iface,
6710 D3DVALUE* PlaneEquation)
6712 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
6714 TRACE("(%p)->(%08x,%p): Relay!\n", This, Index, PlaneEquation);
6717 return DDERR_INVALIDPARAMS;
6719 EnterCriticalSection(&ddraw_cs);
6720 hr = IWineD3DDevice_SetClipPlane(This->wineD3DDevice, Index, PlaneEquation);
6721 LeaveCriticalSection(&ddraw_cs);
6725 static HRESULT WINAPI
6726 IDirect3DDeviceImpl_7_SetClipPlane_FPUSetup(IDirect3DDevice7 *iface,
6728 D3DVALUE* PlaneEquation)
6730 return IDirect3DDeviceImpl_7_SetClipPlane(iface, Index, PlaneEquation);
6733 static HRESULT WINAPI
6734 IDirect3DDeviceImpl_7_SetClipPlane_FPUPreserve(IDirect3DDevice7 *iface,
6736 D3DVALUE* PlaneEquation)
6741 old_fpucw = d3d_fpu_setup();
6742 hr = IDirect3DDeviceImpl_7_SetClipPlane(iface, Index, PlaneEquation);
6743 set_fpu_control_word(old_fpucw);
6748 /*****************************************************************************
6749 * IDirect3DDevice7::GetClipPlane
6751 * Returns the clipping plane with a specific index
6754 * Index: The index of the desired plane
6755 * PlaneEquation: Address to store the plane equation to
6759 * DDERR_INVALIDPARAMS if PlaneEquation is NULL
6760 * See IWineD3DDevice::GetClipPlane for more details
6762 *****************************************************************************/
6764 IDirect3DDeviceImpl_7_GetClipPlane(IDirect3DDevice7 *iface,
6766 D3DVALUE* PlaneEquation)
6768 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
6770 TRACE("(%p)->(%d,%p): Relay!\n", This, Index, PlaneEquation);
6773 return DDERR_INVALIDPARAMS;
6775 EnterCriticalSection(&ddraw_cs);
6776 hr = IWineD3DDevice_GetClipPlane(This->wineD3DDevice, Index, PlaneEquation);
6777 LeaveCriticalSection(&ddraw_cs);
6781 static HRESULT WINAPI
6782 IDirect3DDeviceImpl_7_GetClipPlane_FPUSetup(IDirect3DDevice7 *iface,
6784 D3DVALUE* PlaneEquation)
6786 return IDirect3DDeviceImpl_7_GetClipPlane(iface, Index, PlaneEquation);
6789 static HRESULT WINAPI
6790 IDirect3DDeviceImpl_7_GetClipPlane_FPUPreserve(IDirect3DDevice7 *iface,
6792 D3DVALUE* PlaneEquation)
6797 old_fpucw = d3d_fpu_setup();
6798 hr = IDirect3DDeviceImpl_7_GetClipPlane(iface, Index, PlaneEquation);
6799 set_fpu_control_word(old_fpucw);
6804 /*****************************************************************************
6805 * IDirect3DDevice7::GetInfo
6807 * Retrieves some information about the device. The DirectX sdk says that
6808 * this version returns S_FALSE for all retail builds of DirectX, that's what
6809 * this implementation does.
6812 * DevInfoID: Information type requested
6813 * DevInfoStruct: Pointer to a structure to store the info to
6814 * Size: Size of the structure
6817 * S_FALSE, because it's a non-debug driver
6819 *****************************************************************************/
6820 static HRESULT WINAPI
6821 IDirect3DDeviceImpl_7_GetInfo(IDirect3DDevice7 *iface,
6823 void *DevInfoStruct,
6826 ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface);
6827 TRACE("(%p)->(%08x,%p,%08x)\n", This, DevInfoID, DevInfoStruct, Size);
6831 TRACE(" info requested : ");
6834 case D3DDEVINFOID_TEXTUREMANAGER: TRACE("D3DDEVINFOID_TEXTUREMANAGER\n"); break;
6835 case D3DDEVINFOID_D3DTEXTUREMANAGER: TRACE("D3DDEVINFOID_D3DTEXTUREMANAGER\n"); break;
6836 case D3DDEVINFOID_TEXTURING: TRACE("D3DDEVINFOID_TEXTURING\n"); break;
6837 default: ERR(" invalid flag !!!\n"); return DDERR_INVALIDPARAMS;
6841 return S_FALSE; /* According to MSDN, this is valid for a non-debug driver */
6844 /* For performance optimization, devices created in FPUSETUP and FPUPRESERVE modes
6845 * have separate vtables. Simple functions where this doesn't matter like GetDirect3D
6846 * are not duplicated.
6848 * Device created with DDSCL_FPUSETUP (d3d7 default) - device methods assume that FPU
6849 * has already been setup for optimal d3d operation.
6851 * Device created with DDSCL_FPUPRESERVE - resets and restores FPU mode when necessary in
6852 * d3d calls (FPU may be in a mode non-suitable for d3d when the app calls d3d). Required
6853 * by Sacrifice (game). */
6854 const IDirect3DDevice7Vtbl IDirect3DDevice7_FPUSetup_Vtbl =
6856 /*** IUnknown Methods ***/
6857 IDirect3DDeviceImpl_7_QueryInterface,
6858 IDirect3DDeviceImpl_7_AddRef,
6859 IDirect3DDeviceImpl_7_Release,
6860 /*** IDirect3DDevice7 ***/
6861 IDirect3DDeviceImpl_7_GetCaps_FPUSetup,
6862 IDirect3DDeviceImpl_7_EnumTextureFormats_FPUSetup,
6863 IDirect3DDeviceImpl_7_BeginScene_FPUSetup,
6864 IDirect3DDeviceImpl_7_EndScene_FPUSetup,
6865 IDirect3DDeviceImpl_7_GetDirect3D,
6866 IDirect3DDeviceImpl_7_SetRenderTarget_FPUSetup,
6867 IDirect3DDeviceImpl_7_GetRenderTarget,
6868 IDirect3DDeviceImpl_7_Clear_FPUSetup,
6869 IDirect3DDeviceImpl_7_SetTransform_FPUSetup,
6870 IDirect3DDeviceImpl_7_GetTransform_FPUSetup,
6871 IDirect3DDeviceImpl_7_SetViewport_FPUSetup,
6872 IDirect3DDeviceImpl_7_MultiplyTransform_FPUSetup,
6873 IDirect3DDeviceImpl_7_GetViewport_FPUSetup,
6874 IDirect3DDeviceImpl_7_SetMaterial_FPUSetup,
6875 IDirect3DDeviceImpl_7_GetMaterial_FPUSetup,
6876 IDirect3DDeviceImpl_7_SetLight_FPUSetup,
6877 IDirect3DDeviceImpl_7_GetLight_FPUSetup,
6878 IDirect3DDeviceImpl_7_SetRenderState_FPUSetup,
6879 IDirect3DDeviceImpl_7_GetRenderState_FPUSetup,
6880 IDirect3DDeviceImpl_7_BeginStateBlock_FPUSetup,
6881 IDirect3DDeviceImpl_7_EndStateBlock_FPUSetup,
6882 IDirect3DDeviceImpl_7_PreLoad_FPUSetup,
6883 IDirect3DDeviceImpl_7_DrawPrimitive_FPUSetup,
6884 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUSetup,
6885 IDirect3DDeviceImpl_7_SetClipStatus,
6886 IDirect3DDeviceImpl_7_GetClipStatus,
6887 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUSetup,
6888 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUSetup,
6889 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUSetup,
6890 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUSetup,
6891 IDirect3DDeviceImpl_7_ComputeSphereVisibility,
6892 IDirect3DDeviceImpl_7_GetTexture_FPUSetup,
6893 IDirect3DDeviceImpl_7_SetTexture_FPUSetup,
6894 IDirect3DDeviceImpl_7_GetTextureStageState_FPUSetup,
6895 IDirect3DDeviceImpl_7_SetTextureStageState_FPUSetup,
6896 IDirect3DDeviceImpl_7_ValidateDevice_FPUSetup,
6897 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUSetup,
6898 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUSetup,
6899 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUSetup,
6900 IDirect3DDeviceImpl_7_CreateStateBlock_FPUSetup,
6901 IDirect3DDeviceImpl_7_Load_FPUSetup,
6902 IDirect3DDeviceImpl_7_LightEnable_FPUSetup,
6903 IDirect3DDeviceImpl_7_GetLightEnable_FPUSetup,
6904 IDirect3DDeviceImpl_7_SetClipPlane_FPUSetup,
6905 IDirect3DDeviceImpl_7_GetClipPlane_FPUSetup,
6906 IDirect3DDeviceImpl_7_GetInfo
6909 const IDirect3DDevice7Vtbl IDirect3DDevice7_FPUPreserve_Vtbl =
6911 /*** IUnknown Methods ***/
6912 IDirect3DDeviceImpl_7_QueryInterface,
6913 IDirect3DDeviceImpl_7_AddRef,
6914 IDirect3DDeviceImpl_7_Release,
6915 /*** IDirect3DDevice7 ***/
6916 IDirect3DDeviceImpl_7_GetCaps_FPUPreserve,
6917 IDirect3DDeviceImpl_7_EnumTextureFormats_FPUPreserve,
6918 IDirect3DDeviceImpl_7_BeginScene_FPUPreserve,
6919 IDirect3DDeviceImpl_7_EndScene_FPUPreserve,
6920 IDirect3DDeviceImpl_7_GetDirect3D,
6921 IDirect3DDeviceImpl_7_SetRenderTarget_FPUPreserve,
6922 IDirect3DDeviceImpl_7_GetRenderTarget,
6923 IDirect3DDeviceImpl_7_Clear_FPUPreserve,
6924 IDirect3DDeviceImpl_7_SetTransform_FPUPreserve,
6925 IDirect3DDeviceImpl_7_GetTransform_FPUPreserve,
6926 IDirect3DDeviceImpl_7_SetViewport_FPUPreserve,
6927 IDirect3DDeviceImpl_7_MultiplyTransform_FPUPreserve,
6928 IDirect3DDeviceImpl_7_GetViewport_FPUPreserve,
6929 IDirect3DDeviceImpl_7_SetMaterial_FPUPreserve,
6930 IDirect3DDeviceImpl_7_GetMaterial_FPUPreserve,
6931 IDirect3DDeviceImpl_7_SetLight_FPUPreserve,
6932 IDirect3DDeviceImpl_7_GetLight_FPUPreserve,
6933 IDirect3DDeviceImpl_7_SetRenderState_FPUPreserve,
6934 IDirect3DDeviceImpl_7_GetRenderState_FPUPreserve,
6935 IDirect3DDeviceImpl_7_BeginStateBlock_FPUPreserve,
6936 IDirect3DDeviceImpl_7_EndStateBlock_FPUPreserve,
6937 IDirect3DDeviceImpl_7_PreLoad_FPUPreserve,
6938 IDirect3DDeviceImpl_7_DrawPrimitive_FPUPreserve,
6939 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUPreserve,
6940 IDirect3DDeviceImpl_7_SetClipStatus,
6941 IDirect3DDeviceImpl_7_GetClipStatus,
6942 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUPreserve,
6943 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUPreserve,
6944 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUPreserve,
6945 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUPreserve,
6946 IDirect3DDeviceImpl_7_ComputeSphereVisibility,
6947 IDirect3DDeviceImpl_7_GetTexture_FPUPreserve,
6948 IDirect3DDeviceImpl_7_SetTexture_FPUPreserve,
6949 IDirect3DDeviceImpl_7_GetTextureStageState_FPUPreserve,
6950 IDirect3DDeviceImpl_7_SetTextureStageState_FPUPreserve,
6951 IDirect3DDeviceImpl_7_ValidateDevice_FPUPreserve,
6952 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUPreserve,
6953 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUPreserve,
6954 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUPreserve,
6955 IDirect3DDeviceImpl_7_CreateStateBlock_FPUPreserve,
6956 IDirect3DDeviceImpl_7_Load_FPUPreserve,
6957 IDirect3DDeviceImpl_7_LightEnable_FPUPreserve,
6958 IDirect3DDeviceImpl_7_GetLightEnable_FPUPreserve,
6959 IDirect3DDeviceImpl_7_SetClipPlane_FPUPreserve,
6960 IDirect3DDeviceImpl_7_GetClipPlane_FPUPreserve,
6961 IDirect3DDeviceImpl_7_GetInfo
6964 const IDirect3DDevice3Vtbl IDirect3DDevice3_Vtbl =
6966 /*** IUnknown Methods ***/
6967 Thunk_IDirect3DDeviceImpl_3_QueryInterface,
6968 Thunk_IDirect3DDeviceImpl_3_AddRef,
6969 Thunk_IDirect3DDeviceImpl_3_Release,
6970 /*** IDirect3DDevice3 ***/
6971 IDirect3DDeviceImpl_3_GetCaps,
6972 IDirect3DDeviceImpl_3_GetStats,
6973 IDirect3DDeviceImpl_3_AddViewport,
6974 IDirect3DDeviceImpl_3_DeleteViewport,
6975 IDirect3DDeviceImpl_3_NextViewport,
6976 Thunk_IDirect3DDeviceImpl_3_EnumTextureFormats,
6977 Thunk_IDirect3DDeviceImpl_3_BeginScene,
6978 Thunk_IDirect3DDeviceImpl_3_EndScene,
6979 Thunk_IDirect3DDeviceImpl_3_GetDirect3D,
6980 IDirect3DDeviceImpl_3_SetCurrentViewport,
6981 IDirect3DDeviceImpl_3_GetCurrentViewport,
6982 Thunk_IDirect3DDeviceImpl_3_SetRenderTarget,
6983 Thunk_IDirect3DDeviceImpl_3_GetRenderTarget,
6984 IDirect3DDeviceImpl_3_Begin,
6985 IDirect3DDeviceImpl_3_BeginIndexed,
6986 IDirect3DDeviceImpl_3_Vertex,
6987 IDirect3DDeviceImpl_3_Index,
6988 IDirect3DDeviceImpl_3_End,
6989 IDirect3DDeviceImpl_3_GetRenderState,
6990 IDirect3DDeviceImpl_3_SetRenderState,
6991 IDirect3DDeviceImpl_3_GetLightState,
6992 IDirect3DDeviceImpl_3_SetLightState,
6993 Thunk_IDirect3DDeviceImpl_3_SetTransform,
6994 Thunk_IDirect3DDeviceImpl_3_GetTransform,
6995 Thunk_IDirect3DDeviceImpl_3_MultiplyTransform,
6996 Thunk_IDirect3DDeviceImpl_3_DrawPrimitive,
6997 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitive,
6998 Thunk_IDirect3DDeviceImpl_3_SetClipStatus,
6999 Thunk_IDirect3DDeviceImpl_3_GetClipStatus,
7000 Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveStrided,
7001 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveStrided,
7002 Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveVB,
7003 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveVB,
7004 Thunk_IDirect3DDeviceImpl_3_ComputeSphereVisibility,
7005 Thunk_IDirect3DDeviceImpl_3_GetTexture,
7006 IDirect3DDeviceImpl_3_SetTexture,
7007 Thunk_IDirect3DDeviceImpl_3_GetTextureStageState,
7008 Thunk_IDirect3DDeviceImpl_3_SetTextureStageState,
7009 Thunk_IDirect3DDeviceImpl_3_ValidateDevice
7012 const IDirect3DDevice2Vtbl IDirect3DDevice2_Vtbl =
7014 /*** IUnknown Methods ***/
7015 Thunk_IDirect3DDeviceImpl_2_QueryInterface,
7016 Thunk_IDirect3DDeviceImpl_2_AddRef,
7017 Thunk_IDirect3DDeviceImpl_2_Release,
7018 /*** IDirect3DDevice2 ***/
7019 Thunk_IDirect3DDeviceImpl_2_GetCaps,
7020 IDirect3DDeviceImpl_2_SwapTextureHandles,
7021 Thunk_IDirect3DDeviceImpl_2_GetStats,
7022 Thunk_IDirect3DDeviceImpl_2_AddViewport,
7023 Thunk_IDirect3DDeviceImpl_2_DeleteViewport,
7024 Thunk_IDirect3DDeviceImpl_2_NextViewport,
7025 IDirect3DDeviceImpl_2_EnumTextureFormats,
7026 Thunk_IDirect3DDeviceImpl_2_BeginScene,
7027 Thunk_IDirect3DDeviceImpl_2_EndScene,
7028 Thunk_IDirect3DDeviceImpl_2_GetDirect3D,
7029 Thunk_IDirect3DDeviceImpl_2_SetCurrentViewport,
7030 Thunk_IDirect3DDeviceImpl_2_GetCurrentViewport,
7031 Thunk_IDirect3DDeviceImpl_2_SetRenderTarget,
7032 Thunk_IDirect3DDeviceImpl_2_GetRenderTarget,
7033 Thunk_IDirect3DDeviceImpl_2_Begin,
7034 Thunk_IDirect3DDeviceImpl_2_BeginIndexed,
7035 Thunk_IDirect3DDeviceImpl_2_Vertex,
7036 Thunk_IDirect3DDeviceImpl_2_Index,
7037 Thunk_IDirect3DDeviceImpl_2_End,
7038 Thunk_IDirect3DDeviceImpl_2_GetRenderState,
7039 Thunk_IDirect3DDeviceImpl_2_SetRenderState,
7040 Thunk_IDirect3DDeviceImpl_2_GetLightState,
7041 Thunk_IDirect3DDeviceImpl_2_SetLightState,
7042 Thunk_IDirect3DDeviceImpl_2_SetTransform,
7043 Thunk_IDirect3DDeviceImpl_2_GetTransform,
7044 Thunk_IDirect3DDeviceImpl_2_MultiplyTransform,
7045 Thunk_IDirect3DDeviceImpl_2_DrawPrimitive,
7046 Thunk_IDirect3DDeviceImpl_2_DrawIndexedPrimitive,
7047 Thunk_IDirect3DDeviceImpl_2_SetClipStatus,
7048 Thunk_IDirect3DDeviceImpl_2_GetClipStatus
7051 const IDirect3DDeviceVtbl IDirect3DDevice1_Vtbl =
7053 /*** IUnknown Methods ***/
7054 Thunk_IDirect3DDeviceImpl_1_QueryInterface,
7055 Thunk_IDirect3DDeviceImpl_1_AddRef,
7056 Thunk_IDirect3DDeviceImpl_1_Release,
7057 /*** IDirect3DDevice1 ***/
7058 IDirect3DDeviceImpl_1_Initialize,
7059 Thunk_IDirect3DDeviceImpl_1_GetCaps,
7060 Thunk_IDirect3DDeviceImpl_1_SwapTextureHandles,
7061 IDirect3DDeviceImpl_1_CreateExecuteBuffer,
7062 Thunk_IDirect3DDeviceImpl_1_GetStats,
7063 IDirect3DDeviceImpl_1_Execute,
7064 Thunk_IDirect3DDeviceImpl_1_AddViewport,
7065 Thunk_IDirect3DDeviceImpl_1_DeleteViewport,
7066 Thunk_IDirect3DDeviceImpl_1_NextViewport,
7067 IDirect3DDeviceImpl_1_Pick,
7068 IDirect3DDeviceImpl_1_GetPickRecords,
7069 Thunk_IDirect3DDeviceImpl_1_EnumTextureFormats,
7070 IDirect3DDeviceImpl_1_CreateMatrix,
7071 IDirect3DDeviceImpl_1_SetMatrix,
7072 IDirect3DDeviceImpl_1_GetMatrix,
7073 IDirect3DDeviceImpl_1_DeleteMatrix,
7074 Thunk_IDirect3DDeviceImpl_1_BeginScene,
7075 Thunk_IDirect3DDeviceImpl_1_EndScene,
7076 Thunk_IDirect3DDeviceImpl_1_GetDirect3D
7079 /*****************************************************************************
7080 * IDirect3DDeviceImpl_CreateHandle
7082 * Not called from the VTable
7084 * Some older interface versions operate with handles, which are basically
7085 * DWORDs which identify an interface, for example
7086 * IDirect3DDevice::SetRenderState with DIRECT3DRENDERSTATE_TEXTUREHANDLE
7088 * Those handle could be just casts to the interface pointers or vice versa,
7089 * but that is not 64 bit safe and would mean blindly derefering a DWORD
7090 * passed by the app. Instead there is a dynamic array in the device which
7091 * keeps a DWORD to pointer information and a type for the handle.
7093 * Basically this array only grows, when a handle is freed its pointer is
7094 * just set to NULL. There will be much more reads from the array than
7095 * insertion operations, so a dynamic array is fine.
7098 * This: D3DDevice implementation for which this handle should be created
7101 * A free handle on success
7104 *****************************************************************************/
7106 IDirect3DDeviceImpl_CreateHandle(IDirect3DDeviceImpl *This)
7109 struct HandleEntry *oldHandles = This->Handles;
7111 TRACE("(%p)\n", This);
7113 for(i = 0; i < This->numHandles; i++)
7115 if(This->Handles[i].ptr == NULL &&
7116 This->Handles[i].type == DDrawHandle_Unknown)
7118 TRACE("Reusing freed handle %d\n", i + 1);
7123 TRACE("Growing the handle array\n");
7126 This->Handles = HeapAlloc(GetProcessHeap(), 0, sizeof(struct HandleEntry) * This->numHandles);
7129 ERR("Out of memory\n");
7130 This->Handles = oldHandles;
7136 memcpy(This->Handles, oldHandles, (This->numHandles - 1) * sizeof(struct HandleEntry));
7137 HeapFree(GetProcessHeap(), 0, oldHandles);
7140 TRACE("Returning %d\n", This->numHandles);
7141 return This->numHandles;
7144 /*****************************************************************************
7145 * IDirect3DDeviceImpl_UpdateDepthStencil
7147 * Checks the current render target for attached depth stencils and sets the
7148 * WineD3D depth stencil accordingly.
7151 * The depth stencil state to set if creating the device
7153 *****************************************************************************/
7155 IDirect3DDeviceImpl_UpdateDepthStencil(IDirect3DDeviceImpl *This)
7157 IDirectDrawSurface7 *depthStencil = NULL;
7158 IDirectDrawSurfaceImpl *dsi;
7159 static DDSCAPS2 depthcaps = { DDSCAPS_ZBUFFER, 0, 0, 0 };
7161 IDirectDrawSurface7_GetAttachedSurface(ICOM_INTERFACE(This->target, IDirectDrawSurface7),
7166 TRACE("Setting wined3d depth stencil to NULL\n");
7167 IWineD3DDevice_SetDepthStencilSurface(This->wineD3DDevice,
7169 return WINED3DZB_FALSE;
7172 dsi = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, depthStencil);
7173 TRACE("Setting wined3d depth stencil to %p (wined3d %p)\n", dsi, dsi->WineD3DSurface);
7174 IWineD3DDevice_SetDepthStencilSurface(This->wineD3DDevice,
7175 dsi->WineD3DSurface);
7177 IDirectDrawSurface7_Release(depthStencil);
7178 return WINED3DZB_TRUE;