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 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)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 ) )
137 /* Check DirectDraw Interfac
\ 1s */
138 else if( IsEqualGUID( &IID_IDirectDraw7, refiid ) )
141 TRACE("(%p) Returning IDirectDraw7 interface at %p\n", This, *obj);
143 else if ( IsEqualGUID( &IID_IDirectDraw4, refiid ) )
145 *obj = &This->ddraw->IDirectDraw4_vtbl;
146 TRACE("(%p) Returning IDirectDraw4 interface at %p\n", This, *obj);
148 else if ( IsEqualGUID( &IID_IDirectDraw2, refiid ) )
150 *obj = &This->ddraw->IDirectDraw2_vtbl;
151 TRACE("(%p) Returning IDirectDraw2 interface at %p\n", This, *obj);
153 else if( IsEqualGUID( &IID_IDirectDraw, refiid ) )
155 *obj = &This->ddraw->IDirectDraw_vtbl;
156 TRACE("(%p) Returning IDirectDraw interface at %p\n", This, *obj);
160 else if ( IsEqualGUID( &IID_IDirect3D , refiid ) )
162 *obj = &This->ddraw->IDirect3D_vtbl;
163 TRACE("(%p) Returning IDirect3D interface at %p\n", This, *obj);
165 else if ( IsEqualGUID( &IID_IDirect3D2 , refiid ) )
167 *obj = &This->ddraw->IDirect3D2_vtbl;
168 TRACE("(%p) Returning IDirect3D2 interface at %p\n", This, *obj);
170 else if ( IsEqualGUID( &IID_IDirect3D3 , refiid ) )
172 *obj = &This->ddraw->IDirect3D3_vtbl;
173 TRACE("(%p) Returning IDirect3D3 interface at %p\n", This, *obj);
175 else if ( IsEqualGUID( &IID_IDirect3D7 , refiid ) )
177 *obj = &This->ddraw->IDirect3D7_vtbl;
178 TRACE("(%p) Returning IDirect3D7 interface at %p\n", This, *obj);
182 else if ( IsEqualGUID( &IID_IDirect3DDevice , refiid ) )
184 *obj = &This->IDirect3DDevice_vtbl;
185 TRACE("(%p) Returning IDirect3DDevice interface at %p\n", This, *obj);
187 else if ( IsEqualGUID( &IID_IDirect3DDevice2 , refiid ) ) {
188 *obj = &This->IDirect3DDevice2_vtbl;
189 TRACE("(%p) Returning IDirect3DDevice2 interface at %p\n", This, *obj);
191 else if ( IsEqualGUID( &IID_IDirect3DDevice3 , refiid ) ) {
192 *obj = &This->IDirect3DDevice3_vtbl;
193 TRACE("(%p) Returning IDirect3DDevice3 interface at %p\n", This, *obj);
195 else if ( IsEqualGUID( &IID_IDirect3DDevice7 , refiid ) ) {
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 IDirect3DDeviceImpl *This = device_from_device3(iface);
218 TRACE_(ddraw_thunk)("(%p)->(%s,%p) thunking to IDirect3DDevice7 interface.\n", This, debugstr_guid(riid), obj);
219 return IDirect3DDevice7_QueryInterface((IDirect3DDevice7 *)This, riid, obj);
222 static HRESULT WINAPI
223 Thunk_IDirect3DDeviceImpl_2_QueryInterface(IDirect3DDevice2 *iface,
227 IDirect3DDeviceImpl *This = device_from_device2(iface);
228 TRACE_(ddraw_thunk)("(%p)->(%s,%p) thunking to IDirect3DDevice7 interface.\n", This, debugstr_guid(riid), obj);
229 return IDirect3DDevice7_QueryInterface((IDirect3DDevice7 *)This, riid, obj);
232 static HRESULT WINAPI
233 Thunk_IDirect3DDeviceImpl_1_QueryInterface(IDirect3DDevice *iface,
237 IDirect3DDeviceImpl *This = device_from_device1(iface);
238 TRACE_(ddraw_thunk)("(%p)->(%s,%p) thunking to IDirect3DDevice7 interface.\n", This, debugstr_guid(riid), obp);
239 return IDirect3DDevice7_QueryInterface((IDirect3DDevice7 *)This, riid, obp);
242 /*****************************************************************************
243 * IDirect3DDevice7::AddRef
245 * Increases the refcount....
246 * The most exciting Method, definitely
248 * Exists in Version 1, 2, 3 and 7
253 *****************************************************************************/
255 IDirect3DDeviceImpl_7_AddRef(IDirect3DDevice7 *iface)
257 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
258 ULONG ref = InterlockedIncrement(&This->ref);
260 TRACE("(%p) : incrementing from %u.\n", This, ref -1);
266 Thunk_IDirect3DDeviceImpl_3_AddRef(IDirect3DDevice3 *iface)
268 IDirect3DDeviceImpl *This = device_from_device3(iface);
269 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
270 return IDirect3DDevice7_AddRef((IDirect3DDevice7 *)This);
274 Thunk_IDirect3DDeviceImpl_2_AddRef(IDirect3DDevice2 *iface)
276 IDirect3DDeviceImpl *This = device_from_device2(iface);
277 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
278 return IDirect3DDevice7_AddRef((IDirect3DDevice7 *)This);
282 Thunk_IDirect3DDeviceImpl_1_AddRef(IDirect3DDevice *iface)
284 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", iface);
285 return IDirect3DDevice7_AddRef((IDirect3DDevice7 *)device_from_device1(iface));
288 /*****************************************************************************
289 * IDirect3DDevice7::Release
291 * Decreases the refcount of the interface
292 * When the refcount is reduced to 0, the object is destroyed.
294 * Exists in Version 1, 2, 3 and 7
299 *****************************************************************************/
301 IDirect3DDeviceImpl_7_Release(IDirect3DDevice7 *iface)
303 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
304 ULONG ref = InterlockedDecrement(&This->ref);
306 TRACE("(%p)->() decrementing from %u.\n", This, ref +1);
308 /* This method doesn't destroy the WineD3DDevice, because it's still in use for
309 * 2D rendering. IDirectDrawSurface7::Release will destroy the WineD3DDevice
310 * when the render target is released
314 IParent *IndexBufferParent;
317 EnterCriticalSection(&ddraw_cs);
318 /* Free the index buffer. */
319 IWineD3DDevice_SetIndexBuffer(This->wineD3DDevice, NULL, WINED3DFMT_UNKNOWN);
320 IWineD3DBuffer_GetParent(This->indexbuffer,
321 (IUnknown **) &IndexBufferParent);
322 IParent_Release(IndexBufferParent); /* Once for the getParent */
323 if( IParent_Release(IndexBufferParent) != 0) /* And now to destroy it */
325 ERR(" (%p) Something is still holding the index buffer parent %p\n", This, IndexBufferParent);
328 /* There is no need to unset the vertex buffer here, IWineD3DDevice_Uninit3D will do that when
329 * destroying the primary stateblock. If a vertex buffer is destroyed while it is bound
330 * IDirect3DVertexBuffer::Release will unset it.
333 /* Restore the render targets */
334 if(This->OffScreenTarget)
340 vp.Width = This->ddraw->d3d_target->surface_desc.dwWidth;
341 vp.Height = This->ddraw->d3d_target->surface_desc.dwHeight;
344 IWineD3DDevice_SetViewport(This->wineD3DDevice,
347 /* Set the device up to render to the front buffer since the back buffer will
350 IWineD3DDevice_SetRenderTarget(This->wineD3DDevice, 0,
351 This->ddraw->d3d_target->WineD3DSurface,
353 /* This->target is the offscreen target.
354 * This->ddraw->d3d_target is the target used by DDraw
356 TRACE("(%p) Release: Using %p as front buffer, %p as back buffer\n", This, This->ddraw->d3d_target, NULL);
357 IWineD3DDevice_SetFrontBackBuffers(This->wineD3DDevice,
358 This->ddraw->d3d_target->WineD3DSurface,
362 /* Release the WineD3DDevice. This won't destroy it */
363 if(IWineD3DDevice_Release(This->wineD3DDevice) <= 0)
365 ERR(" (%p) The wineD3D device %p was destroyed unexpectedly. Prepare for trouble\n", This, This->wineD3DDevice);
368 /* The texture handles should be unset by now, but there might be some bits
369 * missing in our reference counting(needs test). Do a sanity check. */
370 for (i = 0; i < This->handle_table.entry_count; ++i)
372 struct ddraw_handle_entry *entry = &This->handle_table.entries[i];
376 case DDRAW_HANDLE_FREE:
379 case DDRAW_HANDLE_MATERIAL:
381 IDirect3DMaterialImpl *m = entry->object;
382 FIXME("Material handle %#x (%p) not unset properly.\n", i + 1, m);
387 case DDRAW_HANDLE_MATRIX:
389 /* No FIXME here because this might happen because of sloppy applications. */
390 WARN("Leftover matrix handle %#x (%p), deleting.\n", i + 1, entry->object);
391 IDirect3DDevice_DeleteMatrix((IDirect3DDevice *)&This->IDirect3DDevice_vtbl, i + 1);
395 case DDRAW_HANDLE_STATEBLOCK:
397 /* No FIXME here because this might happen because of sloppy applications. */
398 WARN("Leftover stateblock handle %#x (%p), deleting.\n", i + 1, entry->object);
399 IDirect3DDevice7_DeleteStateBlock(iface, i + 1);
403 case DDRAW_HANDLE_SURFACE:
405 IDirectDrawSurfaceImpl *surf = entry->object;
406 FIXME("Texture handle %#x (%p) not unset properly.\n", i + 1, surf);
412 FIXME("Handle %#x (%p) has unknown type %#x.\n", i + 1, entry->object, entry->type);
417 ddraw_handle_table_destroy(&This->handle_table);
419 TRACE("Releasing target %p %p\n", This->target, This->ddraw->d3d_target);
420 /* Release the render target and the WineD3D render target
421 * (See IDirect3D7::CreateDevice for more comments on this)
423 IDirectDrawSurface7_Release((IDirectDrawSurface7 *)This->target);
424 IDirectDrawSurface7_Release((IDirectDrawSurface7 *)This->ddraw->d3d_target);
425 TRACE("Target release done\n");
427 This->ddraw->d3ddevice = NULL;
429 /* Now free the structure */
430 HeapFree(GetProcessHeap(), 0, This);
431 LeaveCriticalSection(&ddraw_cs);
439 Thunk_IDirect3DDeviceImpl_3_Release(IDirect3DDevice3 *iface)
441 IDirect3DDeviceImpl *This = device_from_device3(iface);
442 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
443 return IDirect3DDevice7_Release((IDirect3DDevice7 *)This);
447 Thunk_IDirect3DDeviceImpl_2_Release(IDirect3DDevice2 *iface)
449 IDirect3DDeviceImpl *This = device_from_device2(iface);
450 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
451 return IDirect3DDevice7_Release((IDirect3DDevice7 *)This);
455 Thunk_IDirect3DDeviceImpl_1_Release(IDirect3DDevice *iface)
457 IDirect3DDeviceImpl *This = device_from_device1(iface);
458 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
459 return IDirect3DDevice7_Release((IDirect3DDevice7 *)This);
462 /*****************************************************************************
463 * IDirect3DDevice Methods
464 *****************************************************************************/
466 /*****************************************************************************
467 * IDirect3DDevice::Initialize
469 * Initializes a Direct3DDevice. This implementation is a no-op, as all
470 * initialization is done at create time.
472 * Exists in Version 1
475 * No idea what they mean, as the MSDN page is gone
479 *****************************************************************************/
480 static HRESULT WINAPI
481 IDirect3DDeviceImpl_1_Initialize(IDirect3DDevice *iface,
482 IDirect3D *Direct3D, GUID *guid,
485 IDirect3DDeviceImpl *This = device_from_device1(iface);
487 /* It shouldn't be crucial, but print a FIXME, I'm interested if
488 * any game calls it and when
490 FIXME("(%p)->(%p,%p,%p): No-op!\n", This, Direct3D, guid, Desc);
495 /*****************************************************************************
496 * IDirect3DDevice7::GetCaps
498 * Retrieves the device's capabilities
500 * This implementation is used for Version 7 only, the older versions have
501 * their own implementation.
504 * Desc: Pointer to a D3DDEVICEDESC7 structure to fill
508 * D3DERR_* if a problem occurs. See WineD3D
510 *****************************************************************************/
512 IDirect3DDeviceImpl_7_GetCaps(IDirect3DDevice7 *iface,
513 D3DDEVICEDESC7 *Desc)
515 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
516 D3DDEVICEDESC OldDesc;
517 TRACE("(%p)->(%p)\n", This, Desc);
519 /* Call the same function used by IDirect3D, this saves code */
520 return IDirect3DImpl_GetCaps(This->ddraw->wineD3D, &OldDesc, Desc);
523 static HRESULT WINAPI
524 IDirect3DDeviceImpl_7_GetCaps_FPUSetup(IDirect3DDevice7 *iface,
525 D3DDEVICEDESC7 *Desc)
527 return IDirect3DDeviceImpl_7_GetCaps(iface, Desc);
530 static HRESULT WINAPI
531 IDirect3DDeviceImpl_7_GetCaps_FPUPreserve(IDirect3DDevice7 *iface,
532 D3DDEVICEDESC7 *Desc)
537 old_fpucw = d3d_fpu_setup();
538 hr = IDirect3DDeviceImpl_7_GetCaps(iface, Desc);
539 set_fpu_control_word(old_fpucw);
543 /*****************************************************************************
544 * IDirect3DDevice3::GetCaps
546 * Retrieves the capabilities of the hardware device and the emulation
547 * device. For Wine, hardware and emulation are the same (it's all HW).
549 * This implementation is used for Version 1, 2, and 3. Version 7 has its own
552 * HWDesc: Structure to fill with the HW caps
553 * HelDesc: Structure to fill with the hardware emulation caps
557 * D3DERR_* if a problem occurs. See WineD3D
559 *****************************************************************************/
560 static HRESULT WINAPI
561 IDirect3DDeviceImpl_3_GetCaps(IDirect3DDevice3 *iface,
562 D3DDEVICEDESC *HWDesc,
563 D3DDEVICEDESC *HelDesc)
565 IDirect3DDeviceImpl *This = device_from_device3(iface);
566 D3DDEVICEDESC7 newDesc;
568 TRACE("(%p)->(%p,%p)\n", iface, HWDesc, HelDesc);
570 hr = IDirect3DImpl_GetCaps(This->ddraw->wineD3D, HWDesc, &newDesc);
571 if(hr != D3D_OK) return hr;
577 static HRESULT WINAPI
578 Thunk_IDirect3DDeviceImpl_2_GetCaps(IDirect3DDevice2 *iface,
579 D3DDEVICEDESC *D3DHWDevDesc,
580 D3DDEVICEDESC *D3DHELDevDesc)
582 IDirect3DDeviceImpl *This = device_from_device2(iface);
583 TRACE_(ddraw_thunk)("(%p)->(%p,%p) thunking to IDirect3DDevice3 interface.\n", This, D3DHWDevDesc, D3DHELDevDesc);
584 return IDirect3DDevice3_GetCaps((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl, D3DHWDevDesc, D3DHELDevDesc);
587 static HRESULT WINAPI
588 Thunk_IDirect3DDeviceImpl_1_GetCaps(IDirect3DDevice *iface,
589 D3DDEVICEDESC *D3DHWDevDesc,
590 D3DDEVICEDESC *D3DHELDevDesc)
592 IDirect3DDeviceImpl *This = device_from_device1(iface);
593 TRACE_(ddraw_thunk)("(%p)->(%p,%p) thunking to IDirect3DDevice3 interface.\n", This, D3DHWDevDesc, D3DHELDevDesc);
594 return IDirect3DDevice3_GetCaps((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl, D3DHWDevDesc, D3DHELDevDesc);
597 /*****************************************************************************
598 * IDirect3DDevice2::SwapTextureHandles
600 * Swaps the texture handles of 2 Texture interfaces. Version 1 and 2
603 * Tex1, Tex2: The 2 Textures to swap
608 *****************************************************************************/
609 static HRESULT WINAPI
610 IDirect3DDeviceImpl_2_SwapTextureHandles(IDirect3DDevice2 *iface,
611 IDirect3DTexture2 *Tex1,
612 IDirect3DTexture2 *Tex2)
614 IDirect3DDeviceImpl *This = device_from_device2(iface);
615 IDirectDrawSurfaceImpl *surf1 = surface_from_texture2(Tex1);
616 IDirectDrawSurfaceImpl *surf2 = surface_from_texture2(Tex2);
619 TRACE("(%p)->(%p,%p)\n", This, surf1, surf2);
621 EnterCriticalSection(&ddraw_cs);
623 h1 = surf1->Handle - 1;
624 h2 = surf2->Handle - 1;
625 This->handle_table.entries[h1].object = surf2;
626 This->handle_table.entries[h2].object = surf1;
627 surf2->Handle = h1 + 1;
628 surf1->Handle = h2 + 1;
630 LeaveCriticalSection(&ddraw_cs);
635 static HRESULT WINAPI
636 Thunk_IDirect3DDeviceImpl_1_SwapTextureHandles(IDirect3DDevice *iface,
637 IDirect3DTexture *D3DTex1,
638 IDirect3DTexture *D3DTex2)
640 IDirect3DDeviceImpl *This = device_from_device1(iface);
641 IDirectDrawSurfaceImpl *surf1 = surface_from_texture1(D3DTex1);
642 IDirectDrawSurfaceImpl *surf2 = surface_from_texture1(D3DTex2);
643 IDirect3DTexture2 *t1 = surf1 ? (IDirect3DTexture2 *)&surf1->IDirect3DTexture2_vtbl : NULL;
644 IDirect3DTexture2 *t2 = surf2 ? (IDirect3DTexture2 *)&surf2->IDirect3DTexture2_vtbl : NULL;
645 TRACE_(ddraw_thunk)("(%p)->(%p,%p) thunking to IDirect3DDevice2 interface.\n", This, surf1, surf2);
646 return IDirect3DDevice2_SwapTextureHandles((IDirect3DDevice2 *)&This->IDirect3DDevice2_vtbl, t1, t2);
649 /*****************************************************************************
650 * IDirect3DDevice3::GetStats
652 * This method seems to retrieve some stats from the device.
653 * The MSDN documentation doesn't exist any more, but the D3DSTATS
654 * structure suggests that the amount of drawn primitives and processed
655 * vertices is returned.
657 * Exists in Version 1, 2 and 3
660 * Stats: Pointer to a D3DSTATS structure to be filled
664 * DDERR_INVALIDPARAMS if Stats == NULL
666 *****************************************************************************/
667 static HRESULT WINAPI
668 IDirect3DDeviceImpl_3_GetStats(IDirect3DDevice3 *iface,
671 IDirect3DDeviceImpl *This = device_from_device3(iface);
672 FIXME("(%p)->(%p): Stub!\n", This, Stats);
675 return DDERR_INVALIDPARAMS;
677 /* Fill the Stats with 0 */
678 Stats->dwTrianglesDrawn = 0;
679 Stats->dwLinesDrawn = 0;
680 Stats->dwPointsDrawn = 0;
681 Stats->dwSpansDrawn = 0;
682 Stats->dwVerticesProcessed = 0;
687 static HRESULT WINAPI
688 Thunk_IDirect3DDeviceImpl_2_GetStats(IDirect3DDevice2 *iface,
691 IDirect3DDeviceImpl *This = device_from_device2(iface);
692 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, Stats);
693 return IDirect3DDevice3_GetStats((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl, Stats);
696 static HRESULT WINAPI
697 Thunk_IDirect3DDeviceImpl_1_GetStats(IDirect3DDevice *iface,
700 IDirect3DDeviceImpl *This = device_from_device1(iface);
701 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, Stats);
702 return IDirect3DDevice3_GetStats((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl, Stats);
705 /*****************************************************************************
706 * IDirect3DDevice::CreateExecuteBuffer
708 * Creates an IDirect3DExecuteBuffer, used for rendering with a
714 * Desc: Buffer description
715 * ExecuteBuffer: Address to return the Interface pointer at
716 * UnkOuter: Must be NULL. Basically for aggregation, which ddraw doesn't
720 * CLASS_E_NOAGGREGATION if UnkOuter != NULL
721 * DDERR_OUTOFMEMORY if we ran out of memory
724 *****************************************************************************/
725 static HRESULT WINAPI
726 IDirect3DDeviceImpl_1_CreateExecuteBuffer(IDirect3DDevice *iface,
727 D3DEXECUTEBUFFERDESC *Desc,
728 IDirect3DExecuteBuffer **ExecuteBuffer,
731 IDirect3DDeviceImpl *This = device_from_device1(iface);
732 IDirect3DExecuteBufferImpl* object;
733 TRACE("(%p)->(%p,%p,%p)!\n", This, Desc, ExecuteBuffer, UnkOuter);
736 return CLASS_E_NOAGGREGATION;
738 /* Allocate the new Execute Buffer */
739 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DExecuteBufferImpl));
742 ERR("Out of memory when allocating a IDirect3DExecuteBufferImpl structure\n");
743 return DDERR_OUTOFMEMORY;
746 object->lpVtbl = &IDirect3DExecuteBuffer_Vtbl;
748 object->d3ddev = This;
750 /* Initializes memory */
751 memcpy(&object->desc, Desc, Desc->dwSize);
753 /* No buffer given */
754 if ((object->desc.dwFlags & D3DDEB_LPDATA) == 0)
755 object->desc.lpData = NULL;
757 /* No buffer size given */
758 if ((object->desc.dwFlags & D3DDEB_BUFSIZE) == 0)
759 object->desc.dwBufferSize = 0;
761 /* Create buffer if asked */
762 if ((object->desc.lpData == NULL) && (object->desc.dwBufferSize > 0))
764 object->need_free = TRUE;
765 object->desc.lpData = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,object->desc.dwBufferSize);
766 if(!object->desc.lpData)
768 ERR("Out of memory when allocating the execute buffer data\n");
769 HeapFree(GetProcessHeap(), 0, object);
770 return DDERR_OUTOFMEMORY;
775 object->need_free = FALSE;
778 /* No vertices for the moment */
779 object->vertex_data = NULL;
781 object->desc.dwFlags |= D3DDEB_LPDATA;
783 object->indices = NULL;
784 object->nb_indices = 0;
786 *ExecuteBuffer = (IDirect3DExecuteBuffer *)object;
788 TRACE(" Returning IDirect3DExecuteBuffer at %p, implementation is at %p\n", *ExecuteBuffer, object);
793 /*****************************************************************************
794 * IDirect3DDevice::Execute
796 * Executes all the stuff in an execute buffer.
799 * ExecuteBuffer: The buffer to execute
800 * Viewport: The viewport used for rendering
804 * DDERR_INVALIDPARAMS if ExecuteBuffer == NULL
807 *****************************************************************************/
808 static HRESULT WINAPI
809 IDirect3DDeviceImpl_1_Execute(IDirect3DDevice *iface,
810 IDirect3DExecuteBuffer *ExecuteBuffer,
811 IDirect3DViewport *Viewport,
814 IDirect3DDeviceImpl *This = device_from_device1(iface);
815 IDirect3DExecuteBufferImpl *Direct3DExecuteBufferImpl = (IDirect3DExecuteBufferImpl *)ExecuteBuffer;
816 IDirect3DViewportImpl *Direct3DViewportImpl = (IDirect3DViewportImpl *)Viewport;
818 TRACE("(%p)->(%p,%p,%08x)\n", This, Direct3DExecuteBufferImpl, Direct3DViewportImpl, Flags);
820 if(!Direct3DExecuteBufferImpl)
821 return DDERR_INVALIDPARAMS;
824 EnterCriticalSection(&ddraw_cs);
825 IDirect3DExecuteBufferImpl_Execute(Direct3DExecuteBufferImpl, This, Direct3DViewportImpl);
826 LeaveCriticalSection(&ddraw_cs);
831 /*****************************************************************************
832 * IDirect3DDevice3::AddViewport
834 * Add a Direct3DViewport to the device's viewport list. These viewports
835 * are wrapped to IDirect3DDevice7 viewports in viewport.c
837 * Exists in Version 1, 2 and 3. Note that IDirect3DViewport 1, 2 and 3
838 * are the same interfaces.
841 * Viewport: The viewport to add
844 * DDERR_INVALIDPARAMS if Viewport == NULL
847 *****************************************************************************/
848 static HRESULT WINAPI
849 IDirect3DDeviceImpl_3_AddViewport(IDirect3DDevice3 *iface,
850 IDirect3DViewport3 *Viewport)
852 IDirect3DDeviceImpl *This = device_from_device3(iface);
853 IDirect3DViewportImpl *vp = (IDirect3DViewportImpl *)Viewport;
855 TRACE("(%p)->(%p)\n", This, vp);
859 return DDERR_INVALIDPARAMS;
861 EnterCriticalSection(&ddraw_cs);
862 vp->next = This->viewport_list;
863 This->viewport_list = vp;
864 vp->active_device = This; /* Viewport must be usable for Clear() after AddViewport,
865 so set active_device here. */
866 LeaveCriticalSection(&ddraw_cs);
871 static HRESULT WINAPI
872 Thunk_IDirect3DDeviceImpl_2_AddViewport(IDirect3DDevice2 *iface,
873 IDirect3DViewport2 *Direct3DViewport2)
875 IDirect3DDeviceImpl *This = device_from_device2(iface);
876 IDirect3DViewportImpl *vp = (IDirect3DViewportImpl *)Direct3DViewport2;
877 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, vp);
878 return IDirect3DDevice3_AddViewport((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl, (IDirect3DViewport3 *)vp);
881 static HRESULT WINAPI
882 Thunk_IDirect3DDeviceImpl_1_AddViewport(IDirect3DDevice *iface,
883 IDirect3DViewport *Direct3DViewport)
885 IDirect3DDeviceImpl *This = device_from_device1(iface);
886 IDirect3DViewportImpl *vp = (IDirect3DViewportImpl *)Direct3DViewport;
887 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, vp);
888 return IDirect3DDevice3_AddViewport((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl, (IDirect3DViewport3 *)vp);
891 /*****************************************************************************
892 * IDirect3DDevice3::DeleteViewport
894 * Deletes a Direct3DViewport from the device's viewport list.
896 * Exists in Version 1, 2 and 3. Note that all Viewport interface versions
900 * Viewport: The viewport to delete
904 * DDERR_INVALIDPARAMS if the viewport wasn't found in the list
906 *****************************************************************************/
907 static HRESULT WINAPI
908 IDirect3DDeviceImpl_3_DeleteViewport(IDirect3DDevice3 *iface,
909 IDirect3DViewport3 *Viewport)
911 IDirect3DDeviceImpl *This = device_from_device3(iface);
912 IDirect3DViewportImpl *vp = (IDirect3DViewportImpl *) Viewport;
913 IDirect3DViewportImpl *cur_viewport, *prev_viewport = NULL;
915 TRACE("(%p)->(%p)\n", This, vp);
917 EnterCriticalSection(&ddraw_cs);
918 cur_viewport = This->viewport_list;
919 while (cur_viewport != NULL)
921 if (cur_viewport == vp)
923 if (prev_viewport == NULL) This->viewport_list = cur_viewport->next;
924 else prev_viewport->next = cur_viewport->next;
925 /* TODO : add desactivate of the viewport and all associated lights... */
926 LeaveCriticalSection(&ddraw_cs);
929 prev_viewport = cur_viewport;
930 cur_viewport = cur_viewport->next;
933 LeaveCriticalSection(&ddraw_cs);
934 return DDERR_INVALIDPARAMS;
937 static HRESULT WINAPI
938 Thunk_IDirect3DDeviceImpl_2_DeleteViewport(IDirect3DDevice2 *iface,
939 IDirect3DViewport2 *Direct3DViewport2)
941 IDirect3DDeviceImpl *This = device_from_device2(iface);
942 IDirect3DViewportImpl *vp = (IDirect3DViewportImpl *)Direct3DViewport2;
943 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, vp);
944 return IDirect3DDevice3_DeleteViewport((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl, (IDirect3DViewport3 *)vp);
947 static HRESULT WINAPI
948 Thunk_IDirect3DDeviceImpl_1_DeleteViewport(IDirect3DDevice *iface,
949 IDirect3DViewport *Direct3DViewport)
951 IDirect3DDeviceImpl *This = device_from_device1(iface);
952 IDirect3DViewportImpl *vp = (IDirect3DViewportImpl *)Direct3DViewport;
953 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, vp);
954 return IDirect3DDevice3_DeleteViewport((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl, (IDirect3DViewport3 *)vp);
957 /*****************************************************************************
958 * IDirect3DDevice3::NextViewport
960 * Returns a viewport from the viewport list, depending on the
961 * passed viewport and the flags.
963 * Exists in Version 1, 2 and 3. Note that all Viewport interface versions
967 * Viewport: Viewport to use for beginning the search
968 * Flags: D3DNEXT_NEXT, D3DNEXT_HEAD or D3DNEXT_TAIL
972 * DDERR_INVALIDPARAMS if the flags were wrong, or Viewport was NULL
974 *****************************************************************************/
975 static HRESULT WINAPI
976 IDirect3DDeviceImpl_3_NextViewport(IDirect3DDevice3 *iface,
977 IDirect3DViewport3 *Viewport3,
978 IDirect3DViewport3 **lplpDirect3DViewport3,
981 IDirect3DDeviceImpl *This = device_from_device3(iface);
982 IDirect3DViewportImpl *vp = (IDirect3DViewportImpl *)Viewport3;
983 IDirect3DViewportImpl *res = NULL;
985 TRACE("(%p)->(%p,%p,%08x)\n", This, vp, lplpDirect3DViewport3, Flags);
989 *lplpDirect3DViewport3 = NULL;
990 return DDERR_INVALIDPARAMS;
994 EnterCriticalSection(&ddraw_cs);
1004 res = This->viewport_list;
1009 IDirect3DViewportImpl *cur_viewport = This->viewport_list;
1010 if (cur_viewport != NULL)
1012 while (cur_viewport->next != NULL) cur_viewport = cur_viewport->next;
1018 *lplpDirect3DViewport3 = NULL;
1019 LeaveCriticalSection(&ddraw_cs);
1020 return DDERR_INVALIDPARAMS;
1023 *lplpDirect3DViewport3 = (IDirect3DViewport3 *)res;
1024 LeaveCriticalSection(&ddraw_cs);
1028 static HRESULT WINAPI
1029 Thunk_IDirect3DDeviceImpl_2_NextViewport(IDirect3DDevice2 *iface,
1030 IDirect3DViewport2 *Viewport2,
1031 IDirect3DViewport2 **lplpDirect3DViewport2,
1034 IDirect3DDeviceImpl *This = device_from_device2(iface);
1035 IDirect3DViewportImpl *vp = (IDirect3DViewportImpl *)Viewport2;
1036 IDirect3DViewport3 *res;
1038 TRACE_(ddraw_thunk)("(%p)->(%p,%p,%08x) thunking to IDirect3DDevice3 interface.\n", This, vp, lplpDirect3DViewport2, Flags);
1039 hr = IDirect3DDevice3_NextViewport((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl,
1040 (IDirect3DViewport3 *)vp, &res, Flags);
1041 *lplpDirect3DViewport2 = (IDirect3DViewport2 *)res;
1045 static HRESULT WINAPI
1046 Thunk_IDirect3DDeviceImpl_1_NextViewport(IDirect3DDevice *iface,
1047 IDirect3DViewport *Viewport,
1048 IDirect3DViewport **lplpDirect3DViewport,
1051 IDirect3DDeviceImpl *This = device_from_device1(iface);
1052 IDirect3DViewportImpl *vp = (IDirect3DViewportImpl *)Viewport;
1053 IDirect3DViewport3 *res;
1055 TRACE_(ddraw_thunk)("(%p)->(%p,%p,%08x) thunking to IDirect3DDevice3 interface.\n", This, vp, lplpDirect3DViewport, Flags);
1056 hr = IDirect3DDevice3_NextViewport((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl,
1057 (IDirect3DViewport3 *)vp, &res, Flags);
1058 *lplpDirect3DViewport = (IDirect3DViewport *)res;
1062 /*****************************************************************************
1063 * IDirect3DDevice::Pick
1065 * Executes an execute buffer without performing rendering. Instead, a
1066 * list of primitives that intersect with (x1,y1) of the passed rectangle
1067 * is created. IDirect3DDevice::GetPickRecords can be used to retrieve
1073 * ExecuteBuffer: Buffer to execute
1074 * Viewport: Viewport to use for execution
1075 * Flags: None are defined, according to the SDK
1076 * Rect: Specifies the coordinates to be picked. Only x1 and y2 are used,
1077 * x2 and y2 are ignored.
1080 * D3D_OK because it's a stub
1082 *****************************************************************************/
1083 static HRESULT WINAPI
1084 IDirect3DDeviceImpl_1_Pick(IDirect3DDevice *iface,
1085 IDirect3DExecuteBuffer *ExecuteBuffer,
1086 IDirect3DViewport *Viewport,
1090 IDirect3DDeviceImpl *This = device_from_device1(iface);
1091 IDirect3DExecuteBufferImpl *execbuf = (IDirect3DExecuteBufferImpl *)ExecuteBuffer;
1092 IDirect3DViewportImpl *vp = (IDirect3DViewportImpl *)Viewport;
1093 FIXME("(%p)->(%p,%p,%08x,%p): stub!\n", This, execbuf, vp, Flags, Rect);
1098 /*****************************************************************************
1099 * IDirect3DDevice::GetPickRecords
1101 * Retrieves the pick records generated by IDirect3DDevice::GetPickRecords
1106 * Count: Pointer to a DWORD containing the numbers of pick records to
1108 * D3DPickRec: Address to store the resulting D3DPICKRECORD array.
1111 * D3D_OK, because it's a stub
1113 *****************************************************************************/
1114 static HRESULT WINAPI
1115 IDirect3DDeviceImpl_1_GetPickRecords(IDirect3DDevice *iface,
1117 D3DPICKRECORD *D3DPickRec)
1119 IDirect3DDeviceImpl *This = device_from_device1(iface);
1120 FIXME("(%p)->(%p,%p): stub!\n", This, Count, D3DPickRec);
1125 /*****************************************************************************
1126 * IDirect3DDevice7::EnumTextureformats
1128 * Enumerates the supported texture formats. It has a list of all possible
1129 * formats and calls IWineD3D::CheckDeviceFormat for each format to see if
1130 * WineD3D supports it. If so, then it is passed to the app.
1132 * This is for Version 7 and 3, older versions have a different
1133 * callback function and their own implementation
1136 * Callback: Callback to call for each enumerated format
1137 * Arg: Argument to pass to the callback
1141 * DDERR_INVALIDPARAMS if Callback == NULL
1143 *****************************************************************************/
1145 IDirect3DDeviceImpl_7_EnumTextureFormats(IDirect3DDevice7 *iface,
1146 LPD3DENUMPIXELFORMATSCALLBACK Callback,
1149 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
1151 WINED3DDISPLAYMODE mode;
1154 WINED3DFORMAT FormatList[] = {
1156 WINED3DFMT_B8G8R8A8_UNORM,
1157 WINED3DFMT_B8G8R8X8_UNORM,
1159 WINED3DFMT_B8G8R8_UNORM,
1161 WINED3DFMT_B5G5R5A1_UNORM,
1162 WINED3DFMT_B4G4R4A4_UNORM,
1163 WINED3DFMT_B5G6R5_UNORM,
1164 WINED3DFMT_B5G5R5X1_UNORM,
1166 WINED3DFMT_B2G3R3_UNORM,
1174 WINED3DFORMAT BumpFormatList[] = {
1175 WINED3DFMT_R8G8_SNORM,
1176 WINED3DFMT_R5G5_SNORM_L6_UNORM,
1177 WINED3DFMT_R8G8_SNORM_L8X8_UNORM,
1178 WINED3DFMT_R8G8B8A8_SNORM,
1179 WINED3DFMT_R16G16_SNORM,
1180 WINED3DFMT_R10G11B11_SNORM,
1181 WINED3DFMT_R10G10B10_SNORM_A2_UNORM
1184 TRACE("(%p)->(%p,%p): Relay\n", This, Callback, Arg);
1187 return DDERR_INVALIDPARAMS;
1189 EnterCriticalSection(&ddraw_cs);
1191 memset(&mode, 0, sizeof(mode));
1192 hr = IWineD3DDevice_GetDisplayMode(This->ddraw->wineD3DDevice,
1196 LeaveCriticalSection(&ddraw_cs);
1197 WARN("Cannot get the current adapter format\n");
1201 for(i = 0; i < sizeof(FormatList) / sizeof(WINED3DFORMAT); i++)
1203 hr = IWineD3D_CheckDeviceFormat(This->ddraw->wineD3D,
1204 WINED3DADAPTER_DEFAULT,
1208 WINED3DRTYPE_TEXTURE,
1213 DDPIXELFORMAT pformat;
1215 memset(&pformat, 0, sizeof(pformat));
1216 pformat.dwSize = sizeof(pformat);
1217 PixelFormat_WineD3DtoDD(&pformat, FormatList[i]);
1219 TRACE("Enumerating WineD3DFormat %d\n", FormatList[i]);
1220 hr = Callback(&pformat, Arg);
1221 if(hr != DDENUMRET_OK)
1223 TRACE("Format enumeration cancelled by application\n");
1224 LeaveCriticalSection(&ddraw_cs);
1230 for(i = 0; i < sizeof(BumpFormatList) / sizeof(WINED3DFORMAT); i++)
1232 hr = IWineD3D_CheckDeviceFormat(This->ddraw->wineD3D,
1233 WINED3DADAPTER_DEFAULT,
1236 WINED3DUSAGE_QUERY_LEGACYBUMPMAP,
1237 WINED3DRTYPE_TEXTURE,
1242 DDPIXELFORMAT pformat;
1244 memset(&pformat, 0, sizeof(pformat));
1245 pformat.dwSize = sizeof(pformat);
1246 PixelFormat_WineD3DtoDD(&pformat, BumpFormatList[i]);
1248 TRACE("Enumerating WineD3DFormat %d\n", BumpFormatList[i]);
1249 hr = Callback(&pformat, Arg);
1250 if(hr != DDENUMRET_OK)
1252 TRACE("Format enumeration cancelled by application\n");
1253 LeaveCriticalSection(&ddraw_cs);
1258 TRACE("End of enumeration\n");
1259 LeaveCriticalSection(&ddraw_cs);
1263 static HRESULT WINAPI
1264 IDirect3DDeviceImpl_7_EnumTextureFormats_FPUSetup(IDirect3DDevice7 *iface,
1265 LPD3DENUMPIXELFORMATSCALLBACK Callback,
1268 return IDirect3DDeviceImpl_7_EnumTextureFormats(iface, Callback, Arg);
1271 static HRESULT WINAPI
1272 IDirect3DDeviceImpl_7_EnumTextureFormats_FPUPreserve(IDirect3DDevice7 *iface,
1273 LPD3DENUMPIXELFORMATSCALLBACK Callback,
1279 old_fpucw = d3d_fpu_setup();
1280 hr = IDirect3DDeviceImpl_7_EnumTextureFormats(iface, Callback, Arg);
1281 set_fpu_control_word(old_fpucw);
1286 static HRESULT WINAPI
1287 Thunk_IDirect3DDeviceImpl_3_EnumTextureFormats(IDirect3DDevice3 *iface,
1288 LPD3DENUMPIXELFORMATSCALLBACK Callback,
1291 IDirect3DDeviceImpl *This = device_from_device3(iface);
1292 TRACE_(ddraw_thunk)("(%p)->(%p,%p) thunking to IDirect3DDevice7 interface.\n", This, Callback, Arg);
1293 return IDirect3DDevice7_EnumTextureFormats((IDirect3DDevice7 *)This, Callback, Arg);
1296 /*****************************************************************************
1297 * IDirect3DDevice2::EnumTextureformats
1299 * EnumTextureFormats for Version 1 and 2, see
1300 * IDirect3DDevice7::EnumTexureFormats for a more detailed description.
1302 * This version has a different callback and does not enumerate FourCC
1305 *****************************************************************************/
1306 static HRESULT WINAPI
1307 IDirect3DDeviceImpl_2_EnumTextureFormats(IDirect3DDevice2 *iface,
1308 LPD3DENUMTEXTUREFORMATSCALLBACK Callback,
1311 IDirect3DDeviceImpl *This = device_from_device2(iface);
1314 WINED3DDISPLAYMODE mode;
1316 WINED3DFORMAT FormatList[] = {
1318 WINED3DFMT_B8G8R8A8_UNORM,
1319 WINED3DFMT_B8G8R8X8_UNORM,
1321 WINED3DFMT_B8G8R8_UNORM,
1323 WINED3DFMT_B5G5R5A1_UNORM,
1324 WINED3DFMT_B4G4R4A4_UNORM,
1325 WINED3DFMT_B5G6R5_UNORM,
1326 WINED3DFMT_B5G5R5X1_UNORM,
1328 WINED3DFMT_B2G3R3_UNORM,
1330 /* FOURCC codes - Not in this version*/
1333 TRACE("(%p)->(%p,%p): Relay\n", This, Callback, Arg);
1336 return DDERR_INVALIDPARAMS;
1338 EnterCriticalSection(&ddraw_cs);
1340 memset(&mode, 0, sizeof(mode));
1341 hr = IWineD3DDevice_GetDisplayMode(This->ddraw->wineD3DDevice,
1345 LeaveCriticalSection(&ddraw_cs);
1346 WARN("Cannot get the current adapter format\n");
1350 for(i = 0; i < sizeof(FormatList) / sizeof(WINED3DFORMAT); i++)
1352 hr = IWineD3D_CheckDeviceFormat(This->ddraw->wineD3D,
1357 WINED3DRTYPE_TEXTURE,
1362 DDSURFACEDESC sdesc;
1364 memset(&sdesc, 0, sizeof(sdesc));
1365 sdesc.dwSize = sizeof(sdesc);
1366 sdesc.dwFlags = DDSD_PIXELFORMAT | DDSD_CAPS;
1367 sdesc.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1368 sdesc.ddpfPixelFormat.dwSize = sizeof(sdesc.ddpfPixelFormat);
1369 PixelFormat_WineD3DtoDD(&sdesc.ddpfPixelFormat, FormatList[i]);
1371 TRACE("Enumerating WineD3DFormat %d\n", FormatList[i]);
1372 hr = Callback(&sdesc, Arg);
1373 if(hr != DDENUMRET_OK)
1375 TRACE("Format enumeration cancelled by application\n");
1376 LeaveCriticalSection(&ddraw_cs);
1381 TRACE("End of enumeration\n");
1382 LeaveCriticalSection(&ddraw_cs);
1386 static HRESULT WINAPI
1387 Thunk_IDirect3DDeviceImpl_1_EnumTextureFormats(IDirect3DDevice *iface,
1388 LPD3DENUMTEXTUREFORMATSCALLBACK Callback,
1391 IDirect3DDeviceImpl *This = device_from_device1(iface);
1392 TRACE_(ddraw_thunk)("(%p)->(%p,%p) thunking to IDirect3DDevice2 interface.\n", This, Callback, Arg);
1393 return IDirect3DDevice2_EnumTextureFormats((IDirect3DDevice2 *)&This->IDirect3DDevice2_vtbl, Callback, Arg);
1396 /*****************************************************************************
1397 * IDirect3DDevice::CreateMatrix
1399 * Creates a matrix handle. A handle is created and memory for a D3DMATRIX is
1400 * allocated for the handle.
1405 * D3DMatHandle: Address to return the handle at
1409 * DDERR_INVALIDPARAMS if D3DMatHandle = NULL
1411 *****************************************************************************/
1412 static HRESULT WINAPI
1413 IDirect3DDeviceImpl_1_CreateMatrix(IDirect3DDevice *iface, D3DMATRIXHANDLE *D3DMatHandle)
1415 IDirect3DDeviceImpl *This = device_from_device1(iface);
1419 TRACE("(%p)->(%p)\n", This, D3DMatHandle);
1422 return DDERR_INVALIDPARAMS;
1424 Matrix = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(D3DMATRIX));
1427 ERR("Out of memory when allocating a D3DMATRIX\n");
1428 return DDERR_OUTOFMEMORY;
1431 EnterCriticalSection(&ddraw_cs);
1433 h = ddraw_allocate_handle(&This->handle_table, Matrix, DDRAW_HANDLE_MATRIX);
1434 if (h == DDRAW_INVALID_HANDLE)
1436 ERR("Failed to allocate a matrix handle.\n");
1437 HeapFree(GetProcessHeap(), 0, Matrix);
1438 LeaveCriticalSection(&ddraw_cs);
1439 return DDERR_OUTOFMEMORY;
1442 *D3DMatHandle = h + 1;
1444 TRACE(" returning matrix handle %d\n", *D3DMatHandle);
1446 LeaveCriticalSection(&ddraw_cs);
1450 /*****************************************************************************
1451 * IDirect3DDevice::SetMatrix
1453 * Sets a matrix for a matrix handle. The matrix is copied into the memory
1454 * allocated for the handle
1459 * D3DMatHandle: Handle to set the matrix to
1460 * D3DMatrix: Matrix to set
1464 * DDERR_INVALIDPARAMS if the handle of the matrix is invalid or the matrix
1467 *****************************************************************************/
1468 static HRESULT WINAPI
1469 IDirect3DDeviceImpl_1_SetMatrix(IDirect3DDevice *iface,
1470 D3DMATRIXHANDLE D3DMatHandle,
1471 D3DMATRIX *D3DMatrix)
1473 IDirect3DDeviceImpl *This = device_from_device1(iface);
1476 TRACE("(%p)->(%08x,%p)\n", This, D3DMatHandle, D3DMatrix);
1478 if (!D3DMatrix) return DDERR_INVALIDPARAMS;
1480 EnterCriticalSection(&ddraw_cs);
1482 m = ddraw_get_object(&This->handle_table, D3DMatHandle - 1, DDRAW_HANDLE_MATRIX);
1485 WARN("Invalid matrix handle.\n");
1486 LeaveCriticalSection(&ddraw_cs);
1487 return DDERR_INVALIDPARAMS;
1491 dump_D3DMATRIX(D3DMatrix);
1495 if(This->world == D3DMatHandle)
1497 IWineD3DDevice_SetTransform(This->wineD3DDevice,
1498 WINED3DTS_WORLDMATRIX(0),
1499 (WINED3DMATRIX *) D3DMatrix);
1501 if(This->view == D3DMatHandle)
1503 IWineD3DDevice_SetTransform(This->wineD3DDevice,
1505 (WINED3DMATRIX *) D3DMatrix);
1507 if(This->proj == D3DMatHandle)
1509 IWineD3DDevice_SetTransform(This->wineD3DDevice,
1510 WINED3DTS_PROJECTION,
1511 (WINED3DMATRIX *) D3DMatrix);
1514 LeaveCriticalSection(&ddraw_cs);
1518 /*****************************************************************************
1519 * IDirect3DDevice::SetMatrix
1521 * Returns the content of a D3DMATRIX handle
1526 * D3DMatHandle: Matrix handle to read the content from
1527 * D3DMatrix: Address to store the content at
1531 * DDERR_INVALIDPARAMS if D3DMatHandle is invalid or D3DMatrix is NULL
1533 *****************************************************************************/
1534 static HRESULT WINAPI
1535 IDirect3DDeviceImpl_1_GetMatrix(IDirect3DDevice *iface,
1536 D3DMATRIXHANDLE D3DMatHandle,
1537 D3DMATRIX *D3DMatrix)
1539 IDirect3DDeviceImpl *This = device_from_device1(iface);
1542 TRACE("(%p)->(%08x,%p)\n", This, D3DMatHandle, D3DMatrix);
1544 if (!D3DMatrix) return DDERR_INVALIDPARAMS;
1546 EnterCriticalSection(&ddraw_cs);
1548 m = ddraw_get_object(&This->handle_table, D3DMatHandle - 1, DDRAW_HANDLE_MATRIX);
1551 WARN("Invalid matrix handle.\n");
1552 LeaveCriticalSection(&ddraw_cs);
1553 return DDERR_INVALIDPARAMS;
1558 LeaveCriticalSection(&ddraw_cs);
1562 /*****************************************************************************
1563 * IDirect3DDevice::DeleteMatrix
1565 * Destroys a Matrix handle. Frees the memory and unsets the handle data
1570 * D3DMatHandle: Handle to destroy
1574 * DDERR_INVALIDPARAMS if D3DMatHandle is invalid
1576 *****************************************************************************/
1577 static HRESULT WINAPI
1578 IDirect3DDeviceImpl_1_DeleteMatrix(IDirect3DDevice *iface,
1579 D3DMATRIXHANDLE D3DMatHandle)
1581 IDirect3DDeviceImpl *This = device_from_device1(iface);
1584 TRACE("(%p)->(%08x)\n", This, D3DMatHandle);
1586 EnterCriticalSection(&ddraw_cs);
1588 m = ddraw_free_handle(&This->handle_table, D3DMatHandle - 1, DDRAW_HANDLE_MATRIX);
1591 WARN("Invalid matrix handle.\n");
1592 LeaveCriticalSection(&ddraw_cs);
1593 return DDERR_INVALIDPARAMS;
1596 LeaveCriticalSection(&ddraw_cs);
1598 HeapFree(GetProcessHeap(), 0, m);
1603 /*****************************************************************************
1604 * IDirect3DDevice7::BeginScene
1606 * This method must be called before any rendering is performed.
1607 * IDirect3DDevice::EndScene has to be called after the scene is complete
1609 * Version 1, 2, 3 and 7
1612 * D3D_OK on success, for details see IWineD3DDevice::BeginScene
1613 * D3DERR_SCENE_IN_SCENE if WineD3D returns an error(Only in case of an already
1616 *****************************************************************************/
1618 IDirect3DDeviceImpl_7_BeginScene(IDirect3DDevice7 *iface)
1620 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
1622 TRACE("(%p): Relay\n", This);
1624 EnterCriticalSection(&ddraw_cs);
1625 hr = IWineD3DDevice_BeginScene(This->wineD3DDevice);
1626 LeaveCriticalSection(&ddraw_cs);
1627 if(hr == WINED3D_OK) return D3D_OK;
1628 else return D3DERR_SCENE_IN_SCENE; /* TODO: Other possible causes of failure */
1631 static HRESULT WINAPI
1632 IDirect3DDeviceImpl_7_BeginScene_FPUSetup(IDirect3DDevice7 *iface)
1634 return IDirect3DDeviceImpl_7_BeginScene(iface);
1637 static HRESULT WINAPI
1638 IDirect3DDeviceImpl_7_BeginScene_FPUPreserve(IDirect3DDevice7 *iface)
1643 old_fpucw = d3d_fpu_setup();
1644 hr = IDirect3DDeviceImpl_7_BeginScene(iface);
1645 set_fpu_control_word(old_fpucw);
1650 static HRESULT WINAPI
1651 Thunk_IDirect3DDeviceImpl_3_BeginScene(IDirect3DDevice3 *iface)
1653 IDirect3DDeviceImpl *This = device_from_device3(iface);
1654 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
1655 return IDirect3DDevice7_BeginScene((IDirect3DDevice7 *)This);
1658 static HRESULT WINAPI
1659 Thunk_IDirect3DDeviceImpl_2_BeginScene(IDirect3DDevice2 *iface)
1661 IDirect3DDeviceImpl *This = device_from_device2(iface);
1662 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
1663 return IDirect3DDevice7_BeginScene((IDirect3DDevice7 *)This);
1666 static HRESULT WINAPI
1667 Thunk_IDirect3DDeviceImpl_1_BeginScene(IDirect3DDevice *iface)
1669 IDirect3DDeviceImpl *This = device_from_device1(iface);
1670 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
1671 return IDirect3DDevice7_BeginScene((IDirect3DDevice7 *)This);
1674 /*****************************************************************************
1675 * IDirect3DDevice7::EndScene
1677 * Ends a scene that has been begun with IDirect3DDevice7::BeginScene.
1678 * This method must be called after rendering is finished.
1680 * Version 1, 2, 3 and 7
1683 * D3D_OK on success, for details see IWineD3DDevice::EndScene
1684 * D3DERR_SCENE_NOT_IN_SCENE is returned if WineD3D returns an error. It does
1685 * that only if the scene was already ended.
1687 *****************************************************************************/
1689 IDirect3DDeviceImpl_7_EndScene(IDirect3DDevice7 *iface)
1691 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
1693 TRACE("(%p): Relay\n", This);
1695 EnterCriticalSection(&ddraw_cs);
1696 hr = IWineD3DDevice_EndScene(This->wineD3DDevice);
1697 LeaveCriticalSection(&ddraw_cs);
1698 if(hr == WINED3D_OK) return D3D_OK;
1699 else return D3DERR_SCENE_NOT_IN_SCENE;
1702 static HRESULT WINAPI DECLSPEC_HOTPATCH
1703 IDirect3DDeviceImpl_7_EndScene_FPUSetup(IDirect3DDevice7 *iface)
1705 return IDirect3DDeviceImpl_7_EndScene(iface);
1708 static HRESULT WINAPI DECLSPEC_HOTPATCH
1709 IDirect3DDeviceImpl_7_EndScene_FPUPreserve(IDirect3DDevice7 *iface)
1714 old_fpucw = d3d_fpu_setup();
1715 hr = IDirect3DDeviceImpl_7_EndScene(iface);
1716 set_fpu_control_word(old_fpucw);
1721 static HRESULT WINAPI DECLSPEC_HOTPATCH
1722 Thunk_IDirect3DDeviceImpl_3_EndScene(IDirect3DDevice3 *iface)
1724 IDirect3DDeviceImpl *This = device_from_device3(iface);
1725 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
1726 return IDirect3DDevice7_EndScene((IDirect3DDevice7 *)This);
1729 static HRESULT WINAPI DECLSPEC_HOTPATCH
1730 Thunk_IDirect3DDeviceImpl_2_EndScene(IDirect3DDevice2 *iface)
1732 IDirect3DDeviceImpl *This = device_from_device2(iface);
1733 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
1734 return IDirect3DDevice7_EndScene((IDirect3DDevice7 *)This);
1737 static HRESULT WINAPI DECLSPEC_HOTPATCH
1738 Thunk_IDirect3DDeviceImpl_1_EndScene(IDirect3DDevice *iface)
1740 IDirect3DDeviceImpl *This = device_from_device1(iface);
1741 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
1742 return IDirect3DDevice7_EndScene((IDirect3DDevice7 *)This);
1745 /*****************************************************************************
1746 * IDirect3DDevice7::GetDirect3D
1748 * Returns the IDirect3D(= interface to the DirectDraw object) used to create
1752 * Direct3D7: Address to store the interface pointer at
1756 * DDERR_INVALIDPARAMS if Direct3D7 == NULL
1758 *****************************************************************************/
1759 static HRESULT WINAPI
1760 IDirect3DDeviceImpl_7_GetDirect3D(IDirect3DDevice7 *iface,
1761 IDirect3D7 **Direct3D7)
1763 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
1764 TRACE("(%p)->(%p)\n", This, Direct3D7);
1767 return DDERR_INVALIDPARAMS;
1769 *Direct3D7 = (IDirect3D7 *)&This->ddraw->IDirect3D7_vtbl;
1770 IDirect3D7_AddRef(*Direct3D7);
1772 TRACE(" returning interface %p\n", *Direct3D7);
1776 static HRESULT WINAPI
1777 Thunk_IDirect3DDeviceImpl_3_GetDirect3D(IDirect3DDevice3 *iface,
1778 IDirect3D3 **Direct3D3)
1780 IDirect3DDeviceImpl *This = device_from_device3(iface);
1782 IDirect3D7 *ret_ptr;
1784 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, Direct3D3);
1785 ret = IDirect3DDevice7_GetDirect3D((IDirect3DDevice7 *)This, &ret_ptr);
1788 *Direct3D3 = ret_ptr ? (IDirect3D3 *)&ddraw_from_d3d7(ret_ptr)->IDirect3D3_vtbl : NULL;
1789 TRACE(" returning interface %p\n", *Direct3D3);
1793 static HRESULT WINAPI
1794 Thunk_IDirect3DDeviceImpl_2_GetDirect3D(IDirect3DDevice2 *iface,
1795 IDirect3D2 **Direct3D2)
1797 IDirect3DDeviceImpl *This = device_from_device2(iface);
1799 IDirect3D7 *ret_ptr;
1801 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, Direct3D2);
1802 ret = IDirect3DDevice7_GetDirect3D((IDirect3DDevice7 *)This, &ret_ptr);
1805 *Direct3D2 = ret_ptr ? (IDirect3D2 *)&ddraw_from_d3d7(ret_ptr)->IDirect3D2_vtbl : NULL;
1806 TRACE(" returning interface %p\n", *Direct3D2);
1810 static HRESULT WINAPI
1811 Thunk_IDirect3DDeviceImpl_1_GetDirect3D(IDirect3DDevice *iface,
1812 IDirect3D **Direct3D)
1814 IDirect3DDeviceImpl *This = device_from_device1(iface);
1816 IDirect3D7 *ret_ptr;
1818 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, Direct3D);
1819 ret = IDirect3DDevice7_GetDirect3D((IDirect3DDevice7 *)This, &ret_ptr);
1822 *Direct3D = ret_ptr ? (IDirect3D *)&ddraw_from_d3d7(ret_ptr)->IDirect3D_vtbl : NULL;
1823 TRACE(" returning interface %p\n", *Direct3D);
1827 /*****************************************************************************
1828 * IDirect3DDevice3::SetCurrentViewport
1830 * Sets a Direct3DViewport as the current viewport.
1831 * For the thunks note that all viewport interface versions are equal
1834 * Direct3DViewport3: The viewport to set
1840 * (Is a NULL viewport valid?)
1842 *****************************************************************************/
1843 static HRESULT WINAPI
1844 IDirect3DDeviceImpl_3_SetCurrentViewport(IDirect3DDevice3 *iface,
1845 IDirect3DViewport3 *Direct3DViewport3)
1847 IDirect3DDeviceImpl *This = device_from_device3(iface);
1848 IDirect3DViewportImpl *vp = (IDirect3DViewportImpl *)Direct3DViewport3;
1849 TRACE("(%p)->(%p)\n", This, Direct3DViewport3);
1851 EnterCriticalSection(&ddraw_cs);
1852 /* Do nothing if the specified viewport is the same as the current one */
1853 if (This->current_viewport == vp )
1855 LeaveCriticalSection(&ddraw_cs);
1859 /* Should check if the viewport was added or not */
1861 /* Release previous viewport and AddRef the new one */
1862 if (This->current_viewport)
1864 TRACE("ViewportImpl is at %p, interface is at %p\n", This->current_viewport,
1865 (IDirect3DViewport3 *)This->current_viewport);
1866 IDirect3DViewport3_Release((IDirect3DViewport3 *)This->current_viewport);
1868 IDirect3DViewport3_AddRef(Direct3DViewport3);
1870 /* Set this viewport as the current viewport */
1871 This->current_viewport = vp;
1873 /* Activate this viewport */
1874 This->current_viewport->active_device = This;
1875 This->current_viewport->activate(This->current_viewport, FALSE);
1877 LeaveCriticalSection(&ddraw_cs);
1881 static HRESULT WINAPI
1882 Thunk_IDirect3DDeviceImpl_2_SetCurrentViewport(IDirect3DDevice2 *iface,
1883 IDirect3DViewport2 *Direct3DViewport2)
1885 IDirect3DDeviceImpl *This = device_from_device2(iface);
1886 IDirect3DViewportImpl *vp = (IDirect3DViewportImpl *)Direct3DViewport2;
1887 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, vp);
1888 return IDirect3DDevice3_SetCurrentViewport((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl,
1889 (IDirect3DViewport3 *)vp);
1892 /*****************************************************************************
1893 * IDirect3DDevice3::GetCurrentViewport
1895 * Returns the currently active viewport.
1900 * Direct3DViewport3: Address to return the interface pointer at
1904 * DDERR_INVALIDPARAMS if Direct3DViewport == NULL
1906 *****************************************************************************/
1907 static HRESULT WINAPI
1908 IDirect3DDeviceImpl_3_GetCurrentViewport(IDirect3DDevice3 *iface,
1909 IDirect3DViewport3 **Direct3DViewport3)
1911 IDirect3DDeviceImpl *This = device_from_device3(iface);
1912 TRACE("(%p)->(%p)\n", This, Direct3DViewport3);
1914 if(!Direct3DViewport3)
1915 return DDERR_INVALIDPARAMS;
1917 EnterCriticalSection(&ddraw_cs);
1918 *Direct3DViewport3 = (IDirect3DViewport3 *)This->current_viewport;
1920 /* AddRef the returned viewport */
1921 if(*Direct3DViewport3) IDirect3DViewport3_AddRef(*Direct3DViewport3);
1923 TRACE(" returning interface %p\n", *Direct3DViewport3);
1925 LeaveCriticalSection(&ddraw_cs);
1929 static HRESULT WINAPI
1930 Thunk_IDirect3DDeviceImpl_2_GetCurrentViewport(IDirect3DDevice2 *iface,
1931 IDirect3DViewport2 **Direct3DViewport2)
1933 IDirect3DDeviceImpl *This = device_from_device2(iface);
1935 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, Direct3DViewport2);
1936 hr = IDirect3DDevice3_GetCurrentViewport((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl,
1937 (IDirect3DViewport3 **)Direct3DViewport2);
1938 if(hr != D3D_OK) return hr;
1942 /*****************************************************************************
1943 * IDirect3DDevice7::SetRenderTarget
1945 * Sets the render target for the Direct3DDevice.
1946 * For the thunks note that IDirectDrawSurface7 == IDirectDrawSurface4 and
1947 * IDirectDrawSurface3 == IDirectDrawSurface
1949 * Version 2, 3 and 7
1952 * NewTarget: Pointer to an IDirectDrawSurface7 interface to set as the new
1957 * D3D_OK on success, for details see IWineD3DDevice::SetRenderTarget
1959 *****************************************************************************/
1961 IDirect3DDeviceImpl_7_SetRenderTarget(IDirect3DDevice7 *iface,
1962 IDirectDrawSurface7 *NewTarget,
1965 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
1966 IDirectDrawSurfaceImpl *Target = (IDirectDrawSurfaceImpl *)NewTarget;
1968 TRACE("(%p)->(%p,%08x): Relay\n", This, NewTarget, Flags);
1970 EnterCriticalSection(&ddraw_cs);
1971 /* Flags: Not used */
1973 if(This->target == Target)
1975 TRACE("No-op SetRenderTarget operation, not doing anything\n");
1976 LeaveCriticalSection(&ddraw_cs);
1980 hr = IWineD3DDevice_SetRenderTarget(This->wineD3DDevice,
1982 Target ? Target->WineD3DSurface : NULL,
1986 LeaveCriticalSection(&ddraw_cs);
1989 IDirectDrawSurface7_AddRef(NewTarget);
1990 IDirectDrawSurface7_Release((IDirectDrawSurface7 *)This->target);
1991 This->target = Target;
1992 IDirect3DDeviceImpl_UpdateDepthStencil(This);
1993 LeaveCriticalSection(&ddraw_cs);
1997 static HRESULT WINAPI
1998 IDirect3DDeviceImpl_7_SetRenderTarget_FPUSetup(IDirect3DDevice7 *iface,
1999 IDirectDrawSurface7 *NewTarget,
2002 return IDirect3DDeviceImpl_7_SetRenderTarget(iface, NewTarget, Flags);
2005 static HRESULT WINAPI
2006 IDirect3DDeviceImpl_7_SetRenderTarget_FPUPreserve(IDirect3DDevice7 *iface,
2007 IDirectDrawSurface7 *NewTarget,
2013 old_fpucw = d3d_fpu_setup();
2014 hr = IDirect3DDeviceImpl_7_SetRenderTarget(iface, NewTarget, Flags);
2015 set_fpu_control_word(old_fpucw);
2020 static HRESULT WINAPI
2021 Thunk_IDirect3DDeviceImpl_3_SetRenderTarget(IDirect3DDevice3 *iface,
2022 IDirectDrawSurface4 *NewRenderTarget,
2025 IDirect3DDeviceImpl *This = device_from_device3(iface);
2026 IDirectDrawSurfaceImpl *Target = (IDirectDrawSurfaceImpl *)NewRenderTarget;
2027 TRACE_(ddraw_thunk)("(%p)->(%p,%08x) thunking to IDirect3DDevice7 interface.\n", This, Target, Flags);
2028 return IDirect3DDevice7_SetRenderTarget((IDirect3DDevice7 *)This, (IDirectDrawSurface7 *)Target, Flags);
2031 static HRESULT WINAPI
2032 Thunk_IDirect3DDeviceImpl_2_SetRenderTarget(IDirect3DDevice2 *iface,
2033 IDirectDrawSurface *NewRenderTarget,
2036 IDirect3DDeviceImpl *This = device_from_device2(iface);
2037 IDirectDrawSurfaceImpl *Target = (IDirectDrawSurfaceImpl *)NewRenderTarget;
2038 TRACE_(ddraw_thunk)("(%p)->(%p,%08x) thunking to IDirect3DDevice7 interface.\n", This, Target, Flags);
2039 return IDirect3DDevice7_SetRenderTarget((IDirect3DDevice7 *)This, (IDirectDrawSurface7 *)Target, Flags);
2042 /*****************************************************************************
2043 * IDirect3DDevice7::GetRenderTarget
2045 * Returns the current render target.
2046 * This is handled locally, because the WineD3D render target's parent
2049 * Version 2, 3 and 7
2052 * RenderTarget: Address to store the surface interface pointer
2056 * DDERR_INVALIDPARAMS if RenderTarget == NULL
2058 *****************************************************************************/
2059 static HRESULT WINAPI
2060 IDirect3DDeviceImpl_7_GetRenderTarget(IDirect3DDevice7 *iface,
2061 IDirectDrawSurface7 **RenderTarget)
2063 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
2064 TRACE("(%p)->(%p): Relay\n", This, RenderTarget);
2067 return DDERR_INVALIDPARAMS;
2069 EnterCriticalSection(&ddraw_cs);
2070 *RenderTarget = (IDirectDrawSurface7 *)This->target;
2071 IDirectDrawSurface7_AddRef(*RenderTarget);
2073 LeaveCriticalSection(&ddraw_cs);
2077 static HRESULT WINAPI
2078 Thunk_IDirect3DDeviceImpl_3_GetRenderTarget(IDirect3DDevice3 *iface,
2079 IDirectDrawSurface4 **RenderTarget)
2081 IDirect3DDeviceImpl *This = device_from_device3(iface);
2083 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, RenderTarget);
2084 hr = IDirect3DDevice7_GetRenderTarget((IDirect3DDevice7 *)This, (IDirectDrawSurface7 **)RenderTarget);
2085 if(hr != D3D_OK) return hr;
2089 static HRESULT WINAPI
2090 Thunk_IDirect3DDeviceImpl_2_GetRenderTarget(IDirect3DDevice2 *iface,
2091 IDirectDrawSurface **RenderTarget)
2093 IDirect3DDeviceImpl *This = device_from_device2(iface);
2095 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, RenderTarget);
2096 hr = IDirect3DDevice7_GetRenderTarget((IDirect3DDevice7 *)This, (IDirectDrawSurface7 **)RenderTarget);
2097 if(hr != D3D_OK) return hr;
2098 *RenderTarget = *RenderTarget ?
2099 (IDirectDrawSurface *)&((IDirectDrawSurfaceImpl *)*RenderTarget)->IDirectDrawSurface3_vtbl : NULL;
2103 /*****************************************************************************
2104 * IDirect3DDevice3::Begin
2106 * Begins a description block of vertices. This is similar to glBegin()
2107 * and glEnd(). After a call to IDirect3DDevice3::End, the vertices
2108 * described with IDirect3DDevice::Vertex are drawn.
2113 * PrimitiveType: The type of primitives to draw
2114 * VertexTypeDesc: A flexible vertex format description of the vertices
2115 * Flags: Some flags..
2120 *****************************************************************************/
2121 static HRESULT WINAPI
2122 IDirect3DDeviceImpl_3_Begin(IDirect3DDevice3 *iface,
2123 D3DPRIMITIVETYPE PrimitiveType,
2124 DWORD VertexTypeDesc,
2127 IDirect3DDeviceImpl *This = device_from_device3(iface);
2128 TRACE("(%p)->(%d,%d,%08x)\n", This, PrimitiveType, VertexTypeDesc, Flags);
2130 EnterCriticalSection(&ddraw_cs);
2131 This->primitive_type = PrimitiveType;
2132 This->vertex_type = VertexTypeDesc;
2133 This->render_flags = Flags;
2134 This->vertex_size = get_flexible_vertex_size(This->vertex_type);
2135 This->nb_vertices = 0;
2136 LeaveCriticalSection(&ddraw_cs);
2141 static HRESULT WINAPI
2142 Thunk_IDirect3DDeviceImpl_2_Begin(IDirect3DDevice2 *iface,
2143 D3DPRIMITIVETYPE d3dpt,
2144 D3DVERTEXTYPE dwVertexTypeDesc,
2148 IDirect3DDeviceImpl *This = device_from_device2(iface);
2149 TRACE_(ddraw_thunk)("(%p/%p)->(%08x,%08x,%08x): Thunking to IDirect3DDevice3\n", This, iface, d3dpt, dwVertexTypeDesc, dwFlags);
2151 switch(dwVertexTypeDesc)
2153 case D3DVT_VERTEX: FVF = D3DFVF_VERTEX; break;
2154 case D3DVT_LVERTEX: FVF = D3DFVF_LVERTEX; break;
2155 case D3DVT_TLVERTEX: FVF = D3DFVF_TLVERTEX; break;
2157 ERR("Unexpected vertex type %d\n", dwVertexTypeDesc);
2158 return DDERR_INVALIDPARAMS; /* Should never happen */
2161 return IDirect3DDevice3_Begin((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl, d3dpt, FVF, dwFlags);
2164 /*****************************************************************************
2165 * IDirect3DDevice3::BeginIndexed
2167 * Draws primitives based on vertices in a vertex array which are specified
2173 * PrimitiveType: Primitive type to draw
2174 * VertexType: A FVF description of the vertex format
2175 * Vertices: pointer to an array containing the vertices
2176 * NumVertices: The number of vertices in the vertex array
2177 * Flags: Some flags ...
2180 * D3D_OK, because it's a stub
2182 *****************************************************************************/
2183 static HRESULT WINAPI
2184 IDirect3DDeviceImpl_3_BeginIndexed(IDirect3DDevice3 *iface,
2185 D3DPRIMITIVETYPE PrimitiveType,
2191 IDirect3DDeviceImpl *This = device_from_device3(iface);
2192 FIXME("(%p)->(%08x,%08x,%p,%08x,%08x): stub!\n", This, PrimitiveType, VertexType, Vertices, NumVertices, Flags);
2197 static HRESULT WINAPI
2198 Thunk_IDirect3DDeviceImpl_2_BeginIndexed(IDirect3DDevice2 *iface,
2199 D3DPRIMITIVETYPE d3dptPrimitiveType,
2200 D3DVERTEXTYPE d3dvtVertexType,
2202 DWORD dwNumVertices,
2206 IDirect3DDeviceImpl *This = device_from_device2(iface);
2207 TRACE_(ddraw_thunk)("(%p/%p)->(%08x,%08x,%p,%08x,%08x): Thunking to IDirect3DDevice3\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwNumVertices, dwFlags);
2209 switch(d3dvtVertexType)
2211 case D3DVT_VERTEX: FVF = D3DFVF_VERTEX; break;
2212 case D3DVT_LVERTEX: FVF = D3DFVF_LVERTEX; break;
2213 case D3DVT_TLVERTEX: FVF = D3DFVF_TLVERTEX; break;
2215 ERR("Unexpected vertex type %d\n", d3dvtVertexType);
2216 return DDERR_INVALIDPARAMS; /* Should never happen */
2219 return IDirect3DDevice3_BeginIndexed((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl,
2220 d3dptPrimitiveType, FVF, lpvVertices, dwNumVertices, dwFlags);
2223 /*****************************************************************************
2224 * IDirect3DDevice3::Vertex
2226 * Draws a vertex as described by IDirect3DDevice3::Begin. It places all
2227 * drawn vertices in a vertex buffer. If the buffer is too small, its
2228 * size is increased.
2233 * Vertex: Pointer to the vertex
2236 * D3D_OK, on success
2237 * DDERR_INVALIDPARAMS if Vertex is NULL
2239 *****************************************************************************/
2240 static HRESULT WINAPI
2241 IDirect3DDeviceImpl_3_Vertex(IDirect3DDevice3 *iface,
2244 IDirect3DDeviceImpl *This = device_from_device3(iface);
2245 TRACE("(%p)->(%p)\n", This, Vertex);
2248 return DDERR_INVALIDPARAMS;
2250 EnterCriticalSection(&ddraw_cs);
2251 if ((This->nb_vertices+1)*This->vertex_size > This->buffer_size)
2254 This->buffer_size = This->buffer_size ? This->buffer_size * 2 : This->vertex_size * 3;
2255 old_buffer = This->vertex_buffer;
2256 This->vertex_buffer = HeapAlloc(GetProcessHeap(), 0, This->buffer_size);
2259 CopyMemory(This->vertex_buffer, old_buffer, This->nb_vertices * This->vertex_size);
2260 HeapFree(GetProcessHeap(), 0, old_buffer);
2264 CopyMemory(This->vertex_buffer + This->nb_vertices++ * This->vertex_size, Vertex, This->vertex_size);
2266 LeaveCriticalSection(&ddraw_cs);
2270 static HRESULT WINAPI
2271 Thunk_IDirect3DDeviceImpl_2_Vertex(IDirect3DDevice2 *iface,
2274 IDirect3DDeviceImpl *This = device_from_device2(iface);
2275 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, lpVertexType);
2276 return IDirect3DDevice3_Vertex((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl, lpVertexType);
2279 /*****************************************************************************
2280 * IDirect3DDevice3::Index
2282 * Specifies an index to a vertex to be drawn. The vertex array has to
2283 * be specified with BeginIndexed first.
2286 * VertexIndex: The index of the vertex to draw
2289 * D3D_OK because it's a stub
2291 *****************************************************************************/
2292 static HRESULT WINAPI
2293 IDirect3DDeviceImpl_3_Index(IDirect3DDevice3 *iface,
2296 IDirect3DDeviceImpl *This = device_from_device3(iface);
2297 FIXME("(%p)->(%04x): stub!\n", This, VertexIndex);
2301 static HRESULT WINAPI
2302 Thunk_IDirect3DDeviceImpl_2_Index(IDirect3DDevice2 *iface,
2305 IDirect3DDeviceImpl *This = device_from_device2(iface);
2306 TRACE_(ddraw_thunk)("(%p)->(%04x) thunking to IDirect3DDevice3 interface.\n", This, wVertexIndex);
2307 return IDirect3DDevice3_Index((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl, wVertexIndex);
2310 /*****************************************************************************
2311 * IDirect3DDevice3::End
2313 * Ends a draw begun with IDirect3DDevice3::Begin or
2314 * IDirect3DDevice::BeginIndexed. The vertices specified with
2315 * IDirect3DDevice::Vertex or IDirect3DDevice::Index are drawn using
2316 * the IDirect3DDevice7::DrawPrimitive method. So far only
2317 * non-indexed mode is supported
2322 * Flags: Some flags, as usual. Don't know which are defined
2325 * The return value of IDirect3DDevice7::DrawPrimitive
2327 *****************************************************************************/
2328 static HRESULT WINAPI
2329 IDirect3DDeviceImpl_3_End(IDirect3DDevice3 *iface,
2332 IDirect3DDeviceImpl *This = device_from_device3(iface);
2333 TRACE("(%p)->(%08x)\n", This, Flags);
2335 return IDirect3DDevice7_DrawPrimitive((IDirect3DDevice7 *)This, This->primitive_type,
2336 This->vertex_type, This->vertex_buffer, This->nb_vertices, This->render_flags);
2339 static HRESULT WINAPI
2340 Thunk_IDirect3DDeviceImpl_2_End(IDirect3DDevice2 *iface,
2343 IDirect3DDeviceImpl *This = device_from_device2(iface);
2344 TRACE_(ddraw_thunk)("(%p)->(%08x) thunking to IDirect3DDevice3 interface.\n", This, dwFlags);
2345 return IDirect3DDevice3_End((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl, dwFlags);
2348 /*****************************************************************************
2349 * IDirect3DDevice7::GetRenderState
2351 * Returns the value of a render state. The possible render states are
2352 * defined in include/d3dtypes.h
2354 * Version 2, 3 and 7
2357 * RenderStateType: Render state to return the current setting of
2358 * Value: Address to store the value at
2361 * D3D_OK on success, for details see IWineD3DDevice::GetRenderState
2362 * DDERR_INVALIDPARAMS if Value == NULL
2364 *****************************************************************************/
2366 IDirect3DDeviceImpl_7_GetRenderState(IDirect3DDevice7 *iface,
2367 D3DRENDERSTATETYPE RenderStateType,
2370 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
2372 TRACE("(%p)->(%08x,%p): Relay\n", This, RenderStateType, Value);
2375 return DDERR_INVALIDPARAMS;
2377 EnterCriticalSection(&ddraw_cs);
2378 switch(RenderStateType)
2380 case D3DRENDERSTATE_TEXTUREMAG:
2382 WINED3DTEXTUREFILTERTYPE tex_mag;
2384 hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice,
2385 0, WINED3DSAMP_MAGFILTER,
2390 case WINED3DTEXF_POINT:
2391 *Value = D3DFILTER_NEAREST;
2393 case WINED3DTEXF_LINEAR:
2394 *Value = D3DFILTER_LINEAR;
2397 ERR("Unhandled texture mag %d !\n",tex_mag);
2403 case D3DRENDERSTATE_TEXTUREMIN:
2405 WINED3DTEXTUREFILTERTYPE tex_min;
2406 WINED3DTEXTUREFILTERTYPE tex_mip;
2408 hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice,
2409 0, WINED3DSAMP_MINFILTER, &tex_min);
2412 LeaveCriticalSection(&ddraw_cs);
2415 hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice,
2416 0, WINED3DSAMP_MIPFILTER, &tex_mip);
2420 case WINED3DTEXF_POINT:
2423 case WINED3DTEXF_NONE:
2424 *Value = D3DFILTER_NEAREST;
2426 case WINED3DTEXF_POINT:
2427 *Value = D3DFILTER_MIPNEAREST;
2429 case WINED3DTEXF_LINEAR:
2430 *Value = D3DFILTER_LINEARMIPNEAREST;
2433 ERR("Unhandled mip filter %#x.\n", tex_mip);
2434 *Value = D3DFILTER_NEAREST;
2438 case WINED3DTEXF_LINEAR:
2441 case WINED3DTEXF_NONE:
2442 *Value = D3DFILTER_LINEAR;
2444 case WINED3DTEXF_POINT:
2445 *Value = D3DFILTER_MIPLINEAR;
2447 case WINED3DTEXF_LINEAR:
2448 *Value = D3DFILTER_LINEARMIPLINEAR;
2451 ERR("Unhandled mip filter %#x.\n", tex_mip);
2452 *Value = D3DFILTER_LINEAR;
2457 ERR("Unhandled texture min filter %#x.\n",tex_min);
2458 *Value = D3DFILTER_NEAREST;
2464 case D3DRENDERSTATE_TEXTUREADDRESS:
2465 case D3DRENDERSTATE_TEXTUREADDRESSU:
2466 hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice,
2467 0, WINED3DSAMP_ADDRESSU,
2470 case D3DRENDERSTATE_TEXTUREADDRESSV:
2471 hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice,
2472 0, WINED3DSAMP_ADDRESSV,
2476 case D3DRENDERSTATE_BORDERCOLOR:
2477 FIXME("Unhandled render state D3DRENDERSTATE_BORDERCOLOR.\n");
2482 if (RenderStateType >= D3DRENDERSTATE_STIPPLEPATTERN00
2483 && RenderStateType <= D3DRENDERSTATE_STIPPLEPATTERN31)
2485 FIXME("Unhandled stipple pattern render state (%#x).\n",
2490 hr = IWineD3DDevice_GetRenderState(This->wineD3DDevice,
2494 LeaveCriticalSection(&ddraw_cs);
2498 static HRESULT WINAPI
2499 IDirect3DDeviceImpl_7_GetRenderState_FPUSetup(IDirect3DDevice7 *iface,
2500 D3DRENDERSTATETYPE RenderStateType,
2503 return IDirect3DDeviceImpl_7_GetRenderState(iface, RenderStateType, Value);
2506 static HRESULT WINAPI
2507 IDirect3DDeviceImpl_7_GetRenderState_FPUPreserve(IDirect3DDevice7 *iface,
2508 D3DRENDERSTATETYPE RenderStateType,
2514 old_fpucw = d3d_fpu_setup();
2515 hr = IDirect3DDeviceImpl_7_GetRenderState(iface, RenderStateType, Value);
2516 set_fpu_control_word(old_fpucw);
2521 static HRESULT WINAPI
2522 IDirect3DDeviceImpl_3_GetRenderState(IDirect3DDevice3 *iface,
2523 D3DRENDERSTATETYPE dwRenderStateType,
2524 DWORD *lpdwRenderState)
2526 IDirect3DDeviceImpl *This = device_from_device3(iface);
2528 TRACE("(%p)->(%08x,%p)\n", This, dwRenderStateType, lpdwRenderState);
2530 switch(dwRenderStateType)
2532 case D3DRENDERSTATE_TEXTUREHANDLE:
2534 /* This state is wrapped to SetTexture in SetRenderState, so
2535 * it has to be wrapped to GetTexture here
2537 IWineD3DBaseTexture *tex = NULL;
2538 *lpdwRenderState = 0;
2540 EnterCriticalSection(&ddraw_cs);
2542 hr = IWineD3DDevice_GetTexture(This->wineD3DDevice,
2546 if(hr == WINED3D_OK && tex)
2548 IDirectDrawSurface7 *parent = NULL;
2549 hr = IWineD3DBaseTexture_GetParent(tex,
2550 (IUnknown **) &parent);
2553 /* The parent of the texture is the IDirectDrawSurface7 interface
2554 * of the ddraw surface
2556 IDirectDrawSurfaceImpl *texImpl = (IDirectDrawSurfaceImpl *)parent;
2557 *lpdwRenderState = texImpl->Handle;
2558 IDirectDrawSurface7_Release(parent);
2560 IWineD3DBaseTexture_Release(tex);
2563 LeaveCriticalSection(&ddraw_cs);
2568 case D3DRENDERSTATE_TEXTUREMAPBLEND:
2570 /* D3DRENDERSTATE_TEXTUREMAPBLEND is mapped to texture state stages in SetRenderState; reverse
2571 the mapping to get the value. */
2572 DWORD colorop, colorarg1, colorarg2;
2573 DWORD alphaop, alphaarg1, alphaarg2;
2575 EnterCriticalSection(&ddraw_cs);
2577 This->legacyTextureBlending = TRUE;
2579 IWineD3DDevice_GetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLOROP, &colorop);
2580 IWineD3DDevice_GetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG1, &colorarg1);
2581 IWineD3DDevice_GetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG2, &colorarg2);
2582 IWineD3DDevice_GetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAOP, &alphaop);
2583 IWineD3DDevice_GetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG1, &alphaarg1);
2584 IWineD3DDevice_GetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG2, &alphaarg2);
2586 if (colorop == WINED3DTOP_SELECTARG1 && colorarg1 == WINED3DTA_TEXTURE &&
2587 alphaop == WINED3DTOP_SELECTARG1 && alphaarg1 == WINED3DTA_TEXTURE)
2589 *lpdwRenderState = D3DTBLEND_DECAL;
2591 else if (colorop == WINED3DTOP_SELECTARG1 && colorarg1 == WINED3DTA_TEXTURE &&
2592 alphaop == WINED3DTOP_MODULATE && alphaarg1 == WINED3DTA_TEXTURE && alphaarg2 == WINED3DTA_CURRENT)
2594 *lpdwRenderState = D3DTBLEND_DECALALPHA;
2596 else if (colorop == WINED3DTOP_MODULATE && colorarg1 == WINED3DTA_TEXTURE && colorarg2 == WINED3DTA_CURRENT &&
2597 alphaop == WINED3DTOP_MODULATE && alphaarg1 == WINED3DTA_TEXTURE && alphaarg2 == WINED3DTA_CURRENT)
2599 *lpdwRenderState = D3DTBLEND_MODULATEALPHA;
2604 BOOL tex_alpha = FALSE;
2605 IWineD3DBaseTexture *tex = NULL;
2606 WINED3DSURFACE_DESC desc;
2607 DDPIXELFORMAT ddfmt;
2609 hr = IWineD3DDevice_GetTexture(This->wineD3DDevice,
2613 if(hr == WINED3D_OK && tex)
2615 hr = IWineD3DTexture_GetLevelDesc((IWineD3DTexture*) tex, 0, &desc);
2618 ddfmt.dwSize = sizeof(ddfmt);
2619 PixelFormat_WineD3DtoDD(&ddfmt, desc.format);
2620 if (ddfmt.u5.dwRGBAlphaBitMask) tex_alpha = TRUE;
2623 IWineD3DBaseTexture_Release(tex);
2626 if (!(colorop == WINED3DTOP_MODULATE && colorarg1 == WINED3DTA_TEXTURE && colorarg2 == WINED3DTA_CURRENT &&
2627 alphaop == (tex_alpha ? WINED3DTOP_SELECTARG1 : WINED3DTOP_SELECTARG2) &&
2628 alphaarg1 == WINED3DTA_TEXTURE && alphaarg2 == WINED3DTA_CURRENT))
2630 ERR("Unexpected texture stage state setup, returning D3DTBLEND_MODULATE - likely erroneous\n");
2633 *lpdwRenderState = D3DTBLEND_MODULATE;
2636 LeaveCriticalSection(&ddraw_cs);
2642 return IDirect3DDevice7_GetRenderState((IDirect3DDevice7 *)This, dwRenderStateType, lpdwRenderState);
2646 static HRESULT WINAPI
2647 Thunk_IDirect3DDeviceImpl_2_GetRenderState(IDirect3DDevice2 *iface,
2648 D3DRENDERSTATETYPE dwRenderStateType,
2649 DWORD *lpdwRenderState)
2651 IDirect3DDeviceImpl *This = device_from_device2(iface);
2652 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice3 interface.\n", This, dwRenderStateType, lpdwRenderState);
2653 return IDirect3DDevice3_GetRenderState((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl,
2654 dwRenderStateType, lpdwRenderState);
2657 /*****************************************************************************
2658 * IDirect3DDevice7::SetRenderState
2660 * Sets a render state. The possible render states are defined in
2661 * include/d3dtypes.h
2663 * Version 2, 3 and 7
2666 * RenderStateType: State to set
2667 * Value: Value to assign to that state
2670 * D3D_OK on success,
2671 * for details see IWineD3DDevice::SetRenderState
2673 *****************************************************************************/
2675 IDirect3DDeviceImpl_7_SetRenderState(IDirect3DDevice7 *iface,
2676 D3DRENDERSTATETYPE RenderStateType,
2679 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
2681 TRACE("(%p)->(%08x,%d): Relay\n", This, RenderStateType, Value);
2683 EnterCriticalSection(&ddraw_cs);
2684 /* Some render states need special care */
2685 switch(RenderStateType)
2688 * The ddraw texture filter mapping works like this:
2689 * D3DFILTER_NEAREST Point min/mag, no mip
2690 * D3DFILTER_MIPNEAREST Point min/mag, point mip
2691 * D3DFILTER_LINEARMIPNEAREST: Point min/mag, linear mip
2693 * D3DFILTER_LINEAR Linear min/mag, no mip
2694 * D3DFILTER_MIPLINEAR Linear min/mag, point mip
2695 * D3DFILTER_LINEARMIPLINEAR Linear min/mag, linear mip
2697 * This is the opposite of the GL naming convention,
2698 * D3DFILTER_LINEARMIPNEAREST corresponds to GL_NEAREST_MIPMAP_LINEAR.
2700 case D3DRENDERSTATE_TEXTUREMAG:
2702 WINED3DTEXTUREFILTERTYPE tex_mag;
2706 case D3DFILTER_NEAREST:
2707 case D3DFILTER_MIPNEAREST:
2708 case D3DFILTER_LINEARMIPNEAREST:
2709 tex_mag = WINED3DTEXF_POINT;
2711 case D3DFILTER_LINEAR:
2712 case D3DFILTER_MIPLINEAR:
2713 case D3DFILTER_LINEARMIPLINEAR:
2714 tex_mag = WINED3DTEXF_LINEAR;
2717 tex_mag = WINED3DTEXF_POINT;
2718 ERR("Unhandled texture mag %d !\n",Value);
2722 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
2723 0, WINED3DSAMP_MAGFILTER,
2728 case D3DRENDERSTATE_TEXTUREMIN:
2730 WINED3DTEXTUREFILTERTYPE tex_min;
2731 WINED3DTEXTUREFILTERTYPE tex_mip;
2733 switch ((D3DTEXTUREFILTER) Value)
2735 case D3DFILTER_NEAREST:
2736 tex_min = WINED3DTEXF_POINT;
2737 tex_mip = WINED3DTEXF_NONE;
2739 case D3DFILTER_LINEAR:
2740 tex_min = WINED3DTEXF_LINEAR;
2741 tex_mip = WINED3DTEXF_NONE;
2743 case D3DFILTER_MIPNEAREST:
2744 tex_min = WINED3DTEXF_POINT;
2745 tex_mip = WINED3DTEXF_POINT;
2747 case D3DFILTER_MIPLINEAR:
2748 tex_min = WINED3DTEXF_LINEAR;
2749 tex_mip = WINED3DTEXF_POINT;
2751 case D3DFILTER_LINEARMIPNEAREST:
2752 tex_min = WINED3DTEXF_POINT;
2753 tex_mip = WINED3DTEXF_LINEAR;
2755 case D3DFILTER_LINEARMIPLINEAR:
2756 tex_min = WINED3DTEXF_LINEAR;
2757 tex_mip = WINED3DTEXF_LINEAR;
2761 ERR("Unhandled texture min %d !\n",Value);
2762 tex_min = WINED3DTEXF_POINT;
2763 tex_mip = WINED3DTEXF_NONE;
2767 IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
2768 0, WINED3DSAMP_MIPFILTER, tex_mip);
2769 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
2770 0, WINED3DSAMP_MINFILTER,
2775 case D3DRENDERSTATE_TEXTUREADDRESS:
2776 IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
2777 0, WINED3DSAMP_ADDRESSV,
2780 case D3DRENDERSTATE_TEXTUREADDRESSU:
2781 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
2782 0, WINED3DSAMP_ADDRESSU,
2785 case D3DRENDERSTATE_TEXTUREADDRESSV:
2786 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
2787 0, WINED3DSAMP_ADDRESSV,
2791 case D3DRENDERSTATE_BORDERCOLOR:
2792 /* This should probably just forward to the corresponding sampler
2793 * state. Needs tests. */
2794 FIXME("Unhandled render state D3DRENDERSTATE_BORDERCOLOR.\n");
2799 if (RenderStateType >= D3DRENDERSTATE_STIPPLEPATTERN00
2800 && RenderStateType <= D3DRENDERSTATE_STIPPLEPATTERN31)
2802 FIXME("Unhandled stipple pattern render state (%#x).\n",
2808 hr = IWineD3DDevice_SetRenderState(This->wineD3DDevice,
2813 LeaveCriticalSection(&ddraw_cs);
2817 static HRESULT WINAPI
2818 IDirect3DDeviceImpl_7_SetRenderState_FPUSetup(IDirect3DDevice7 *iface,
2819 D3DRENDERSTATETYPE RenderStateType,
2822 return IDirect3DDeviceImpl_7_SetRenderState(iface, RenderStateType, Value);
2825 static HRESULT WINAPI
2826 IDirect3DDeviceImpl_7_SetRenderState_FPUPreserve(IDirect3DDevice7 *iface,
2827 D3DRENDERSTATETYPE RenderStateType,
2833 old_fpucw = d3d_fpu_setup();
2834 hr = IDirect3DDeviceImpl_7_SetRenderState(iface, RenderStateType, Value);
2835 set_fpu_control_word(old_fpucw);
2840 static HRESULT WINAPI
2841 IDirect3DDeviceImpl_3_SetRenderState(IDirect3DDevice3 *iface,
2842 D3DRENDERSTATETYPE RenderStateType,
2845 /* Note about D3DRENDERSTATE_TEXTUREMAPBLEND implementation: most of values
2846 for this state can be directly mapped to texture stage colorop and alphaop, but
2847 D3DTBLEND_MODULATE is tricky: it uses alpha from texture when available and alpha
2848 from diffuse otherwise. So changing the texture must be monitored in SetTexture to modify
2849 alphaarg when needed.
2851 Aliens vs Predator 1 depends on accurate D3DTBLEND_MODULATE emulation
2853 Legacy texture blending (TEXTUREMAPBLEND) and texture stage states: directx6 docs state that
2854 TEXTUREMAPBLEND is deprecated, yet can still be used. Games must not use both or results
2855 are undefined. D3DTBLEND_MODULATE mode in particular is dependent on texture pixel format and
2856 requires fixup of stage 0 texture states when texture changes, but this fixup can interfere
2857 with games not using this deprecated state. So a flag 'legacyTextureBlending' has to be kept
2858 in device - TRUE if the app is using TEXTUREMAPBLEND.
2860 Tests show that setting TEXTUREMAPBLEND on native doesn't seem to change values returned by
2861 GetTextureStageState and vice versa. Not so on Wine, but it is 'undefined' anyway so, probably, ok,
2862 unless some broken game will be found that cares. */
2865 IDirect3DDeviceImpl *This = device_from_device3(iface);
2866 TRACE("(%p)->(%08x,%d)\n", This, RenderStateType, Value);
2868 EnterCriticalSection(&ddraw_cs);
2870 switch(RenderStateType)
2872 case D3DRENDERSTATE_TEXTUREHANDLE:
2874 IDirectDrawSurfaceImpl *surf;
2878 hr = IWineD3DDevice_SetTexture(This->wineD3DDevice,
2884 surf = ddraw_get_object(&This->handle_table, Value - 1, DDRAW_HANDLE_SURFACE);
2887 WARN("Invalid texture handle.\n");
2888 hr = DDERR_INVALIDPARAMS;
2892 hr = IDirect3DDevice3_SetTexture(iface, 0, (IDirect3DTexture2 *)&surf->IDirect3DTexture2_vtbl);
2896 case D3DRENDERSTATE_TEXTUREMAPBLEND:
2898 This->legacyTextureBlending = TRUE;
2900 switch ( (D3DTEXTUREBLEND) Value)
2902 case D3DTBLEND_MODULATE:
2904 BOOL tex_alpha = FALSE;
2905 IWineD3DBaseTexture *tex = NULL;
2906 WINED3DSURFACE_DESC desc;
2907 DDPIXELFORMAT ddfmt;
2909 hr = IWineD3DDevice_GetTexture(This->wineD3DDevice,
2913 if(hr == WINED3D_OK && tex)
2915 memset(&desc, 0, sizeof(desc));
2916 hr = IWineD3DTexture_GetLevelDesc((IWineD3DTexture*) tex, 0, &desc);
2919 ddfmt.dwSize = sizeof(ddfmt);
2920 PixelFormat_WineD3DtoDD(&ddfmt, desc.format);
2921 if (ddfmt.u5.dwRGBAlphaBitMask) tex_alpha = TRUE;
2924 IWineD3DBaseTexture_Release(tex);
2928 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAOP, WINED3DTOP_SELECTARG1);
2930 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAOP, WINED3DTOP_SELECTARG2);
2931 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG1, WINED3DTA_TEXTURE);
2932 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG2, WINED3DTA_CURRENT);
2933 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG1, WINED3DTA_TEXTURE);
2934 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG2, WINED3DTA_CURRENT);
2935 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLOROP, WINED3DTOP_MODULATE);
2941 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLOROP, WINED3DTOP_ADD);
2942 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG1, WINED3DTA_TEXTURE);
2943 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG2, WINED3DTA_CURRENT);
2944 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAOP, WINED3DTOP_SELECTARG2);
2945 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG2, WINED3DTA_CURRENT);
2948 case D3DTBLEND_MODULATEALPHA:
2949 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG1, WINED3DTA_TEXTURE);
2950 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG1, WINED3DTA_TEXTURE);
2951 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG2, WINED3DTA_CURRENT);
2952 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG2, WINED3DTA_CURRENT);
2953 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLOROP, WINED3DTOP_MODULATE);
2954 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAOP, WINED3DTOP_MODULATE);
2957 case D3DTBLEND_COPY:
2958 case D3DTBLEND_DECAL:
2959 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG1, WINED3DTA_TEXTURE);
2960 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG1, WINED3DTA_TEXTURE);
2961 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLOROP, WINED3DTOP_SELECTARG1);
2962 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAOP, WINED3DTOP_SELECTARG1);
2965 case D3DTBLEND_DECALALPHA:
2966 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLOROP, WINED3DTOP_BLENDTEXTUREALPHA);
2967 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG1, WINED3DTA_TEXTURE);
2968 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG2, WINED3DTA_CURRENT);
2969 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAOP, WINED3DTOP_SELECTARG2);
2970 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG2, WINED3DTA_CURRENT);
2974 ERR("Unhandled texture environment %d !\n",Value);
2982 hr = IDirect3DDevice7_SetRenderState((IDirect3DDevice7 *)This, RenderStateType, Value);
2986 LeaveCriticalSection(&ddraw_cs);
2991 static HRESULT WINAPI
2992 Thunk_IDirect3DDeviceImpl_2_SetRenderState(IDirect3DDevice2 *iface,
2993 D3DRENDERSTATETYPE RenderStateType,
2996 IDirect3DDeviceImpl *This = device_from_device2(iface);
2997 TRACE_(ddraw_thunk)("(%p)->(%08x,%d) thunking to IDirect3DDevice3 interface.\n", This, RenderStateType, Value);
2998 return IDirect3DDevice3_SetRenderState((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl, RenderStateType, Value);
3001 /*****************************************************************************
3002 * Direct3DDevice3::SetLightState
3004 * Sets a light state for Direct3DDevice3 and Direct3DDevice2. The
3005 * light states are forwarded to Direct3DDevice7 render states
3010 * LightStateType: The light state to change
3011 * Value: The value to assign to that light state
3015 * DDERR_INVALIDPARAMS if the parameters were incorrect
3016 * Also check IDirect3DDevice7::SetRenderState
3018 *****************************************************************************/
3019 static HRESULT WINAPI
3020 IDirect3DDeviceImpl_3_SetLightState(IDirect3DDevice3 *iface,
3021 D3DLIGHTSTATETYPE LightStateType,
3024 IDirect3DDeviceImpl *This = device_from_device3(iface);
3027 TRACE("(%p)->(%08x,%08x)\n", This, LightStateType, Value);
3029 if (!LightStateType || (LightStateType > D3DLIGHTSTATE_COLORVERTEX))
3031 TRACE("Unexpected Light State Type\n");
3032 return DDERR_INVALIDPARAMS;
3035 EnterCriticalSection(&ddraw_cs);
3036 if (LightStateType == D3DLIGHTSTATE_MATERIAL /* 1 */)
3038 IDirect3DMaterialImpl *m = ddraw_get_object(&This->handle_table, Value - 1, DDRAW_HANDLE_MATERIAL);
3041 WARN("Invalid material handle.\n");
3042 LeaveCriticalSection(&ddraw_cs);
3043 return DDERR_INVALIDPARAMS;
3046 TRACE(" activating material %p.\n", m);
3049 This->material = Value;
3051 else if (LightStateType == D3DLIGHTSTATE_COLORMODEL /* 3 */)
3056 ERR("DDCOLOR_MONO should not happen!\n");
3059 /* We are already in this mode */
3060 TRACE("Setting color model to RGB (no-op).\n");
3063 ERR("Unknown color model!\n");
3064 LeaveCriticalSection(&ddraw_cs);
3065 return DDERR_INVALIDPARAMS;
3070 D3DRENDERSTATETYPE rs;
3071 switch (LightStateType)
3073 case D3DLIGHTSTATE_AMBIENT: /* 2 */
3074 rs = D3DRENDERSTATE_AMBIENT;
3076 case D3DLIGHTSTATE_FOGMODE: /* 4 */
3077 rs = D3DRENDERSTATE_FOGVERTEXMODE;
3079 case D3DLIGHTSTATE_FOGSTART: /* 5 */
3080 rs = D3DRENDERSTATE_FOGSTART;
3082 case D3DLIGHTSTATE_FOGEND: /* 6 */
3083 rs = D3DRENDERSTATE_FOGEND;
3085 case D3DLIGHTSTATE_FOGDENSITY: /* 7 */
3086 rs = D3DRENDERSTATE_FOGDENSITY;
3088 case D3DLIGHTSTATE_COLORVERTEX: /* 8 */
3089 rs = D3DRENDERSTATE_COLORVERTEX;
3092 ERR("Unknown D3DLIGHTSTATETYPE %d.\n", LightStateType);
3093 LeaveCriticalSection(&ddraw_cs);
3094 return DDERR_INVALIDPARAMS;
3097 hr = IDirect3DDevice7_SetRenderState((IDirect3DDevice7 *)This, rs, Value);
3098 LeaveCriticalSection(&ddraw_cs);
3102 LeaveCriticalSection(&ddraw_cs);
3106 static HRESULT WINAPI
3107 Thunk_IDirect3DDeviceImpl_2_SetLightState(IDirect3DDevice2 *iface,
3108 D3DLIGHTSTATETYPE LightStateType,
3111 IDirect3DDeviceImpl *This = device_from_device2(iface);
3112 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x) thunking to IDirect3DDevice3 interface.\n", This, LightStateType, Value);
3113 return IDirect3DDevice3_SetLightState((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl, LightStateType, Value);
3116 /*****************************************************************************
3117 * IDirect3DDevice3::GetLightState
3119 * Returns the current setting of a light state. The state is read from
3120 * the Direct3DDevice7 render state.
3125 * LightStateType: The light state to return
3126 * Value: The address to store the light state setting at
3130 * DDDERR_INVALIDPARAMS if the parameters were incorrect
3131 * Also see IDirect3DDevice7::GetRenderState
3133 *****************************************************************************/
3134 static HRESULT WINAPI
3135 IDirect3DDeviceImpl_3_GetLightState(IDirect3DDevice3 *iface,
3136 D3DLIGHTSTATETYPE LightStateType,
3139 IDirect3DDeviceImpl *This = device_from_device3(iface);
3142 TRACE("(%p)->(%08x,%p)\n", This, LightStateType, Value);
3144 if (!LightStateType || (LightStateType > D3DLIGHTSTATE_COLORVERTEX))
3146 TRACE("Unexpected Light State Type\n");
3147 return DDERR_INVALIDPARAMS;
3151 return DDERR_INVALIDPARAMS;
3153 EnterCriticalSection(&ddraw_cs);
3154 if (LightStateType == D3DLIGHTSTATE_MATERIAL /* 1 */)
3156 *Value = This->material;
3158 else if (LightStateType == D3DLIGHTSTATE_COLORMODEL /* 3 */)
3160 *Value = D3DCOLOR_RGB;
3164 D3DRENDERSTATETYPE rs;
3165 switch (LightStateType)
3167 case D3DLIGHTSTATE_AMBIENT: /* 2 */
3168 rs = D3DRENDERSTATE_AMBIENT;
3170 case D3DLIGHTSTATE_FOGMODE: /* 4 */
3171 rs = D3DRENDERSTATE_FOGVERTEXMODE;
3173 case D3DLIGHTSTATE_FOGSTART: /* 5 */
3174 rs = D3DRENDERSTATE_FOGSTART;
3176 case D3DLIGHTSTATE_FOGEND: /* 6 */
3177 rs = D3DRENDERSTATE_FOGEND;
3179 case D3DLIGHTSTATE_FOGDENSITY: /* 7 */
3180 rs = D3DRENDERSTATE_FOGDENSITY;
3182 case D3DLIGHTSTATE_COLORVERTEX: /* 8 */
3183 rs = D3DRENDERSTATE_COLORVERTEX;
3186 ERR("Unknown D3DLIGHTSTATETYPE %d.\n", LightStateType);
3187 LeaveCriticalSection(&ddraw_cs);
3188 return DDERR_INVALIDPARAMS;
3191 hr = IDirect3DDevice7_GetRenderState((IDirect3DDevice7 *)This, rs, Value);
3192 LeaveCriticalSection(&ddraw_cs);
3196 LeaveCriticalSection(&ddraw_cs);
3200 static HRESULT WINAPI
3201 Thunk_IDirect3DDeviceImpl_2_GetLightState(IDirect3DDevice2 *iface,
3202 D3DLIGHTSTATETYPE LightStateType,
3205 IDirect3DDeviceImpl *This = device_from_device2(iface);
3206 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice3 interface.\n", This, LightStateType, Value);
3207 return IDirect3DDevice3_GetLightState((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl, LightStateType, Value);
3210 /*****************************************************************************
3211 * IDirect3DDevice7::SetTransform
3213 * Assigns a D3DMATRIX to a transform type. The transform types are defined
3214 * in include/d3dtypes.h.
3215 * The D3DTRANSFORMSTATE_WORLD (=1) is translated to D3DTS_WORLDMATRIX(0)
3216 * (=255) for wined3d, because the 1 transform state was removed in d3d8
3217 * and WineD3D already understands the replacement D3DTS_WORLDMATRIX(0)
3219 * Version 2, 3 and 7
3222 * TransformStateType: transform state to set
3223 * Matrix: Matrix to assign to the state
3227 * DDERR_INVALIDPARAMS if Matrix == NULL
3228 * For details see IWineD3DDevice::SetTransform
3230 *****************************************************************************/
3232 IDirect3DDeviceImpl_7_SetTransform(IDirect3DDevice7 *iface,
3233 D3DTRANSFORMSTATETYPE TransformStateType,
3236 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
3237 D3DTRANSFORMSTATETYPE type;
3239 TRACE("(%p)->(%08x,%p): Relay\n", This, TransformStateType, Matrix);
3241 switch(TransformStateType)
3243 case D3DTRANSFORMSTATE_WORLD : type = WINED3DTS_WORLDMATRIX(0); break;
3244 case D3DTRANSFORMSTATE_WORLD1: type = WINED3DTS_WORLDMATRIX(1); break;
3245 case D3DTRANSFORMSTATE_WORLD2: type = WINED3DTS_WORLDMATRIX(2); break;
3246 case D3DTRANSFORMSTATE_WORLD3: type = WINED3DTS_WORLDMATRIX(3); break;
3247 default: type = TransformStateType;
3251 return DDERR_INVALIDPARAMS;
3253 /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
3254 EnterCriticalSection(&ddraw_cs);
3255 hr = IWineD3DDevice_SetTransform(This->wineD3DDevice,
3257 (WINED3DMATRIX*) Matrix);
3258 LeaveCriticalSection(&ddraw_cs);
3262 static HRESULT WINAPI
3263 IDirect3DDeviceImpl_7_SetTransform_FPUSetup(IDirect3DDevice7 *iface,
3264 D3DTRANSFORMSTATETYPE TransformStateType,
3267 return IDirect3DDeviceImpl_7_SetTransform(iface, TransformStateType, Matrix);
3270 static HRESULT WINAPI
3271 IDirect3DDeviceImpl_7_SetTransform_FPUPreserve(IDirect3DDevice7 *iface,
3272 D3DTRANSFORMSTATETYPE TransformStateType,
3278 old_fpucw = d3d_fpu_setup();
3279 hr = IDirect3DDeviceImpl_7_SetTransform(iface, TransformStateType, Matrix);
3280 set_fpu_control_word(old_fpucw);
3285 static HRESULT WINAPI
3286 Thunk_IDirect3DDeviceImpl_3_SetTransform(IDirect3DDevice3 *iface,
3287 D3DTRANSFORMSTATETYPE TransformStateType,
3288 D3DMATRIX *D3DMatrix)
3290 IDirect3DDeviceImpl *This = device_from_device3(iface);
3291 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, TransformStateType, D3DMatrix);
3292 return IDirect3DDevice7_SetTransform((IDirect3DDevice7 *)This, TransformStateType, D3DMatrix);
3295 static HRESULT WINAPI
3296 Thunk_IDirect3DDeviceImpl_2_SetTransform(IDirect3DDevice2 *iface,
3297 D3DTRANSFORMSTATETYPE TransformStateType,
3298 D3DMATRIX *D3DMatrix)
3300 IDirect3DDeviceImpl *This = device_from_device2(iface);
3301 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, TransformStateType, D3DMatrix);
3302 return IDirect3DDevice7_SetTransform((IDirect3DDevice7 *)This, TransformStateType, D3DMatrix);
3305 /*****************************************************************************
3306 * IDirect3DDevice7::GetTransform
3308 * Returns the matrix assigned to a transform state
3309 * D3DTRANSFORMSTATE_WORLD is translated to D3DTS_WORLDMATRIX(0), see
3313 * TransformStateType: State to read the matrix from
3314 * Matrix: Address to store the matrix at
3318 * DDERR_INVALIDPARAMS if Matrix == NULL
3319 * For details, see IWineD3DDevice::GetTransform
3321 *****************************************************************************/
3323 IDirect3DDeviceImpl_7_GetTransform(IDirect3DDevice7 *iface,
3324 D3DTRANSFORMSTATETYPE TransformStateType,
3327 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
3328 D3DTRANSFORMSTATETYPE type;
3330 TRACE("(%p)->(%08x,%p): Relay\n", This, TransformStateType, Matrix);
3332 switch(TransformStateType)
3334 case D3DTRANSFORMSTATE_WORLD : type = WINED3DTS_WORLDMATRIX(0); break;
3335 case D3DTRANSFORMSTATE_WORLD1: type = WINED3DTS_WORLDMATRIX(1); break;
3336 case D3DTRANSFORMSTATE_WORLD2: type = WINED3DTS_WORLDMATRIX(2); break;
3337 case D3DTRANSFORMSTATE_WORLD3: type = WINED3DTS_WORLDMATRIX(3); break;
3338 default: type = TransformStateType;
3342 return DDERR_INVALIDPARAMS;
3344 /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
3345 EnterCriticalSection(&ddraw_cs);
3346 hr = IWineD3DDevice_GetTransform(This->wineD3DDevice, type, (WINED3DMATRIX*) Matrix);
3347 LeaveCriticalSection(&ddraw_cs);
3351 static HRESULT WINAPI
3352 IDirect3DDeviceImpl_7_GetTransform_FPUSetup(IDirect3DDevice7 *iface,
3353 D3DTRANSFORMSTATETYPE TransformStateType,
3356 return IDirect3DDeviceImpl_7_GetTransform(iface, TransformStateType, Matrix);
3359 static HRESULT WINAPI
3360 IDirect3DDeviceImpl_7_GetTransform_FPUPreserve(IDirect3DDevice7 *iface,
3361 D3DTRANSFORMSTATETYPE TransformStateType,
3367 old_fpucw = d3d_fpu_setup();
3368 hr = IDirect3DDeviceImpl_7_GetTransform(iface, TransformStateType, Matrix);
3369 set_fpu_control_word(old_fpucw);
3374 static HRESULT WINAPI
3375 Thunk_IDirect3DDeviceImpl_3_GetTransform(IDirect3DDevice3 *iface,
3376 D3DTRANSFORMSTATETYPE TransformStateType,
3377 D3DMATRIX *D3DMatrix)
3379 IDirect3DDeviceImpl *This = device_from_device3(iface);
3380 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, TransformStateType, D3DMatrix);
3381 return IDirect3DDevice7_GetTransform((IDirect3DDevice7 *)This, TransformStateType, D3DMatrix);
3384 static HRESULT WINAPI
3385 Thunk_IDirect3DDeviceImpl_2_GetTransform(IDirect3DDevice2 *iface,
3386 D3DTRANSFORMSTATETYPE TransformStateType,
3387 D3DMATRIX *D3DMatrix)
3389 IDirect3DDeviceImpl *This = device_from_device2(iface);
3390 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, TransformStateType, D3DMatrix);
3391 return IDirect3DDevice7_GetTransform((IDirect3DDevice7 *)This, TransformStateType, D3DMatrix);
3394 /*****************************************************************************
3395 * IDirect3DDevice7::MultiplyTransform
3397 * Multiplies the already-set transform matrix of a transform state
3398 * with another matrix. For the world matrix, see SetTransform
3400 * Version 2, 3 and 7
3403 * TransformStateType: Transform state to multiply
3404 * D3DMatrix Matrix to multiply with.
3408 * DDERR_INVALIDPARAMS if D3DMatrix is NULL
3409 * For details, see IWineD3DDevice::MultiplyTransform
3411 *****************************************************************************/
3413 IDirect3DDeviceImpl_7_MultiplyTransform(IDirect3DDevice7 *iface,
3414 D3DTRANSFORMSTATETYPE TransformStateType,
3415 D3DMATRIX *D3DMatrix)
3417 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
3419 D3DTRANSFORMSTATETYPE type;
3420 TRACE("(%p)->(%08x,%p): Relay\n", This, TransformStateType, D3DMatrix);
3422 switch(TransformStateType)
3424 case D3DTRANSFORMSTATE_WORLD : type = WINED3DTS_WORLDMATRIX(0); break;
3425 case D3DTRANSFORMSTATE_WORLD1: type = WINED3DTS_WORLDMATRIX(1); break;
3426 case D3DTRANSFORMSTATE_WORLD2: type = WINED3DTS_WORLDMATRIX(2); break;
3427 case D3DTRANSFORMSTATE_WORLD3: type = WINED3DTS_WORLDMATRIX(3); break;
3428 default: type = TransformStateType;
3431 /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
3432 EnterCriticalSection(&ddraw_cs);
3433 hr = IWineD3DDevice_MultiplyTransform(This->wineD3DDevice,
3435 (WINED3DMATRIX*) D3DMatrix);
3436 LeaveCriticalSection(&ddraw_cs);
3440 static HRESULT WINAPI
3441 IDirect3DDeviceImpl_7_MultiplyTransform_FPUSetup(IDirect3DDevice7 *iface,
3442 D3DTRANSFORMSTATETYPE TransformStateType,
3443 D3DMATRIX *D3DMatrix)
3445 return IDirect3DDeviceImpl_7_MultiplyTransform(iface, TransformStateType, D3DMatrix);
3448 static HRESULT WINAPI
3449 IDirect3DDeviceImpl_7_MultiplyTransform_FPUPreserve(IDirect3DDevice7 *iface,
3450 D3DTRANSFORMSTATETYPE TransformStateType,
3451 D3DMATRIX *D3DMatrix)
3456 old_fpucw = d3d_fpu_setup();
3457 hr = IDirect3DDeviceImpl_7_MultiplyTransform(iface, TransformStateType, D3DMatrix);
3458 set_fpu_control_word(old_fpucw);
3463 static HRESULT WINAPI
3464 Thunk_IDirect3DDeviceImpl_3_MultiplyTransform(IDirect3DDevice3 *iface,
3465 D3DTRANSFORMSTATETYPE TransformStateType,
3466 D3DMATRIX *D3DMatrix)
3468 IDirect3DDeviceImpl *This = device_from_device3(iface);
3469 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, TransformStateType, D3DMatrix);
3470 return IDirect3DDevice7_MultiplyTransform((IDirect3DDevice7 *)This, TransformStateType, D3DMatrix);
3473 static HRESULT WINAPI
3474 Thunk_IDirect3DDeviceImpl_2_MultiplyTransform(IDirect3DDevice2 *iface,
3475 D3DTRANSFORMSTATETYPE TransformStateType,
3476 D3DMATRIX *D3DMatrix)
3478 IDirect3DDeviceImpl *This = device_from_device2(iface);
3479 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, TransformStateType, D3DMatrix);
3480 return IDirect3DDevice7_MultiplyTransform((IDirect3DDevice7 *)This, TransformStateType, D3DMatrix);
3483 /*****************************************************************************
3484 * IDirect3DDevice7::DrawPrimitive
3486 * Draws primitives based on vertices in an application-provided pointer
3488 * Version 2, 3 and 7. The IDirect3DDevice2 thunk converts the fixed vertex type into
3489 * an FVF format for D3D7
3492 * PrimitiveType: The type of the primitives to draw
3493 * Vertex type: Flexible vertex format vertex description
3494 * Vertices: Pointer to the vertex array
3495 * VertexCount: The number of vertices to draw
3496 * Flags: As usual a few flags
3500 * DDERR_INVALIDPARAMS if Vertices is NULL
3501 * For details, see IWineD3DDevice::DrawPrimitiveUP
3503 *****************************************************************************/
3505 IDirect3DDeviceImpl_7_DrawPrimitive(IDirect3DDevice7 *iface,
3506 D3DPRIMITIVETYPE PrimitiveType,
3512 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
3515 TRACE("(%p)->(%08x,%08x,%p,%08x,%08x): Relay!\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Flags);
3518 return DDERR_INVALIDPARAMS;
3520 /* Get the stride */
3521 stride = get_flexible_vertex_size(VertexType);
3524 EnterCriticalSection(&ddraw_cs);
3525 hr = IWineD3DDevice_SetVertexDeclaration(This->wineD3DDevice, ddraw_find_decl(This->ddraw, VertexType));
3528 LeaveCriticalSection(&ddraw_cs);
3532 /* This method translates to the user pointer draw of WineD3D */
3533 IWineD3DDevice_SetPrimitiveType(This->wineD3DDevice, PrimitiveType);
3534 hr = IWineD3DDevice_DrawPrimitiveUP(This->wineD3DDevice, VertexCount, Vertices, stride);
3535 LeaveCriticalSection(&ddraw_cs);
3539 static HRESULT WINAPI
3540 IDirect3DDeviceImpl_7_DrawPrimitive_FPUSetup(IDirect3DDevice7 *iface,
3541 D3DPRIMITIVETYPE PrimitiveType,
3547 return IDirect3DDeviceImpl_7_DrawPrimitive(iface, PrimitiveType, VertexType, Vertices, VertexCount, Flags);
3550 static HRESULT WINAPI
3551 IDirect3DDeviceImpl_7_DrawPrimitive_FPUPreserve(IDirect3DDevice7 *iface,
3552 D3DPRIMITIVETYPE PrimitiveType,
3561 old_fpucw = d3d_fpu_setup();
3562 hr = IDirect3DDeviceImpl_7_DrawPrimitive(iface, PrimitiveType, VertexType, Vertices, VertexCount, Flags);
3563 set_fpu_control_word(old_fpucw);
3568 static HRESULT WINAPI
3569 Thunk_IDirect3DDeviceImpl_3_DrawPrimitive(IDirect3DDevice3 *iface,
3570 D3DPRIMITIVETYPE PrimitiveType,
3576 IDirect3DDeviceImpl *This = device_from_device3(iface);
3577 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Flags);
3578 return IDirect3DDevice7_DrawPrimitive((IDirect3DDevice7 *)This,
3579 PrimitiveType, VertexType, Vertices, VertexCount, Flags);
3582 static HRESULT WINAPI
3583 Thunk_IDirect3DDeviceImpl_2_DrawPrimitive(IDirect3DDevice2 *iface,
3584 D3DPRIMITIVETYPE PrimitiveType,
3585 D3DVERTEXTYPE VertexType,
3590 IDirect3DDeviceImpl *This = device_from_device2(iface);
3592 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Flags);
3596 case D3DVT_VERTEX: FVF = D3DFVF_VERTEX; break;
3597 case D3DVT_LVERTEX: FVF = D3DFVF_LVERTEX; break;
3598 case D3DVT_TLVERTEX: FVF = D3DFVF_TLVERTEX; break;
3600 ERR("Unexpected vertex type %d\n", VertexType);
3601 return DDERR_INVALIDPARAMS; /* Should never happen */
3604 return IDirect3DDevice7_DrawPrimitive((IDirect3DDevice7 *)This, PrimitiveType, FVF, Vertices, VertexCount, Flags);
3607 /*****************************************************************************
3608 * IDirect3DDevice7::DrawIndexedPrimitive
3610 * Draws vertices from an application-provided pointer, based on the index
3611 * numbers in a WORD array.
3613 * Version 2, 3 and 7. The version 7 thunk translates the vertex type into
3614 * an FVF format for D3D7
3617 * PrimitiveType: The primitive type to draw
3618 * VertexType: The FVF vertex description
3619 * Vertices: Pointer to the vertex array
3621 * Indices: Pointer to the index array
3622 * IndexCount: Number of indices = Number of vertices to draw
3623 * Flags: As usual, some flags
3627 * DDERR_INVALIDPARAMS if Vertices or Indices is NULL
3628 * For details, see IWineD3DDevice::DrawIndexedPrimitiveUP
3630 *****************************************************************************/
3632 IDirect3DDeviceImpl_7_DrawIndexedPrimitive(IDirect3DDevice7 *iface,
3633 D3DPRIMITIVETYPE PrimitiveType,
3641 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
3643 TRACE("(%p)->(%08x,%08x,%p,%08x,%p,%08x,%08x): Relay!\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Indices, IndexCount, Flags);
3645 /* Set the D3DDevice's FVF */
3646 EnterCriticalSection(&ddraw_cs);
3647 hr = IWineD3DDevice_SetVertexDeclaration(This->wineD3DDevice, ddraw_find_decl(This->ddraw, VertexType));
3650 ERR(" (%p) Setting the FVF failed, hr = %x!\n", This, hr);
3651 LeaveCriticalSection(&ddraw_cs);
3655 IWineD3DDevice_SetPrimitiveType(This->wineD3DDevice, PrimitiveType);
3656 hr = IWineD3DDevice_DrawIndexedPrimitiveUP(This->wineD3DDevice, IndexCount, Indices,
3657 WINED3DFMT_R16_UINT, Vertices, get_flexible_vertex_size(VertexType));
3658 LeaveCriticalSection(&ddraw_cs);
3662 static HRESULT WINAPI
3663 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUSetup(IDirect3DDevice7 *iface,
3664 D3DPRIMITIVETYPE PrimitiveType,
3672 return IDirect3DDeviceImpl_7_DrawIndexedPrimitive(iface, PrimitiveType, VertexType, Vertices, VertexCount, Indices, IndexCount, Flags);
3675 static HRESULT WINAPI
3676 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUPreserve(IDirect3DDevice7 *iface,
3677 D3DPRIMITIVETYPE PrimitiveType,
3688 old_fpucw = d3d_fpu_setup();
3689 hr = IDirect3DDeviceImpl_7_DrawIndexedPrimitive(iface, PrimitiveType, VertexType, Vertices, VertexCount, Indices, IndexCount, Flags);
3690 set_fpu_control_word(old_fpucw);
3695 static HRESULT WINAPI
3696 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitive(IDirect3DDevice3 *iface,
3697 D3DPRIMITIVETYPE PrimitiveType,
3705 IDirect3DDeviceImpl *This = device_from_device3(iface);
3706 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Indices, IndexCount, Flags);
3707 return IDirect3DDevice7_DrawIndexedPrimitive((IDirect3DDevice7 *)This,
3708 PrimitiveType, VertexType, Vertices, VertexCount, Indices, IndexCount, Flags);
3711 static HRESULT WINAPI
3712 Thunk_IDirect3DDeviceImpl_2_DrawIndexedPrimitive(IDirect3DDevice2 *iface,
3713 D3DPRIMITIVETYPE PrimitiveType,
3714 D3DVERTEXTYPE VertexType,
3722 IDirect3DDeviceImpl *This = device_from_device2(iface);
3723 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Indices, IndexCount, Flags);
3727 case D3DVT_VERTEX: FVF = D3DFVF_VERTEX; break;
3728 case D3DVT_LVERTEX: FVF = D3DFVF_LVERTEX; break;
3729 case D3DVT_TLVERTEX: FVF = D3DFVF_TLVERTEX; break;
3731 ERR("Unexpected vertex type %d\n", VertexType);
3732 return DDERR_INVALIDPARAMS; /* Should never happen */
3735 return IDirect3DDevice7_DrawIndexedPrimitive((IDirect3DDevice7 *)This,
3736 PrimitiveType, FVF, Vertices, VertexCount, Indices, IndexCount, Flags);
3739 /*****************************************************************************
3740 * IDirect3DDevice7::SetClipStatus
3742 * Sets the clip status. This defines things as clipping conditions and
3743 * the extents of the clipping region.
3745 * Version 2, 3 and 7
3751 * D3D_OK because it's a stub
3752 * (DDERR_INVALIDPARAMS if ClipStatus == NULL)
3754 *****************************************************************************/
3755 static HRESULT WINAPI
3756 IDirect3DDeviceImpl_7_SetClipStatus(IDirect3DDevice7 *iface,
3757 D3DCLIPSTATUS *ClipStatus)
3759 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
3760 FIXME("(%p)->(%p): Stub!\n", This, ClipStatus);
3762 /* D3DCLIPSTATUS and WINED3DCLIPSTATUS are different. I don't know how to convert them
3763 * Perhaps this needs a new data type and an additional IWineD3DDevice method
3765 /* return IWineD3DDevice_SetClipStatus(This->wineD3DDevice, ClipStatus);*/
3769 static HRESULT WINAPI
3770 Thunk_IDirect3DDeviceImpl_3_SetClipStatus(IDirect3DDevice3 *iface,
3771 D3DCLIPSTATUS *ClipStatus)
3773 IDirect3DDeviceImpl *This = device_from_device3(iface);
3774 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, ClipStatus);
3775 return IDirect3DDevice7_SetClipStatus((IDirect3DDevice7 *)This, ClipStatus);
3778 static HRESULT WINAPI
3779 Thunk_IDirect3DDeviceImpl_2_SetClipStatus(IDirect3DDevice2 *iface,
3780 D3DCLIPSTATUS *ClipStatus)
3782 IDirect3DDeviceImpl *This = device_from_device2(iface);
3783 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, ClipStatus);
3784 return IDirect3DDevice7_SetClipStatus((IDirect3DDevice7 *)This, ClipStatus);
3787 /*****************************************************************************
3788 * IDirect3DDevice7::GetClipStatus
3790 * Returns the clip status
3793 * ClipStatus: Address to write the clip status to
3796 * D3D_OK because it's a stub
3798 *****************************************************************************/
3799 static HRESULT WINAPI
3800 IDirect3DDeviceImpl_7_GetClipStatus(IDirect3DDevice7 *iface,
3801 D3DCLIPSTATUS *ClipStatus)
3803 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
3804 FIXME("(%p)->(%p): Stub!\n", This, ClipStatus);
3806 /* D3DCLIPSTATUS and WINED3DCLIPSTATUS are different. I don't know how to convert them */
3807 /* return IWineD3DDevice_GetClipStatus(This->wineD3DDevice, ClipStatus);*/
3811 static HRESULT WINAPI
3812 Thunk_IDirect3DDeviceImpl_3_GetClipStatus(IDirect3DDevice3 *iface,
3813 D3DCLIPSTATUS *ClipStatus)
3815 IDirect3DDeviceImpl *This = device_from_device3(iface);
3816 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, ClipStatus);
3817 return IDirect3DDevice7_GetClipStatus((IDirect3DDevice7 *)This, ClipStatus);
3820 static HRESULT WINAPI
3821 Thunk_IDirect3DDeviceImpl_2_GetClipStatus(IDirect3DDevice2 *iface,
3822 D3DCLIPSTATUS *ClipStatus)
3824 IDirect3DDeviceImpl *This = device_from_device2(iface);
3825 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, ClipStatus);
3826 return IDirect3DDevice7_GetClipStatus((IDirect3DDevice7 *)This, ClipStatus);
3829 /*****************************************************************************
3830 * IDirect3DDevice::DrawPrimitiveStrided
3832 * Draws vertices described by a D3DDRAWPRIMITIVESTRIDEDDATA structure.
3837 * PrimitiveType: The primitive type to draw
3838 * VertexType: The FVF description of the vertices to draw (for the stride??)
3839 * D3DDrawPrimStrideData: A D3DDRAWPRIMITIVESTRIDEDDATA structure describing
3840 * the vertex data locations
3841 * VertexCount: The number of vertices to draw
3845 * D3D_OK, because it's a stub
3846 * (DDERR_INVALIDPARAMS if D3DDrawPrimStrideData is NULL)
3847 * (For details, see IWineD3DDevice::DrawPrimitiveStrided)
3849 *****************************************************************************/
3851 IDirect3DDeviceImpl_7_DrawPrimitiveStrided(IDirect3DDevice7 *iface,
3852 D3DPRIMITIVETYPE PrimitiveType,
3854 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
3858 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
3859 WineDirect3DVertexStridedData WineD3DStrided;
3863 TRACE("(%p)->(%08x,%08x,%p,%08x,%08x): stub!\n", This, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Flags);
3865 memset(&WineD3DStrided, 0, sizeof(WineD3DStrided));
3866 /* Get the strided data right. the wined3d structure is a bit bigger
3867 * Watch out: The contents of the strided data are determined by the fvf,
3868 * not by the members set in D3DDrawPrimStrideData. So it's valid
3869 * to have diffuse.lpvData set to 0xdeadbeef if the diffuse flag is
3870 * not set in the fvf.
3872 if(VertexType & D3DFVF_POSITION_MASK)
3874 WineD3DStrided.position.format = WINED3DFMT_R32G32B32_FLOAT;
3875 WineD3DStrided.position.lpData = D3DDrawPrimStrideData->position.lpvData;
3876 WineD3DStrided.position.dwStride = D3DDrawPrimStrideData->position.dwStride;
3877 if (VertexType & D3DFVF_XYZRHW)
3879 WineD3DStrided.position.format = WINED3DFMT_R32G32B32A32_FLOAT;
3880 WineD3DStrided.position_transformed = TRUE;
3882 WineD3DStrided.position_transformed = FALSE;
3885 if(VertexType & D3DFVF_NORMAL)
3887 WineD3DStrided.normal.format = WINED3DFMT_R32G32B32_FLOAT;
3888 WineD3DStrided.normal.lpData = D3DDrawPrimStrideData->normal.lpvData;
3889 WineD3DStrided.normal.dwStride = D3DDrawPrimStrideData->normal.dwStride;
3892 if(VertexType & D3DFVF_DIFFUSE)
3894 WineD3DStrided.diffuse.format = WINED3DFMT_B8G8R8A8_UNORM;
3895 WineD3DStrided.diffuse.lpData = D3DDrawPrimStrideData->diffuse.lpvData;
3896 WineD3DStrided.diffuse.dwStride = D3DDrawPrimStrideData->diffuse.dwStride;
3899 if(VertexType & D3DFVF_SPECULAR)
3901 WineD3DStrided.specular.format = WINED3DFMT_B8G8R8A8_UNORM;
3902 WineD3DStrided.specular.lpData = D3DDrawPrimStrideData->specular.lpvData;
3903 WineD3DStrided.specular.dwStride = D3DDrawPrimStrideData->specular.dwStride;
3906 for( i = 0; i < GET_TEXCOUNT_FROM_FVF(VertexType); i++)
3908 switch(GET_TEXCOORD_SIZE_FROM_FVF(VertexType, i))
3910 case 1: WineD3DStrided.texCoords[i].format = WINED3DFMT_R32_FLOAT; break;
3911 case 2: WineD3DStrided.texCoords[i].format = WINED3DFMT_R32G32_FLOAT; break;
3912 case 3: WineD3DStrided.texCoords[i].format = WINED3DFMT_R32G32B32_FLOAT; break;
3913 case 4: WineD3DStrided.texCoords[i].format = WINED3DFMT_R32G32B32A32_FLOAT; break;
3914 default: ERR("Unexpected texture coordinate size %d\n",
3915 GET_TEXCOORD_SIZE_FROM_FVF(VertexType, i));
3917 WineD3DStrided.texCoords[i].lpData = D3DDrawPrimStrideData->textureCoords[i].lpvData;
3918 WineD3DStrided.texCoords[i].dwStride = D3DDrawPrimStrideData->textureCoords[i].dwStride;
3921 /* WineD3D doesn't need the FVF here */
3922 EnterCriticalSection(&ddraw_cs);
3923 IWineD3DDevice_SetPrimitiveType(This->wineD3DDevice, PrimitiveType);
3924 hr = IWineD3DDevice_DrawPrimitiveStrided(This->wineD3DDevice, VertexCount, &WineD3DStrided);
3925 LeaveCriticalSection(&ddraw_cs);
3929 static HRESULT WINAPI
3930 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUSetup(IDirect3DDevice7 *iface,
3931 D3DPRIMITIVETYPE PrimitiveType,
3933 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
3937 return IDirect3DDeviceImpl_7_DrawPrimitiveStrided(iface, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Flags);
3940 static HRESULT WINAPI
3941 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUPreserve(IDirect3DDevice7 *iface,
3942 D3DPRIMITIVETYPE PrimitiveType,
3944 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
3951 old_fpucw = d3d_fpu_setup();
3952 hr = IDirect3DDeviceImpl_7_DrawPrimitiveStrided(iface, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Flags);
3953 set_fpu_control_word(old_fpucw);
3958 static HRESULT WINAPI
3959 Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveStrided(IDirect3DDevice3 *iface,
3960 D3DPRIMITIVETYPE PrimitiveType,
3962 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
3966 IDirect3DDeviceImpl *This = device_from_device3(iface);
3967 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Flags);
3968 return IDirect3DDevice7_DrawPrimitiveStrided((IDirect3DDevice7 *)This,
3969 PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Flags);
3972 /*****************************************************************************
3973 * IDirect3DDevice7::DrawIndexedPrimitiveStrided
3975 * Draws primitives specified by strided data locations based on indices
3983 * D3D_OK, because it's a stub
3984 * (DDERR_INVALIDPARAMS if D3DDrawPrimStrideData is NULL)
3985 * (DDERR_INVALIDPARAMS if Indices is NULL)
3986 * (For more details, see IWineD3DDevice::DrawIndexedPrimitiveStrided)
3988 *****************************************************************************/
3990 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided(IDirect3DDevice7 *iface,
3991 D3DPRIMITIVETYPE PrimitiveType,
3993 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
3999 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
4000 WineDirect3DVertexStridedData WineD3DStrided;
4004 TRACE("(%p)->(%08x,%08x,%p,%08x,%p,%08x,%08x)\n", This, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Indices, IndexCount, Flags);
4006 memset(&WineD3DStrided, 0, sizeof(WineD3DStrided));
4007 /* Get the strided data right. the wined3d structure is a bit bigger
4008 * Watch out: The contents of the strided data are determined by the fvf,
4009 * not by the members set in D3DDrawPrimStrideData. So it's valid
4010 * to have diffuse.lpvData set to 0xdeadbeef if the diffuse flag is
4011 * not set in the fvf.
4013 if(VertexType & D3DFVF_POSITION_MASK)
4015 WineD3DStrided.position.format = WINED3DFMT_R32G32B32_FLOAT;
4016 WineD3DStrided.position.lpData = D3DDrawPrimStrideData->position.lpvData;
4017 WineD3DStrided.position.dwStride = D3DDrawPrimStrideData->position.dwStride;
4018 if (VertexType & D3DFVF_XYZRHW)
4020 WineD3DStrided.position.format = WINED3DFMT_R32G32B32A32_FLOAT;
4021 WineD3DStrided.position_transformed = TRUE;
4023 WineD3DStrided.position_transformed = FALSE;
4026 if(VertexType & D3DFVF_NORMAL)
4028 WineD3DStrided.normal.format = WINED3DFMT_R32G32B32_FLOAT;
4029 WineD3DStrided.normal.lpData = D3DDrawPrimStrideData->normal.lpvData;
4030 WineD3DStrided.normal.dwStride = D3DDrawPrimStrideData->normal.dwStride;
4033 if(VertexType & D3DFVF_DIFFUSE)
4035 WineD3DStrided.diffuse.format = WINED3DFMT_B8G8R8A8_UNORM;
4036 WineD3DStrided.diffuse.lpData = D3DDrawPrimStrideData->diffuse.lpvData;
4037 WineD3DStrided.diffuse.dwStride = D3DDrawPrimStrideData->diffuse.dwStride;
4040 if(VertexType & D3DFVF_SPECULAR)
4042 WineD3DStrided.specular.format = WINED3DFMT_B8G8R8A8_UNORM;
4043 WineD3DStrided.specular.lpData = D3DDrawPrimStrideData->specular.lpvData;
4044 WineD3DStrided.specular.dwStride = D3DDrawPrimStrideData->specular.dwStride;
4047 for( i = 0; i < GET_TEXCOUNT_FROM_FVF(VertexType); i++)
4049 switch(GET_TEXCOORD_SIZE_FROM_FVF(VertexType, i))
4051 case 1: WineD3DStrided.texCoords[i].format = WINED3DFMT_R32_FLOAT; break;
4052 case 2: WineD3DStrided.texCoords[i].format = WINED3DFMT_R32G32_FLOAT; break;
4053 case 3: WineD3DStrided.texCoords[i].format = WINED3DFMT_R32G32B32_FLOAT; break;
4054 case 4: WineD3DStrided.texCoords[i].format = WINED3DFMT_R32G32B32A32_FLOAT; break;
4055 default: ERR("Unexpected texture coordinate size %d\n",
4056 GET_TEXCOORD_SIZE_FROM_FVF(VertexType, i));
4058 WineD3DStrided.texCoords[i].lpData = D3DDrawPrimStrideData->textureCoords[i].lpvData;
4059 WineD3DStrided.texCoords[i].dwStride = D3DDrawPrimStrideData->textureCoords[i].dwStride;
4062 /* WineD3D doesn't need the FVF here */
4063 EnterCriticalSection(&ddraw_cs);
4064 IWineD3DDevice_SetPrimitiveType(This->wineD3DDevice, PrimitiveType);
4065 hr = IWineD3DDevice_DrawIndexedPrimitiveStrided(This->wineD3DDevice,
4066 IndexCount, &WineD3DStrided, VertexCount, Indices, WINED3DFMT_R16_UINT);
4067 LeaveCriticalSection(&ddraw_cs);
4071 static HRESULT WINAPI
4072 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUSetup(IDirect3DDevice7 *iface,
4073 D3DPRIMITIVETYPE PrimitiveType,
4075 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
4081 return IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided(iface, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Indices, IndexCount, Flags);
4084 static HRESULT WINAPI
4085 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUPreserve(IDirect3DDevice7 *iface,
4086 D3DPRIMITIVETYPE PrimitiveType,
4088 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
4097 old_fpucw = d3d_fpu_setup();
4098 hr = IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided(iface, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Indices, IndexCount, Flags);
4099 set_fpu_control_word(old_fpucw);
4104 static HRESULT WINAPI
4105 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveStrided(IDirect3DDevice3 *iface,
4106 D3DPRIMITIVETYPE PrimitiveType,
4108 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
4114 IDirect3DDeviceImpl *This = device_from_device3(iface);
4115 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", iface, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Indices, IndexCount, Flags);
4116 return IDirect3DDevice7_DrawIndexedPrimitiveStrided((IDirect3DDevice7 *)This, PrimitiveType,
4117 VertexType, D3DDrawPrimStrideData, VertexCount, Indices, IndexCount, Flags);
4120 /*****************************************************************************
4121 * IDirect3DDevice7::DrawPrimitiveVB
4123 * Draws primitives from a vertex buffer to the screen.
4128 * PrimitiveType: Type of primitive to be rendered.
4129 * D3DVertexBuf: Source Vertex Buffer
4130 * StartVertex: Index of the first vertex from the buffer to be rendered
4131 * NumVertices: Number of vertices to be rendered
4132 * Flags: Can be D3DDP_WAIT to wait until rendering has finished
4136 * DDERR_INVALIDPARAMS if D3DVertexBuf is NULL
4138 *****************************************************************************/
4140 IDirect3DDeviceImpl_7_DrawPrimitiveVB(IDirect3DDevice7 *iface,
4141 D3DPRIMITIVETYPE PrimitiveType,
4142 IDirect3DVertexBuffer7 *D3DVertexBuf,
4147 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
4148 IDirect3DVertexBufferImpl *vb = (IDirect3DVertexBufferImpl *)D3DVertexBuf;
4152 TRACE("(%p)->(%08x,%p,%08x,%08x,%08x)\n", This, PrimitiveType, D3DVertexBuf, StartVertex, NumVertices, Flags);
4157 ERR("(%p) No Vertex buffer specified\n", This);
4158 return DDERR_INVALIDPARAMS;
4160 stride = get_flexible_vertex_size(vb->fvf);
4162 EnterCriticalSection(&ddraw_cs);
4163 hr = IWineD3DDevice_SetVertexDeclaration(This->wineD3DDevice,
4164 vb->wineD3DVertexDeclaration);
4167 ERR(" (%p) Setting the FVF failed, hr = %x!\n", This, hr);
4168 LeaveCriticalSection(&ddraw_cs);
4172 /* Set the vertex stream source */
4173 hr = IWineD3DDevice_SetStreamSource(This->wineD3DDevice,
4174 0 /* StreamNumber */,
4175 vb->wineD3DVertexBuffer,
4176 0 /* StartVertex - we pass this to DrawPrimitive */,
4180 ERR("(%p) IDirect3DDevice::SetStreamSource failed with hr = %08x\n", This, hr);
4181 LeaveCriticalSection(&ddraw_cs);
4185 /* Now draw the primitives */
4186 IWineD3DDevice_SetPrimitiveType(This->wineD3DDevice, PrimitiveType);
4187 hr = IWineD3DDevice_DrawPrimitive(This->wineD3DDevice, StartVertex, NumVertices);
4188 LeaveCriticalSection(&ddraw_cs);
4192 static HRESULT WINAPI
4193 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUSetup(IDirect3DDevice7 *iface,
4194 D3DPRIMITIVETYPE PrimitiveType,
4195 IDirect3DVertexBuffer7 *D3DVertexBuf,
4200 return IDirect3DDeviceImpl_7_DrawPrimitiveVB(iface, PrimitiveType, D3DVertexBuf, StartVertex, NumVertices, Flags);
4203 static HRESULT WINAPI
4204 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUPreserve(IDirect3DDevice7 *iface,
4205 D3DPRIMITIVETYPE PrimitiveType,
4206 IDirect3DVertexBuffer7 *D3DVertexBuf,
4214 old_fpucw = d3d_fpu_setup();
4215 hr = IDirect3DDeviceImpl_7_DrawPrimitiveVB(iface, PrimitiveType, D3DVertexBuf, StartVertex, NumVertices, Flags);
4216 set_fpu_control_word(old_fpucw);
4221 static HRESULT WINAPI
4222 Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveVB(IDirect3DDevice3 *iface,
4223 D3DPRIMITIVETYPE PrimitiveType,
4224 IDirect3DVertexBuffer *D3DVertexBuf,
4229 IDirect3DDeviceImpl *This = device_from_device3(iface);
4230 IDirect3DVertexBufferImpl *vb = D3DVertexBuf ? vb_from_vb1(D3DVertexBuf) : NULL;
4231 TRACE_(ddraw_thunk)("(%p)->(%08x,%p,%08x,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, vb, StartVertex, NumVertices, Flags);
4232 return IDirect3DDevice7_DrawPrimitiveVB((IDirect3DDevice7 *)This, PrimitiveType,
4233 (IDirect3DVertexBuffer7 *)vb, StartVertex, NumVertices, Flags);
4237 /*****************************************************************************
4238 * IDirect3DDevice7::DrawIndexedPrimitiveVB
4240 * Draws primitives from a vertex buffer to the screen
4243 * PrimitiveType: Type of primitive to be rendered.
4244 * D3DVertexBuf: Source Vertex Buffer
4245 * StartVertex: Index of the first vertex from the buffer to be rendered
4246 * NumVertices: Number of vertices to be rendered
4247 * Indices: Array of DWORDs used to index into the Vertices
4248 * IndexCount: Number of indices in Indices
4249 * Flags: Can be D3DDP_WAIT to wait until rendering has finished
4253 *****************************************************************************/
4255 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB(IDirect3DDevice7 *iface,
4256 D3DPRIMITIVETYPE PrimitiveType,
4257 IDirect3DVertexBuffer7 *D3DVertexBuf,
4264 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
4265 IDirect3DVertexBufferImpl *vb = (IDirect3DVertexBufferImpl *)D3DVertexBuf;
4266 DWORD stride = get_flexible_vertex_size(vb->fvf);
4267 WORD *LockedIndices;
4269 WINED3DBUFFER_DESC desc;
4271 TRACE("(%p)->(%08x,%p,%d,%d,%p,%d,%08x)\n", This, PrimitiveType, vb, StartVertex, NumVertices, Indices, IndexCount, Flags);
4274 * 1) Upload the Indices to the index buffer
4275 * 2) Set the index source
4276 * 3) Set the Vertex Buffer as the Stream source
4277 * 4) Call IWineD3DDevice::DrawIndexedPrimitive
4280 EnterCriticalSection(&ddraw_cs);
4282 hr = IWineD3DDevice_SetVertexDeclaration(This->wineD3DDevice,
4283 vb->wineD3DVertexDeclaration);
4286 ERR(" (%p) Setting the FVF failed, hr = %x!\n", This, hr);
4287 LeaveCriticalSection(&ddraw_cs);
4291 /* check that the buffer is large enough to hold the indices,
4292 * reallocate if necessary.
4294 hr = IWineD3DBuffer_GetDesc(This->indexbuffer, &desc);
4295 if(desc.Size < IndexCount * sizeof(WORD))
4297 UINT size = max(desc.Size * 2, IndexCount * sizeof(WORD));
4298 IWineD3DBuffer *buffer;
4301 TRACE("Growing index buffer to %u bytes\n", size);
4303 IWineD3DBuffer_GetParent(This->indexbuffer, &parent);
4304 hr = IWineD3DDevice_CreateIndexBuffer(This->wineD3DDevice, size,
4305 WINED3DUSAGE_DYNAMIC /* Usage */, WINED3DPOOL_DEFAULT, &buffer, parent,
4306 &ddraw_null_wined3d_parent_ops);
4309 ERR("(%p) IWineD3DDevice::CreateIndexBuffer failed with hr = %08x\n", This, hr);
4310 IParent_Release(parent);
4311 LeaveCriticalSection(&ddraw_cs);
4315 IWineD3DBuffer_Release(This->indexbuffer);
4316 This->indexbuffer = buffer;
4318 ((IParentImpl *)parent)->child = (IUnknown *)buffer;
4319 IParent_Release(parent);
4322 /* copy the index stream into the index buffer.
4323 * A new IWineD3DDevice method could be created
4324 * which takes an user pointer containing the indices
4325 * or a SetData-Method for the index buffer, which
4326 * overrides the index buffer data with our pointer.
4328 hr = IWineD3DBuffer_Map(This->indexbuffer,
4329 0 /* OffSetToLock */,
4330 IndexCount * sizeof(WORD),
4331 (BYTE **) &LockedIndices,
4335 ERR("(%p) IWineD3DBuffer::Map failed with hr = %08x\n", This, hr);
4336 LeaveCriticalSection(&ddraw_cs);
4339 memcpy(LockedIndices, Indices, IndexCount * sizeof(WORD));
4340 hr = IWineD3DBuffer_Unmap(This->indexbuffer);
4343 ERR("(%p) IWineD3DBuffer::Unmap failed with hr = %08x\n", This, hr);
4344 LeaveCriticalSection(&ddraw_cs);
4348 /* Set the index stream */
4349 IWineD3DDevice_SetBaseVertexIndex(This->wineD3DDevice, StartVertex);
4350 hr = IWineD3DDevice_SetIndexBuffer(This->wineD3DDevice, This->indexbuffer,
4351 WINED3DFMT_R16_UINT);
4353 /* Set the vertex stream source */
4354 hr = IWineD3DDevice_SetStreamSource(This->wineD3DDevice,
4355 0 /* StreamNumber */,
4356 vb->wineD3DVertexBuffer,
4357 0 /* offset, we pass this to DrawIndexedPrimitive */,
4361 ERR("(%p) IDirect3DDevice::SetStreamSource failed with hr = %08x\n", This, hr);
4362 LeaveCriticalSection(&ddraw_cs);
4367 IWineD3DDevice_SetPrimitiveType(This->wineD3DDevice, PrimitiveType);
4368 hr = IWineD3DDevice_DrawIndexedPrimitive(This->wineD3DDevice, 0 /* StartIndex */, IndexCount);
4370 LeaveCriticalSection(&ddraw_cs);
4374 static HRESULT WINAPI
4375 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUSetup(IDirect3DDevice7 *iface,
4376 D3DPRIMITIVETYPE PrimitiveType,
4377 IDirect3DVertexBuffer7 *D3DVertexBuf,
4384 return IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB(iface, PrimitiveType, D3DVertexBuf, StartVertex, NumVertices, Indices, IndexCount, Flags);
4387 static HRESULT WINAPI
4388 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUPreserve(IDirect3DDevice7 *iface,
4389 D3DPRIMITIVETYPE PrimitiveType,
4390 IDirect3DVertexBuffer7 *D3DVertexBuf,
4400 old_fpucw = d3d_fpu_setup();
4401 hr = IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB(iface, PrimitiveType, D3DVertexBuf, StartVertex, NumVertices, Indices, IndexCount, Flags);
4402 set_fpu_control_word(old_fpucw);
4407 static HRESULT WINAPI
4408 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveVB(IDirect3DDevice3 *iface,
4409 D3DPRIMITIVETYPE PrimitiveType,
4410 IDirect3DVertexBuffer *D3DVertexBuf,
4415 IDirect3DDeviceImpl *This = device_from_device3(iface);
4416 IDirect3DVertexBufferImpl *VB = vb_from_vb1(D3DVertexBuf);
4417 TRACE_(ddraw_thunk)("(%p)->(%08x,%p,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, VB, Indices, IndexCount, Flags);
4419 return IDirect3DDevice7_DrawIndexedPrimitiveVB((IDirect3DDevice7 *)This, PrimitiveType,
4420 (IDirect3DVertexBuffer7 *)VB, 0, IndexCount, Indices, IndexCount, Flags);
4423 /*****************************************************************************
4424 * IDirect3DDevice7::ComputeSphereVisibility
4426 * Calculates the visibility of spheres in the current viewport. The spheres
4427 * are passed in the Centers and Radii arrays, the results are passed back
4428 * in the ReturnValues array. Return values are either completely visible,
4429 * partially visible or completely invisible.
4430 * The return value consist of a combination of D3DCLIP_* flags, or it's
4431 * 0 if the sphere is completely visible(according to the SDK, not checked)
4436 * Centers: Array containing the sphere centers
4437 * Radii: Array containing the sphere radii
4438 * NumSpheres: The number of centers and radii in the arrays
4440 * ReturnValues: Array to write the results to
4444 * (DDERR_INVALIDPARAMS if Centers, Radii or ReturnValues are NULL)
4445 * (D3DERR_INVALIDMATRIX if the combined world, view and proj matrix
4448 *****************************************************************************/
4450 static DWORD in_plane(UINT plane, D3DVECTOR normal, D3DVALUE origin_plane, D3DVECTOR center, D3DVALUE radius)
4452 float distance, norm;
4454 norm = sqrt( normal.u1.x * normal.u1.x + normal.u2.y * normal.u2.y + normal.u3.z * normal.u3.z );
4455 distance = ( origin_plane + normal.u1.x * center.u1.x + normal.u2.y * center.u2.y + normal.u3.z * center.u3.z ) / norm;
4457 if ( fabs( distance ) < radius ) return D3DSTATUS_CLIPUNIONLEFT << plane;
4458 if ( distance < -radius ) return (D3DSTATUS_CLIPUNIONLEFT | D3DSTATUS_CLIPINTERSECTIONLEFT) << plane;
4462 static HRESULT WINAPI
4463 IDirect3DDeviceImpl_7_ComputeSphereVisibility(IDirect3DDevice7 *iface,
4468 DWORD *ReturnValues)
4471 D3DVALUE origin_plane[6];
4476 TRACE("(%p)->(%p,%p,%08x,%08x,%p)\n", iface, Centers, Radii, NumSpheres, Flags, ReturnValues);
4478 hr = IDirect3DDeviceImpl_7_GetTransform(iface, D3DTRANSFORMSTATE_WORLD, &m);
4479 if ( hr != DD_OK ) return DDERR_INVALIDPARAMS;
4480 hr = IDirect3DDeviceImpl_7_GetTransform(iface, D3DTRANSFORMSTATE_VIEW, &temp);
4481 if ( hr != DD_OK ) return DDERR_INVALIDPARAMS;
4482 multiply_matrix_D3D_way(&m, &m, &temp);
4484 hr = IDirect3DDeviceImpl_7_GetTransform(iface, D3DTRANSFORMSTATE_PROJECTION, &temp);
4485 if ( hr != DD_OK ) return DDERR_INVALIDPARAMS;
4486 multiply_matrix_D3D_way(&m, &m, &temp);
4489 vec[0].u1.x = m._14 + m._11;
4490 vec[0].u2.y = m._24 + m._21;
4491 vec[0].u3.z = m._34 + m._31;
4492 origin_plane[0] = m._44 + m._41;
4495 vec[1].u1.x = m._14 - m._11;
4496 vec[1].u2.y = m._24 - m._21;
4497 vec[1].u3.z = m._34 - m._31;
4498 origin_plane[1] = m._44 - m._41;
4501 vec[2].u1.x = m._14 - m._12;
4502 vec[2].u2.y = m._24 - m._22;
4503 vec[2].u3.z = m._34 - m._32;
4504 origin_plane[2] = m._44 - m._42;
4507 vec[3].u1.x = m._14 + m._12;
4508 vec[3].u2.y = m._24 + m._22;
4509 vec[3].u3.z = m._34 + m._32;
4510 origin_plane[3] = m._44 + m._42;
4513 vec[4].u1.x = m._13;
4514 vec[4].u2.y = m._23;
4515 vec[4].u3.z = m._33;
4516 origin_plane[4] = m._43;
4519 vec[5].u1.x = m._14 - m._13;
4520 vec[5].u2.y = m._24 - m._23;
4521 vec[5].u3.z = m._34 - m._33;
4522 origin_plane[5] = m._44 - m._43;
4524 for(i=0; i<NumSpheres; i++)
4526 ReturnValues[i] = 0;
4527 for(j=0; j<6; j++) ReturnValues[i] |= in_plane(j, vec[j], origin_plane[j], Centers[i], Radii[i]);
4533 static HRESULT WINAPI
4534 Thunk_IDirect3DDeviceImpl_3_ComputeSphereVisibility(IDirect3DDevice3 *iface,
4539 DWORD *ReturnValues)
4541 IDirect3DDeviceImpl *This = device_from_device3(iface);
4542 TRACE_(ddraw_thunk)("(%p)->(%p,%p,%08x,%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, Centers, Radii, NumSpheres, Flags, ReturnValues);
4543 return IDirect3DDevice7_ComputeSphereVisibility((IDirect3DDevice7 *)This,
4544 Centers, Radii, NumSpheres, Flags, ReturnValues);
4547 /*****************************************************************************
4548 * IDirect3DDevice7::GetTexture
4550 * Returns the texture interface handle assigned to a texture stage.
4551 * The returned texture is AddRefed. This is taken from old ddraw,
4552 * not checked in Windows.
4557 * Stage: Texture stage to read the texture from
4558 * Texture: Address to store the interface pointer at
4562 * DDERR_INVALIDPARAMS if Texture is NULL
4563 * For details, see IWineD3DDevice::GetTexture
4565 *****************************************************************************/
4567 IDirect3DDeviceImpl_7_GetTexture(IDirect3DDevice7 *iface,
4569 IDirectDrawSurface7 **Texture)
4571 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
4572 IWineD3DBaseTexture *Surf;
4574 TRACE("(%p)->(%d,%p): Relay\n", This, Stage, Texture);
4578 TRACE("Texture == NULL, failing with DDERR_INVALIDPARAMS\n");
4579 return DDERR_INVALIDPARAMS;
4582 EnterCriticalSection(&ddraw_cs);
4583 hr = IWineD3DDevice_GetTexture(This->wineD3DDevice, Stage, &Surf);
4584 if( (hr != D3D_OK) || (!Surf) )
4587 LeaveCriticalSection(&ddraw_cs);
4591 /* GetParent AddRef()s, which is perfectly OK.
4592 * We have passed the IDirectDrawSurface7 interface to WineD3D, so that's OK too.
4594 hr = IWineD3DBaseTexture_GetParent(Surf,
4595 (IUnknown **) Texture);
4596 LeaveCriticalSection(&ddraw_cs);
4600 static HRESULT WINAPI
4601 IDirect3DDeviceImpl_7_GetTexture_FPUSetup(IDirect3DDevice7 *iface,
4603 IDirectDrawSurface7 **Texture)
4605 return IDirect3DDeviceImpl_7_GetTexture(iface, Stage, Texture);
4608 static HRESULT WINAPI
4609 IDirect3DDeviceImpl_7_GetTexture_FPUPreserve(IDirect3DDevice7 *iface,
4611 IDirectDrawSurface7 **Texture)
4616 old_fpucw = d3d_fpu_setup();
4617 hr = IDirect3DDeviceImpl_7_GetTexture(iface, Stage, Texture);
4618 set_fpu_control_word(old_fpucw);
4623 static HRESULT WINAPI
4624 Thunk_IDirect3DDeviceImpl_3_GetTexture(IDirect3DDevice3 *iface,
4626 IDirect3DTexture2 **Texture2)
4628 IDirect3DDeviceImpl *This = device_from_device3(iface);
4630 IDirectDrawSurface7 *ret_val;
4632 TRACE_(ddraw_thunk)("(%p)->(%d,%p) thunking to IDirect3DDevice7 interface.\n", This, Stage, Texture2);
4633 ret = IDirect3DDevice7_GetTexture((IDirect3DDevice7 *)This, Stage, &ret_val);
4635 *Texture2 = ret_val ? (IDirect3DTexture2 *)&((IDirectDrawSurfaceImpl *)ret_val)->IDirect3DTexture2_vtbl : NULL;
4637 TRACE_(ddraw_thunk)(" returning interface %p.\n", *Texture2);
4642 /*****************************************************************************
4643 * IDirect3DDevice7::SetTexture
4645 * Assigns a texture to a texture stage. Is the texture AddRef-ed?
4650 * Stage: The stage to assign the texture to
4651 * Texture: Interface pointer to the texture surface
4655 * For details, see IWineD3DDevice::SetTexture
4657 *****************************************************************************/
4659 IDirect3DDeviceImpl_7_SetTexture(IDirect3DDevice7 *iface,
4661 IDirectDrawSurface7 *Texture)
4663 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
4664 IDirectDrawSurfaceImpl *surf = (IDirectDrawSurfaceImpl *)Texture;
4666 TRACE("(%p)->(%08x,%p): Relay!\n", This, Stage, surf);
4668 /* Texture may be NULL here */
4669 EnterCriticalSection(&ddraw_cs);
4670 hr = IWineD3DDevice_SetTexture(This->wineD3DDevice,
4672 surf ? surf->wineD3DTexture : NULL);
4673 LeaveCriticalSection(&ddraw_cs);
4677 static HRESULT WINAPI
4678 IDirect3DDeviceImpl_7_SetTexture_FPUSetup(IDirect3DDevice7 *iface,
4680 IDirectDrawSurface7 *Texture)
4682 return IDirect3DDeviceImpl_7_SetTexture(iface, Stage, Texture);
4685 static HRESULT WINAPI
4686 IDirect3DDeviceImpl_7_SetTexture_FPUPreserve(IDirect3DDevice7 *iface,
4688 IDirectDrawSurface7 *Texture)
4693 old_fpucw = d3d_fpu_setup();
4694 hr = IDirect3DDeviceImpl_7_SetTexture(iface, Stage, Texture);
4695 set_fpu_control_word(old_fpucw);
4700 static HRESULT WINAPI
4701 IDirect3DDeviceImpl_3_SetTexture(IDirect3DDevice3 *iface,
4703 IDirect3DTexture2 *Texture2)
4705 IDirect3DDeviceImpl *This = device_from_device3(iface);
4706 IDirectDrawSurfaceImpl *tex = Texture2 ? surface_from_texture2(Texture2) : NULL;
4709 TRACE("(%p)->(%d,%p)\n", This, Stage, tex);
4711 EnterCriticalSection(&ddraw_cs);
4713 if (This->legacyTextureBlending)
4714 IDirect3DDevice3_GetRenderState(iface, D3DRENDERSTATE_TEXTUREMAPBLEND, &texmapblend);
4716 hr = IDirect3DDevice7_SetTexture((IDirect3DDevice7 *)This, Stage, (IDirectDrawSurface7 *)tex);
4718 if (This->legacyTextureBlending && texmapblend == D3DTBLEND_MODULATE)
4720 /* This fixup is required by the way D3DTBLEND_MODULATE maps to texture stage states.
4721 See IDirect3DDeviceImpl_3_SetRenderState for details. */
4722 BOOL tex_alpha = FALSE;
4723 IWineD3DBaseTexture *tex = NULL;
4724 WINED3DSURFACE_DESC desc;
4725 DDPIXELFORMAT ddfmt;
4728 result = IWineD3DDevice_GetTexture(This->wineD3DDevice,
4732 if(result == WINED3D_OK && tex)
4734 memset(&desc, 0, sizeof(desc));
4735 result = IWineD3DTexture_GetLevelDesc((IWineD3DTexture*) tex, 0, &desc);
4736 if (SUCCEEDED(result))
4738 ddfmt.dwSize = sizeof(ddfmt);
4739 PixelFormat_WineD3DtoDD(&ddfmt, desc.format);
4740 if (ddfmt.u5.dwRGBAlphaBitMask) tex_alpha = TRUE;
4743 IWineD3DBaseTexture_Release(tex);
4746 /* Arg 1/2 are already set to WINED3DTA_TEXTURE/WINED3DTA_CURRENT in case of D3DTBLEND_MODULATE */
4748 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAOP, WINED3DTOP_SELECTARG1);
4750 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAOP, WINED3DTOP_SELECTARG2);
4753 LeaveCriticalSection(&ddraw_cs);
4758 static const struct tss_lookup
4765 {FALSE, WINED3DTSS_FORCE_DWORD}, /* 0, unused */
4766 {FALSE, WINED3DTSS_COLOROP}, /* 1, D3DTSS_COLOROP */
4767 {FALSE, WINED3DTSS_COLORARG1}, /* 2, D3DTSS_COLORARG1 */
4768 {FALSE, WINED3DTSS_COLORARG2}, /* 3, D3DTSS_COLORARG2 */
4769 {FALSE, WINED3DTSS_ALPHAOP}, /* 4, D3DTSS_ALPHAOP */
4770 {FALSE, WINED3DTSS_ALPHAARG1}, /* 5, D3DTSS_ALPHAARG1 */
4771 {FALSE, WINED3DTSS_ALPHAARG2}, /* 6, D3DTSS_ALPHAARG2 */
4772 {FALSE, WINED3DTSS_BUMPENVMAT00}, /* 7, D3DTSS_BUMPENVMAT00 */
4773 {FALSE, WINED3DTSS_BUMPENVMAT01}, /* 8, D3DTSS_BUMPENVMAT01 */
4774 {FALSE, WINED3DTSS_BUMPENVMAT10}, /* 9, D3DTSS_BUMPENVMAT10 */
4775 {FALSE, WINED3DTSS_BUMPENVMAT11}, /* 10, D3DTSS_BUMPENVMAT11 */
4776 {FALSE, WINED3DTSS_TEXCOORDINDEX}, /* 11, D3DTSS_TEXCOORDINDEX */
4777 {TRUE, WINED3DSAMP_ADDRESSU}, /* 12, D3DTSS_ADDRESS */
4778 {TRUE, WINED3DSAMP_ADDRESSU}, /* 13, D3DTSS_ADDRESSU */
4779 {TRUE, WINED3DSAMP_ADDRESSV}, /* 14, D3DTSS_ADDRESSV */
4780 {TRUE, WINED3DSAMP_BORDERCOLOR}, /* 15, D3DTSS_BORDERCOLOR */
4781 {TRUE, WINED3DSAMP_MAGFILTER}, /* 16, D3DTSS_MAGFILTER */
4782 {TRUE, WINED3DSAMP_MINFILTER}, /* 17, D3DTSS_MINFILTER */
4783 {TRUE, WINED3DSAMP_MIPFILTER}, /* 18, D3DTSS_MIPFILTER */
4784 {TRUE, WINED3DSAMP_MIPMAPLODBIAS}, /* 19, D3DTSS_MIPMAPLODBIAS */
4785 {TRUE, WINED3DSAMP_MAXMIPLEVEL}, /* 20, D3DTSS_MAXMIPLEVEL */
4786 {TRUE, WINED3DSAMP_MAXANISOTROPY}, /* 21, D3DTSS_MAXANISOTROPY */
4787 {FALSE, WINED3DTSS_BUMPENVLSCALE}, /* 22, D3DTSS_BUMPENVLSCALE */
4788 {FALSE, WINED3DTSS_BUMPENVLOFFSET}, /* 23, D3DTSS_BUMPENVLOFFSET */
4789 {FALSE, WINED3DTSS_TEXTURETRANSFORMFLAGS}, /* 24, D3DTSS_TEXTURETRANSFORMFLAGS */
4792 /*****************************************************************************
4793 * IDirect3DDevice7::GetTextureStageState
4795 * Retrieves a state from a texture stage.
4800 * Stage: The stage to retrieve the state from
4801 * TexStageStateType: The state type to retrieve
4802 * State: Address to store the state's value at
4806 * DDERR_INVALIDPARAMS if State is NULL
4807 * For details, see IWineD3DDevice::GetTextureStageState
4809 *****************************************************************************/
4811 IDirect3DDeviceImpl_7_GetTextureStageState(IDirect3DDevice7 *iface,
4813 D3DTEXTURESTAGESTATETYPE TexStageStateType,
4816 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
4818 const struct tss_lookup *l = &tss_lookup[TexStageStateType];
4819 TRACE("(%p)->(%08x,%08x,%p): Relay!\n", This, Stage, TexStageStateType, State);
4822 return DDERR_INVALIDPARAMS;
4824 if (TexStageStateType > D3DTSS_TEXTURETRANSFORMFLAGS)
4826 WARN("Invalid TexStageStateType %#x passed.\n", TexStageStateType);
4831 EnterCriticalSection(&ddraw_cs);
4833 if (l->sampler_state)
4835 hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice, Stage, l->state, State);
4837 switch(TexStageStateType)
4839 /* Mipfilter is a sampler state with different values */
4840 case D3DTSS_MIPFILTER:
4844 case WINED3DTEXF_NONE: *State = D3DTFP_NONE; break;
4845 case WINED3DTEXF_POINT: *State = D3DTFP_POINT; break;
4846 case WINED3DTEXF_LINEAR: *State = D3DTFP_LINEAR; break;
4848 ERR("Unexpected mipfilter value %#x\n", *State);
4849 *State = D3DTFP_NONE;
4855 /* Magfilter has slightly different values */
4856 case D3DTSS_MAGFILTER:
4860 case WINED3DTEXF_POINT: *State = D3DTFG_POINT; break;
4861 case WINED3DTEXF_LINEAR: *State = D3DTFG_LINEAR; break;
4862 case WINED3DTEXF_ANISOTROPIC: *State = D3DTFG_ANISOTROPIC; break;
4863 case WINED3DTEXF_FLATCUBIC: *State = D3DTFG_FLATCUBIC; break;
4864 case WINED3DTEXF_GAUSSIANCUBIC: *State = D3DTFG_GAUSSIANCUBIC; break;
4866 ERR("Unexpected wined3d mag filter value %#x\n", *State);
4867 *State = D3DTFG_POINT;
4879 hr = IWineD3DDevice_GetTextureStageState(This->wineD3DDevice, Stage, l->state, State);
4882 LeaveCriticalSection(&ddraw_cs);
4886 static HRESULT WINAPI
4887 IDirect3DDeviceImpl_7_GetTextureStageState_FPUSetup(IDirect3DDevice7 *iface,
4889 D3DTEXTURESTAGESTATETYPE TexStageStateType,
4892 return IDirect3DDeviceImpl_7_GetTextureStageState(iface, Stage, TexStageStateType, State);
4895 static HRESULT WINAPI
4896 IDirect3DDeviceImpl_7_GetTextureStageState_FPUPreserve(IDirect3DDevice7 *iface,
4898 D3DTEXTURESTAGESTATETYPE TexStageStateType,
4904 old_fpucw = d3d_fpu_setup();
4905 hr = IDirect3DDeviceImpl_7_GetTextureStageState(iface, Stage, TexStageStateType, State);
4906 set_fpu_control_word(old_fpucw);
4911 static HRESULT WINAPI
4912 Thunk_IDirect3DDeviceImpl_3_GetTextureStageState(IDirect3DDevice3 *iface,
4914 D3DTEXTURESTAGESTATETYPE TexStageStateType,
4917 IDirect3DDeviceImpl *This = device_from_device3(iface);
4918 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, Stage, TexStageStateType, State);
4919 return IDirect3DDevice7_GetTextureStageState((IDirect3DDevice7 *)This, Stage, TexStageStateType, State);
4922 /*****************************************************************************
4923 * IDirect3DDevice7::SetTextureStageState
4925 * Sets a texture stage state. Some stage types need to be handled specially,
4926 * because they do not exist in WineD3D and were moved to another place
4931 * Stage: The stage to modify
4932 * TexStageStateType: The state to change
4933 * State: The new value for the state
4937 * For details, see IWineD3DDevice::SetTextureStageState
4939 *****************************************************************************/
4941 IDirect3DDeviceImpl_7_SetTextureStageState(IDirect3DDevice7 *iface,
4943 D3DTEXTURESTAGESTATETYPE TexStageStateType,
4946 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
4947 const struct tss_lookup *l = &tss_lookup[TexStageStateType];
4949 TRACE("(%p)->(%08x,%08x,%08x): Relay!\n", This, Stage, TexStageStateType, State);
4951 if (TexStageStateType > D3DTSS_TEXTURETRANSFORMFLAGS)
4953 WARN("Invalid TexStageStateType %#x passed.\n", TexStageStateType);
4957 EnterCriticalSection(&ddraw_cs);
4959 if (l->sampler_state)
4961 switch(TexStageStateType)
4963 /* Mipfilter is a sampler state with different values */
4964 case D3DTSS_MIPFILTER:
4968 case D3DTFP_NONE: State = WINED3DTEXF_NONE; break;
4969 case D3DTFP_POINT: State = WINED3DTEXF_POINT; break;
4970 case 0: /* Unchecked */
4971 case D3DTFP_LINEAR: State = WINED3DTEXF_LINEAR; break;
4973 ERR("Unexpected mipfilter value %d\n", State);
4974 State = WINED3DTEXF_NONE;
4980 /* Magfilter has slightly different values */
4981 case D3DTSS_MAGFILTER:
4985 case D3DTFG_POINT: State = WINED3DTEXF_POINT; break;
4986 case D3DTFG_LINEAR: State = WINED3DTEXF_LINEAR; break;
4987 case D3DTFG_FLATCUBIC: State = WINED3DTEXF_FLATCUBIC; break;
4988 case D3DTFG_GAUSSIANCUBIC: State = WINED3DTEXF_GAUSSIANCUBIC; break;
4989 case D3DTFG_ANISOTROPIC: State = WINED3DTEXF_ANISOTROPIC; break;
4991 ERR("Unexpected d3d7 mag filter type %d\n", State);
4992 State = WINED3DTEXF_POINT;
4998 case D3DTSS_ADDRESS:
4999 IWineD3DDevice_SetSamplerState(This->wineD3DDevice, Stage, WINED3DSAMP_ADDRESSV, State);
5006 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice, Stage, l->state, State);
5010 hr = IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, Stage, l->state, State);
5013 LeaveCriticalSection(&ddraw_cs);
5017 static HRESULT WINAPI
5018 IDirect3DDeviceImpl_7_SetTextureStageState_FPUSetup(IDirect3DDevice7 *iface,
5020 D3DTEXTURESTAGESTATETYPE TexStageStateType,
5023 return IDirect3DDeviceImpl_7_SetTextureStageState(iface, Stage, TexStageStateType, State);
5026 static HRESULT WINAPI
5027 IDirect3DDeviceImpl_7_SetTextureStageState_FPUPreserve(IDirect3DDevice7 *iface,
5029 D3DTEXTURESTAGESTATETYPE TexStageStateType,
5035 old_fpucw = d3d_fpu_setup();
5036 hr = IDirect3DDeviceImpl_7_SetTextureStageState(iface, Stage, TexStageStateType, State);
5037 set_fpu_control_word(old_fpucw);
5042 static HRESULT WINAPI
5043 Thunk_IDirect3DDeviceImpl_3_SetTextureStageState(IDirect3DDevice3 *iface,
5045 D3DTEXTURESTAGESTATETYPE TexStageStateType,
5048 IDirect3DDeviceImpl *This = device_from_device3(iface);
5049 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, Stage, TexStageStateType, State);
5050 return IDirect3DDevice7_SetTextureStageState((IDirect3DDevice7 *)This, Stage, TexStageStateType, State);
5053 /*****************************************************************************
5054 * IDirect3DDevice7::ValidateDevice
5056 * SDK: "Reports the device's ability to render the currently set
5057 * texture-blending operations in a single pass". Whatever that means
5063 * NumPasses: Address to write the number of necessary passes for the
5064 * desired effect to.
5068 * See IWineD3DDevice::ValidateDevice for more details
5070 *****************************************************************************/
5072 IDirect3DDeviceImpl_7_ValidateDevice(IDirect3DDevice7 *iface,
5075 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5077 TRACE("(%p)->(%p): Relay\n", This, NumPasses);
5079 EnterCriticalSection(&ddraw_cs);
5080 hr = IWineD3DDevice_ValidateDevice(This->wineD3DDevice, NumPasses);
5081 LeaveCriticalSection(&ddraw_cs);
5085 static HRESULT WINAPI
5086 IDirect3DDeviceImpl_7_ValidateDevice_FPUSetup(IDirect3DDevice7 *iface,
5089 return IDirect3DDeviceImpl_7_ValidateDevice(iface, NumPasses);
5092 static HRESULT WINAPI
5093 IDirect3DDeviceImpl_7_ValidateDevice_FPUPreserve(IDirect3DDevice7 *iface,
5099 old_fpucw = d3d_fpu_setup();
5100 hr = IDirect3DDeviceImpl_7_ValidateDevice(iface, NumPasses);
5101 set_fpu_control_word(old_fpucw);
5106 static HRESULT WINAPI
5107 Thunk_IDirect3DDeviceImpl_3_ValidateDevice(IDirect3DDevice3 *iface,
5110 IDirect3DDeviceImpl *This = device_from_device3(iface);
5111 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, Passes);
5112 return IDirect3DDevice7_ValidateDevice((IDirect3DDevice7 *)This, Passes);
5115 /*****************************************************************************
5116 * IDirect3DDevice7::Clear
5118 * Fills the render target, the z buffer and the stencil buffer with a
5119 * clear color / value
5124 * Count: Number of rectangles in Rects must be 0 if Rects is NULL
5125 * Rects: Rectangles to clear. If NULL, the whole surface is cleared
5126 * Flags: Some flags, as usual
5127 * Color: Clear color for the render target
5128 * Z: Clear value for the Z buffer
5129 * Stencil: Clear value to store in each stencil buffer entry
5133 * For details, see IWineD3DDevice::Clear
5135 *****************************************************************************/
5137 IDirect3DDeviceImpl_7_Clear(IDirect3DDevice7 *iface,
5145 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5147 TRACE("(%p)->(%08x,%p,%08x,%08x,%f,%08x): Relay\n", This, Count, Rects, Flags, Color, Z, Stencil);
5149 /* Note; D3DRECT is compatible with WINED3DRECT */
5150 EnterCriticalSection(&ddraw_cs);
5151 hr = IWineD3DDevice_Clear(This->wineD3DDevice, Count, (WINED3DRECT*) Rects, Flags, Color, Z, Stencil);
5152 LeaveCriticalSection(&ddraw_cs);
5156 static HRESULT WINAPI
5157 IDirect3DDeviceImpl_7_Clear_FPUSetup(IDirect3DDevice7 *iface,
5165 return IDirect3DDeviceImpl_7_Clear(iface, Count, Rects, Flags, Color, Z, Stencil);
5168 static HRESULT WINAPI
5169 IDirect3DDeviceImpl_7_Clear_FPUPreserve(IDirect3DDevice7 *iface,
5180 old_fpucw = d3d_fpu_setup();
5181 hr = IDirect3DDeviceImpl_7_Clear(iface, Count, Rects, Flags, Color, Z, Stencil);
5182 set_fpu_control_word(old_fpucw);
5187 /*****************************************************************************
5188 * IDirect3DDevice7::SetViewport
5190 * Sets the current viewport.
5192 * Version 7 only, but IDirect3DViewport uses this call for older
5196 * Data: The new viewport to set
5200 * DDERR_INVALIDPARAMS if Data is NULL
5201 * For more details, see IWineDDDevice::SetViewport
5203 *****************************************************************************/
5205 IDirect3DDeviceImpl_7_SetViewport(IDirect3DDevice7 *iface,
5208 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5210 TRACE("(%p)->(%p) Relay!\n", This, Data);
5213 return DDERR_INVALIDPARAMS;
5215 /* Note: D3DVIEWPORT7 is compatible with WINED3DVIEWPORT */
5216 EnterCriticalSection(&ddraw_cs);
5217 hr = IWineD3DDevice_SetViewport(This->wineD3DDevice,
5218 (WINED3DVIEWPORT*) Data);
5219 LeaveCriticalSection(&ddraw_cs);
5223 static HRESULT WINAPI
5224 IDirect3DDeviceImpl_7_SetViewport_FPUSetup(IDirect3DDevice7 *iface,
5227 return IDirect3DDeviceImpl_7_SetViewport(iface, Data);
5230 static HRESULT WINAPI
5231 IDirect3DDeviceImpl_7_SetViewport_FPUPreserve(IDirect3DDevice7 *iface,
5237 old_fpucw = d3d_fpu_setup();
5238 hr = IDirect3DDeviceImpl_7_SetViewport(iface, Data);
5239 set_fpu_control_word(old_fpucw);
5244 /*****************************************************************************
5245 * IDirect3DDevice::GetViewport
5247 * Returns the current viewport
5252 * Data: D3D7Viewport structure to write the viewport information to
5256 * DDERR_INVALIDPARAMS if Data is NULL
5257 * For more details, see IWineD3DDevice::GetViewport
5259 *****************************************************************************/
5261 IDirect3DDeviceImpl_7_GetViewport(IDirect3DDevice7 *iface,
5264 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5266 TRACE("(%p)->(%p) Relay!\n", This, Data);
5269 return DDERR_INVALIDPARAMS;
5271 /* Note: D3DVIEWPORT7 is compatible with WINED3DVIEWPORT */
5272 EnterCriticalSection(&ddraw_cs);
5273 hr = IWineD3DDevice_GetViewport(This->wineD3DDevice,
5274 (WINED3DVIEWPORT*) Data);
5276 LeaveCriticalSection(&ddraw_cs);
5277 return hr_ddraw_from_wined3d(hr);
5280 static HRESULT WINAPI
5281 IDirect3DDeviceImpl_7_GetViewport_FPUSetup(IDirect3DDevice7 *iface,
5284 return IDirect3DDeviceImpl_7_GetViewport(iface, Data);
5287 static HRESULT WINAPI
5288 IDirect3DDeviceImpl_7_GetViewport_FPUPreserve(IDirect3DDevice7 *iface,
5294 old_fpucw = d3d_fpu_setup();
5295 hr = IDirect3DDeviceImpl_7_GetViewport(iface, Data);
5296 set_fpu_control_word(old_fpucw);
5301 /*****************************************************************************
5302 * IDirect3DDevice7::SetMaterial
5309 * Mat: The material to set
5313 * DDERR_INVALIDPARAMS if Mat is NULL.
5314 * For more details, see IWineD3DDevice::SetMaterial
5316 *****************************************************************************/
5318 IDirect3DDeviceImpl_7_SetMaterial(IDirect3DDevice7 *iface,
5321 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5323 TRACE("(%p)->(%p): Relay!\n", This, Mat);
5325 if (!Mat) return DDERR_INVALIDPARAMS;
5326 /* Note: D3DMATERIAL7 is compatible with WINED3DMATERIAL */
5327 EnterCriticalSection(&ddraw_cs);
5328 hr = IWineD3DDevice_SetMaterial(This->wineD3DDevice,
5329 (WINED3DMATERIAL*) Mat);
5330 LeaveCriticalSection(&ddraw_cs);
5331 return hr_ddraw_from_wined3d(hr);
5334 static HRESULT WINAPI
5335 IDirect3DDeviceImpl_7_SetMaterial_FPUSetup(IDirect3DDevice7 *iface,
5338 return IDirect3DDeviceImpl_7_SetMaterial(iface, Mat);
5341 static HRESULT WINAPI
5342 IDirect3DDeviceImpl_7_SetMaterial_FPUPreserve(IDirect3DDevice7 *iface,
5348 old_fpucw = d3d_fpu_setup();
5349 hr = IDirect3DDeviceImpl_7_SetMaterial(iface, Mat);
5350 set_fpu_control_word(old_fpucw);
5355 /*****************************************************************************
5356 * IDirect3DDevice7::GetMaterial
5358 * Returns the current material
5363 * Mat: D3DMATERIAL7 structure to write the material parameters to
5367 * DDERR_INVALIDPARAMS if Mat is NULL
5368 * For more details, see IWineD3DDevice::GetMaterial
5370 *****************************************************************************/
5372 IDirect3DDeviceImpl_7_GetMaterial(IDirect3DDevice7 *iface,
5375 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5377 TRACE("(%p)->(%p): Relay!\n", This, Mat);
5379 EnterCriticalSection(&ddraw_cs);
5380 /* Note: D3DMATERIAL7 is compatible with WINED3DMATERIAL */
5381 hr = IWineD3DDevice_GetMaterial(This->wineD3DDevice,
5382 (WINED3DMATERIAL*) Mat);
5383 LeaveCriticalSection(&ddraw_cs);
5384 return hr_ddraw_from_wined3d(hr);
5387 static HRESULT WINAPI
5388 IDirect3DDeviceImpl_7_GetMaterial_FPUSetup(IDirect3DDevice7 *iface,
5391 return IDirect3DDeviceImpl_7_GetMaterial(iface, Mat);
5394 static HRESULT WINAPI
5395 IDirect3DDeviceImpl_7_GetMaterial_FPUPreserve(IDirect3DDevice7 *iface,
5401 old_fpucw = d3d_fpu_setup();
5402 hr = IDirect3DDeviceImpl_7_GetMaterial(iface, Mat);
5403 set_fpu_control_word(old_fpucw);
5408 /*****************************************************************************
5409 * IDirect3DDevice7::SetLight
5411 * Assigns a light to a light index, but doesn't activate it yet.
5413 * Version 7, IDirect3DLight uses this method for older versions
5416 * LightIndex: The index of the new light
5417 * Light: A D3DLIGHT7 structure describing the light
5421 * For more details, see IWineD3DDevice::SetLight
5423 *****************************************************************************/
5425 IDirect3DDeviceImpl_7_SetLight(IDirect3DDevice7 *iface,
5429 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5431 TRACE("(%p)->(%08x,%p): Relay!\n", This, LightIndex, Light);
5433 EnterCriticalSection(&ddraw_cs);
5434 /* Note: D3DLIGHT7 is compatible with WINED3DLIGHT */
5435 hr = IWineD3DDevice_SetLight(This->wineD3DDevice,
5437 (WINED3DLIGHT*) Light);
5438 LeaveCriticalSection(&ddraw_cs);
5439 return hr_ddraw_from_wined3d(hr);
5442 static HRESULT WINAPI
5443 IDirect3DDeviceImpl_7_SetLight_FPUSetup(IDirect3DDevice7 *iface,
5447 return IDirect3DDeviceImpl_7_SetLight(iface, LightIndex, Light);
5450 static HRESULT WINAPI
5451 IDirect3DDeviceImpl_7_SetLight_FPUPreserve(IDirect3DDevice7 *iface,
5458 old_fpucw = d3d_fpu_setup();
5459 hr = IDirect3DDeviceImpl_7_SetLight(iface, LightIndex, Light);
5460 set_fpu_control_word(old_fpucw);
5465 /*****************************************************************************
5466 * IDirect3DDevice7::GetLight
5468 * Returns the light assigned to a light index
5471 * Light: Structure to write the light information to
5475 * DDERR_INVALIDPARAMS if Light is NULL
5476 * For details, see IWineD3DDevice::GetLight
5478 *****************************************************************************/
5480 IDirect3DDeviceImpl_7_GetLight(IDirect3DDevice7 *iface,
5484 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5486 TRACE("(%p)->(%08x,%p): Relay!\n", This, LightIndex, Light);
5488 EnterCriticalSection(&ddraw_cs);
5489 /* Note: D3DLIGHT7 is compatible with WINED3DLIGHT */
5490 rc = IWineD3DDevice_GetLight(This->wineD3DDevice,
5492 (WINED3DLIGHT*) Light);
5494 /* Translate the result. WineD3D returns other values than D3D7 */
5495 LeaveCriticalSection(&ddraw_cs);
5496 return hr_ddraw_from_wined3d(rc);
5499 static HRESULT WINAPI
5500 IDirect3DDeviceImpl_7_GetLight_FPUSetup(IDirect3DDevice7 *iface,
5504 return IDirect3DDeviceImpl_7_GetLight(iface, LightIndex, Light);
5507 static HRESULT WINAPI
5508 IDirect3DDeviceImpl_7_GetLight_FPUPreserve(IDirect3DDevice7 *iface,
5515 old_fpucw = d3d_fpu_setup();
5516 hr = IDirect3DDeviceImpl_7_GetLight(iface, LightIndex, Light);
5517 set_fpu_control_word(old_fpucw);
5522 /*****************************************************************************
5523 * IDirect3DDevice7::BeginStateBlock
5525 * Begins recording to a stateblock
5531 * For details see IWineD3DDevice::BeginStateBlock
5533 *****************************************************************************/
5535 IDirect3DDeviceImpl_7_BeginStateBlock(IDirect3DDevice7 *iface)
5537 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5539 TRACE("(%p)->(): Relay!\n", This);
5541 EnterCriticalSection(&ddraw_cs);
5542 hr = IWineD3DDevice_BeginStateBlock(This->wineD3DDevice);
5543 LeaveCriticalSection(&ddraw_cs);
5544 return hr_ddraw_from_wined3d(hr);
5547 static HRESULT WINAPI
5548 IDirect3DDeviceImpl_7_BeginStateBlock_FPUSetup(IDirect3DDevice7 *iface)
5550 return IDirect3DDeviceImpl_7_BeginStateBlock(iface);
5553 static HRESULT WINAPI
5554 IDirect3DDeviceImpl_7_BeginStateBlock_FPUPreserve(IDirect3DDevice7 *iface)
5559 old_fpucw = d3d_fpu_setup();
5560 hr = IDirect3DDeviceImpl_7_BeginStateBlock(iface);
5561 set_fpu_control_word(old_fpucw);
5566 /*****************************************************************************
5567 * IDirect3DDevice7::EndStateBlock
5569 * Stops recording to a state block and returns the created stateblock
5575 * BlockHandle: Address to store the stateblock's handle to
5579 * DDERR_INVALIDPARAMS if BlockHandle is NULL
5580 * See IWineD3DDevice::EndStateBlock for more details
5582 *****************************************************************************/
5584 IDirect3DDeviceImpl_7_EndStateBlock(IDirect3DDevice7 *iface,
5587 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5588 IWineD3DStateBlock *wined3d_sb;
5592 TRACE("(%p)->(%p): Relay!\n", This, BlockHandle);
5596 WARN("BlockHandle == NULL, returning DDERR_INVALIDPARAMS\n");
5597 return DDERR_INVALIDPARAMS;
5600 EnterCriticalSection(&ddraw_cs);
5602 hr = IWineD3DDevice_EndStateBlock(This->wineD3DDevice, &wined3d_sb);
5605 WARN("Failed to end stateblock, hr %#x.\n", hr);
5606 LeaveCriticalSection(&ddraw_cs);
5608 return hr_ddraw_from_wined3d(hr);
5611 h = ddraw_allocate_handle(&This->handle_table, wined3d_sb, DDRAW_HANDLE_STATEBLOCK);
5612 if (h == DDRAW_INVALID_HANDLE)
5614 ERR("Failed to allocate a stateblock handle.\n");
5615 IWineD3DStateBlock_Release(wined3d_sb);
5616 LeaveCriticalSection(&ddraw_cs);
5618 return DDERR_OUTOFMEMORY;
5621 LeaveCriticalSection(&ddraw_cs);
5622 *BlockHandle = h + 1;
5624 return hr_ddraw_from_wined3d(hr);
5627 static HRESULT WINAPI
5628 IDirect3DDeviceImpl_7_EndStateBlock_FPUSetup(IDirect3DDevice7 *iface,
5631 return IDirect3DDeviceImpl_7_EndStateBlock(iface, BlockHandle);
5634 static HRESULT WINAPI
5635 IDirect3DDeviceImpl_7_EndStateBlock_FPUPreserve(IDirect3DDevice7 *iface,
5641 old_fpucw = d3d_fpu_setup();
5642 hr = IDirect3DDeviceImpl_7_EndStateBlock(iface, BlockHandle);
5643 set_fpu_control_word(old_fpucw);
5648 /*****************************************************************************
5649 * IDirect3DDevice7::PreLoad
5651 * Allows the app to signal that a texture will be used soon, to allow
5652 * the Direct3DDevice to load it to the video card in the meantime.
5657 * Texture: The texture to preload
5661 * DDERR_INVALIDPARAMS if Texture is NULL
5662 * See IWineD3DSurface::PreLoad for details
5664 *****************************************************************************/
5666 IDirect3DDeviceImpl_7_PreLoad(IDirect3DDevice7 *iface,
5667 IDirectDrawSurface7 *Texture)
5669 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5670 IDirectDrawSurfaceImpl *surf = (IDirectDrawSurfaceImpl *)Texture;
5672 TRACE("(%p)->(%p): Relay!\n", This, surf);
5675 return DDERR_INVALIDPARAMS;
5677 EnterCriticalSection(&ddraw_cs);
5678 IWineD3DSurface_PreLoad(surf->WineD3DSurface);
5679 LeaveCriticalSection(&ddraw_cs);
5683 static HRESULT WINAPI
5684 IDirect3DDeviceImpl_7_PreLoad_FPUSetup(IDirect3DDevice7 *iface,
5685 IDirectDrawSurface7 *Texture)
5687 return IDirect3DDeviceImpl_7_PreLoad(iface, Texture);
5690 static HRESULT WINAPI
5691 IDirect3DDeviceImpl_7_PreLoad_FPUPreserve(IDirect3DDevice7 *iface,
5692 IDirectDrawSurface7 *Texture)
5697 old_fpucw = d3d_fpu_setup();
5698 hr = IDirect3DDeviceImpl_7_PreLoad(iface, Texture);
5699 set_fpu_control_word(old_fpucw);
5704 /*****************************************************************************
5705 * IDirect3DDevice7::ApplyStateBlock
5707 * Activates the state stored in a state block handle.
5710 * BlockHandle: The stateblock handle to activate
5714 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is NULL
5716 *****************************************************************************/
5718 IDirect3DDeviceImpl_7_ApplyStateBlock(IDirect3DDevice7 *iface,
5721 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5722 IWineD3DStateBlock *wined3d_sb;
5724 TRACE("(%p)->(%08x): Relay!\n", This, BlockHandle);
5726 EnterCriticalSection(&ddraw_cs);
5728 wined3d_sb = ddraw_get_object(&This->handle_table, BlockHandle - 1, DDRAW_HANDLE_STATEBLOCK);
5731 WARN("Invalid stateblock handle.\n");
5732 LeaveCriticalSection(&ddraw_cs);
5733 return D3DERR_INVALIDSTATEBLOCK;
5736 hr = IWineD3DStateBlock_Apply(wined3d_sb);
5737 LeaveCriticalSection(&ddraw_cs);
5739 return hr_ddraw_from_wined3d(hr);
5742 static HRESULT WINAPI
5743 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUSetup(IDirect3DDevice7 *iface,
5746 return IDirect3DDeviceImpl_7_ApplyStateBlock(iface, BlockHandle);
5749 static HRESULT WINAPI
5750 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUPreserve(IDirect3DDevice7 *iface,
5756 old_fpucw = d3d_fpu_setup();
5757 hr = IDirect3DDeviceImpl_7_ApplyStateBlock(iface, BlockHandle);
5758 set_fpu_control_word(old_fpucw);
5763 /*****************************************************************************
5764 * IDirect3DDevice7::CaptureStateBlock
5766 * Updates a stateblock's values to the values currently set for the device
5771 * BlockHandle: Stateblock to update
5775 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is NULL
5776 * See IWineD3DDevice::CaptureStateBlock for more details
5778 *****************************************************************************/
5780 IDirect3DDeviceImpl_7_CaptureStateBlock(IDirect3DDevice7 *iface,
5783 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5784 IWineD3DStateBlock *wined3d_sb;
5786 TRACE("(%p)->(%08x): Relay!\n", This, BlockHandle);
5788 EnterCriticalSection(&ddraw_cs);
5790 wined3d_sb = ddraw_get_object(&This->handle_table, BlockHandle - 1, DDRAW_HANDLE_STATEBLOCK);
5793 WARN("Invalid stateblock handle.\n");
5794 LeaveCriticalSection(&ddraw_cs);
5795 return D3DERR_INVALIDSTATEBLOCK;
5798 hr = IWineD3DStateBlock_Capture(wined3d_sb);
5799 LeaveCriticalSection(&ddraw_cs);
5800 return hr_ddraw_from_wined3d(hr);
5803 static HRESULT WINAPI
5804 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUSetup(IDirect3DDevice7 *iface,
5807 return IDirect3DDeviceImpl_7_CaptureStateBlock(iface, BlockHandle);
5810 static HRESULT WINAPI
5811 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUPreserve(IDirect3DDevice7 *iface,
5817 old_fpucw = d3d_fpu_setup();
5818 hr = IDirect3DDeviceImpl_7_CaptureStateBlock(iface, BlockHandle);
5819 set_fpu_control_word(old_fpucw);
5824 /*****************************************************************************
5825 * IDirect3DDevice7::DeleteStateBlock
5827 * Deletes a stateblock handle. This means releasing the WineD3DStateBlock
5832 * BlockHandle: Stateblock handle to delete
5836 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is 0
5838 *****************************************************************************/
5840 IDirect3DDeviceImpl_7_DeleteStateBlock(IDirect3DDevice7 *iface,
5843 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5844 IWineD3DStateBlock *wined3d_sb;
5846 TRACE("(%p)->(%08x): Relay!\n", This, BlockHandle);
5848 EnterCriticalSection(&ddraw_cs);
5850 wined3d_sb = ddraw_free_handle(&This->handle_table, BlockHandle - 1, DDRAW_HANDLE_STATEBLOCK);
5853 WARN("Invalid stateblock handle.\n");
5854 LeaveCriticalSection(&ddraw_cs);
5855 return D3DERR_INVALIDSTATEBLOCK;
5858 if ((ref = IWineD3DStateBlock_Release(wined3d_sb)))
5860 ERR("Something is still holding stateblock %p (refcount %u).\n", wined3d_sb, ref);
5863 LeaveCriticalSection(&ddraw_cs);
5867 static HRESULT WINAPI
5868 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUSetup(IDirect3DDevice7 *iface,
5871 return IDirect3DDeviceImpl_7_DeleteStateBlock(iface, BlockHandle);
5874 static HRESULT WINAPI
5875 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUPreserve(IDirect3DDevice7 *iface,
5881 old_fpucw = d3d_fpu_setup();
5882 hr = IDirect3DDeviceImpl_7_DeleteStateBlock(iface, BlockHandle);
5883 set_fpu_control_word(old_fpucw);
5888 /*****************************************************************************
5889 * IDirect3DDevice7::CreateStateBlock
5891 * Creates a new state block handle.
5896 * Type: The state block type
5897 * BlockHandle: Address to write the created handle to
5901 * DDERR_INVALIDPARAMS if BlockHandle is NULL
5903 *****************************************************************************/
5905 IDirect3DDeviceImpl_7_CreateStateBlock(IDirect3DDevice7 *iface,
5906 D3DSTATEBLOCKTYPE Type,
5909 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5910 IWineD3DStateBlock *wined3d_sb;
5914 TRACE("(%p)->(%08x,%p)!\n", This, Type, BlockHandle);
5918 WARN("BlockHandle == NULL, returning DDERR_INVALIDPARAMS\n");
5919 return DDERR_INVALIDPARAMS;
5921 if(Type != D3DSBT_ALL && Type != D3DSBT_PIXELSTATE &&
5922 Type != D3DSBT_VERTEXSTATE ) {
5923 WARN("Unexpected stateblock type, returning DDERR_INVALIDPARAMS\n");
5924 return DDERR_INVALIDPARAMS;
5927 EnterCriticalSection(&ddraw_cs);
5929 /* The D3DSTATEBLOCKTYPE enum is fine here. */
5930 hr = IWineD3DDevice_CreateStateBlock(This->wineD3DDevice, Type, &wined3d_sb);
5933 WARN("Failed to create stateblock, hr %#x.\n", hr);
5934 LeaveCriticalSection(&ddraw_cs);
5935 return hr_ddraw_from_wined3d(hr);
5938 h = ddraw_allocate_handle(&This->handle_table, wined3d_sb, DDRAW_HANDLE_STATEBLOCK);
5939 if (h == DDRAW_INVALID_HANDLE)
5941 ERR("Failed to allocate stateblock handle.\n");
5942 IWineD3DStateBlock_Release(wined3d_sb);
5943 LeaveCriticalSection(&ddraw_cs);
5944 return DDERR_OUTOFMEMORY;
5947 *BlockHandle = h + 1;
5948 LeaveCriticalSection(&ddraw_cs);
5950 return hr_ddraw_from_wined3d(hr);
5953 static HRESULT WINAPI
5954 IDirect3DDeviceImpl_7_CreateStateBlock_FPUSetup(IDirect3DDevice7 *iface,
5955 D3DSTATEBLOCKTYPE Type,
5958 return IDirect3DDeviceImpl_7_CreateStateBlock(iface, Type, BlockHandle);
5961 static HRESULT WINAPI
5962 IDirect3DDeviceImpl_7_CreateStateBlock_FPUPreserve(IDirect3DDevice7 *iface,
5963 D3DSTATEBLOCKTYPE Type,
5969 old_fpucw = d3d_fpu_setup();
5970 hr =IDirect3DDeviceImpl_7_CreateStateBlock(iface, Type, BlockHandle);
5971 set_fpu_control_word(old_fpucw);
5976 /* Helper function for IDirect3DDeviceImpl_7_Load. */
5977 static BOOL is_mip_level_subset(IDirectDrawSurfaceImpl *dest,
5978 IDirectDrawSurfaceImpl *src)
5980 IDirectDrawSurfaceImpl *src_level, *dest_level;
5981 IDirectDrawSurface7 *temp;
5982 DDSURFACEDESC2 ddsd;
5983 BOOL levelFound; /* at least one suitable sublevel in dest found */
5985 /* To satisfy "destination is mip level subset of source" criteria (regular texture counts as 1 level),
5986 * 1) there must be at least one mip level in destination that matched dimensions of some mip level in source and
5987 * 2) there must be no destination levels that don't match any levels in source. Otherwise it's INVALIDPARAMS.
5994 for (;src_level && dest_level;)
5996 if (src_level->surface_desc.dwWidth == dest_level->surface_desc.dwWidth &&
5997 src_level->surface_desc.dwHeight == dest_level->surface_desc.dwHeight)
6001 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
6002 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_MIPMAPSUBLEVEL;
6003 IDirectDrawSurface7_GetAttachedSurface((IDirectDrawSurface7 *)dest_level, &ddsd.ddsCaps, &temp);
6005 if (dest_level != dest) IDirectDrawSurface7_Release((IDirectDrawSurface7 *)dest_level);
6007 dest_level = (IDirectDrawSurfaceImpl *)temp;
6010 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
6011 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_MIPMAPSUBLEVEL;
6012 IDirectDrawSurface7_GetAttachedSurface((IDirectDrawSurface7 *)src_level, &ddsd.ddsCaps, &temp);
6014 if (src_level != src) IDirectDrawSurface7_Release((IDirectDrawSurface7 *)src_level);
6016 src_level = (IDirectDrawSurfaceImpl *)temp;
6019 if (src_level && src_level != src) IDirectDrawSurface7_Release((IDirectDrawSurface7 *)src_level);
6020 if (dest_level && dest_level != dest) IDirectDrawSurface7_Release((IDirectDrawSurface7 *)dest_level);
6022 return !dest_level && levelFound;
6025 /* Helper function for IDirect3DDeviceImpl_7_Load. */
6026 static void copy_mipmap_chain(IDirect3DDeviceImpl *device,
6027 IDirectDrawSurfaceImpl *dest,
6028 IDirectDrawSurfaceImpl *src,
6029 const POINT *DestPoint,
6030 const RECT *SrcRect)
6032 IDirectDrawSurfaceImpl *src_level, *dest_level;
6033 IDirectDrawSurface7 *temp;
6034 DDSURFACEDESC2 ddsd;
6038 IDirectDrawPalette *pal = NULL, *pal_src = NULL;
6041 BOOL palette_missing = FALSE;
6043 /* Copy palette, if possible. */
6044 IDirectDrawSurface7_GetPalette((IDirectDrawSurface7 *)src, &pal_src);
6045 IDirectDrawSurface7_GetPalette((IDirectDrawSurface7 *)dest, &pal);
6047 if (pal_src != NULL && pal != NULL)
6049 PALETTEENTRY palent[256];
6051 IDirectDrawPalette_GetEntries(pal_src, 0, 0, 256, palent);
6052 IDirectDrawPalette_SetEntries(pal, 0, 0, 256, palent);
6055 if (dest->surface_desc.u4.ddpfPixelFormat.dwFlags & (DDPF_PALETTEINDEXED1 | DDPF_PALETTEINDEXED2 |
6056 DDPF_PALETTEINDEXED4 | DDPF_PALETTEINDEXED8 | DDPF_PALETTEINDEXEDTO8) && !pal)
6058 palette_missing = TRUE;
6061 if (pal) IDirectDrawPalette_Release(pal);
6062 if (pal_src) IDirectDrawPalette_Release(pal_src);
6064 /* Copy colorkeys, if present. */
6065 for (ckeyflag = DDCKEY_DESTBLT; ckeyflag <= DDCKEY_SRCOVERLAY; ckeyflag <<= 1)
6067 hr = IDirectDrawSurface7_GetColorKey((IDirectDrawSurface7 *)src, ckeyflag, &ddckey);
6071 IDirectDrawSurface7_SetColorKey((IDirectDrawSurface7 *)dest, ckeyflag, &ddckey);
6081 for (;src_level && dest_level;)
6083 if (src_level->surface_desc.dwWidth == dest_level->surface_desc.dwWidth &&
6084 src_level->surface_desc.dwHeight == dest_level->surface_desc.dwHeight)
6086 /* Try UpdateSurface that may perform a more direct opengl loading. But skip this if destination is paletted texture and has no palette.
6087 * Some games like Sacrifice set palette after Load, and it is a waste of effort to try to load texture without palette and generates
6088 * warnings in wined3d. */
6089 if (!palette_missing)
6090 hr = IWineD3DDevice_UpdateSurface(device->wineD3DDevice, src_level->WineD3DSurface, &rect, dest_level->WineD3DSurface,
6093 if (palette_missing || FAILED(hr))
6095 /* UpdateSurface may fail e.g. if dest is in system memory. Fall back to BltFast that is less strict. */
6096 IWineD3DSurface_BltFast(dest_level->WineD3DSurface,
6098 src_level->WineD3DSurface, &rect, 0);
6101 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
6102 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_MIPMAPSUBLEVEL;
6103 IDirectDrawSurface7_GetAttachedSurface((IDirectDrawSurface7 *)dest_level, &ddsd.ddsCaps, &temp);
6105 if (dest_level != dest) IDirectDrawSurface7_Release((IDirectDrawSurface7 *)dest_level);
6107 dest_level = (IDirectDrawSurfaceImpl *)temp;
6110 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
6111 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_MIPMAPSUBLEVEL;
6112 IDirectDrawSurface7_GetAttachedSurface((IDirectDrawSurface7 *)src_level, &ddsd.ddsCaps, &temp);
6114 if (src_level != src) IDirectDrawSurface7_Release((IDirectDrawSurface7 *)src_level);
6116 src_level = (IDirectDrawSurfaceImpl *)temp;
6123 rect.right = (rect.right + 1) / 2;
6124 rect.bottom = (rect.bottom + 1) / 2;
6127 if (src_level && src_level != src) IDirectDrawSurface7_Release((IDirectDrawSurface7 *)src_level);
6128 if (dest_level && dest_level != dest) IDirectDrawSurface7_Release((IDirectDrawSurface7 *)dest_level);
6131 /*****************************************************************************
6132 * IDirect3DDevice7::Load
6134 * Loads a rectangular area from the source into the destination texture.
6135 * It can also copy the source to the faces of a cubic environment map
6140 * DestTex: Destination texture
6141 * DestPoint: Point in the destination where the source image should be
6143 * SrcTex: Source texture
6144 * SrcRect: Source rectangle
6145 * Flags: Cubemap faces to load (DDSCAPS2_CUBEMAP_ALLFACES, DDSCAPS2_CUBEMAP_POSITIVEX,
6146 * DDSCAPS2_CUBEMAP_NEGATIVEX, DDSCAPS2_CUBEMAP_POSITIVEY, DDSCAPS2_CUBEMAP_NEGATIVEY,
6147 * DDSCAPS2_CUBEMAP_POSITIVEZ, DDSCAPS2_CUBEMAP_NEGATIVEZ)
6151 * DDERR_INVALIDPARAMS if DestTex or SrcTex are NULL, broken coordinates or anything unexpected.
6154 *****************************************************************************/
6157 IDirect3DDeviceImpl_7_Load(IDirect3DDevice7 *iface,
6158 IDirectDrawSurface7 *DestTex,
6160 IDirectDrawSurface7 *SrcTex,
6164 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
6165 IDirectDrawSurfaceImpl *dest = (IDirectDrawSurfaceImpl *)DestTex;
6166 IDirectDrawSurfaceImpl *src = (IDirectDrawSurfaceImpl *)SrcTex;
6169 TRACE("(%p)->(%p,%p,%p,%p,%08x)\n", This, dest, DestPoint, src, SrcRect, Flags);
6171 if( (!src) || (!dest) )
6172 return DDERR_INVALIDPARAMS;
6174 EnterCriticalSection(&ddraw_cs);
6176 if (SrcRect) srcrect = *SrcRect;
6179 srcrect.left = srcrect.top = 0;
6180 srcrect.right = src->surface_desc.dwWidth;
6181 srcrect.bottom = src->surface_desc.dwHeight;
6184 if (DestPoint) destpoint = *DestPoint;
6187 destpoint.x = destpoint.y = 0;
6189 /* Check bad dimensions. DestPoint is validated against src, not dest, because
6190 * destination can be a subset of mip levels, in which case actual coordinates used
6191 * for it may be divided. If any dimension of dest is larger than source, it can't be
6192 * mip level subset, so an error can be returned early.
6194 if (srcrect.left >= srcrect.right || srcrect.top >= srcrect.bottom ||
6195 srcrect.right > src->surface_desc.dwWidth ||
6196 srcrect.bottom > src->surface_desc.dwHeight ||
6197 destpoint.x + srcrect.right - srcrect.left > src->surface_desc.dwWidth ||
6198 destpoint.y + srcrect.bottom - srcrect.top > src->surface_desc.dwHeight ||
6199 dest->surface_desc.dwWidth > src->surface_desc.dwWidth ||
6200 dest->surface_desc.dwHeight > src->surface_desc.dwHeight)
6202 LeaveCriticalSection(&ddraw_cs);
6203 return DDERR_INVALIDPARAMS;
6206 /* Must be top level surfaces. */
6207 if (src->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_MIPMAPSUBLEVEL ||
6208 dest->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_MIPMAPSUBLEVEL)
6210 LeaveCriticalSection(&ddraw_cs);
6211 return DDERR_INVALIDPARAMS;
6214 if (src->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP)
6216 DWORD src_face_flag, dest_face_flag;
6217 IDirectDrawSurfaceImpl *src_face, *dest_face;
6218 IDirectDrawSurface7 *temp;
6219 DDSURFACEDESC2 ddsd;
6222 if (!(dest->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP))
6224 LeaveCriticalSection(&ddraw_cs);
6225 return DDERR_INVALIDPARAMS;
6228 /* Iterate through cube faces 2 times. First time is just to check INVALIDPARAMS conditions, second
6229 * time it's actual surface loading. */
6230 for (i = 0; i < 2; i++)
6235 for (;dest_face && src_face;)
6237 src_face_flag = src_face->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP_ALLFACES;
6238 dest_face_flag = dest_face->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP_ALLFACES;
6240 if (src_face_flag == dest_face_flag)
6244 /* Destination mip levels must be subset of source mip levels. */
6245 if (!is_mip_level_subset(dest_face, src_face))
6247 LeaveCriticalSection(&ddraw_cs);
6248 return DDERR_INVALIDPARAMS;
6251 else if (Flags & dest_face_flag)
6253 copy_mipmap_chain(This, dest_face, src_face, &destpoint, &srcrect);
6256 if (src_face_flag < DDSCAPS2_CUBEMAP_NEGATIVEZ)
6258 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
6259 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | (src_face_flag << 1);
6260 IDirectDrawSurface7_GetAttachedSurface((IDirectDrawSurface7 *)src, &ddsd.ddsCaps, &temp);
6262 if (src_face != src) IDirectDrawSurface7_Release((IDirectDrawSurface7 *)src_face);
6264 src_face = (IDirectDrawSurfaceImpl *)temp;
6268 if (src_face != src) IDirectDrawSurface7_Release((IDirectDrawSurface7 *)src_face);
6274 if (dest_face_flag < DDSCAPS2_CUBEMAP_NEGATIVEZ)
6276 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
6277 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | (dest_face_flag << 1);
6278 IDirectDrawSurface7_GetAttachedSurface((IDirectDrawSurface7 *)dest, &ddsd.ddsCaps, &temp);
6280 if (dest_face != dest) IDirectDrawSurface7_Release((IDirectDrawSurface7 *)dest_face);
6282 dest_face = (IDirectDrawSurfaceImpl *)temp;
6286 if (dest_face != dest) IDirectDrawSurface7_Release((IDirectDrawSurface7 *)dest_face);
6294 /* Native returns error if src faces are not subset of dest faces. */
6297 LeaveCriticalSection(&ddraw_cs);
6298 return DDERR_INVALIDPARAMS;
6303 LeaveCriticalSection(&ddraw_cs);
6306 else if (dest->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP)
6308 LeaveCriticalSection(&ddraw_cs);
6309 return DDERR_INVALIDPARAMS;
6312 /* Handle non cube map textures. */
6314 /* Destination mip levels must be subset of source mip levels. */
6315 if (!is_mip_level_subset(dest, src))
6317 LeaveCriticalSection(&ddraw_cs);
6318 return DDERR_INVALIDPARAMS;
6321 copy_mipmap_chain(This, dest, src, &destpoint, &srcrect);
6323 LeaveCriticalSection(&ddraw_cs);
6327 static HRESULT WINAPI
6328 IDirect3DDeviceImpl_7_Load_FPUSetup(IDirect3DDevice7 *iface,
6329 IDirectDrawSurface7 *DestTex,
6331 IDirectDrawSurface7 *SrcTex,
6335 return IDirect3DDeviceImpl_7_Load(iface, DestTex, DestPoint, SrcTex, SrcRect, Flags);
6338 static HRESULT WINAPI
6339 IDirect3DDeviceImpl_7_Load_FPUPreserve(IDirect3DDevice7 *iface,
6340 IDirectDrawSurface7 *DestTex,
6342 IDirectDrawSurface7 *SrcTex,
6349 old_fpucw = d3d_fpu_setup();
6350 hr = IDirect3DDeviceImpl_7_Load(iface, DestTex, DestPoint, SrcTex, SrcRect, Flags);
6351 set_fpu_control_word(old_fpucw);
6356 /*****************************************************************************
6357 * IDirect3DDevice7::LightEnable
6359 * Enables or disables a light
6361 * Version 7, IDirect3DLight uses this method too.
6364 * LightIndex: The index of the light to enable / disable
6365 * Enable: Enable or disable the light
6369 * For more details, see IWineD3DDevice::SetLightEnable
6371 *****************************************************************************/
6373 IDirect3DDeviceImpl_7_LightEnable(IDirect3DDevice7 *iface,
6377 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
6379 TRACE("(%p)->(%08x,%d): Relay!\n", This, LightIndex, Enable);
6381 EnterCriticalSection(&ddraw_cs);
6382 hr = IWineD3DDevice_SetLightEnable(This->wineD3DDevice, LightIndex, Enable);
6383 LeaveCriticalSection(&ddraw_cs);
6384 return hr_ddraw_from_wined3d(hr);
6387 static HRESULT WINAPI
6388 IDirect3DDeviceImpl_7_LightEnable_FPUSetup(IDirect3DDevice7 *iface,
6392 return IDirect3DDeviceImpl_7_LightEnable(iface, LightIndex, Enable);
6395 static HRESULT WINAPI
6396 IDirect3DDeviceImpl_7_LightEnable_FPUPreserve(IDirect3DDevice7 *iface,
6403 old_fpucw = d3d_fpu_setup();
6404 hr = IDirect3DDeviceImpl_7_LightEnable(iface, LightIndex, Enable);
6405 set_fpu_control_word(old_fpucw);
6410 /*****************************************************************************
6411 * IDirect3DDevice7::GetLightEnable
6413 * Retrieves if the light with the given index is enabled or not
6418 * LightIndex: Index of desired light
6419 * Enable: Pointer to a BOOL which contains the result
6423 * DDERR_INVALIDPARAMS if Enable is NULL
6424 * See IWineD3DDevice::GetLightEnable for more details
6426 *****************************************************************************/
6428 IDirect3DDeviceImpl_7_GetLightEnable(IDirect3DDevice7 *iface,
6432 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
6434 TRACE("(%p)->(%08x,%p): Relay\n", This, LightIndex, Enable);
6437 return DDERR_INVALIDPARAMS;
6439 EnterCriticalSection(&ddraw_cs);
6440 hr = IWineD3DDevice_GetLightEnable(This->wineD3DDevice, LightIndex, Enable);
6441 LeaveCriticalSection(&ddraw_cs);
6442 return hr_ddraw_from_wined3d(hr);
6445 static HRESULT WINAPI
6446 IDirect3DDeviceImpl_7_GetLightEnable_FPUSetup(IDirect3DDevice7 *iface,
6450 return IDirect3DDeviceImpl_7_GetLightEnable(iface, LightIndex, Enable);
6453 static HRESULT WINAPI
6454 IDirect3DDeviceImpl_7_GetLightEnable_FPUPreserve(IDirect3DDevice7 *iface,
6461 old_fpucw = d3d_fpu_setup();
6462 hr = IDirect3DDeviceImpl_7_GetLightEnable(iface, LightIndex, Enable);
6463 set_fpu_control_word(old_fpucw);
6468 /*****************************************************************************
6469 * IDirect3DDevice7::SetClipPlane
6471 * Sets custom clipping plane
6476 * Index: The index of the clipping plane
6477 * PlaneEquation: An equation defining the clipping plane
6481 * DDERR_INVALIDPARAMS if PlaneEquation is NULL
6482 * See IWineD3DDevice::SetClipPlane for more details
6484 *****************************************************************************/
6486 IDirect3DDeviceImpl_7_SetClipPlane(IDirect3DDevice7 *iface,
6488 D3DVALUE* PlaneEquation)
6490 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
6492 TRACE("(%p)->(%08x,%p): Relay!\n", This, Index, PlaneEquation);
6495 return DDERR_INVALIDPARAMS;
6497 EnterCriticalSection(&ddraw_cs);
6498 hr = IWineD3DDevice_SetClipPlane(This->wineD3DDevice, Index, PlaneEquation);
6499 LeaveCriticalSection(&ddraw_cs);
6503 static HRESULT WINAPI
6504 IDirect3DDeviceImpl_7_SetClipPlane_FPUSetup(IDirect3DDevice7 *iface,
6506 D3DVALUE* PlaneEquation)
6508 return IDirect3DDeviceImpl_7_SetClipPlane(iface, Index, PlaneEquation);
6511 static HRESULT WINAPI
6512 IDirect3DDeviceImpl_7_SetClipPlane_FPUPreserve(IDirect3DDevice7 *iface,
6514 D3DVALUE* PlaneEquation)
6519 old_fpucw = d3d_fpu_setup();
6520 hr = IDirect3DDeviceImpl_7_SetClipPlane(iface, Index, PlaneEquation);
6521 set_fpu_control_word(old_fpucw);
6526 /*****************************************************************************
6527 * IDirect3DDevice7::GetClipPlane
6529 * Returns the clipping plane with a specific index
6532 * Index: The index of the desired plane
6533 * PlaneEquation: Address to store the plane equation to
6537 * DDERR_INVALIDPARAMS if PlaneEquation is NULL
6538 * See IWineD3DDevice::GetClipPlane for more details
6540 *****************************************************************************/
6542 IDirect3DDeviceImpl_7_GetClipPlane(IDirect3DDevice7 *iface,
6544 D3DVALUE* PlaneEquation)
6546 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
6548 TRACE("(%p)->(%d,%p): Relay!\n", This, Index, PlaneEquation);
6551 return DDERR_INVALIDPARAMS;
6553 EnterCriticalSection(&ddraw_cs);
6554 hr = IWineD3DDevice_GetClipPlane(This->wineD3DDevice, Index, PlaneEquation);
6555 LeaveCriticalSection(&ddraw_cs);
6559 static HRESULT WINAPI
6560 IDirect3DDeviceImpl_7_GetClipPlane_FPUSetup(IDirect3DDevice7 *iface,
6562 D3DVALUE* PlaneEquation)
6564 return IDirect3DDeviceImpl_7_GetClipPlane(iface, Index, PlaneEquation);
6567 static HRESULT WINAPI
6568 IDirect3DDeviceImpl_7_GetClipPlane_FPUPreserve(IDirect3DDevice7 *iface,
6570 D3DVALUE* PlaneEquation)
6575 old_fpucw = d3d_fpu_setup();
6576 hr = IDirect3DDeviceImpl_7_GetClipPlane(iface, Index, PlaneEquation);
6577 set_fpu_control_word(old_fpucw);
6582 /*****************************************************************************
6583 * IDirect3DDevice7::GetInfo
6585 * Retrieves some information about the device. The DirectX sdk says that
6586 * this version returns S_FALSE for all retail builds of DirectX, that's what
6587 * this implementation does.
6590 * DevInfoID: Information type requested
6591 * DevInfoStruct: Pointer to a structure to store the info to
6592 * Size: Size of the structure
6595 * S_FALSE, because it's a non-debug driver
6597 *****************************************************************************/
6598 static HRESULT WINAPI
6599 IDirect3DDeviceImpl_7_GetInfo(IDirect3DDevice7 *iface,
6601 void *DevInfoStruct,
6604 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
6605 TRACE("(%p)->(%08x,%p,%08x)\n", This, DevInfoID, DevInfoStruct, Size);
6609 TRACE(" info requested : ");
6612 case D3DDEVINFOID_TEXTUREMANAGER: TRACE("D3DDEVINFOID_TEXTUREMANAGER\n"); break;
6613 case D3DDEVINFOID_D3DTEXTUREMANAGER: TRACE("D3DDEVINFOID_D3DTEXTUREMANAGER\n"); break;
6614 case D3DDEVINFOID_TEXTURING: TRACE("D3DDEVINFOID_TEXTURING\n"); break;
6615 default: ERR(" invalid flag !!!\n"); return DDERR_INVALIDPARAMS;
6619 return S_FALSE; /* According to MSDN, this is valid for a non-debug driver */
6622 /* For performance optimization, devices created in FPUSETUP and FPUPRESERVE modes
6623 * have separate vtables. Simple functions where this doesn't matter like GetDirect3D
6624 * are not duplicated.
6626 * Device created with DDSCL_FPUSETUP (d3d7 default) - device methods assume that FPU
6627 * has already been setup for optimal d3d operation.
6629 * Device created with DDSCL_FPUPRESERVE - resets and restores FPU mode when necessary in
6630 * d3d calls (FPU may be in a mode non-suitable for d3d when the app calls d3d). Required
6631 * by Sacrifice (game). */
6632 const IDirect3DDevice7Vtbl IDirect3DDevice7_FPUSetup_Vtbl =
6634 /*** IUnknown Methods ***/
6635 IDirect3DDeviceImpl_7_QueryInterface,
6636 IDirect3DDeviceImpl_7_AddRef,
6637 IDirect3DDeviceImpl_7_Release,
6638 /*** IDirect3DDevice7 ***/
6639 IDirect3DDeviceImpl_7_GetCaps_FPUSetup,
6640 IDirect3DDeviceImpl_7_EnumTextureFormats_FPUSetup,
6641 IDirect3DDeviceImpl_7_BeginScene_FPUSetup,
6642 IDirect3DDeviceImpl_7_EndScene_FPUSetup,
6643 IDirect3DDeviceImpl_7_GetDirect3D,
6644 IDirect3DDeviceImpl_7_SetRenderTarget_FPUSetup,
6645 IDirect3DDeviceImpl_7_GetRenderTarget,
6646 IDirect3DDeviceImpl_7_Clear_FPUSetup,
6647 IDirect3DDeviceImpl_7_SetTransform_FPUSetup,
6648 IDirect3DDeviceImpl_7_GetTransform_FPUSetup,
6649 IDirect3DDeviceImpl_7_SetViewport_FPUSetup,
6650 IDirect3DDeviceImpl_7_MultiplyTransform_FPUSetup,
6651 IDirect3DDeviceImpl_7_GetViewport_FPUSetup,
6652 IDirect3DDeviceImpl_7_SetMaterial_FPUSetup,
6653 IDirect3DDeviceImpl_7_GetMaterial_FPUSetup,
6654 IDirect3DDeviceImpl_7_SetLight_FPUSetup,
6655 IDirect3DDeviceImpl_7_GetLight_FPUSetup,
6656 IDirect3DDeviceImpl_7_SetRenderState_FPUSetup,
6657 IDirect3DDeviceImpl_7_GetRenderState_FPUSetup,
6658 IDirect3DDeviceImpl_7_BeginStateBlock_FPUSetup,
6659 IDirect3DDeviceImpl_7_EndStateBlock_FPUSetup,
6660 IDirect3DDeviceImpl_7_PreLoad_FPUSetup,
6661 IDirect3DDeviceImpl_7_DrawPrimitive_FPUSetup,
6662 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUSetup,
6663 IDirect3DDeviceImpl_7_SetClipStatus,
6664 IDirect3DDeviceImpl_7_GetClipStatus,
6665 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUSetup,
6666 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUSetup,
6667 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUSetup,
6668 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUSetup,
6669 IDirect3DDeviceImpl_7_ComputeSphereVisibility,
6670 IDirect3DDeviceImpl_7_GetTexture_FPUSetup,
6671 IDirect3DDeviceImpl_7_SetTexture_FPUSetup,
6672 IDirect3DDeviceImpl_7_GetTextureStageState_FPUSetup,
6673 IDirect3DDeviceImpl_7_SetTextureStageState_FPUSetup,
6674 IDirect3DDeviceImpl_7_ValidateDevice_FPUSetup,
6675 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUSetup,
6676 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUSetup,
6677 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUSetup,
6678 IDirect3DDeviceImpl_7_CreateStateBlock_FPUSetup,
6679 IDirect3DDeviceImpl_7_Load_FPUSetup,
6680 IDirect3DDeviceImpl_7_LightEnable_FPUSetup,
6681 IDirect3DDeviceImpl_7_GetLightEnable_FPUSetup,
6682 IDirect3DDeviceImpl_7_SetClipPlane_FPUSetup,
6683 IDirect3DDeviceImpl_7_GetClipPlane_FPUSetup,
6684 IDirect3DDeviceImpl_7_GetInfo
6687 const IDirect3DDevice7Vtbl IDirect3DDevice7_FPUPreserve_Vtbl =
6689 /*** IUnknown Methods ***/
6690 IDirect3DDeviceImpl_7_QueryInterface,
6691 IDirect3DDeviceImpl_7_AddRef,
6692 IDirect3DDeviceImpl_7_Release,
6693 /*** IDirect3DDevice7 ***/
6694 IDirect3DDeviceImpl_7_GetCaps_FPUPreserve,
6695 IDirect3DDeviceImpl_7_EnumTextureFormats_FPUPreserve,
6696 IDirect3DDeviceImpl_7_BeginScene_FPUPreserve,
6697 IDirect3DDeviceImpl_7_EndScene_FPUPreserve,
6698 IDirect3DDeviceImpl_7_GetDirect3D,
6699 IDirect3DDeviceImpl_7_SetRenderTarget_FPUPreserve,
6700 IDirect3DDeviceImpl_7_GetRenderTarget,
6701 IDirect3DDeviceImpl_7_Clear_FPUPreserve,
6702 IDirect3DDeviceImpl_7_SetTransform_FPUPreserve,
6703 IDirect3DDeviceImpl_7_GetTransform_FPUPreserve,
6704 IDirect3DDeviceImpl_7_SetViewport_FPUPreserve,
6705 IDirect3DDeviceImpl_7_MultiplyTransform_FPUPreserve,
6706 IDirect3DDeviceImpl_7_GetViewport_FPUPreserve,
6707 IDirect3DDeviceImpl_7_SetMaterial_FPUPreserve,
6708 IDirect3DDeviceImpl_7_GetMaterial_FPUPreserve,
6709 IDirect3DDeviceImpl_7_SetLight_FPUPreserve,
6710 IDirect3DDeviceImpl_7_GetLight_FPUPreserve,
6711 IDirect3DDeviceImpl_7_SetRenderState_FPUPreserve,
6712 IDirect3DDeviceImpl_7_GetRenderState_FPUPreserve,
6713 IDirect3DDeviceImpl_7_BeginStateBlock_FPUPreserve,
6714 IDirect3DDeviceImpl_7_EndStateBlock_FPUPreserve,
6715 IDirect3DDeviceImpl_7_PreLoad_FPUPreserve,
6716 IDirect3DDeviceImpl_7_DrawPrimitive_FPUPreserve,
6717 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUPreserve,
6718 IDirect3DDeviceImpl_7_SetClipStatus,
6719 IDirect3DDeviceImpl_7_GetClipStatus,
6720 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUPreserve,
6721 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUPreserve,
6722 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUPreserve,
6723 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUPreserve,
6724 IDirect3DDeviceImpl_7_ComputeSphereVisibility,
6725 IDirect3DDeviceImpl_7_GetTexture_FPUPreserve,
6726 IDirect3DDeviceImpl_7_SetTexture_FPUPreserve,
6727 IDirect3DDeviceImpl_7_GetTextureStageState_FPUPreserve,
6728 IDirect3DDeviceImpl_7_SetTextureStageState_FPUPreserve,
6729 IDirect3DDeviceImpl_7_ValidateDevice_FPUPreserve,
6730 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUPreserve,
6731 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUPreserve,
6732 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUPreserve,
6733 IDirect3DDeviceImpl_7_CreateStateBlock_FPUPreserve,
6734 IDirect3DDeviceImpl_7_Load_FPUPreserve,
6735 IDirect3DDeviceImpl_7_LightEnable_FPUPreserve,
6736 IDirect3DDeviceImpl_7_GetLightEnable_FPUPreserve,
6737 IDirect3DDeviceImpl_7_SetClipPlane_FPUPreserve,
6738 IDirect3DDeviceImpl_7_GetClipPlane_FPUPreserve,
6739 IDirect3DDeviceImpl_7_GetInfo
6742 const IDirect3DDevice3Vtbl IDirect3DDevice3_Vtbl =
6744 /*** IUnknown Methods ***/
6745 Thunk_IDirect3DDeviceImpl_3_QueryInterface,
6746 Thunk_IDirect3DDeviceImpl_3_AddRef,
6747 Thunk_IDirect3DDeviceImpl_3_Release,
6748 /*** IDirect3DDevice3 ***/
6749 IDirect3DDeviceImpl_3_GetCaps,
6750 IDirect3DDeviceImpl_3_GetStats,
6751 IDirect3DDeviceImpl_3_AddViewport,
6752 IDirect3DDeviceImpl_3_DeleteViewport,
6753 IDirect3DDeviceImpl_3_NextViewport,
6754 Thunk_IDirect3DDeviceImpl_3_EnumTextureFormats,
6755 Thunk_IDirect3DDeviceImpl_3_BeginScene,
6756 Thunk_IDirect3DDeviceImpl_3_EndScene,
6757 Thunk_IDirect3DDeviceImpl_3_GetDirect3D,
6758 IDirect3DDeviceImpl_3_SetCurrentViewport,
6759 IDirect3DDeviceImpl_3_GetCurrentViewport,
6760 Thunk_IDirect3DDeviceImpl_3_SetRenderTarget,
6761 Thunk_IDirect3DDeviceImpl_3_GetRenderTarget,
6762 IDirect3DDeviceImpl_3_Begin,
6763 IDirect3DDeviceImpl_3_BeginIndexed,
6764 IDirect3DDeviceImpl_3_Vertex,
6765 IDirect3DDeviceImpl_3_Index,
6766 IDirect3DDeviceImpl_3_End,
6767 IDirect3DDeviceImpl_3_GetRenderState,
6768 IDirect3DDeviceImpl_3_SetRenderState,
6769 IDirect3DDeviceImpl_3_GetLightState,
6770 IDirect3DDeviceImpl_3_SetLightState,
6771 Thunk_IDirect3DDeviceImpl_3_SetTransform,
6772 Thunk_IDirect3DDeviceImpl_3_GetTransform,
6773 Thunk_IDirect3DDeviceImpl_3_MultiplyTransform,
6774 Thunk_IDirect3DDeviceImpl_3_DrawPrimitive,
6775 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitive,
6776 Thunk_IDirect3DDeviceImpl_3_SetClipStatus,
6777 Thunk_IDirect3DDeviceImpl_3_GetClipStatus,
6778 Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveStrided,
6779 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveStrided,
6780 Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveVB,
6781 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveVB,
6782 Thunk_IDirect3DDeviceImpl_3_ComputeSphereVisibility,
6783 Thunk_IDirect3DDeviceImpl_3_GetTexture,
6784 IDirect3DDeviceImpl_3_SetTexture,
6785 Thunk_IDirect3DDeviceImpl_3_GetTextureStageState,
6786 Thunk_IDirect3DDeviceImpl_3_SetTextureStageState,
6787 Thunk_IDirect3DDeviceImpl_3_ValidateDevice
6790 const IDirect3DDevice2Vtbl IDirect3DDevice2_Vtbl =
6792 /*** IUnknown Methods ***/
6793 Thunk_IDirect3DDeviceImpl_2_QueryInterface,
6794 Thunk_IDirect3DDeviceImpl_2_AddRef,
6795 Thunk_IDirect3DDeviceImpl_2_Release,
6796 /*** IDirect3DDevice2 ***/
6797 Thunk_IDirect3DDeviceImpl_2_GetCaps,
6798 IDirect3DDeviceImpl_2_SwapTextureHandles,
6799 Thunk_IDirect3DDeviceImpl_2_GetStats,
6800 Thunk_IDirect3DDeviceImpl_2_AddViewport,
6801 Thunk_IDirect3DDeviceImpl_2_DeleteViewport,
6802 Thunk_IDirect3DDeviceImpl_2_NextViewport,
6803 IDirect3DDeviceImpl_2_EnumTextureFormats,
6804 Thunk_IDirect3DDeviceImpl_2_BeginScene,
6805 Thunk_IDirect3DDeviceImpl_2_EndScene,
6806 Thunk_IDirect3DDeviceImpl_2_GetDirect3D,
6807 Thunk_IDirect3DDeviceImpl_2_SetCurrentViewport,
6808 Thunk_IDirect3DDeviceImpl_2_GetCurrentViewport,
6809 Thunk_IDirect3DDeviceImpl_2_SetRenderTarget,
6810 Thunk_IDirect3DDeviceImpl_2_GetRenderTarget,
6811 Thunk_IDirect3DDeviceImpl_2_Begin,
6812 Thunk_IDirect3DDeviceImpl_2_BeginIndexed,
6813 Thunk_IDirect3DDeviceImpl_2_Vertex,
6814 Thunk_IDirect3DDeviceImpl_2_Index,
6815 Thunk_IDirect3DDeviceImpl_2_End,
6816 Thunk_IDirect3DDeviceImpl_2_GetRenderState,
6817 Thunk_IDirect3DDeviceImpl_2_SetRenderState,
6818 Thunk_IDirect3DDeviceImpl_2_GetLightState,
6819 Thunk_IDirect3DDeviceImpl_2_SetLightState,
6820 Thunk_IDirect3DDeviceImpl_2_SetTransform,
6821 Thunk_IDirect3DDeviceImpl_2_GetTransform,
6822 Thunk_IDirect3DDeviceImpl_2_MultiplyTransform,
6823 Thunk_IDirect3DDeviceImpl_2_DrawPrimitive,
6824 Thunk_IDirect3DDeviceImpl_2_DrawIndexedPrimitive,
6825 Thunk_IDirect3DDeviceImpl_2_SetClipStatus,
6826 Thunk_IDirect3DDeviceImpl_2_GetClipStatus
6829 const IDirect3DDeviceVtbl IDirect3DDevice1_Vtbl =
6831 /*** IUnknown Methods ***/
6832 Thunk_IDirect3DDeviceImpl_1_QueryInterface,
6833 Thunk_IDirect3DDeviceImpl_1_AddRef,
6834 Thunk_IDirect3DDeviceImpl_1_Release,
6835 /*** IDirect3DDevice1 ***/
6836 IDirect3DDeviceImpl_1_Initialize,
6837 Thunk_IDirect3DDeviceImpl_1_GetCaps,
6838 Thunk_IDirect3DDeviceImpl_1_SwapTextureHandles,
6839 IDirect3DDeviceImpl_1_CreateExecuteBuffer,
6840 Thunk_IDirect3DDeviceImpl_1_GetStats,
6841 IDirect3DDeviceImpl_1_Execute,
6842 Thunk_IDirect3DDeviceImpl_1_AddViewport,
6843 Thunk_IDirect3DDeviceImpl_1_DeleteViewport,
6844 Thunk_IDirect3DDeviceImpl_1_NextViewport,
6845 IDirect3DDeviceImpl_1_Pick,
6846 IDirect3DDeviceImpl_1_GetPickRecords,
6847 Thunk_IDirect3DDeviceImpl_1_EnumTextureFormats,
6848 IDirect3DDeviceImpl_1_CreateMatrix,
6849 IDirect3DDeviceImpl_1_SetMatrix,
6850 IDirect3DDeviceImpl_1_GetMatrix,
6851 IDirect3DDeviceImpl_1_DeleteMatrix,
6852 Thunk_IDirect3DDeviceImpl_1_BeginScene,
6853 Thunk_IDirect3DDeviceImpl_1_EndScene,
6854 Thunk_IDirect3DDeviceImpl_1_GetDirect3D
6857 /*****************************************************************************
6858 * IDirect3DDeviceImpl_UpdateDepthStencil
6860 * Checks the current render target for attached depth stencils and sets the
6861 * WineD3D depth stencil accordingly.
6864 * The depth stencil state to set if creating the device
6866 *****************************************************************************/
6868 IDirect3DDeviceImpl_UpdateDepthStencil(IDirect3DDeviceImpl *This)
6870 IDirectDrawSurface7 *depthStencil = NULL;
6871 IDirectDrawSurfaceImpl *dsi;
6872 static DDSCAPS2 depthcaps = { DDSCAPS_ZBUFFER, 0, 0, 0 };
6874 IDirectDrawSurface7_GetAttachedSurface((IDirectDrawSurface7 *)This->target, &depthcaps, &depthStencil);
6877 TRACE("Setting wined3d depth stencil to NULL\n");
6878 IWineD3DDevice_SetDepthStencilSurface(This->wineD3DDevice,
6880 return WINED3DZB_FALSE;
6883 dsi = (IDirectDrawSurfaceImpl *)depthStencil;
6884 TRACE("Setting wined3d depth stencil to %p (wined3d %p)\n", dsi, dsi->WineD3DSurface);
6885 IWineD3DDevice_SetDepthStencilSurface(This->wineD3DDevice,
6886 dsi->WineD3DSurface);
6888 IDirectDrawSurface7_Release(depthStencil);
6889 return WINED3DZB_TRUE;