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
371 for(i = 0; i < This->numHandles; i++)
373 if(This->Handles[i].ptr)
375 switch(This->Handles[i].type)
377 case DDrawHandle_Texture:
379 IDirectDrawSurfaceImpl *surf = This->Handles[i].ptr;
380 FIXME("Texture Handle %d not unset properly\n", i + 1);
385 case DDrawHandle_Matrix:
387 /* No fixme here because this might happen because of sloppy apps */
388 WARN("Leftover matrix handle %d, deleting\n", i + 1);
389 IDirect3DDevice_DeleteMatrix((IDirect3DDevice *)&This->IDirect3DDevice_vtbl, i + 1);
393 case DDrawHandle_StateBlock:
395 /* No fixme here because this might happen because of sloppy apps */
396 WARN("Leftover stateblock handle %d, deleting\n", i + 1);
397 IDirect3DDevice7_DeleteStateBlock((IDirect3DDevice7 *)This, i + 1);
402 FIXME("Unknown handle %d not unset properly\n", i + 1);
407 HeapFree(GetProcessHeap(), 0, This->Handles);
409 for (i = 0; i < This->handle_table.entry_count; ++i)
411 struct ddraw_handle_entry *entry = &This->handle_table.entries[i];
415 case DDRAW_HANDLE_FREE:
418 case DDRAW_HANDLE_MATERIAL:
420 IDirect3DMaterialImpl *m = entry->object;
421 FIXME("Material handle %#x (%p) not unset properly.\n", i + 1, m);
427 FIXME("Handle %#x (%p) has unknown type %#x.\n", i + 1, entry->object, entry->type);
432 ddraw_handle_table_destroy(&This->handle_table);
434 TRACE("Releasing target %p %p\n", This->target, This->ddraw->d3d_target);
435 /* Release the render target and the WineD3D render target
436 * (See IDirect3D7::CreateDevice for more comments on this)
438 IDirectDrawSurface7_Release((IDirectDrawSurface7 *)This->target);
439 IDirectDrawSurface7_Release((IDirectDrawSurface7 *)This->ddraw->d3d_target);
440 TRACE("Target release done\n");
442 This->ddraw->d3ddevice = NULL;
444 /* Now free the structure */
445 HeapFree(GetProcessHeap(), 0, This);
446 LeaveCriticalSection(&ddraw_cs);
454 Thunk_IDirect3DDeviceImpl_3_Release(IDirect3DDevice3 *iface)
456 IDirect3DDeviceImpl *This = device_from_device3(iface);
457 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
458 return IDirect3DDevice7_Release((IDirect3DDevice7 *)This);
462 Thunk_IDirect3DDeviceImpl_2_Release(IDirect3DDevice2 *iface)
464 IDirect3DDeviceImpl *This = device_from_device2(iface);
465 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
466 return IDirect3DDevice7_Release((IDirect3DDevice7 *)This);
470 Thunk_IDirect3DDeviceImpl_1_Release(IDirect3DDevice *iface)
472 IDirect3DDeviceImpl *This = device_from_device1(iface);
473 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
474 return IDirect3DDevice7_Release((IDirect3DDevice7 *)This);
477 /*****************************************************************************
478 * IDirect3DDevice Methods
479 *****************************************************************************/
481 /*****************************************************************************
482 * IDirect3DDevice::Initialize
484 * Initializes a Direct3DDevice. This implementation is a no-op, as all
485 * initialization is done at create time.
487 * Exists in Version 1
490 * No idea what they mean, as the MSDN page is gone
494 *****************************************************************************/
495 static HRESULT WINAPI
496 IDirect3DDeviceImpl_1_Initialize(IDirect3DDevice *iface,
497 IDirect3D *Direct3D, GUID *guid,
500 IDirect3DDeviceImpl *This = device_from_device1(iface);
502 /* It shouldn't be crucial, but print a FIXME, I'm interested if
503 * any game calls it and when
505 FIXME("(%p)->(%p,%p,%p): No-op!\n", This, Direct3D, guid, Desc);
510 /*****************************************************************************
511 * IDirect3DDevice7::GetCaps
513 * Retrieves the device's capabilities
515 * This implementation is used for Version 7 only, the older versions have
516 * their own implementation.
519 * Desc: Pointer to a D3DDEVICEDESC7 structure to fill
523 * D3DERR_* if a problem occurs. See WineD3D
525 *****************************************************************************/
527 IDirect3DDeviceImpl_7_GetCaps(IDirect3DDevice7 *iface,
528 D3DDEVICEDESC7 *Desc)
530 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
531 D3DDEVICEDESC OldDesc;
532 TRACE("(%p)->(%p)\n", This, Desc);
534 /* Call the same function used by IDirect3D, this saves code */
535 return IDirect3DImpl_GetCaps(This->ddraw->wineD3D, &OldDesc, Desc);
538 static HRESULT WINAPI
539 IDirect3DDeviceImpl_7_GetCaps_FPUSetup(IDirect3DDevice7 *iface,
540 D3DDEVICEDESC7 *Desc)
542 return IDirect3DDeviceImpl_7_GetCaps(iface, Desc);
545 static HRESULT WINAPI
546 IDirect3DDeviceImpl_7_GetCaps_FPUPreserve(IDirect3DDevice7 *iface,
547 D3DDEVICEDESC7 *Desc)
552 old_fpucw = d3d_fpu_setup();
553 hr = IDirect3DDeviceImpl_7_GetCaps(iface, Desc);
554 set_fpu_control_word(old_fpucw);
558 /*****************************************************************************
559 * IDirect3DDevice3::GetCaps
561 * Retrieves the capabilities of the hardware device and the emulation
562 * device. For Wine, hardware and emulation are the same (it's all HW).
564 * This implementation is used for Version 1, 2, and 3. Version 7 has its own
567 * HWDesc: Structure to fill with the HW caps
568 * HelDesc: Structure to fill with the hardware emulation caps
572 * D3DERR_* if a problem occurs. See WineD3D
574 *****************************************************************************/
575 static HRESULT WINAPI
576 IDirect3DDeviceImpl_3_GetCaps(IDirect3DDevice3 *iface,
577 D3DDEVICEDESC *HWDesc,
578 D3DDEVICEDESC *HelDesc)
580 IDirect3DDeviceImpl *This = device_from_device3(iface);
581 D3DDEVICEDESC7 newDesc;
583 TRACE("(%p)->(%p,%p)\n", iface, HWDesc, HelDesc);
585 hr = IDirect3DImpl_GetCaps(This->ddraw->wineD3D, HWDesc, &newDesc);
586 if(hr != D3D_OK) return hr;
592 static HRESULT WINAPI
593 Thunk_IDirect3DDeviceImpl_2_GetCaps(IDirect3DDevice2 *iface,
594 D3DDEVICEDESC *D3DHWDevDesc,
595 D3DDEVICEDESC *D3DHELDevDesc)
597 IDirect3DDeviceImpl *This = device_from_device2(iface);
598 TRACE_(ddraw_thunk)("(%p)->(%p,%p) thunking to IDirect3DDevice3 interface.\n", This, D3DHWDevDesc, D3DHELDevDesc);
599 return IDirect3DDevice3_GetCaps((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl, D3DHWDevDesc, D3DHELDevDesc);
602 static HRESULT WINAPI
603 Thunk_IDirect3DDeviceImpl_1_GetCaps(IDirect3DDevice *iface,
604 D3DDEVICEDESC *D3DHWDevDesc,
605 D3DDEVICEDESC *D3DHELDevDesc)
607 IDirect3DDeviceImpl *This = device_from_device1(iface);
608 TRACE_(ddraw_thunk)("(%p)->(%p,%p) thunking to IDirect3DDevice3 interface.\n", This, D3DHWDevDesc, D3DHELDevDesc);
609 return IDirect3DDevice3_GetCaps((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl, D3DHWDevDesc, D3DHELDevDesc);
612 /*****************************************************************************
613 * IDirect3DDevice2::SwapTextureHandles
615 * Swaps the texture handles of 2 Texture interfaces. Version 1 and 2
618 * Tex1, Tex2: The 2 Textures to swap
623 *****************************************************************************/
624 static HRESULT WINAPI
625 IDirect3DDeviceImpl_2_SwapTextureHandles(IDirect3DDevice2 *iface,
626 IDirect3DTexture2 *Tex1,
627 IDirect3DTexture2 *Tex2)
629 IDirect3DDeviceImpl *This = device_from_device2(iface);
631 IDirectDrawSurfaceImpl *surf1 = surface_from_texture2(Tex1);
632 IDirectDrawSurfaceImpl *surf2 = surface_from_texture2(Tex2);
633 TRACE("(%p)->(%p,%p)\n", This, surf1, surf2);
635 EnterCriticalSection(&ddraw_cs);
636 This->Handles[surf1->Handle - 1].ptr = surf2;
637 This->Handles[surf2->Handle - 1].ptr = surf1;
639 swap = surf2->Handle;
640 surf2->Handle = surf1->Handle;
641 surf1->Handle = swap;
642 LeaveCriticalSection(&ddraw_cs);
647 static HRESULT WINAPI
648 Thunk_IDirect3DDeviceImpl_1_SwapTextureHandles(IDirect3DDevice *iface,
649 IDirect3DTexture *D3DTex1,
650 IDirect3DTexture *D3DTex2)
652 IDirect3DDeviceImpl *This = device_from_device1(iface);
653 IDirectDrawSurfaceImpl *surf1 = surface_from_texture1(D3DTex1);
654 IDirectDrawSurfaceImpl *surf2 = surface_from_texture1(D3DTex2);
655 IDirect3DTexture2 *t1 = surf1 ? (IDirect3DTexture2 *)&surf1->IDirect3DTexture2_vtbl : NULL;
656 IDirect3DTexture2 *t2 = surf2 ? (IDirect3DTexture2 *)&surf2->IDirect3DTexture2_vtbl : NULL;
657 TRACE_(ddraw_thunk)("(%p)->(%p,%p) thunking to IDirect3DDevice2 interface.\n", This, surf1, surf2);
658 return IDirect3DDevice2_SwapTextureHandles((IDirect3DDevice2 *)&This->IDirect3DDevice2_vtbl, t1, t2);
661 /*****************************************************************************
662 * IDirect3DDevice3::GetStats
664 * This method seems to retrieve some stats from the device.
665 * The MSDN documentation doesn't exist any more, but the D3DSTATS
666 * structure suggests that the amount of drawn primitives and processed
667 * vertices is returned.
669 * Exists in Version 1, 2 and 3
672 * Stats: Pointer to a D3DSTATS structure to be filled
676 * DDERR_INVALIDPARAMS if Stats == NULL
678 *****************************************************************************/
679 static HRESULT WINAPI
680 IDirect3DDeviceImpl_3_GetStats(IDirect3DDevice3 *iface,
683 IDirect3DDeviceImpl *This = device_from_device3(iface);
684 FIXME("(%p)->(%p): Stub!\n", This, Stats);
687 return DDERR_INVALIDPARAMS;
689 /* Fill the Stats with 0 */
690 Stats->dwTrianglesDrawn = 0;
691 Stats->dwLinesDrawn = 0;
692 Stats->dwPointsDrawn = 0;
693 Stats->dwSpansDrawn = 0;
694 Stats->dwVerticesProcessed = 0;
699 static HRESULT WINAPI
700 Thunk_IDirect3DDeviceImpl_2_GetStats(IDirect3DDevice2 *iface,
703 IDirect3DDeviceImpl *This = device_from_device2(iface);
704 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, Stats);
705 return IDirect3DDevice3_GetStats((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl, Stats);
708 static HRESULT WINAPI
709 Thunk_IDirect3DDeviceImpl_1_GetStats(IDirect3DDevice *iface,
712 IDirect3DDeviceImpl *This = device_from_device1(iface);
713 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, Stats);
714 return IDirect3DDevice3_GetStats((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl, Stats);
717 /*****************************************************************************
718 * IDirect3DDevice::CreateExecuteBuffer
720 * Creates an IDirect3DExecuteBuffer, used for rendering with a
726 * Desc: Buffer description
727 * ExecuteBuffer: Address to return the Interface pointer at
728 * UnkOuter: Must be NULL. Basically for aggregation, which ddraw doesn't
732 * CLASS_E_NOAGGREGATION if UnkOuter != NULL
733 * DDERR_OUTOFMEMORY if we ran out of memory
736 *****************************************************************************/
737 static HRESULT WINAPI
738 IDirect3DDeviceImpl_1_CreateExecuteBuffer(IDirect3DDevice *iface,
739 D3DEXECUTEBUFFERDESC *Desc,
740 IDirect3DExecuteBuffer **ExecuteBuffer,
743 IDirect3DDeviceImpl *This = device_from_device1(iface);
744 IDirect3DExecuteBufferImpl* object;
745 TRACE("(%p)->(%p,%p,%p)!\n", This, Desc, ExecuteBuffer, UnkOuter);
748 return CLASS_E_NOAGGREGATION;
750 /* Allocate the new Execute Buffer */
751 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DExecuteBufferImpl));
754 ERR("Out of memory when allocating a IDirect3DExecuteBufferImpl structure\n");
755 return DDERR_OUTOFMEMORY;
758 object->lpVtbl = &IDirect3DExecuteBuffer_Vtbl;
760 object->d3ddev = This;
762 /* Initializes memory */
763 memcpy(&object->desc, Desc, Desc->dwSize);
765 /* No buffer given */
766 if ((object->desc.dwFlags & D3DDEB_LPDATA) == 0)
767 object->desc.lpData = NULL;
769 /* No buffer size given */
770 if ((object->desc.dwFlags & D3DDEB_BUFSIZE) == 0)
771 object->desc.dwBufferSize = 0;
773 /* Create buffer if asked */
774 if ((object->desc.lpData == NULL) && (object->desc.dwBufferSize > 0))
776 object->need_free = TRUE;
777 object->desc.lpData = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,object->desc.dwBufferSize);
778 if(!object->desc.lpData)
780 ERR("Out of memory when allocating the execute buffer data\n");
781 HeapFree(GetProcessHeap(), 0, object);
782 return DDERR_OUTOFMEMORY;
787 object->need_free = FALSE;
790 /* No vertices for the moment */
791 object->vertex_data = NULL;
793 object->desc.dwFlags |= D3DDEB_LPDATA;
795 object->indices = NULL;
796 object->nb_indices = 0;
798 *ExecuteBuffer = (IDirect3DExecuteBuffer *)object;
800 TRACE(" Returning IDirect3DExecuteBuffer at %p, implementation is at %p\n", *ExecuteBuffer, object);
805 /*****************************************************************************
806 * IDirect3DDevice::Execute
808 * Executes all the stuff in an execute buffer.
811 * ExecuteBuffer: The buffer to execute
812 * Viewport: The viewport used for rendering
816 * DDERR_INVALIDPARAMS if ExecuteBuffer == NULL
819 *****************************************************************************/
820 static HRESULT WINAPI
821 IDirect3DDeviceImpl_1_Execute(IDirect3DDevice *iface,
822 IDirect3DExecuteBuffer *ExecuteBuffer,
823 IDirect3DViewport *Viewport,
826 IDirect3DDeviceImpl *This = device_from_device1(iface);
827 IDirect3DExecuteBufferImpl *Direct3DExecuteBufferImpl = (IDirect3DExecuteBufferImpl *)ExecuteBuffer;
828 IDirect3DViewportImpl *Direct3DViewportImpl = (IDirect3DViewportImpl *)Viewport;
830 TRACE("(%p)->(%p,%p,%08x)\n", This, Direct3DExecuteBufferImpl, Direct3DViewportImpl, Flags);
832 if(!Direct3DExecuteBufferImpl)
833 return DDERR_INVALIDPARAMS;
836 EnterCriticalSection(&ddraw_cs);
837 IDirect3DExecuteBufferImpl_Execute(Direct3DExecuteBufferImpl, This, Direct3DViewportImpl);
838 LeaveCriticalSection(&ddraw_cs);
843 /*****************************************************************************
844 * IDirect3DDevice3::AddViewport
846 * Add a Direct3DViewport to the device's viewport list. These viewports
847 * are wrapped to IDirect3DDevice7 viewports in viewport.c
849 * Exists in Version 1, 2 and 3. Note that IDirect3DViewport 1, 2 and 3
850 * are the same interfaces.
853 * Viewport: The viewport to add
856 * DDERR_INVALIDPARAMS if Viewport == NULL
859 *****************************************************************************/
860 static HRESULT WINAPI
861 IDirect3DDeviceImpl_3_AddViewport(IDirect3DDevice3 *iface,
862 IDirect3DViewport3 *Viewport)
864 IDirect3DDeviceImpl *This = device_from_device3(iface);
865 IDirect3DViewportImpl *vp = (IDirect3DViewportImpl *)Viewport;
867 TRACE("(%p)->(%p)\n", This, vp);
871 return DDERR_INVALIDPARAMS;
873 EnterCriticalSection(&ddraw_cs);
874 vp->next = This->viewport_list;
875 This->viewport_list = vp;
876 vp->active_device = This; /* Viewport must be usable for Clear() after AddViewport,
877 so set active_device here. */
878 LeaveCriticalSection(&ddraw_cs);
883 static HRESULT WINAPI
884 Thunk_IDirect3DDeviceImpl_2_AddViewport(IDirect3DDevice2 *iface,
885 IDirect3DViewport2 *Direct3DViewport2)
887 IDirect3DDeviceImpl *This = device_from_device2(iface);
888 IDirect3DViewportImpl *vp = (IDirect3DViewportImpl *)Direct3DViewport2;
889 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, vp);
890 return IDirect3DDevice3_AddViewport((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl, (IDirect3DViewport3 *)vp);
893 static HRESULT WINAPI
894 Thunk_IDirect3DDeviceImpl_1_AddViewport(IDirect3DDevice *iface,
895 IDirect3DViewport *Direct3DViewport)
897 IDirect3DDeviceImpl *This = device_from_device1(iface);
898 IDirect3DViewportImpl *vp = (IDirect3DViewportImpl *)Direct3DViewport;
899 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, vp);
900 return IDirect3DDevice3_AddViewport((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl, (IDirect3DViewport3 *)vp);
903 /*****************************************************************************
904 * IDirect3DDevice3::DeleteViewport
906 * Deletes a Direct3DViewport from the device's viewport list.
908 * Exists in Version 1, 2 and 3. Note that all Viewport interface versions
912 * Viewport: The viewport to delete
916 * DDERR_INVALIDPARAMS if the viewport wasn't found in the list
918 *****************************************************************************/
919 static HRESULT WINAPI
920 IDirect3DDeviceImpl_3_DeleteViewport(IDirect3DDevice3 *iface,
921 IDirect3DViewport3 *Viewport)
923 IDirect3DDeviceImpl *This = device_from_device3(iface);
924 IDirect3DViewportImpl *vp = (IDirect3DViewportImpl *) Viewport;
925 IDirect3DViewportImpl *cur_viewport, *prev_viewport = NULL;
927 TRACE("(%p)->(%p)\n", This, vp);
929 EnterCriticalSection(&ddraw_cs);
930 cur_viewport = This->viewport_list;
931 while (cur_viewport != NULL)
933 if (cur_viewport == vp)
935 if (prev_viewport == NULL) This->viewport_list = cur_viewport->next;
936 else prev_viewport->next = cur_viewport->next;
937 /* TODO : add desactivate of the viewport and all associated lights... */
938 LeaveCriticalSection(&ddraw_cs);
941 prev_viewport = cur_viewport;
942 cur_viewport = cur_viewport->next;
945 LeaveCriticalSection(&ddraw_cs);
946 return DDERR_INVALIDPARAMS;
949 static HRESULT WINAPI
950 Thunk_IDirect3DDeviceImpl_2_DeleteViewport(IDirect3DDevice2 *iface,
951 IDirect3DViewport2 *Direct3DViewport2)
953 IDirect3DDeviceImpl *This = device_from_device2(iface);
954 IDirect3DViewportImpl *vp = (IDirect3DViewportImpl *)Direct3DViewport2;
955 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, vp);
956 return IDirect3DDevice3_DeleteViewport((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl, (IDirect3DViewport3 *)vp);
959 static HRESULT WINAPI
960 Thunk_IDirect3DDeviceImpl_1_DeleteViewport(IDirect3DDevice *iface,
961 IDirect3DViewport *Direct3DViewport)
963 IDirect3DDeviceImpl *This = device_from_device1(iface);
964 IDirect3DViewportImpl *vp = (IDirect3DViewportImpl *)Direct3DViewport;
965 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, vp);
966 return IDirect3DDevice3_DeleteViewport((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl, (IDirect3DViewport3 *)vp);
969 /*****************************************************************************
970 * IDirect3DDevice3::NextViewport
972 * Returns a viewport from the viewport list, depending on the
973 * passed viewport and the flags.
975 * Exists in Version 1, 2 and 3. Note that all Viewport interface versions
979 * Viewport: Viewport to use for beginning the search
980 * Flags: D3DNEXT_NEXT, D3DNEXT_HEAD or D3DNEXT_TAIL
984 * DDERR_INVALIDPARAMS if the flags were wrong, or Viewport was NULL
986 *****************************************************************************/
987 static HRESULT WINAPI
988 IDirect3DDeviceImpl_3_NextViewport(IDirect3DDevice3 *iface,
989 IDirect3DViewport3 *Viewport3,
990 IDirect3DViewport3 **lplpDirect3DViewport3,
993 IDirect3DDeviceImpl *This = device_from_device3(iface);
994 IDirect3DViewportImpl *vp = (IDirect3DViewportImpl *)Viewport3;
995 IDirect3DViewportImpl *res = NULL;
997 TRACE("(%p)->(%p,%p,%08x)\n", This, vp, lplpDirect3DViewport3, Flags);
1001 *lplpDirect3DViewport3 = NULL;
1002 return DDERR_INVALIDPARAMS;
1006 EnterCriticalSection(&ddraw_cs);
1016 res = This->viewport_list;
1021 IDirect3DViewportImpl *cur_viewport = This->viewport_list;
1022 if (cur_viewport != NULL)
1024 while (cur_viewport->next != NULL) cur_viewport = cur_viewport->next;
1030 *lplpDirect3DViewport3 = NULL;
1031 LeaveCriticalSection(&ddraw_cs);
1032 return DDERR_INVALIDPARAMS;
1035 *lplpDirect3DViewport3 = (IDirect3DViewport3 *)res;
1036 LeaveCriticalSection(&ddraw_cs);
1040 static HRESULT WINAPI
1041 Thunk_IDirect3DDeviceImpl_2_NextViewport(IDirect3DDevice2 *iface,
1042 IDirect3DViewport2 *Viewport2,
1043 IDirect3DViewport2 **lplpDirect3DViewport2,
1046 IDirect3DDeviceImpl *This = device_from_device2(iface);
1047 IDirect3DViewportImpl *vp = (IDirect3DViewportImpl *)Viewport2;
1048 IDirect3DViewport3 *res;
1050 TRACE_(ddraw_thunk)("(%p)->(%p,%p,%08x) thunking to IDirect3DDevice3 interface.\n", This, vp, lplpDirect3DViewport2, Flags);
1051 hr = IDirect3DDevice3_NextViewport((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl,
1052 (IDirect3DViewport3 *)vp, &res, Flags);
1053 *lplpDirect3DViewport2 = (IDirect3DViewport2 *)res;
1057 static HRESULT WINAPI
1058 Thunk_IDirect3DDeviceImpl_1_NextViewport(IDirect3DDevice *iface,
1059 IDirect3DViewport *Viewport,
1060 IDirect3DViewport **lplpDirect3DViewport,
1063 IDirect3DDeviceImpl *This = device_from_device1(iface);
1064 IDirect3DViewportImpl *vp = (IDirect3DViewportImpl *)Viewport;
1065 IDirect3DViewport3 *res;
1067 TRACE_(ddraw_thunk)("(%p)->(%p,%p,%08x) thunking to IDirect3DDevice3 interface.\n", This, vp, lplpDirect3DViewport, Flags);
1068 hr = IDirect3DDevice3_NextViewport((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl,
1069 (IDirect3DViewport3 *)vp, &res, Flags);
1070 *lplpDirect3DViewport = (IDirect3DViewport *)res;
1074 /*****************************************************************************
1075 * IDirect3DDevice::Pick
1077 * Executes an execute buffer without performing rendering. Instead, a
1078 * list of primitives that intersect with (x1,y1) of the passed rectangle
1079 * is created. IDirect3DDevice::GetPickRecords can be used to retrieve
1085 * ExecuteBuffer: Buffer to execute
1086 * Viewport: Viewport to use for execution
1087 * Flags: None are defined, according to the SDK
1088 * Rect: Specifies the coordinates to be picked. Only x1 and y2 are used,
1089 * x2 and y2 are ignored.
1092 * D3D_OK because it's a stub
1094 *****************************************************************************/
1095 static HRESULT WINAPI
1096 IDirect3DDeviceImpl_1_Pick(IDirect3DDevice *iface,
1097 IDirect3DExecuteBuffer *ExecuteBuffer,
1098 IDirect3DViewport *Viewport,
1102 IDirect3DDeviceImpl *This = device_from_device1(iface);
1103 IDirect3DExecuteBufferImpl *execbuf = (IDirect3DExecuteBufferImpl *)ExecuteBuffer;
1104 IDirect3DViewportImpl *vp = (IDirect3DViewportImpl *)Viewport;
1105 FIXME("(%p)->(%p,%p,%08x,%p): stub!\n", This, execbuf, vp, Flags, Rect);
1110 /*****************************************************************************
1111 * IDirect3DDevice::GetPickRecords
1113 * Retrieves the pick records generated by IDirect3DDevice::GetPickRecords
1118 * Count: Pointer to a DWORD containing the numbers of pick records to
1120 * D3DPickRec: Address to store the resulting D3DPICKRECORD array.
1123 * D3D_OK, because it's a stub
1125 *****************************************************************************/
1126 static HRESULT WINAPI
1127 IDirect3DDeviceImpl_1_GetPickRecords(IDirect3DDevice *iface,
1129 D3DPICKRECORD *D3DPickRec)
1131 IDirect3DDeviceImpl *This = device_from_device1(iface);
1132 FIXME("(%p)->(%p,%p): stub!\n", This, Count, D3DPickRec);
1137 /*****************************************************************************
1138 * IDirect3DDevice7::EnumTextureformats
1140 * Enumerates the supported texture formats. It has a list of all possible
1141 * formats and calls IWineD3D::CheckDeviceFormat for each format to see if
1142 * WineD3D supports it. If so, then it is passed to the app.
1144 * This is for Version 7 and 3, older versions have a different
1145 * callback function and their own implementation
1148 * Callback: Callback to call for each enumerated format
1149 * Arg: Argument to pass to the callback
1153 * DDERR_INVALIDPARAMS if Callback == NULL
1155 *****************************************************************************/
1157 IDirect3DDeviceImpl_7_EnumTextureFormats(IDirect3DDevice7 *iface,
1158 LPD3DENUMPIXELFORMATSCALLBACK Callback,
1161 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
1163 WINED3DDISPLAYMODE mode;
1166 WINED3DFORMAT FormatList[] = {
1168 WINED3DFMT_B8G8R8A8_UNORM,
1169 WINED3DFMT_B8G8R8X8_UNORM,
1171 WINED3DFMT_B8G8R8_UNORM,
1173 WINED3DFMT_B5G5R5A1_UNORM,
1174 WINED3DFMT_B4G4R4A4_UNORM,
1175 WINED3DFMT_B5G6R5_UNORM,
1176 WINED3DFMT_B5G5R5X1_UNORM,
1178 WINED3DFMT_B2G3R3_UNORM,
1186 WINED3DFORMAT BumpFormatList[] = {
1187 WINED3DFMT_R8G8_SNORM,
1188 WINED3DFMT_R5G5_SNORM_L6_UNORM,
1189 WINED3DFMT_R8G8_SNORM_L8X8_UNORM,
1190 WINED3DFMT_R8G8B8A8_SNORM,
1191 WINED3DFMT_R16G16_SNORM,
1192 WINED3DFMT_R10G11B11_SNORM,
1193 WINED3DFMT_R10G10B10_SNORM_A2_UNORM
1196 TRACE("(%p)->(%p,%p): Relay\n", This, Callback, Arg);
1199 return DDERR_INVALIDPARAMS;
1201 EnterCriticalSection(&ddraw_cs);
1203 memset(&mode, 0, sizeof(mode));
1204 hr = IWineD3DDevice_GetDisplayMode(This->ddraw->wineD3DDevice,
1208 LeaveCriticalSection(&ddraw_cs);
1209 WARN("Cannot get the current adapter format\n");
1213 for(i = 0; i < sizeof(FormatList) / sizeof(WINED3DFORMAT); i++)
1215 hr = IWineD3D_CheckDeviceFormat(This->ddraw->wineD3D,
1216 WINED3DADAPTER_DEFAULT,
1220 WINED3DRTYPE_TEXTURE,
1225 DDPIXELFORMAT pformat;
1227 memset(&pformat, 0, sizeof(pformat));
1228 pformat.dwSize = sizeof(pformat);
1229 PixelFormat_WineD3DtoDD(&pformat, FormatList[i]);
1231 TRACE("Enumerating WineD3DFormat %d\n", FormatList[i]);
1232 hr = Callback(&pformat, Arg);
1233 if(hr != DDENUMRET_OK)
1235 TRACE("Format enumeration cancelled by application\n");
1236 LeaveCriticalSection(&ddraw_cs);
1242 for(i = 0; i < sizeof(BumpFormatList) / sizeof(WINED3DFORMAT); i++)
1244 hr = IWineD3D_CheckDeviceFormat(This->ddraw->wineD3D,
1245 WINED3DADAPTER_DEFAULT,
1248 WINED3DUSAGE_QUERY_LEGACYBUMPMAP,
1249 WINED3DRTYPE_TEXTURE,
1254 DDPIXELFORMAT pformat;
1256 memset(&pformat, 0, sizeof(pformat));
1257 pformat.dwSize = sizeof(pformat);
1258 PixelFormat_WineD3DtoDD(&pformat, BumpFormatList[i]);
1260 TRACE("Enumerating WineD3DFormat %d\n", BumpFormatList[i]);
1261 hr = Callback(&pformat, Arg);
1262 if(hr != DDENUMRET_OK)
1264 TRACE("Format enumeration cancelled by application\n");
1265 LeaveCriticalSection(&ddraw_cs);
1270 TRACE("End of enumeration\n");
1271 LeaveCriticalSection(&ddraw_cs);
1275 static HRESULT WINAPI
1276 IDirect3DDeviceImpl_7_EnumTextureFormats_FPUSetup(IDirect3DDevice7 *iface,
1277 LPD3DENUMPIXELFORMATSCALLBACK Callback,
1280 return IDirect3DDeviceImpl_7_EnumTextureFormats(iface, Callback, Arg);
1283 static HRESULT WINAPI
1284 IDirect3DDeviceImpl_7_EnumTextureFormats_FPUPreserve(IDirect3DDevice7 *iface,
1285 LPD3DENUMPIXELFORMATSCALLBACK Callback,
1291 old_fpucw = d3d_fpu_setup();
1292 hr = IDirect3DDeviceImpl_7_EnumTextureFormats(iface, Callback, Arg);
1293 set_fpu_control_word(old_fpucw);
1298 static HRESULT WINAPI
1299 Thunk_IDirect3DDeviceImpl_3_EnumTextureFormats(IDirect3DDevice3 *iface,
1300 LPD3DENUMPIXELFORMATSCALLBACK Callback,
1303 IDirect3DDeviceImpl *This = device_from_device3(iface);
1304 TRACE_(ddraw_thunk)("(%p)->(%p,%p) thunking to IDirect3DDevice7 interface.\n", This, Callback, Arg);
1305 return IDirect3DDevice7_EnumTextureFormats((IDirect3DDevice7 *)This, Callback, Arg);
1308 /*****************************************************************************
1309 * IDirect3DDevice2::EnumTextureformats
1311 * EnumTextureFormats for Version 1 and 2, see
1312 * IDirect3DDevice7::EnumTexureFormats for a more detailed description.
1314 * This version has a different callback and does not enumerate FourCC
1317 *****************************************************************************/
1318 static HRESULT WINAPI
1319 IDirect3DDeviceImpl_2_EnumTextureFormats(IDirect3DDevice2 *iface,
1320 LPD3DENUMTEXTUREFORMATSCALLBACK Callback,
1323 IDirect3DDeviceImpl *This = device_from_device2(iface);
1326 WINED3DDISPLAYMODE mode;
1328 WINED3DFORMAT FormatList[] = {
1330 WINED3DFMT_B8G8R8A8_UNORM,
1331 WINED3DFMT_B8G8R8X8_UNORM,
1333 WINED3DFMT_B8G8R8_UNORM,
1335 WINED3DFMT_B5G5R5A1_UNORM,
1336 WINED3DFMT_B4G4R4A4_UNORM,
1337 WINED3DFMT_B5G6R5_UNORM,
1338 WINED3DFMT_B5G5R5X1_UNORM,
1340 WINED3DFMT_B2G3R3_UNORM,
1342 /* FOURCC codes - Not in this version*/
1345 TRACE("(%p)->(%p,%p): Relay\n", This, Callback, Arg);
1348 return DDERR_INVALIDPARAMS;
1350 EnterCriticalSection(&ddraw_cs);
1352 memset(&mode, 0, sizeof(mode));
1353 hr = IWineD3DDevice_GetDisplayMode(This->ddraw->wineD3DDevice,
1357 LeaveCriticalSection(&ddraw_cs);
1358 WARN("Cannot get the current adapter format\n");
1362 for(i = 0; i < sizeof(FormatList) / sizeof(WINED3DFORMAT); i++)
1364 hr = IWineD3D_CheckDeviceFormat(This->ddraw->wineD3D,
1369 WINED3DRTYPE_TEXTURE,
1374 DDSURFACEDESC sdesc;
1376 memset(&sdesc, 0, sizeof(sdesc));
1377 sdesc.dwSize = sizeof(sdesc);
1378 sdesc.dwFlags = DDSD_PIXELFORMAT | DDSD_CAPS;
1379 sdesc.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1380 sdesc.ddpfPixelFormat.dwSize = sizeof(sdesc.ddpfPixelFormat);
1381 PixelFormat_WineD3DtoDD(&sdesc.ddpfPixelFormat, FormatList[i]);
1383 TRACE("Enumerating WineD3DFormat %d\n", FormatList[i]);
1384 hr = Callback(&sdesc, Arg);
1385 if(hr != DDENUMRET_OK)
1387 TRACE("Format enumeration cancelled by application\n");
1388 LeaveCriticalSection(&ddraw_cs);
1393 TRACE("End of enumeration\n");
1394 LeaveCriticalSection(&ddraw_cs);
1398 static HRESULT WINAPI
1399 Thunk_IDirect3DDeviceImpl_1_EnumTextureFormats(IDirect3DDevice *iface,
1400 LPD3DENUMTEXTUREFORMATSCALLBACK Callback,
1403 IDirect3DDeviceImpl *This = device_from_device1(iface);
1404 TRACE_(ddraw_thunk)("(%p)->(%p,%p) thunking to IDirect3DDevice2 interface.\n", This, Callback, Arg);
1405 return IDirect3DDevice2_EnumTextureFormats((IDirect3DDevice2 *)&This->IDirect3DDevice2_vtbl, Callback, Arg);
1408 /*****************************************************************************
1409 * IDirect3DDevice::CreateMatrix
1411 * Creates a matrix handle. A handle is created and memory for a D3DMATRIX is
1412 * allocated for the handle.
1417 * D3DMatHandle: Address to return the handle at
1421 * DDERR_INVALIDPARAMS if D3DMatHandle = NULL
1423 *****************************************************************************/
1424 static HRESULT WINAPI
1425 IDirect3DDeviceImpl_1_CreateMatrix(IDirect3DDevice *iface, D3DMATRIXHANDLE *D3DMatHandle)
1427 IDirect3DDeviceImpl *This = device_from_device1(iface);
1429 TRACE("(%p)->(%p)\n", This, D3DMatHandle);
1432 return DDERR_INVALIDPARAMS;
1434 Matrix = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(D3DMATRIX));
1437 ERR("Out of memory when allocating a D3DMATRIX\n");
1438 return DDERR_OUTOFMEMORY;
1441 EnterCriticalSection(&ddraw_cs);
1442 *D3DMatHandle = IDirect3DDeviceImpl_CreateHandle(This);
1443 if(!(*D3DMatHandle))
1445 ERR("Failed to create a matrix handle\n");
1446 HeapFree(GetProcessHeap(), 0, Matrix);
1447 LeaveCriticalSection(&ddraw_cs);
1448 return DDERR_OUTOFMEMORY;
1450 This->Handles[*D3DMatHandle - 1].ptr = Matrix;
1451 This->Handles[*D3DMatHandle - 1].type = DDrawHandle_Matrix;
1452 TRACE(" returning matrix handle %d\n", *D3DMatHandle);
1454 LeaveCriticalSection(&ddraw_cs);
1458 /*****************************************************************************
1459 * IDirect3DDevice::SetMatrix
1461 * Sets a matrix for a matrix handle. The matrix is copied into the memory
1462 * allocated for the handle
1467 * D3DMatHandle: Handle to set the matrix to
1468 * D3DMatrix: Matrix to set
1472 * DDERR_INVALIDPARAMS if the handle of the matrix is invalid or the matrix
1475 *****************************************************************************/
1476 static HRESULT WINAPI
1477 IDirect3DDeviceImpl_1_SetMatrix(IDirect3DDevice *iface,
1478 D3DMATRIXHANDLE D3DMatHandle,
1479 D3DMATRIX *D3DMatrix)
1481 IDirect3DDeviceImpl *This = device_from_device1(iface);
1482 TRACE("(%p)->(%08x,%p)\n", This, D3DMatHandle, D3DMatrix);
1484 if( (!D3DMatHandle) || (!D3DMatrix) )
1485 return DDERR_INVALIDPARAMS;
1487 EnterCriticalSection(&ddraw_cs);
1488 if(D3DMatHandle > This->numHandles)
1490 ERR("Handle %d out of range\n", D3DMatHandle);
1491 LeaveCriticalSection(&ddraw_cs);
1492 return DDERR_INVALIDPARAMS;
1494 else if(This->Handles[D3DMatHandle - 1].type != DDrawHandle_Matrix)
1496 ERR("Handle %d is not a matrix handle\n", D3DMatHandle);
1497 LeaveCriticalSection(&ddraw_cs);
1498 return DDERR_INVALIDPARAMS;
1502 dump_D3DMATRIX(D3DMatrix);
1504 *((D3DMATRIX *) This->Handles[D3DMatHandle - 1].ptr) = *D3DMatrix;
1506 if(This->world == D3DMatHandle)
1508 IWineD3DDevice_SetTransform(This->wineD3DDevice,
1509 WINED3DTS_WORLDMATRIX(0),
1510 (WINED3DMATRIX *) D3DMatrix);
1512 if(This->view == D3DMatHandle)
1514 IWineD3DDevice_SetTransform(This->wineD3DDevice,
1516 (WINED3DMATRIX *) D3DMatrix);
1518 if(This->proj == D3DMatHandle)
1520 IWineD3DDevice_SetTransform(This->wineD3DDevice,
1521 WINED3DTS_PROJECTION,
1522 (WINED3DMATRIX *) D3DMatrix);
1525 LeaveCriticalSection(&ddraw_cs);
1529 /*****************************************************************************
1530 * IDirect3DDevice::SetMatrix
1532 * Returns the content of a D3DMATRIX handle
1537 * D3DMatHandle: Matrix handle to read the content from
1538 * D3DMatrix: Address to store the content at
1542 * DDERR_INVALIDPARAMS if D3DMatHandle is invalid or D3DMatrix is NULL
1544 *****************************************************************************/
1545 static HRESULT WINAPI
1546 IDirect3DDeviceImpl_1_GetMatrix(IDirect3DDevice *iface,
1547 D3DMATRIXHANDLE D3DMatHandle,
1548 D3DMATRIX *D3DMatrix)
1550 IDirect3DDeviceImpl *This = device_from_device1(iface);
1551 TRACE("(%p)->(%08x,%p)\n", This, D3DMatHandle, D3DMatrix);
1554 return DDERR_INVALIDPARAMS;
1556 return DDERR_INVALIDPARAMS;
1558 EnterCriticalSection(&ddraw_cs);
1559 if(D3DMatHandle > This->numHandles)
1561 ERR("Handle %d out of range\n", D3DMatHandle);
1562 LeaveCriticalSection(&ddraw_cs);
1563 return DDERR_INVALIDPARAMS;
1565 else if(This->Handles[D3DMatHandle - 1].type != DDrawHandle_Matrix)
1567 ERR("Handle %d is not a matrix handle\n", D3DMatHandle);
1568 LeaveCriticalSection(&ddraw_cs);
1569 return DDERR_INVALIDPARAMS;
1572 /* The handle is simply a pointer to a D3DMATRIX structure */
1573 *D3DMatrix = *((D3DMATRIX *) This->Handles[D3DMatHandle - 1].ptr);
1575 LeaveCriticalSection(&ddraw_cs);
1579 /*****************************************************************************
1580 * IDirect3DDevice::DeleteMatrix
1582 * Destroys a Matrix handle. Frees the memory and unsets the handle data
1587 * D3DMatHandle: Handle to destroy
1591 * DDERR_INVALIDPARAMS if D3DMatHandle is invalid
1593 *****************************************************************************/
1594 static HRESULT WINAPI
1595 IDirect3DDeviceImpl_1_DeleteMatrix(IDirect3DDevice *iface,
1596 D3DMATRIXHANDLE D3DMatHandle)
1598 IDirect3DDeviceImpl *This = device_from_device1(iface);
1599 TRACE("(%p)->(%08x)\n", This, D3DMatHandle);
1602 return DDERR_INVALIDPARAMS;
1604 EnterCriticalSection(&ddraw_cs);
1605 if(D3DMatHandle > This->numHandles)
1607 ERR("Handle %d out of range\n", D3DMatHandle);
1608 LeaveCriticalSection(&ddraw_cs);
1609 return DDERR_INVALIDPARAMS;
1611 else if(This->Handles[D3DMatHandle - 1].type != DDrawHandle_Matrix)
1613 ERR("Handle %d is not a matrix handle\n", D3DMatHandle);
1614 LeaveCriticalSection(&ddraw_cs);
1615 return DDERR_INVALIDPARAMS;
1618 HeapFree(GetProcessHeap(), 0, This->Handles[D3DMatHandle - 1].ptr);
1619 This->Handles[D3DMatHandle - 1].ptr = NULL;
1620 This->Handles[D3DMatHandle - 1].type = DDrawHandle_Unknown;
1622 LeaveCriticalSection(&ddraw_cs);
1626 /*****************************************************************************
1627 * IDirect3DDevice7::BeginScene
1629 * This method must be called before any rendering is performed.
1630 * IDirect3DDevice::EndScene has to be called after the scene is complete
1632 * Version 1, 2, 3 and 7
1635 * D3D_OK on success, for details see IWineD3DDevice::BeginScene
1636 * D3DERR_SCENE_IN_SCENE if WineD3D returns an error(Only in case of an already
1639 *****************************************************************************/
1641 IDirect3DDeviceImpl_7_BeginScene(IDirect3DDevice7 *iface)
1643 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
1645 TRACE("(%p): Relay\n", This);
1647 EnterCriticalSection(&ddraw_cs);
1648 hr = IWineD3DDevice_BeginScene(This->wineD3DDevice);
1649 LeaveCriticalSection(&ddraw_cs);
1650 if(hr == WINED3D_OK) return D3D_OK;
1651 else return D3DERR_SCENE_IN_SCENE; /* TODO: Other possible causes of failure */
1654 static HRESULT WINAPI
1655 IDirect3DDeviceImpl_7_BeginScene_FPUSetup(IDirect3DDevice7 *iface)
1657 return IDirect3DDeviceImpl_7_BeginScene(iface);
1660 static HRESULT WINAPI
1661 IDirect3DDeviceImpl_7_BeginScene_FPUPreserve(IDirect3DDevice7 *iface)
1666 old_fpucw = d3d_fpu_setup();
1667 hr = IDirect3DDeviceImpl_7_BeginScene(iface);
1668 set_fpu_control_word(old_fpucw);
1673 static HRESULT WINAPI
1674 Thunk_IDirect3DDeviceImpl_3_BeginScene(IDirect3DDevice3 *iface)
1676 IDirect3DDeviceImpl *This = device_from_device3(iface);
1677 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
1678 return IDirect3DDevice7_BeginScene((IDirect3DDevice7 *)This);
1681 static HRESULT WINAPI
1682 Thunk_IDirect3DDeviceImpl_2_BeginScene(IDirect3DDevice2 *iface)
1684 IDirect3DDeviceImpl *This = device_from_device2(iface);
1685 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
1686 return IDirect3DDevice7_BeginScene((IDirect3DDevice7 *)This);
1689 static HRESULT WINAPI
1690 Thunk_IDirect3DDeviceImpl_1_BeginScene(IDirect3DDevice *iface)
1692 IDirect3DDeviceImpl *This = device_from_device1(iface);
1693 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
1694 return IDirect3DDevice7_BeginScene((IDirect3DDevice7 *)This);
1697 /*****************************************************************************
1698 * IDirect3DDevice7::EndScene
1700 * Ends a scene that has been begun with IDirect3DDevice7::BeginScene.
1701 * This method must be called after rendering is finished.
1703 * Version 1, 2, 3 and 7
1706 * D3D_OK on success, for details see IWineD3DDevice::EndScene
1707 * D3DERR_SCENE_NOT_IN_SCENE is returned if WineD3D returns an error. It does
1708 * that only if the scene was already ended.
1710 *****************************************************************************/
1712 IDirect3DDeviceImpl_7_EndScene(IDirect3DDevice7 *iface)
1714 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
1716 TRACE("(%p): Relay\n", This);
1718 EnterCriticalSection(&ddraw_cs);
1719 hr = IWineD3DDevice_EndScene(This->wineD3DDevice);
1720 LeaveCriticalSection(&ddraw_cs);
1721 if(hr == WINED3D_OK) return D3D_OK;
1722 else return D3DERR_SCENE_NOT_IN_SCENE;
1725 static HRESULT WINAPI DECLSPEC_HOTPATCH
1726 IDirect3DDeviceImpl_7_EndScene_FPUSetup(IDirect3DDevice7 *iface)
1728 return IDirect3DDeviceImpl_7_EndScene(iface);
1731 static HRESULT WINAPI DECLSPEC_HOTPATCH
1732 IDirect3DDeviceImpl_7_EndScene_FPUPreserve(IDirect3DDevice7 *iface)
1737 old_fpucw = d3d_fpu_setup();
1738 hr = IDirect3DDeviceImpl_7_EndScene(iface);
1739 set_fpu_control_word(old_fpucw);
1744 static HRESULT WINAPI DECLSPEC_HOTPATCH
1745 Thunk_IDirect3DDeviceImpl_3_EndScene(IDirect3DDevice3 *iface)
1747 IDirect3DDeviceImpl *This = device_from_device3(iface);
1748 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
1749 return IDirect3DDevice7_EndScene((IDirect3DDevice7 *)This);
1752 static HRESULT WINAPI DECLSPEC_HOTPATCH
1753 Thunk_IDirect3DDeviceImpl_2_EndScene(IDirect3DDevice2 *iface)
1755 IDirect3DDeviceImpl *This = device_from_device2(iface);
1756 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
1757 return IDirect3DDevice7_EndScene((IDirect3DDevice7 *)This);
1760 static HRESULT WINAPI DECLSPEC_HOTPATCH
1761 Thunk_IDirect3DDeviceImpl_1_EndScene(IDirect3DDevice *iface)
1763 IDirect3DDeviceImpl *This = device_from_device1(iface);
1764 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
1765 return IDirect3DDevice7_EndScene((IDirect3DDevice7 *)This);
1768 /*****************************************************************************
1769 * IDirect3DDevice7::GetDirect3D
1771 * Returns the IDirect3D(= interface to the DirectDraw object) used to create
1775 * Direct3D7: Address to store the interface pointer at
1779 * DDERR_INVALIDPARAMS if Direct3D7 == NULL
1781 *****************************************************************************/
1782 static HRESULT WINAPI
1783 IDirect3DDeviceImpl_7_GetDirect3D(IDirect3DDevice7 *iface,
1784 IDirect3D7 **Direct3D7)
1786 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
1787 TRACE("(%p)->(%p)\n", This, Direct3D7);
1790 return DDERR_INVALIDPARAMS;
1792 *Direct3D7 = (IDirect3D7 *)&This->ddraw->IDirect3D7_vtbl;
1793 IDirect3D7_AddRef(*Direct3D7);
1795 TRACE(" returning interface %p\n", *Direct3D7);
1799 static HRESULT WINAPI
1800 Thunk_IDirect3DDeviceImpl_3_GetDirect3D(IDirect3DDevice3 *iface,
1801 IDirect3D3 **Direct3D3)
1803 IDirect3DDeviceImpl *This = device_from_device3(iface);
1805 IDirect3D7 *ret_ptr;
1807 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, Direct3D3);
1808 ret = IDirect3DDevice7_GetDirect3D((IDirect3DDevice7 *)This, &ret_ptr);
1811 *Direct3D3 = ret_ptr ? (IDirect3D3 *)&ddraw_from_d3d7(ret_ptr)->IDirect3D3_vtbl : NULL;
1812 TRACE(" returning interface %p\n", *Direct3D3);
1816 static HRESULT WINAPI
1817 Thunk_IDirect3DDeviceImpl_2_GetDirect3D(IDirect3DDevice2 *iface,
1818 IDirect3D2 **Direct3D2)
1820 IDirect3DDeviceImpl *This = device_from_device2(iface);
1822 IDirect3D7 *ret_ptr;
1824 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, Direct3D2);
1825 ret = IDirect3DDevice7_GetDirect3D((IDirect3DDevice7 *)This, &ret_ptr);
1828 *Direct3D2 = ret_ptr ? (IDirect3D2 *)&ddraw_from_d3d7(ret_ptr)->IDirect3D2_vtbl : NULL;
1829 TRACE(" returning interface %p\n", *Direct3D2);
1833 static HRESULT WINAPI
1834 Thunk_IDirect3DDeviceImpl_1_GetDirect3D(IDirect3DDevice *iface,
1835 IDirect3D **Direct3D)
1837 IDirect3DDeviceImpl *This = device_from_device1(iface);
1839 IDirect3D7 *ret_ptr;
1841 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, Direct3D);
1842 ret = IDirect3DDevice7_GetDirect3D((IDirect3DDevice7 *)This, &ret_ptr);
1845 *Direct3D = ret_ptr ? (IDirect3D *)&ddraw_from_d3d7(ret_ptr)->IDirect3D_vtbl : NULL;
1846 TRACE(" returning interface %p\n", *Direct3D);
1850 /*****************************************************************************
1851 * IDirect3DDevice3::SetCurrentViewport
1853 * Sets a Direct3DViewport as the current viewport.
1854 * For the thunks note that all viewport interface versions are equal
1857 * Direct3DViewport3: The viewport to set
1863 * (Is a NULL viewport valid?)
1865 *****************************************************************************/
1866 static HRESULT WINAPI
1867 IDirect3DDeviceImpl_3_SetCurrentViewport(IDirect3DDevice3 *iface,
1868 IDirect3DViewport3 *Direct3DViewport3)
1870 IDirect3DDeviceImpl *This = device_from_device3(iface);
1871 IDirect3DViewportImpl *vp = (IDirect3DViewportImpl *)Direct3DViewport3;
1872 TRACE("(%p)->(%p)\n", This, Direct3DViewport3);
1874 EnterCriticalSection(&ddraw_cs);
1875 /* Do nothing if the specified viewport is the same as the current one */
1876 if (This->current_viewport == vp )
1878 LeaveCriticalSection(&ddraw_cs);
1882 /* Should check if the viewport was added or not */
1884 /* Release previous viewport and AddRef the new one */
1885 if (This->current_viewport)
1887 TRACE("ViewportImpl is at %p, interface is at %p\n", This->current_viewport,
1888 (IDirect3DViewport3 *)This->current_viewport);
1889 IDirect3DViewport3_Release((IDirect3DViewport3 *)This->current_viewport);
1891 IDirect3DViewport3_AddRef(Direct3DViewport3);
1893 /* Set this viewport as the current viewport */
1894 This->current_viewport = vp;
1896 /* Activate this viewport */
1897 This->current_viewport->active_device = This;
1898 This->current_viewport->activate(This->current_viewport, FALSE);
1900 LeaveCriticalSection(&ddraw_cs);
1904 static HRESULT WINAPI
1905 Thunk_IDirect3DDeviceImpl_2_SetCurrentViewport(IDirect3DDevice2 *iface,
1906 IDirect3DViewport2 *Direct3DViewport2)
1908 IDirect3DDeviceImpl *This = device_from_device2(iface);
1909 IDirect3DViewportImpl *vp = (IDirect3DViewportImpl *)Direct3DViewport2;
1910 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, vp);
1911 return IDirect3DDevice3_SetCurrentViewport((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl,
1912 (IDirect3DViewport3 *)vp);
1915 /*****************************************************************************
1916 * IDirect3DDevice3::GetCurrentViewport
1918 * Returns the currently active viewport.
1923 * Direct3DViewport3: Address to return the interface pointer at
1927 * DDERR_INVALIDPARAMS if Direct3DViewport == NULL
1929 *****************************************************************************/
1930 static HRESULT WINAPI
1931 IDirect3DDeviceImpl_3_GetCurrentViewport(IDirect3DDevice3 *iface,
1932 IDirect3DViewport3 **Direct3DViewport3)
1934 IDirect3DDeviceImpl *This = device_from_device3(iface);
1935 TRACE("(%p)->(%p)\n", This, Direct3DViewport3);
1937 if(!Direct3DViewport3)
1938 return DDERR_INVALIDPARAMS;
1940 EnterCriticalSection(&ddraw_cs);
1941 *Direct3DViewport3 = (IDirect3DViewport3 *)This->current_viewport;
1943 /* AddRef the returned viewport */
1944 if(*Direct3DViewport3) IDirect3DViewport3_AddRef(*Direct3DViewport3);
1946 TRACE(" returning interface %p\n", *Direct3DViewport3);
1948 LeaveCriticalSection(&ddraw_cs);
1952 static HRESULT WINAPI
1953 Thunk_IDirect3DDeviceImpl_2_GetCurrentViewport(IDirect3DDevice2 *iface,
1954 IDirect3DViewport2 **Direct3DViewport2)
1956 IDirect3DDeviceImpl *This = device_from_device2(iface);
1958 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, Direct3DViewport2);
1959 hr = IDirect3DDevice3_GetCurrentViewport((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl,
1960 (IDirect3DViewport3 **)Direct3DViewport2);
1961 if(hr != D3D_OK) return hr;
1965 /*****************************************************************************
1966 * IDirect3DDevice7::SetRenderTarget
1968 * Sets the render target for the Direct3DDevice.
1969 * For the thunks note that IDirectDrawSurface7 == IDirectDrawSurface4 and
1970 * IDirectDrawSurface3 == IDirectDrawSurface
1972 * Version 2, 3 and 7
1975 * NewTarget: Pointer to an IDirectDrawSurface7 interface to set as the new
1980 * D3D_OK on success, for details see IWineD3DDevice::SetRenderTarget
1982 *****************************************************************************/
1984 IDirect3DDeviceImpl_7_SetRenderTarget(IDirect3DDevice7 *iface,
1985 IDirectDrawSurface7 *NewTarget,
1988 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
1989 IDirectDrawSurfaceImpl *Target = (IDirectDrawSurfaceImpl *)NewTarget;
1991 TRACE("(%p)->(%p,%08x): Relay\n", This, NewTarget, Flags);
1993 EnterCriticalSection(&ddraw_cs);
1994 /* Flags: Not used */
1996 if(This->target == Target)
1998 TRACE("No-op SetRenderTarget operation, not doing anything\n");
1999 LeaveCriticalSection(&ddraw_cs);
2003 hr = IWineD3DDevice_SetRenderTarget(This->wineD3DDevice,
2005 Target ? Target->WineD3DSurface : NULL,
2009 LeaveCriticalSection(&ddraw_cs);
2012 IDirectDrawSurface7_AddRef(NewTarget);
2013 IDirectDrawSurface7_Release((IDirectDrawSurface7 *)This->target);
2014 This->target = Target;
2015 IDirect3DDeviceImpl_UpdateDepthStencil(This);
2016 LeaveCriticalSection(&ddraw_cs);
2020 static HRESULT WINAPI
2021 IDirect3DDeviceImpl_7_SetRenderTarget_FPUSetup(IDirect3DDevice7 *iface,
2022 IDirectDrawSurface7 *NewTarget,
2025 return IDirect3DDeviceImpl_7_SetRenderTarget(iface, NewTarget, Flags);
2028 static HRESULT WINAPI
2029 IDirect3DDeviceImpl_7_SetRenderTarget_FPUPreserve(IDirect3DDevice7 *iface,
2030 IDirectDrawSurface7 *NewTarget,
2036 old_fpucw = d3d_fpu_setup();
2037 hr = IDirect3DDeviceImpl_7_SetRenderTarget(iface, NewTarget, Flags);
2038 set_fpu_control_word(old_fpucw);
2043 static HRESULT WINAPI
2044 Thunk_IDirect3DDeviceImpl_3_SetRenderTarget(IDirect3DDevice3 *iface,
2045 IDirectDrawSurface4 *NewRenderTarget,
2048 IDirect3DDeviceImpl *This = device_from_device3(iface);
2049 IDirectDrawSurfaceImpl *Target = (IDirectDrawSurfaceImpl *)NewRenderTarget;
2050 TRACE_(ddraw_thunk)("(%p)->(%p,%08x) thunking to IDirect3DDevice7 interface.\n", This, Target, Flags);
2051 return IDirect3DDevice7_SetRenderTarget((IDirect3DDevice7 *)This, (IDirectDrawSurface7 *)Target, Flags);
2054 static HRESULT WINAPI
2055 Thunk_IDirect3DDeviceImpl_2_SetRenderTarget(IDirect3DDevice2 *iface,
2056 IDirectDrawSurface *NewRenderTarget,
2059 IDirect3DDeviceImpl *This = device_from_device2(iface);
2060 IDirectDrawSurfaceImpl *Target = (IDirectDrawSurfaceImpl *)NewRenderTarget;
2061 TRACE_(ddraw_thunk)("(%p)->(%p,%08x) thunking to IDirect3DDevice7 interface.\n", This, Target, Flags);
2062 return IDirect3DDevice7_SetRenderTarget((IDirect3DDevice7 *)This, (IDirectDrawSurface7 *)Target, Flags);
2065 /*****************************************************************************
2066 * IDirect3DDevice7::GetRenderTarget
2068 * Returns the current render target.
2069 * This is handled locally, because the WineD3D render target's parent
2072 * Version 2, 3 and 7
2075 * RenderTarget: Address to store the surface interface pointer
2079 * DDERR_INVALIDPARAMS if RenderTarget == NULL
2081 *****************************************************************************/
2082 static HRESULT WINAPI
2083 IDirect3DDeviceImpl_7_GetRenderTarget(IDirect3DDevice7 *iface,
2084 IDirectDrawSurface7 **RenderTarget)
2086 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
2087 TRACE("(%p)->(%p): Relay\n", This, RenderTarget);
2090 return DDERR_INVALIDPARAMS;
2092 EnterCriticalSection(&ddraw_cs);
2093 *RenderTarget = (IDirectDrawSurface7 *)This->target;
2094 IDirectDrawSurface7_AddRef(*RenderTarget);
2096 LeaveCriticalSection(&ddraw_cs);
2100 static HRESULT WINAPI
2101 Thunk_IDirect3DDeviceImpl_3_GetRenderTarget(IDirect3DDevice3 *iface,
2102 IDirectDrawSurface4 **RenderTarget)
2104 IDirect3DDeviceImpl *This = device_from_device3(iface);
2106 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, RenderTarget);
2107 hr = IDirect3DDevice7_GetRenderTarget((IDirect3DDevice7 *)This, (IDirectDrawSurface7 **)RenderTarget);
2108 if(hr != D3D_OK) return hr;
2112 static HRESULT WINAPI
2113 Thunk_IDirect3DDeviceImpl_2_GetRenderTarget(IDirect3DDevice2 *iface,
2114 IDirectDrawSurface **RenderTarget)
2116 IDirect3DDeviceImpl *This = device_from_device2(iface);
2118 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, RenderTarget);
2119 hr = IDirect3DDevice7_GetRenderTarget((IDirect3DDevice7 *)This, (IDirectDrawSurface7 **)RenderTarget);
2120 if(hr != D3D_OK) return hr;
2121 *RenderTarget = *RenderTarget ?
2122 (IDirectDrawSurface *)&((IDirectDrawSurfaceImpl *)*RenderTarget)->IDirectDrawSurface3_vtbl : NULL;
2126 /*****************************************************************************
2127 * IDirect3DDevice3::Begin
2129 * Begins a description block of vertices. This is similar to glBegin()
2130 * and glEnd(). After a call to IDirect3DDevice3::End, the vertices
2131 * described with IDirect3DDevice::Vertex are drawn.
2136 * PrimitiveType: The type of primitives to draw
2137 * VertexTypeDesc: A flexible vertex format description of the vertices
2138 * Flags: Some flags..
2143 *****************************************************************************/
2144 static HRESULT WINAPI
2145 IDirect3DDeviceImpl_3_Begin(IDirect3DDevice3 *iface,
2146 D3DPRIMITIVETYPE PrimitiveType,
2147 DWORD VertexTypeDesc,
2150 IDirect3DDeviceImpl *This = device_from_device3(iface);
2151 TRACE("(%p)->(%d,%d,%08x)\n", This, PrimitiveType, VertexTypeDesc, Flags);
2153 EnterCriticalSection(&ddraw_cs);
2154 This->primitive_type = PrimitiveType;
2155 This->vertex_type = VertexTypeDesc;
2156 This->render_flags = Flags;
2157 This->vertex_size = get_flexible_vertex_size(This->vertex_type);
2158 This->nb_vertices = 0;
2159 LeaveCriticalSection(&ddraw_cs);
2164 static HRESULT WINAPI
2165 Thunk_IDirect3DDeviceImpl_2_Begin(IDirect3DDevice2 *iface,
2166 D3DPRIMITIVETYPE d3dpt,
2167 D3DVERTEXTYPE dwVertexTypeDesc,
2171 IDirect3DDeviceImpl *This = device_from_device2(iface);
2172 TRACE_(ddraw_thunk)("(%p/%p)->(%08x,%08x,%08x): Thunking to IDirect3DDevice3\n", This, iface, d3dpt, dwVertexTypeDesc, dwFlags);
2174 switch(dwVertexTypeDesc)
2176 case D3DVT_VERTEX: FVF = D3DFVF_VERTEX; break;
2177 case D3DVT_LVERTEX: FVF = D3DFVF_LVERTEX; break;
2178 case D3DVT_TLVERTEX: FVF = D3DFVF_TLVERTEX; break;
2180 ERR("Unexpected vertex type %d\n", dwVertexTypeDesc);
2181 return DDERR_INVALIDPARAMS; /* Should never happen */
2184 return IDirect3DDevice3_Begin((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl, d3dpt, FVF, dwFlags);
2187 /*****************************************************************************
2188 * IDirect3DDevice3::BeginIndexed
2190 * Draws primitives based on vertices in a vertex array which are specified
2196 * PrimitiveType: Primitive type to draw
2197 * VertexType: A FVF description of the vertex format
2198 * Vertices: pointer to an array containing the vertices
2199 * NumVertices: The number of vertices in the vertex array
2200 * Flags: Some flags ...
2203 * D3D_OK, because it's a stub
2205 *****************************************************************************/
2206 static HRESULT WINAPI
2207 IDirect3DDeviceImpl_3_BeginIndexed(IDirect3DDevice3 *iface,
2208 D3DPRIMITIVETYPE PrimitiveType,
2214 IDirect3DDeviceImpl *This = device_from_device3(iface);
2215 FIXME("(%p)->(%08x,%08x,%p,%08x,%08x): stub!\n", This, PrimitiveType, VertexType, Vertices, NumVertices, Flags);
2220 static HRESULT WINAPI
2221 Thunk_IDirect3DDeviceImpl_2_BeginIndexed(IDirect3DDevice2 *iface,
2222 D3DPRIMITIVETYPE d3dptPrimitiveType,
2223 D3DVERTEXTYPE d3dvtVertexType,
2225 DWORD dwNumVertices,
2229 IDirect3DDeviceImpl *This = device_from_device2(iface);
2230 TRACE_(ddraw_thunk)("(%p/%p)->(%08x,%08x,%p,%08x,%08x): Thunking to IDirect3DDevice3\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwNumVertices, dwFlags);
2232 switch(d3dvtVertexType)
2234 case D3DVT_VERTEX: FVF = D3DFVF_VERTEX; break;
2235 case D3DVT_LVERTEX: FVF = D3DFVF_LVERTEX; break;
2236 case D3DVT_TLVERTEX: FVF = D3DFVF_TLVERTEX; break;
2238 ERR("Unexpected vertex type %d\n", d3dvtVertexType);
2239 return DDERR_INVALIDPARAMS; /* Should never happen */
2242 return IDirect3DDevice3_BeginIndexed((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl,
2243 d3dptPrimitiveType, FVF, lpvVertices, dwNumVertices, dwFlags);
2246 /*****************************************************************************
2247 * IDirect3DDevice3::Vertex
2249 * Draws a vertex as described by IDirect3DDevice3::Begin. It places all
2250 * drawn vertices in a vertex buffer. If the buffer is too small, its
2251 * size is increased.
2256 * Vertex: Pointer to the vertex
2259 * D3D_OK, on success
2260 * DDERR_INVALIDPARAMS if Vertex is NULL
2262 *****************************************************************************/
2263 static HRESULT WINAPI
2264 IDirect3DDeviceImpl_3_Vertex(IDirect3DDevice3 *iface,
2267 IDirect3DDeviceImpl *This = device_from_device3(iface);
2268 TRACE("(%p)->(%p)\n", This, Vertex);
2271 return DDERR_INVALIDPARAMS;
2273 EnterCriticalSection(&ddraw_cs);
2274 if ((This->nb_vertices+1)*This->vertex_size > This->buffer_size)
2277 This->buffer_size = This->buffer_size ? This->buffer_size * 2 : This->vertex_size * 3;
2278 old_buffer = This->vertex_buffer;
2279 This->vertex_buffer = HeapAlloc(GetProcessHeap(), 0, This->buffer_size);
2282 CopyMemory(This->vertex_buffer, old_buffer, This->nb_vertices * This->vertex_size);
2283 HeapFree(GetProcessHeap(), 0, old_buffer);
2287 CopyMemory(This->vertex_buffer + This->nb_vertices++ * This->vertex_size, Vertex, This->vertex_size);
2289 LeaveCriticalSection(&ddraw_cs);
2293 static HRESULT WINAPI
2294 Thunk_IDirect3DDeviceImpl_2_Vertex(IDirect3DDevice2 *iface,
2297 IDirect3DDeviceImpl *This = device_from_device2(iface);
2298 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, lpVertexType);
2299 return IDirect3DDevice3_Vertex((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl, lpVertexType);
2302 /*****************************************************************************
2303 * IDirect3DDevice3::Index
2305 * Specifies an index to a vertex to be drawn. The vertex array has to
2306 * be specified with BeginIndexed first.
2309 * VertexIndex: The index of the vertex to draw
2312 * D3D_OK because it's a stub
2314 *****************************************************************************/
2315 static HRESULT WINAPI
2316 IDirect3DDeviceImpl_3_Index(IDirect3DDevice3 *iface,
2319 IDirect3DDeviceImpl *This = device_from_device3(iface);
2320 FIXME("(%p)->(%04x): stub!\n", This, VertexIndex);
2324 static HRESULT WINAPI
2325 Thunk_IDirect3DDeviceImpl_2_Index(IDirect3DDevice2 *iface,
2328 IDirect3DDeviceImpl *This = device_from_device2(iface);
2329 TRACE_(ddraw_thunk)("(%p)->(%04x) thunking to IDirect3DDevice3 interface.\n", This, wVertexIndex);
2330 return IDirect3DDevice3_Index((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl, wVertexIndex);
2333 /*****************************************************************************
2334 * IDirect3DDevice3::End
2336 * Ends a draw begun with IDirect3DDevice3::Begin or
2337 * IDirect3DDevice::BeginIndexed. The vertices specified with
2338 * IDirect3DDevice::Vertex or IDirect3DDevice::Index are drawn using
2339 * the IDirect3DDevice7::DrawPrimitive method. So far only
2340 * non-indexed mode is supported
2345 * Flags: Some flags, as usual. Don't know which are defined
2348 * The return value of IDirect3DDevice7::DrawPrimitive
2350 *****************************************************************************/
2351 static HRESULT WINAPI
2352 IDirect3DDeviceImpl_3_End(IDirect3DDevice3 *iface,
2355 IDirect3DDeviceImpl *This = device_from_device3(iface);
2356 TRACE("(%p)->(%08x)\n", This, Flags);
2358 return IDirect3DDevice7_DrawPrimitive((IDirect3DDevice7 *)This, This->primitive_type,
2359 This->vertex_type, This->vertex_buffer, This->nb_vertices, This->render_flags);
2362 static HRESULT WINAPI
2363 Thunk_IDirect3DDeviceImpl_2_End(IDirect3DDevice2 *iface,
2366 IDirect3DDeviceImpl *This = device_from_device2(iface);
2367 TRACE_(ddraw_thunk)("(%p)->(%08x) thunking to IDirect3DDevice3 interface.\n", This, dwFlags);
2368 return IDirect3DDevice3_End((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl, dwFlags);
2371 /*****************************************************************************
2372 * IDirect3DDevice7::GetRenderState
2374 * Returns the value of a render state. The possible render states are
2375 * defined in include/d3dtypes.h
2377 * Version 2, 3 and 7
2380 * RenderStateType: Render state to return the current setting of
2381 * Value: Address to store the value at
2384 * D3D_OK on success, for details see IWineD3DDevice::GetRenderState
2385 * DDERR_INVALIDPARAMS if Value == NULL
2387 *****************************************************************************/
2389 IDirect3DDeviceImpl_7_GetRenderState(IDirect3DDevice7 *iface,
2390 D3DRENDERSTATETYPE RenderStateType,
2393 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
2395 TRACE("(%p)->(%08x,%p): Relay\n", This, RenderStateType, Value);
2398 return DDERR_INVALIDPARAMS;
2400 EnterCriticalSection(&ddraw_cs);
2401 switch(RenderStateType)
2403 case D3DRENDERSTATE_TEXTUREMAG:
2405 WINED3DTEXTUREFILTERTYPE tex_mag;
2407 hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice,
2408 0, WINED3DSAMP_MAGFILTER,
2413 case WINED3DTEXF_POINT:
2414 *Value = D3DFILTER_NEAREST;
2416 case WINED3DTEXF_LINEAR:
2417 *Value = D3DFILTER_LINEAR;
2420 ERR("Unhandled texture mag %d !\n",tex_mag);
2426 case D3DRENDERSTATE_TEXTUREMIN:
2428 WINED3DTEXTUREFILTERTYPE tex_min;
2429 WINED3DTEXTUREFILTERTYPE tex_mip;
2431 hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice,
2432 0, WINED3DSAMP_MINFILTER, &tex_min);
2435 LeaveCriticalSection(&ddraw_cs);
2438 hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice,
2439 0, WINED3DSAMP_MIPFILTER, &tex_mip);
2443 case WINED3DTEXF_POINT:
2446 case WINED3DTEXF_NONE:
2447 *Value = D3DFILTER_NEAREST;
2449 case WINED3DTEXF_POINT:
2450 *Value = D3DFILTER_MIPNEAREST;
2452 case WINED3DTEXF_LINEAR:
2453 *Value = D3DFILTER_LINEARMIPNEAREST;
2456 ERR("Unhandled mip filter %#x.\n", tex_mip);
2457 *Value = D3DFILTER_NEAREST;
2461 case WINED3DTEXF_LINEAR:
2464 case WINED3DTEXF_NONE:
2465 *Value = D3DFILTER_LINEAR;
2467 case WINED3DTEXF_POINT:
2468 *Value = D3DFILTER_MIPLINEAR;
2470 case WINED3DTEXF_LINEAR:
2471 *Value = D3DFILTER_LINEARMIPLINEAR;
2474 ERR("Unhandled mip filter %#x.\n", tex_mip);
2475 *Value = D3DFILTER_LINEAR;
2480 ERR("Unhandled texture min filter %#x.\n",tex_min);
2481 *Value = D3DFILTER_NEAREST;
2487 case D3DRENDERSTATE_TEXTUREADDRESS:
2488 case D3DRENDERSTATE_TEXTUREADDRESSU:
2489 hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice,
2490 0, WINED3DSAMP_ADDRESSU,
2493 case D3DRENDERSTATE_TEXTUREADDRESSV:
2494 hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice,
2495 0, WINED3DSAMP_ADDRESSV,
2499 case D3DRENDERSTATE_BORDERCOLOR:
2500 FIXME("Unhandled render state D3DRENDERSTATE_BORDERCOLOR.\n");
2505 if (RenderStateType >= D3DRENDERSTATE_STIPPLEPATTERN00
2506 && RenderStateType <= D3DRENDERSTATE_STIPPLEPATTERN31)
2508 FIXME("Unhandled stipple pattern render state (%#x).\n",
2513 hr = IWineD3DDevice_GetRenderState(This->wineD3DDevice,
2517 LeaveCriticalSection(&ddraw_cs);
2521 static HRESULT WINAPI
2522 IDirect3DDeviceImpl_7_GetRenderState_FPUSetup(IDirect3DDevice7 *iface,
2523 D3DRENDERSTATETYPE RenderStateType,
2526 return IDirect3DDeviceImpl_7_GetRenderState(iface, RenderStateType, Value);
2529 static HRESULT WINAPI
2530 IDirect3DDeviceImpl_7_GetRenderState_FPUPreserve(IDirect3DDevice7 *iface,
2531 D3DRENDERSTATETYPE RenderStateType,
2537 old_fpucw = d3d_fpu_setup();
2538 hr = IDirect3DDeviceImpl_7_GetRenderState(iface, RenderStateType, Value);
2539 set_fpu_control_word(old_fpucw);
2544 static HRESULT WINAPI
2545 IDirect3DDeviceImpl_3_GetRenderState(IDirect3DDevice3 *iface,
2546 D3DRENDERSTATETYPE dwRenderStateType,
2547 DWORD *lpdwRenderState)
2549 IDirect3DDeviceImpl *This = device_from_device3(iface);
2551 TRACE("(%p)->(%08x,%p)\n", This, dwRenderStateType, lpdwRenderState);
2553 switch(dwRenderStateType)
2555 case D3DRENDERSTATE_TEXTUREHANDLE:
2557 /* This state is wrapped to SetTexture in SetRenderState, so
2558 * it has to be wrapped to GetTexture here
2560 IWineD3DBaseTexture *tex = NULL;
2561 *lpdwRenderState = 0;
2563 EnterCriticalSection(&ddraw_cs);
2565 hr = IWineD3DDevice_GetTexture(This->wineD3DDevice,
2569 if(hr == WINED3D_OK && tex)
2571 IDirectDrawSurface7 *parent = NULL;
2572 hr = IWineD3DBaseTexture_GetParent(tex,
2573 (IUnknown **) &parent);
2576 /* The parent of the texture is the IDirectDrawSurface7 interface
2577 * of the ddraw surface
2579 IDirectDrawSurfaceImpl *texImpl = (IDirectDrawSurfaceImpl *)parent;
2580 *lpdwRenderState = texImpl->Handle;
2581 IDirectDrawSurface7_Release(parent);
2583 IWineD3DBaseTexture_Release(tex);
2586 LeaveCriticalSection(&ddraw_cs);
2591 case D3DRENDERSTATE_TEXTUREMAPBLEND:
2593 /* D3DRENDERSTATE_TEXTUREMAPBLEND is mapped to texture state stages in SetRenderState; reverse
2594 the mapping to get the value. */
2595 DWORD colorop, colorarg1, colorarg2;
2596 DWORD alphaop, alphaarg1, alphaarg2;
2598 EnterCriticalSection(&ddraw_cs);
2600 This->legacyTextureBlending = TRUE;
2602 IWineD3DDevice_GetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLOROP, &colorop);
2603 IWineD3DDevice_GetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG1, &colorarg1);
2604 IWineD3DDevice_GetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG2, &colorarg2);
2605 IWineD3DDevice_GetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAOP, &alphaop);
2606 IWineD3DDevice_GetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG1, &alphaarg1);
2607 IWineD3DDevice_GetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG2, &alphaarg2);
2609 if (colorop == WINED3DTOP_SELECTARG1 && colorarg1 == WINED3DTA_TEXTURE &&
2610 alphaop == WINED3DTOP_SELECTARG1 && alphaarg1 == WINED3DTA_TEXTURE)
2612 *lpdwRenderState = D3DTBLEND_DECAL;
2614 else if (colorop == WINED3DTOP_SELECTARG1 && colorarg1 == WINED3DTA_TEXTURE &&
2615 alphaop == WINED3DTOP_MODULATE && alphaarg1 == WINED3DTA_TEXTURE && alphaarg2 == WINED3DTA_CURRENT)
2617 *lpdwRenderState = D3DTBLEND_DECALALPHA;
2619 else if (colorop == WINED3DTOP_MODULATE && colorarg1 == WINED3DTA_TEXTURE && colorarg2 == WINED3DTA_CURRENT &&
2620 alphaop == WINED3DTOP_MODULATE && alphaarg1 == WINED3DTA_TEXTURE && alphaarg2 == WINED3DTA_CURRENT)
2622 *lpdwRenderState = D3DTBLEND_MODULATEALPHA;
2627 BOOL tex_alpha = FALSE;
2628 IWineD3DBaseTexture *tex = NULL;
2629 WINED3DSURFACE_DESC desc;
2630 DDPIXELFORMAT ddfmt;
2632 hr = IWineD3DDevice_GetTexture(This->wineD3DDevice,
2636 if(hr == WINED3D_OK && tex)
2638 hr = IWineD3DTexture_GetLevelDesc((IWineD3DTexture*) tex, 0, &desc);
2641 ddfmt.dwSize = sizeof(ddfmt);
2642 PixelFormat_WineD3DtoDD(&ddfmt, desc.format);
2643 if (ddfmt.u5.dwRGBAlphaBitMask) tex_alpha = TRUE;
2646 IWineD3DBaseTexture_Release(tex);
2649 if (!(colorop == WINED3DTOP_MODULATE && colorarg1 == WINED3DTA_TEXTURE && colorarg2 == WINED3DTA_CURRENT &&
2650 alphaop == (tex_alpha ? WINED3DTOP_SELECTARG1 : WINED3DTOP_SELECTARG2) &&
2651 alphaarg1 == WINED3DTA_TEXTURE && alphaarg2 == WINED3DTA_CURRENT))
2653 ERR("Unexpected texture stage state setup, returning D3DTBLEND_MODULATE - likely erroneous\n");
2656 *lpdwRenderState = D3DTBLEND_MODULATE;
2659 LeaveCriticalSection(&ddraw_cs);
2665 return IDirect3DDevice7_GetRenderState((IDirect3DDevice7 *)This, dwRenderStateType, lpdwRenderState);
2669 static HRESULT WINAPI
2670 Thunk_IDirect3DDeviceImpl_2_GetRenderState(IDirect3DDevice2 *iface,
2671 D3DRENDERSTATETYPE dwRenderStateType,
2672 DWORD *lpdwRenderState)
2674 IDirect3DDeviceImpl *This = device_from_device2(iface);
2675 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice3 interface.\n", This, dwRenderStateType, lpdwRenderState);
2676 return IDirect3DDevice3_GetRenderState((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl,
2677 dwRenderStateType, lpdwRenderState);
2680 /*****************************************************************************
2681 * IDirect3DDevice7::SetRenderState
2683 * Sets a render state. The possible render states are defined in
2684 * include/d3dtypes.h
2686 * Version 2, 3 and 7
2689 * RenderStateType: State to set
2690 * Value: Value to assign to that state
2693 * D3D_OK on success,
2694 * for details see IWineD3DDevice::SetRenderState
2696 *****************************************************************************/
2698 IDirect3DDeviceImpl_7_SetRenderState(IDirect3DDevice7 *iface,
2699 D3DRENDERSTATETYPE RenderStateType,
2702 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
2704 TRACE("(%p)->(%08x,%d): Relay\n", This, RenderStateType, Value);
2706 EnterCriticalSection(&ddraw_cs);
2707 /* Some render states need special care */
2708 switch(RenderStateType)
2711 * The ddraw texture filter mapping works like this:
2712 * D3DFILTER_NEAREST Point min/mag, no mip
2713 * D3DFILTER_MIPNEAREST Point min/mag, point mip
2714 * D3DFILTER_LINEARMIPNEAREST: Point min/mag, linear mip
2716 * D3DFILTER_LINEAR Linear min/mag, no mip
2717 * D3DFILTER_MIPLINEAR Linear min/mag, point mip
2718 * D3DFILTER_LINEARMIPLINEAR Linear min/mag, linear mip
2720 * This is the opposite of the GL naming convention,
2721 * D3DFILTER_LINEARMIPNEAREST corresponds to GL_NEAREST_MIPMAP_LINEAR.
2723 case D3DRENDERSTATE_TEXTUREMAG:
2725 WINED3DTEXTUREFILTERTYPE tex_mag;
2729 case D3DFILTER_NEAREST:
2730 case D3DFILTER_MIPNEAREST:
2731 case D3DFILTER_LINEARMIPNEAREST:
2732 tex_mag = WINED3DTEXF_POINT;
2734 case D3DFILTER_LINEAR:
2735 case D3DFILTER_MIPLINEAR:
2736 case D3DFILTER_LINEARMIPLINEAR:
2737 tex_mag = WINED3DTEXF_LINEAR;
2740 tex_mag = WINED3DTEXF_POINT;
2741 ERR("Unhandled texture mag %d !\n",Value);
2745 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
2746 0, WINED3DSAMP_MAGFILTER,
2751 case D3DRENDERSTATE_TEXTUREMIN:
2753 WINED3DTEXTUREFILTERTYPE tex_min;
2754 WINED3DTEXTUREFILTERTYPE tex_mip;
2756 switch ((D3DTEXTUREFILTER) Value)
2758 case D3DFILTER_NEAREST:
2759 tex_min = WINED3DTEXF_POINT;
2760 tex_mip = WINED3DTEXF_NONE;
2762 case D3DFILTER_LINEAR:
2763 tex_min = WINED3DTEXF_LINEAR;
2764 tex_mip = WINED3DTEXF_NONE;
2766 case D3DFILTER_MIPNEAREST:
2767 tex_min = WINED3DTEXF_POINT;
2768 tex_mip = WINED3DTEXF_POINT;
2770 case D3DFILTER_MIPLINEAR:
2771 tex_min = WINED3DTEXF_LINEAR;
2772 tex_mip = WINED3DTEXF_POINT;
2774 case D3DFILTER_LINEARMIPNEAREST:
2775 tex_min = WINED3DTEXF_POINT;
2776 tex_mip = WINED3DTEXF_LINEAR;
2778 case D3DFILTER_LINEARMIPLINEAR:
2779 tex_min = WINED3DTEXF_LINEAR;
2780 tex_mip = WINED3DTEXF_LINEAR;
2784 ERR("Unhandled texture min %d !\n",Value);
2785 tex_min = WINED3DTEXF_POINT;
2786 tex_mip = WINED3DTEXF_NONE;
2790 IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
2791 0, WINED3DSAMP_MIPFILTER, tex_mip);
2792 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
2793 0, WINED3DSAMP_MINFILTER,
2798 case D3DRENDERSTATE_TEXTUREADDRESS:
2799 IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
2800 0, WINED3DSAMP_ADDRESSV,
2803 case D3DRENDERSTATE_TEXTUREADDRESSU:
2804 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
2805 0, WINED3DSAMP_ADDRESSU,
2808 case D3DRENDERSTATE_TEXTUREADDRESSV:
2809 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
2810 0, WINED3DSAMP_ADDRESSV,
2814 case D3DRENDERSTATE_BORDERCOLOR:
2815 /* This should probably just forward to the corresponding sampler
2816 * state. Needs tests. */
2817 FIXME("Unhandled render state D3DRENDERSTATE_BORDERCOLOR.\n");
2822 if (RenderStateType >= D3DRENDERSTATE_STIPPLEPATTERN00
2823 && RenderStateType <= D3DRENDERSTATE_STIPPLEPATTERN31)
2825 FIXME("Unhandled stipple pattern render state (%#x).\n",
2831 hr = IWineD3DDevice_SetRenderState(This->wineD3DDevice,
2836 LeaveCriticalSection(&ddraw_cs);
2840 static HRESULT WINAPI
2841 IDirect3DDeviceImpl_7_SetRenderState_FPUSetup(IDirect3DDevice7 *iface,
2842 D3DRENDERSTATETYPE RenderStateType,
2845 return IDirect3DDeviceImpl_7_SetRenderState(iface, RenderStateType, Value);
2848 static HRESULT WINAPI
2849 IDirect3DDeviceImpl_7_SetRenderState_FPUPreserve(IDirect3DDevice7 *iface,
2850 D3DRENDERSTATETYPE RenderStateType,
2856 old_fpucw = d3d_fpu_setup();
2857 hr = IDirect3DDeviceImpl_7_SetRenderState(iface, RenderStateType, Value);
2858 set_fpu_control_word(old_fpucw);
2863 static HRESULT WINAPI
2864 IDirect3DDeviceImpl_3_SetRenderState(IDirect3DDevice3 *iface,
2865 D3DRENDERSTATETYPE RenderStateType,
2868 /* Note about D3DRENDERSTATE_TEXTUREMAPBLEND implementation: most of values
2869 for this state can be directly mapped to texture stage colorop and alphaop, but
2870 D3DTBLEND_MODULATE is tricky: it uses alpha from texture when available and alpha
2871 from diffuse otherwise. So changing the texture must be monitored in SetTexture to modify
2872 alphaarg when needed.
2874 Aliens vs Predator 1 depends on accurate D3DTBLEND_MODULATE emulation
2876 Legacy texture blending (TEXTUREMAPBLEND) and texture stage states: directx6 docs state that
2877 TEXTUREMAPBLEND is deprecated, yet can still be used. Games must not use both or results
2878 are undefined. D3DTBLEND_MODULATE mode in particular is dependent on texture pixel format and
2879 requires fixup of stage 0 texture states when texture changes, but this fixup can interfere
2880 with games not using this deprecated state. So a flag 'legacyTextureBlending' has to be kept
2881 in device - TRUE if the app is using TEXTUREMAPBLEND.
2883 Tests show that setting TEXTUREMAPBLEND on native doesn't seem to change values returned by
2884 GetTextureStageState and vice versa. Not so on Wine, but it is 'undefined' anyway so, probably, ok,
2885 unless some broken game will be found that cares. */
2888 IDirect3DDeviceImpl *This = device_from_device3(iface);
2889 TRACE("(%p)->(%08x,%d)\n", This, RenderStateType, Value);
2891 EnterCriticalSection(&ddraw_cs);
2893 switch(RenderStateType)
2895 case D3DRENDERSTATE_TEXTUREHANDLE:
2899 hr = IWineD3DDevice_SetTexture(This->wineD3DDevice,
2905 if(Value > This->numHandles)
2907 FIXME("Specified handle %d out of range\n", Value);
2908 hr = DDERR_INVALIDPARAMS;
2911 if(This->Handles[Value - 1].type != DDrawHandle_Texture)
2913 FIXME("Handle %d isn't a texture handle\n", Value);
2914 hr = DDERR_INVALIDPARAMS;
2919 IDirectDrawSurfaceImpl *surf = This->Handles[Value - 1].ptr;
2920 IDirect3DTexture2 *tex = surf ? (IDirect3DTexture2 *)&surf->IDirect3DTexture2_vtbl : NULL;
2921 hr = IDirect3DDevice3_SetTexture(iface, 0, tex);
2926 case D3DRENDERSTATE_TEXTUREMAPBLEND:
2928 This->legacyTextureBlending = TRUE;
2930 switch ( (D3DTEXTUREBLEND) Value)
2932 case D3DTBLEND_MODULATE:
2934 BOOL tex_alpha = FALSE;
2935 IWineD3DBaseTexture *tex = NULL;
2936 WINED3DSURFACE_DESC desc;
2937 DDPIXELFORMAT ddfmt;
2939 hr = IWineD3DDevice_GetTexture(This->wineD3DDevice,
2943 if(hr == WINED3D_OK && tex)
2945 memset(&desc, 0, sizeof(desc));
2946 hr = IWineD3DTexture_GetLevelDesc((IWineD3DTexture*) tex, 0, &desc);
2949 ddfmt.dwSize = sizeof(ddfmt);
2950 PixelFormat_WineD3DtoDD(&ddfmt, desc.format);
2951 if (ddfmt.u5.dwRGBAlphaBitMask) tex_alpha = TRUE;
2954 IWineD3DBaseTexture_Release(tex);
2958 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAOP, WINED3DTOP_SELECTARG1);
2960 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAOP, WINED3DTOP_SELECTARG2);
2961 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG1, WINED3DTA_TEXTURE);
2962 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG2, WINED3DTA_CURRENT);
2963 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG1, WINED3DTA_TEXTURE);
2964 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG2, WINED3DTA_CURRENT);
2965 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLOROP, WINED3DTOP_MODULATE);
2971 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLOROP, WINED3DTOP_ADD);
2972 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG1, WINED3DTA_TEXTURE);
2973 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG2, WINED3DTA_CURRENT);
2974 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAOP, WINED3DTOP_SELECTARG2);
2975 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG2, WINED3DTA_CURRENT);
2978 case D3DTBLEND_MODULATEALPHA:
2979 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG1, WINED3DTA_TEXTURE);
2980 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG1, WINED3DTA_TEXTURE);
2981 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG2, WINED3DTA_CURRENT);
2982 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG2, WINED3DTA_CURRENT);
2983 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLOROP, WINED3DTOP_MODULATE);
2984 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAOP, WINED3DTOP_MODULATE);
2987 case D3DTBLEND_COPY:
2988 case D3DTBLEND_DECAL:
2989 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG1, WINED3DTA_TEXTURE);
2990 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG1, WINED3DTA_TEXTURE);
2991 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLOROP, WINED3DTOP_SELECTARG1);
2992 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAOP, WINED3DTOP_SELECTARG1);
2995 case D3DTBLEND_DECALALPHA:
2996 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLOROP, WINED3DTOP_BLENDTEXTUREALPHA);
2997 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG1, WINED3DTA_TEXTURE);
2998 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG2, WINED3DTA_CURRENT);
2999 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAOP, WINED3DTOP_SELECTARG2);
3000 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG2, WINED3DTA_CURRENT);
3004 ERR("Unhandled texture environment %d !\n",Value);
3012 hr = IDirect3DDevice7_SetRenderState((IDirect3DDevice7 *)This, RenderStateType, Value);
3016 LeaveCriticalSection(&ddraw_cs);
3021 static HRESULT WINAPI
3022 Thunk_IDirect3DDeviceImpl_2_SetRenderState(IDirect3DDevice2 *iface,
3023 D3DRENDERSTATETYPE RenderStateType,
3026 IDirect3DDeviceImpl *This = device_from_device2(iface);
3027 TRACE_(ddraw_thunk)("(%p)->(%08x,%d) thunking to IDirect3DDevice3 interface.\n", This, RenderStateType, Value);
3028 return IDirect3DDevice3_SetRenderState((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl, RenderStateType, Value);
3031 /*****************************************************************************
3032 * Direct3DDevice3::SetLightState
3034 * Sets a light state for Direct3DDevice3 and Direct3DDevice2. The
3035 * light states are forwarded to Direct3DDevice7 render states
3040 * LightStateType: The light state to change
3041 * Value: The value to assign to that light state
3045 * DDERR_INVALIDPARAMS if the parameters were incorrect
3046 * Also check IDirect3DDevice7::SetRenderState
3048 *****************************************************************************/
3049 static HRESULT WINAPI
3050 IDirect3DDeviceImpl_3_SetLightState(IDirect3DDevice3 *iface,
3051 D3DLIGHTSTATETYPE LightStateType,
3054 IDirect3DDeviceImpl *This = device_from_device3(iface);
3057 TRACE("(%p)->(%08x,%08x)\n", This, LightStateType, Value);
3059 if (!LightStateType || (LightStateType > D3DLIGHTSTATE_COLORVERTEX))
3061 TRACE("Unexpected Light State Type\n");
3062 return DDERR_INVALIDPARAMS;
3065 EnterCriticalSection(&ddraw_cs);
3066 if (LightStateType == D3DLIGHTSTATE_MATERIAL /* 1 */)
3068 IDirect3DMaterialImpl *m = ddraw_get_object(&This->handle_table, Value - 1, DDRAW_HANDLE_MATERIAL);
3071 WARN("Invalid material handle.\n");
3072 LeaveCriticalSection(&ddraw_cs);
3073 return DDERR_INVALIDPARAMS;
3076 TRACE(" activating material %p.\n", m);
3079 This->material = Value;
3081 else if (LightStateType == D3DLIGHTSTATE_COLORMODEL /* 3 */)
3086 ERR("DDCOLOR_MONO should not happen!\n");
3089 /* We are already in this mode */
3090 TRACE("Setting color model to RGB (no-op).\n");
3093 ERR("Unknown color model!\n");
3094 LeaveCriticalSection(&ddraw_cs);
3095 return DDERR_INVALIDPARAMS;
3100 D3DRENDERSTATETYPE rs;
3101 switch (LightStateType)
3103 case D3DLIGHTSTATE_AMBIENT: /* 2 */
3104 rs = D3DRENDERSTATE_AMBIENT;
3106 case D3DLIGHTSTATE_FOGMODE: /* 4 */
3107 rs = D3DRENDERSTATE_FOGVERTEXMODE;
3109 case D3DLIGHTSTATE_FOGSTART: /* 5 */
3110 rs = D3DRENDERSTATE_FOGSTART;
3112 case D3DLIGHTSTATE_FOGEND: /* 6 */
3113 rs = D3DRENDERSTATE_FOGEND;
3115 case D3DLIGHTSTATE_FOGDENSITY: /* 7 */
3116 rs = D3DRENDERSTATE_FOGDENSITY;
3118 case D3DLIGHTSTATE_COLORVERTEX: /* 8 */
3119 rs = D3DRENDERSTATE_COLORVERTEX;
3122 ERR("Unknown D3DLIGHTSTATETYPE %d.\n", LightStateType);
3123 LeaveCriticalSection(&ddraw_cs);
3124 return DDERR_INVALIDPARAMS;
3127 hr = IDirect3DDevice7_SetRenderState((IDirect3DDevice7 *)This, rs, Value);
3128 LeaveCriticalSection(&ddraw_cs);
3132 LeaveCriticalSection(&ddraw_cs);
3136 static HRESULT WINAPI
3137 Thunk_IDirect3DDeviceImpl_2_SetLightState(IDirect3DDevice2 *iface,
3138 D3DLIGHTSTATETYPE LightStateType,
3141 IDirect3DDeviceImpl *This = device_from_device2(iface);
3142 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x) thunking to IDirect3DDevice3 interface.\n", This, LightStateType, Value);
3143 return IDirect3DDevice3_SetLightState((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl, LightStateType, Value);
3146 /*****************************************************************************
3147 * IDirect3DDevice3::GetLightState
3149 * Returns the current setting of a light state. The state is read from
3150 * the Direct3DDevice7 render state.
3155 * LightStateType: The light state to return
3156 * Value: The address to store the light state setting at
3160 * DDDERR_INVALIDPARAMS if the parameters were incorrect
3161 * Also see IDirect3DDevice7::GetRenderState
3163 *****************************************************************************/
3164 static HRESULT WINAPI
3165 IDirect3DDeviceImpl_3_GetLightState(IDirect3DDevice3 *iface,
3166 D3DLIGHTSTATETYPE LightStateType,
3169 IDirect3DDeviceImpl *This = device_from_device3(iface);
3172 TRACE("(%p)->(%08x,%p)\n", This, LightStateType, Value);
3174 if (!LightStateType || (LightStateType > D3DLIGHTSTATE_COLORVERTEX))
3176 TRACE("Unexpected Light State Type\n");
3177 return DDERR_INVALIDPARAMS;
3181 return DDERR_INVALIDPARAMS;
3183 EnterCriticalSection(&ddraw_cs);
3184 if (LightStateType == D3DLIGHTSTATE_MATERIAL /* 1 */)
3186 *Value = This->material;
3188 else if (LightStateType == D3DLIGHTSTATE_COLORMODEL /* 3 */)
3190 *Value = D3DCOLOR_RGB;
3194 D3DRENDERSTATETYPE rs;
3195 switch (LightStateType)
3197 case D3DLIGHTSTATE_AMBIENT: /* 2 */
3198 rs = D3DRENDERSTATE_AMBIENT;
3200 case D3DLIGHTSTATE_FOGMODE: /* 4 */
3201 rs = D3DRENDERSTATE_FOGVERTEXMODE;
3203 case D3DLIGHTSTATE_FOGSTART: /* 5 */
3204 rs = D3DRENDERSTATE_FOGSTART;
3206 case D3DLIGHTSTATE_FOGEND: /* 6 */
3207 rs = D3DRENDERSTATE_FOGEND;
3209 case D3DLIGHTSTATE_FOGDENSITY: /* 7 */
3210 rs = D3DRENDERSTATE_FOGDENSITY;
3212 case D3DLIGHTSTATE_COLORVERTEX: /* 8 */
3213 rs = D3DRENDERSTATE_COLORVERTEX;
3216 ERR("Unknown D3DLIGHTSTATETYPE %d.\n", LightStateType);
3217 LeaveCriticalSection(&ddraw_cs);
3218 return DDERR_INVALIDPARAMS;
3221 hr = IDirect3DDevice7_GetRenderState((IDirect3DDevice7 *)This, rs, Value);
3222 LeaveCriticalSection(&ddraw_cs);
3226 LeaveCriticalSection(&ddraw_cs);
3230 static HRESULT WINAPI
3231 Thunk_IDirect3DDeviceImpl_2_GetLightState(IDirect3DDevice2 *iface,
3232 D3DLIGHTSTATETYPE LightStateType,
3235 IDirect3DDeviceImpl *This = device_from_device2(iface);
3236 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice3 interface.\n", This, LightStateType, Value);
3237 return IDirect3DDevice3_GetLightState((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl, LightStateType, Value);
3240 /*****************************************************************************
3241 * IDirect3DDevice7::SetTransform
3243 * Assigns a D3DMATRIX to a transform type. The transform types are defined
3244 * in include/d3dtypes.h.
3245 * The D3DTRANSFORMSTATE_WORLD (=1) is translated to D3DTS_WORLDMATRIX(0)
3246 * (=255) for wined3d, because the 1 transform state was removed in d3d8
3247 * and WineD3D already understands the replacement D3DTS_WORLDMATRIX(0)
3249 * Version 2, 3 and 7
3252 * TransformStateType: transform state to set
3253 * Matrix: Matrix to assign to the state
3257 * DDERR_INVALIDPARAMS if Matrix == NULL
3258 * For details see IWineD3DDevice::SetTransform
3260 *****************************************************************************/
3262 IDirect3DDeviceImpl_7_SetTransform(IDirect3DDevice7 *iface,
3263 D3DTRANSFORMSTATETYPE TransformStateType,
3266 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
3267 D3DTRANSFORMSTATETYPE type;
3269 TRACE("(%p)->(%08x,%p): Relay\n", This, TransformStateType, Matrix);
3271 switch(TransformStateType)
3273 case D3DTRANSFORMSTATE_WORLD : type = WINED3DTS_WORLDMATRIX(0); break;
3274 case D3DTRANSFORMSTATE_WORLD1: type = WINED3DTS_WORLDMATRIX(1); break;
3275 case D3DTRANSFORMSTATE_WORLD2: type = WINED3DTS_WORLDMATRIX(2); break;
3276 case D3DTRANSFORMSTATE_WORLD3: type = WINED3DTS_WORLDMATRIX(3); break;
3277 default: type = TransformStateType;
3281 return DDERR_INVALIDPARAMS;
3283 /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
3284 EnterCriticalSection(&ddraw_cs);
3285 hr = IWineD3DDevice_SetTransform(This->wineD3DDevice,
3287 (WINED3DMATRIX*) Matrix);
3288 LeaveCriticalSection(&ddraw_cs);
3292 static HRESULT WINAPI
3293 IDirect3DDeviceImpl_7_SetTransform_FPUSetup(IDirect3DDevice7 *iface,
3294 D3DTRANSFORMSTATETYPE TransformStateType,
3297 return IDirect3DDeviceImpl_7_SetTransform(iface, TransformStateType, Matrix);
3300 static HRESULT WINAPI
3301 IDirect3DDeviceImpl_7_SetTransform_FPUPreserve(IDirect3DDevice7 *iface,
3302 D3DTRANSFORMSTATETYPE TransformStateType,
3308 old_fpucw = d3d_fpu_setup();
3309 hr = IDirect3DDeviceImpl_7_SetTransform(iface, TransformStateType, Matrix);
3310 set_fpu_control_word(old_fpucw);
3315 static HRESULT WINAPI
3316 Thunk_IDirect3DDeviceImpl_3_SetTransform(IDirect3DDevice3 *iface,
3317 D3DTRANSFORMSTATETYPE TransformStateType,
3318 D3DMATRIX *D3DMatrix)
3320 IDirect3DDeviceImpl *This = device_from_device3(iface);
3321 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, TransformStateType, D3DMatrix);
3322 return IDirect3DDevice7_SetTransform((IDirect3DDevice7 *)This, TransformStateType, D3DMatrix);
3325 static HRESULT WINAPI
3326 Thunk_IDirect3DDeviceImpl_2_SetTransform(IDirect3DDevice2 *iface,
3327 D3DTRANSFORMSTATETYPE TransformStateType,
3328 D3DMATRIX *D3DMatrix)
3330 IDirect3DDeviceImpl *This = device_from_device2(iface);
3331 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, TransformStateType, D3DMatrix);
3332 return IDirect3DDevice7_SetTransform((IDirect3DDevice7 *)This, TransformStateType, D3DMatrix);
3335 /*****************************************************************************
3336 * IDirect3DDevice7::GetTransform
3338 * Returns the matrix assigned to a transform state
3339 * D3DTRANSFORMSTATE_WORLD is translated to D3DTS_WORLDMATRIX(0), see
3343 * TransformStateType: State to read the matrix from
3344 * Matrix: Address to store the matrix at
3348 * DDERR_INVALIDPARAMS if Matrix == NULL
3349 * For details, see IWineD3DDevice::GetTransform
3351 *****************************************************************************/
3353 IDirect3DDeviceImpl_7_GetTransform(IDirect3DDevice7 *iface,
3354 D3DTRANSFORMSTATETYPE TransformStateType,
3357 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
3358 D3DTRANSFORMSTATETYPE type;
3360 TRACE("(%p)->(%08x,%p): Relay\n", This, TransformStateType, Matrix);
3362 switch(TransformStateType)
3364 case D3DTRANSFORMSTATE_WORLD : type = WINED3DTS_WORLDMATRIX(0); break;
3365 case D3DTRANSFORMSTATE_WORLD1: type = WINED3DTS_WORLDMATRIX(1); break;
3366 case D3DTRANSFORMSTATE_WORLD2: type = WINED3DTS_WORLDMATRIX(2); break;
3367 case D3DTRANSFORMSTATE_WORLD3: type = WINED3DTS_WORLDMATRIX(3); break;
3368 default: type = TransformStateType;
3372 return DDERR_INVALIDPARAMS;
3374 /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
3375 EnterCriticalSection(&ddraw_cs);
3376 hr = IWineD3DDevice_GetTransform(This->wineD3DDevice, type, (WINED3DMATRIX*) Matrix);
3377 LeaveCriticalSection(&ddraw_cs);
3381 static HRESULT WINAPI
3382 IDirect3DDeviceImpl_7_GetTransform_FPUSetup(IDirect3DDevice7 *iface,
3383 D3DTRANSFORMSTATETYPE TransformStateType,
3386 return IDirect3DDeviceImpl_7_GetTransform(iface, TransformStateType, Matrix);
3389 static HRESULT WINAPI
3390 IDirect3DDeviceImpl_7_GetTransform_FPUPreserve(IDirect3DDevice7 *iface,
3391 D3DTRANSFORMSTATETYPE TransformStateType,
3397 old_fpucw = d3d_fpu_setup();
3398 hr = IDirect3DDeviceImpl_7_GetTransform(iface, TransformStateType, Matrix);
3399 set_fpu_control_word(old_fpucw);
3404 static HRESULT WINAPI
3405 Thunk_IDirect3DDeviceImpl_3_GetTransform(IDirect3DDevice3 *iface,
3406 D3DTRANSFORMSTATETYPE TransformStateType,
3407 D3DMATRIX *D3DMatrix)
3409 IDirect3DDeviceImpl *This = device_from_device3(iface);
3410 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, TransformStateType, D3DMatrix);
3411 return IDirect3DDevice7_GetTransform((IDirect3DDevice7 *)This, TransformStateType, D3DMatrix);
3414 static HRESULT WINAPI
3415 Thunk_IDirect3DDeviceImpl_2_GetTransform(IDirect3DDevice2 *iface,
3416 D3DTRANSFORMSTATETYPE TransformStateType,
3417 D3DMATRIX *D3DMatrix)
3419 IDirect3DDeviceImpl *This = device_from_device2(iface);
3420 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, TransformStateType, D3DMatrix);
3421 return IDirect3DDevice7_GetTransform((IDirect3DDevice7 *)This, TransformStateType, D3DMatrix);
3424 /*****************************************************************************
3425 * IDirect3DDevice7::MultiplyTransform
3427 * Multiplies the already-set transform matrix of a transform state
3428 * with another matrix. For the world matrix, see SetTransform
3430 * Version 2, 3 and 7
3433 * TransformStateType: Transform state to multiply
3434 * D3DMatrix Matrix to multiply with.
3438 * DDERR_INVALIDPARAMS if D3DMatrix is NULL
3439 * For details, see IWineD3DDevice::MultiplyTransform
3441 *****************************************************************************/
3443 IDirect3DDeviceImpl_7_MultiplyTransform(IDirect3DDevice7 *iface,
3444 D3DTRANSFORMSTATETYPE TransformStateType,
3445 D3DMATRIX *D3DMatrix)
3447 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
3449 D3DTRANSFORMSTATETYPE type;
3450 TRACE("(%p)->(%08x,%p): Relay\n", This, TransformStateType, D3DMatrix);
3452 switch(TransformStateType)
3454 case D3DTRANSFORMSTATE_WORLD : type = WINED3DTS_WORLDMATRIX(0); break;
3455 case D3DTRANSFORMSTATE_WORLD1: type = WINED3DTS_WORLDMATRIX(1); break;
3456 case D3DTRANSFORMSTATE_WORLD2: type = WINED3DTS_WORLDMATRIX(2); break;
3457 case D3DTRANSFORMSTATE_WORLD3: type = WINED3DTS_WORLDMATRIX(3); break;
3458 default: type = TransformStateType;
3461 /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
3462 EnterCriticalSection(&ddraw_cs);
3463 hr = IWineD3DDevice_MultiplyTransform(This->wineD3DDevice,
3465 (WINED3DMATRIX*) D3DMatrix);
3466 LeaveCriticalSection(&ddraw_cs);
3470 static HRESULT WINAPI
3471 IDirect3DDeviceImpl_7_MultiplyTransform_FPUSetup(IDirect3DDevice7 *iface,
3472 D3DTRANSFORMSTATETYPE TransformStateType,
3473 D3DMATRIX *D3DMatrix)
3475 return IDirect3DDeviceImpl_7_MultiplyTransform(iface, TransformStateType, D3DMatrix);
3478 static HRESULT WINAPI
3479 IDirect3DDeviceImpl_7_MultiplyTransform_FPUPreserve(IDirect3DDevice7 *iface,
3480 D3DTRANSFORMSTATETYPE TransformStateType,
3481 D3DMATRIX *D3DMatrix)
3486 old_fpucw = d3d_fpu_setup();
3487 hr = IDirect3DDeviceImpl_7_MultiplyTransform(iface, TransformStateType, D3DMatrix);
3488 set_fpu_control_word(old_fpucw);
3493 static HRESULT WINAPI
3494 Thunk_IDirect3DDeviceImpl_3_MultiplyTransform(IDirect3DDevice3 *iface,
3495 D3DTRANSFORMSTATETYPE TransformStateType,
3496 D3DMATRIX *D3DMatrix)
3498 IDirect3DDeviceImpl *This = device_from_device3(iface);
3499 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, TransformStateType, D3DMatrix);
3500 return IDirect3DDevice7_MultiplyTransform((IDirect3DDevice7 *)This, TransformStateType, D3DMatrix);
3503 static HRESULT WINAPI
3504 Thunk_IDirect3DDeviceImpl_2_MultiplyTransform(IDirect3DDevice2 *iface,
3505 D3DTRANSFORMSTATETYPE TransformStateType,
3506 D3DMATRIX *D3DMatrix)
3508 IDirect3DDeviceImpl *This = device_from_device2(iface);
3509 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, TransformStateType, D3DMatrix);
3510 return IDirect3DDevice7_MultiplyTransform((IDirect3DDevice7 *)This, TransformStateType, D3DMatrix);
3513 /*****************************************************************************
3514 * IDirect3DDevice7::DrawPrimitive
3516 * Draws primitives based on vertices in an application-provided pointer
3518 * Version 2, 3 and 7. The IDirect3DDevice2 thunk converts the fixed vertex type into
3519 * an FVF format for D3D7
3522 * PrimitiveType: The type of the primitives to draw
3523 * Vertex type: Flexible vertex format vertex description
3524 * Vertices: Pointer to the vertex array
3525 * VertexCount: The number of vertices to draw
3526 * Flags: As usual a few flags
3530 * DDERR_INVALIDPARAMS if Vertices is NULL
3531 * For details, see IWineD3DDevice::DrawPrimitiveUP
3533 *****************************************************************************/
3535 IDirect3DDeviceImpl_7_DrawPrimitive(IDirect3DDevice7 *iface,
3536 D3DPRIMITIVETYPE PrimitiveType,
3542 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
3545 TRACE("(%p)->(%08x,%08x,%p,%08x,%08x): Relay!\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Flags);
3548 return DDERR_INVALIDPARAMS;
3550 /* Get the stride */
3551 stride = get_flexible_vertex_size(VertexType);
3554 EnterCriticalSection(&ddraw_cs);
3555 hr = IWineD3DDevice_SetVertexDeclaration(This->wineD3DDevice, ddraw_find_decl(This->ddraw, VertexType));
3558 LeaveCriticalSection(&ddraw_cs);
3562 /* This method translates to the user pointer draw of WineD3D */
3563 IWineD3DDevice_SetPrimitiveType(This->wineD3DDevice, PrimitiveType);
3564 hr = IWineD3DDevice_DrawPrimitiveUP(This->wineD3DDevice, VertexCount, Vertices, stride);
3565 LeaveCriticalSection(&ddraw_cs);
3569 static HRESULT WINAPI
3570 IDirect3DDeviceImpl_7_DrawPrimitive_FPUSetup(IDirect3DDevice7 *iface,
3571 D3DPRIMITIVETYPE PrimitiveType,
3577 return IDirect3DDeviceImpl_7_DrawPrimitive(iface, PrimitiveType, VertexType, Vertices, VertexCount, Flags);
3580 static HRESULT WINAPI
3581 IDirect3DDeviceImpl_7_DrawPrimitive_FPUPreserve(IDirect3DDevice7 *iface,
3582 D3DPRIMITIVETYPE PrimitiveType,
3591 old_fpucw = d3d_fpu_setup();
3592 hr = IDirect3DDeviceImpl_7_DrawPrimitive(iface, PrimitiveType, VertexType, Vertices, VertexCount, Flags);
3593 set_fpu_control_word(old_fpucw);
3598 static HRESULT WINAPI
3599 Thunk_IDirect3DDeviceImpl_3_DrawPrimitive(IDirect3DDevice3 *iface,
3600 D3DPRIMITIVETYPE PrimitiveType,
3606 IDirect3DDeviceImpl *This = device_from_device3(iface);
3607 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Flags);
3608 return IDirect3DDevice7_DrawPrimitive((IDirect3DDevice7 *)This,
3609 PrimitiveType, VertexType, Vertices, VertexCount, Flags);
3612 static HRESULT WINAPI
3613 Thunk_IDirect3DDeviceImpl_2_DrawPrimitive(IDirect3DDevice2 *iface,
3614 D3DPRIMITIVETYPE PrimitiveType,
3615 D3DVERTEXTYPE VertexType,
3620 IDirect3DDeviceImpl *This = device_from_device2(iface);
3622 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Flags);
3626 case D3DVT_VERTEX: FVF = D3DFVF_VERTEX; break;
3627 case D3DVT_LVERTEX: FVF = D3DFVF_LVERTEX; break;
3628 case D3DVT_TLVERTEX: FVF = D3DFVF_TLVERTEX; break;
3630 ERR("Unexpected vertex type %d\n", VertexType);
3631 return DDERR_INVALIDPARAMS; /* Should never happen */
3634 return IDirect3DDevice7_DrawPrimitive((IDirect3DDevice7 *)This, PrimitiveType, FVF, Vertices, VertexCount, Flags);
3637 /*****************************************************************************
3638 * IDirect3DDevice7::DrawIndexedPrimitive
3640 * Draws vertices from an application-provided pointer, based on the index
3641 * numbers in a WORD array.
3643 * Version 2, 3 and 7. The version 7 thunk translates the vertex type into
3644 * an FVF format for D3D7
3647 * PrimitiveType: The primitive type to draw
3648 * VertexType: The FVF vertex description
3649 * Vertices: Pointer to the vertex array
3651 * Indices: Pointer to the index array
3652 * IndexCount: Number of indices = Number of vertices to draw
3653 * Flags: As usual, some flags
3657 * DDERR_INVALIDPARAMS if Vertices or Indices is NULL
3658 * For details, see IWineD3DDevice::DrawIndexedPrimitiveUP
3660 *****************************************************************************/
3662 IDirect3DDeviceImpl_7_DrawIndexedPrimitive(IDirect3DDevice7 *iface,
3663 D3DPRIMITIVETYPE PrimitiveType,
3671 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
3673 TRACE("(%p)->(%08x,%08x,%p,%08x,%p,%08x,%08x): Relay!\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Indices, IndexCount, Flags);
3675 /* Set the D3DDevice's FVF */
3676 EnterCriticalSection(&ddraw_cs);
3677 hr = IWineD3DDevice_SetVertexDeclaration(This->wineD3DDevice, ddraw_find_decl(This->ddraw, VertexType));
3680 ERR(" (%p) Setting the FVF failed, hr = %x!\n", This, hr);
3681 LeaveCriticalSection(&ddraw_cs);
3685 IWineD3DDevice_SetPrimitiveType(This->wineD3DDevice, PrimitiveType);
3686 hr = IWineD3DDevice_DrawIndexedPrimitiveUP(This->wineD3DDevice, IndexCount, Indices,
3687 WINED3DFMT_R16_UINT, Vertices, get_flexible_vertex_size(VertexType));
3688 LeaveCriticalSection(&ddraw_cs);
3692 static HRESULT WINAPI
3693 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUSetup(IDirect3DDevice7 *iface,
3694 D3DPRIMITIVETYPE PrimitiveType,
3702 return IDirect3DDeviceImpl_7_DrawIndexedPrimitive(iface, PrimitiveType, VertexType, Vertices, VertexCount, Indices, IndexCount, Flags);
3705 static HRESULT WINAPI
3706 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUPreserve(IDirect3DDevice7 *iface,
3707 D3DPRIMITIVETYPE PrimitiveType,
3718 old_fpucw = d3d_fpu_setup();
3719 hr = IDirect3DDeviceImpl_7_DrawIndexedPrimitive(iface, PrimitiveType, VertexType, Vertices, VertexCount, Indices, IndexCount, Flags);
3720 set_fpu_control_word(old_fpucw);
3725 static HRESULT WINAPI
3726 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitive(IDirect3DDevice3 *iface,
3727 D3DPRIMITIVETYPE PrimitiveType,
3735 IDirect3DDeviceImpl *This = device_from_device3(iface);
3736 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Indices, IndexCount, Flags);
3737 return IDirect3DDevice7_DrawIndexedPrimitive((IDirect3DDevice7 *)This,
3738 PrimitiveType, VertexType, Vertices, VertexCount, Indices, IndexCount, Flags);
3741 static HRESULT WINAPI
3742 Thunk_IDirect3DDeviceImpl_2_DrawIndexedPrimitive(IDirect3DDevice2 *iface,
3743 D3DPRIMITIVETYPE PrimitiveType,
3744 D3DVERTEXTYPE VertexType,
3752 IDirect3DDeviceImpl *This = device_from_device2(iface);
3753 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Indices, IndexCount, Flags);
3757 case D3DVT_VERTEX: FVF = D3DFVF_VERTEX; break;
3758 case D3DVT_LVERTEX: FVF = D3DFVF_LVERTEX; break;
3759 case D3DVT_TLVERTEX: FVF = D3DFVF_TLVERTEX; break;
3761 ERR("Unexpected vertex type %d\n", VertexType);
3762 return DDERR_INVALIDPARAMS; /* Should never happen */
3765 return IDirect3DDevice7_DrawIndexedPrimitive((IDirect3DDevice7 *)This,
3766 PrimitiveType, FVF, Vertices, VertexCount, Indices, IndexCount, Flags);
3769 /*****************************************************************************
3770 * IDirect3DDevice7::SetClipStatus
3772 * Sets the clip status. This defines things as clipping conditions and
3773 * the extents of the clipping region.
3775 * Version 2, 3 and 7
3781 * D3D_OK because it's a stub
3782 * (DDERR_INVALIDPARAMS if ClipStatus == NULL)
3784 *****************************************************************************/
3785 static HRESULT WINAPI
3786 IDirect3DDeviceImpl_7_SetClipStatus(IDirect3DDevice7 *iface,
3787 D3DCLIPSTATUS *ClipStatus)
3789 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
3790 FIXME("(%p)->(%p): Stub!\n", This, ClipStatus);
3792 /* D3DCLIPSTATUS and WINED3DCLIPSTATUS are different. I don't know how to convert them
3793 * Perhaps this needs a new data type and an additional IWineD3DDevice method
3795 /* return IWineD3DDevice_SetClipStatus(This->wineD3DDevice, ClipStatus);*/
3799 static HRESULT WINAPI
3800 Thunk_IDirect3DDeviceImpl_3_SetClipStatus(IDirect3DDevice3 *iface,
3801 D3DCLIPSTATUS *ClipStatus)
3803 IDirect3DDeviceImpl *This = device_from_device3(iface);
3804 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, ClipStatus);
3805 return IDirect3DDevice7_SetClipStatus((IDirect3DDevice7 *)This, ClipStatus);
3808 static HRESULT WINAPI
3809 Thunk_IDirect3DDeviceImpl_2_SetClipStatus(IDirect3DDevice2 *iface,
3810 D3DCLIPSTATUS *ClipStatus)
3812 IDirect3DDeviceImpl *This = device_from_device2(iface);
3813 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, ClipStatus);
3814 return IDirect3DDevice7_SetClipStatus((IDirect3DDevice7 *)This, ClipStatus);
3817 /*****************************************************************************
3818 * IDirect3DDevice7::GetClipStatus
3820 * Returns the clip status
3823 * ClipStatus: Address to write the clip status to
3826 * D3D_OK because it's a stub
3828 *****************************************************************************/
3829 static HRESULT WINAPI
3830 IDirect3DDeviceImpl_7_GetClipStatus(IDirect3DDevice7 *iface,
3831 D3DCLIPSTATUS *ClipStatus)
3833 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
3834 FIXME("(%p)->(%p): Stub!\n", This, ClipStatus);
3836 /* D3DCLIPSTATUS and WINED3DCLIPSTATUS are different. I don't know how to convert them */
3837 /* return IWineD3DDevice_GetClipStatus(This->wineD3DDevice, ClipStatus);*/
3841 static HRESULT WINAPI
3842 Thunk_IDirect3DDeviceImpl_3_GetClipStatus(IDirect3DDevice3 *iface,
3843 D3DCLIPSTATUS *ClipStatus)
3845 IDirect3DDeviceImpl *This = device_from_device3(iface);
3846 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, ClipStatus);
3847 return IDirect3DDevice7_GetClipStatus((IDirect3DDevice7 *)This, ClipStatus);
3850 static HRESULT WINAPI
3851 Thunk_IDirect3DDeviceImpl_2_GetClipStatus(IDirect3DDevice2 *iface,
3852 D3DCLIPSTATUS *ClipStatus)
3854 IDirect3DDeviceImpl *This = device_from_device2(iface);
3855 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, ClipStatus);
3856 return IDirect3DDevice7_GetClipStatus((IDirect3DDevice7 *)This, ClipStatus);
3859 /*****************************************************************************
3860 * IDirect3DDevice::DrawPrimitiveStrided
3862 * Draws vertices described by a D3DDRAWPRIMITIVESTRIDEDDATA structure.
3867 * PrimitiveType: The primitive type to draw
3868 * VertexType: The FVF description of the vertices to draw (for the stride??)
3869 * D3DDrawPrimStrideData: A D3DDRAWPRIMITIVESTRIDEDDATA structure describing
3870 * the vertex data locations
3871 * VertexCount: The number of vertices to draw
3875 * D3D_OK, because it's a stub
3876 * (DDERR_INVALIDPARAMS if D3DDrawPrimStrideData is NULL)
3877 * (For details, see IWineD3DDevice::DrawPrimitiveStrided)
3879 *****************************************************************************/
3881 IDirect3DDeviceImpl_7_DrawPrimitiveStrided(IDirect3DDevice7 *iface,
3882 D3DPRIMITIVETYPE PrimitiveType,
3884 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
3888 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
3889 WineDirect3DVertexStridedData WineD3DStrided;
3893 TRACE("(%p)->(%08x,%08x,%p,%08x,%08x): stub!\n", This, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Flags);
3895 memset(&WineD3DStrided, 0, sizeof(WineD3DStrided));
3896 /* Get the strided data right. the wined3d structure is a bit bigger
3897 * Watch out: The contents of the strided data are determined by the fvf,
3898 * not by the members set in D3DDrawPrimStrideData. So it's valid
3899 * to have diffuse.lpvData set to 0xdeadbeef if the diffuse flag is
3900 * not set in the fvf.
3902 if(VertexType & D3DFVF_POSITION_MASK)
3904 WineD3DStrided.position.format = WINED3DFMT_R32G32B32_FLOAT;
3905 WineD3DStrided.position.lpData = D3DDrawPrimStrideData->position.lpvData;
3906 WineD3DStrided.position.dwStride = D3DDrawPrimStrideData->position.dwStride;
3907 if (VertexType & D3DFVF_XYZRHW)
3909 WineD3DStrided.position.format = WINED3DFMT_R32G32B32A32_FLOAT;
3910 WineD3DStrided.position_transformed = TRUE;
3912 WineD3DStrided.position_transformed = FALSE;
3915 if(VertexType & D3DFVF_NORMAL)
3917 WineD3DStrided.normal.format = WINED3DFMT_R32G32B32_FLOAT;
3918 WineD3DStrided.normal.lpData = D3DDrawPrimStrideData->normal.lpvData;
3919 WineD3DStrided.normal.dwStride = D3DDrawPrimStrideData->normal.dwStride;
3922 if(VertexType & D3DFVF_DIFFUSE)
3924 WineD3DStrided.diffuse.format = WINED3DFMT_B8G8R8A8_UNORM;
3925 WineD3DStrided.diffuse.lpData = D3DDrawPrimStrideData->diffuse.lpvData;
3926 WineD3DStrided.diffuse.dwStride = D3DDrawPrimStrideData->diffuse.dwStride;
3929 if(VertexType & D3DFVF_SPECULAR)
3931 WineD3DStrided.specular.format = WINED3DFMT_B8G8R8A8_UNORM;
3932 WineD3DStrided.specular.lpData = D3DDrawPrimStrideData->specular.lpvData;
3933 WineD3DStrided.specular.dwStride = D3DDrawPrimStrideData->specular.dwStride;
3936 for( i = 0; i < GET_TEXCOUNT_FROM_FVF(VertexType); i++)
3938 switch(GET_TEXCOORD_SIZE_FROM_FVF(VertexType, i))
3940 case 1: WineD3DStrided.texCoords[i].format = WINED3DFMT_R32_FLOAT; break;
3941 case 2: WineD3DStrided.texCoords[i].format = WINED3DFMT_R32G32_FLOAT; break;
3942 case 3: WineD3DStrided.texCoords[i].format = WINED3DFMT_R32G32B32_FLOAT; break;
3943 case 4: WineD3DStrided.texCoords[i].format = WINED3DFMT_R32G32B32A32_FLOAT; break;
3944 default: ERR("Unexpected texture coordinate size %d\n",
3945 GET_TEXCOORD_SIZE_FROM_FVF(VertexType, i));
3947 WineD3DStrided.texCoords[i].lpData = D3DDrawPrimStrideData->textureCoords[i].lpvData;
3948 WineD3DStrided.texCoords[i].dwStride = D3DDrawPrimStrideData->textureCoords[i].dwStride;
3951 /* WineD3D doesn't need the FVF here */
3952 EnterCriticalSection(&ddraw_cs);
3953 IWineD3DDevice_SetPrimitiveType(This->wineD3DDevice, PrimitiveType);
3954 hr = IWineD3DDevice_DrawPrimitiveStrided(This->wineD3DDevice, VertexCount, &WineD3DStrided);
3955 LeaveCriticalSection(&ddraw_cs);
3959 static HRESULT WINAPI
3960 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUSetup(IDirect3DDevice7 *iface,
3961 D3DPRIMITIVETYPE PrimitiveType,
3963 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
3967 return IDirect3DDeviceImpl_7_DrawPrimitiveStrided(iface, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Flags);
3970 static HRESULT WINAPI
3971 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUPreserve(IDirect3DDevice7 *iface,
3972 D3DPRIMITIVETYPE PrimitiveType,
3974 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
3981 old_fpucw = d3d_fpu_setup();
3982 hr = IDirect3DDeviceImpl_7_DrawPrimitiveStrided(iface, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Flags);
3983 set_fpu_control_word(old_fpucw);
3988 static HRESULT WINAPI
3989 Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveStrided(IDirect3DDevice3 *iface,
3990 D3DPRIMITIVETYPE PrimitiveType,
3992 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
3996 IDirect3DDeviceImpl *This = device_from_device3(iface);
3997 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Flags);
3998 return IDirect3DDevice7_DrawPrimitiveStrided((IDirect3DDevice7 *)This,
3999 PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Flags);
4002 /*****************************************************************************
4003 * IDirect3DDevice7::DrawIndexedPrimitiveStrided
4005 * Draws primitives specified by strided data locations based on indices
4013 * D3D_OK, because it's a stub
4014 * (DDERR_INVALIDPARAMS if D3DDrawPrimStrideData is NULL)
4015 * (DDERR_INVALIDPARAMS if Indices is NULL)
4016 * (For more details, see IWineD3DDevice::DrawIndexedPrimitiveStrided)
4018 *****************************************************************************/
4020 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided(IDirect3DDevice7 *iface,
4021 D3DPRIMITIVETYPE PrimitiveType,
4023 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
4029 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
4030 WineDirect3DVertexStridedData WineD3DStrided;
4034 TRACE("(%p)->(%08x,%08x,%p,%08x,%p,%08x,%08x)\n", This, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Indices, IndexCount, Flags);
4036 memset(&WineD3DStrided, 0, sizeof(WineD3DStrided));
4037 /* Get the strided data right. the wined3d structure is a bit bigger
4038 * Watch out: The contents of the strided data are determined by the fvf,
4039 * not by the members set in D3DDrawPrimStrideData. So it's valid
4040 * to have diffuse.lpvData set to 0xdeadbeef if the diffuse flag is
4041 * not set in the fvf.
4043 if(VertexType & D3DFVF_POSITION_MASK)
4045 WineD3DStrided.position.format = WINED3DFMT_R32G32B32_FLOAT;
4046 WineD3DStrided.position.lpData = D3DDrawPrimStrideData->position.lpvData;
4047 WineD3DStrided.position.dwStride = D3DDrawPrimStrideData->position.dwStride;
4048 if (VertexType & D3DFVF_XYZRHW)
4050 WineD3DStrided.position.format = WINED3DFMT_R32G32B32A32_FLOAT;
4051 WineD3DStrided.position_transformed = TRUE;
4053 WineD3DStrided.position_transformed = FALSE;
4056 if(VertexType & D3DFVF_NORMAL)
4058 WineD3DStrided.normal.format = WINED3DFMT_R32G32B32_FLOAT;
4059 WineD3DStrided.normal.lpData = D3DDrawPrimStrideData->normal.lpvData;
4060 WineD3DStrided.normal.dwStride = D3DDrawPrimStrideData->normal.dwStride;
4063 if(VertexType & D3DFVF_DIFFUSE)
4065 WineD3DStrided.diffuse.format = WINED3DFMT_B8G8R8A8_UNORM;
4066 WineD3DStrided.diffuse.lpData = D3DDrawPrimStrideData->diffuse.lpvData;
4067 WineD3DStrided.diffuse.dwStride = D3DDrawPrimStrideData->diffuse.dwStride;
4070 if(VertexType & D3DFVF_SPECULAR)
4072 WineD3DStrided.specular.format = WINED3DFMT_B8G8R8A8_UNORM;
4073 WineD3DStrided.specular.lpData = D3DDrawPrimStrideData->specular.lpvData;
4074 WineD3DStrided.specular.dwStride = D3DDrawPrimStrideData->specular.dwStride;
4077 for( i = 0; i < GET_TEXCOUNT_FROM_FVF(VertexType); i++)
4079 switch(GET_TEXCOORD_SIZE_FROM_FVF(VertexType, i))
4081 case 1: WineD3DStrided.texCoords[i].format = WINED3DFMT_R32_FLOAT; break;
4082 case 2: WineD3DStrided.texCoords[i].format = WINED3DFMT_R32G32_FLOAT; break;
4083 case 3: WineD3DStrided.texCoords[i].format = WINED3DFMT_R32G32B32_FLOAT; break;
4084 case 4: WineD3DStrided.texCoords[i].format = WINED3DFMT_R32G32B32A32_FLOAT; break;
4085 default: ERR("Unexpected texture coordinate size %d\n",
4086 GET_TEXCOORD_SIZE_FROM_FVF(VertexType, i));
4088 WineD3DStrided.texCoords[i].lpData = D3DDrawPrimStrideData->textureCoords[i].lpvData;
4089 WineD3DStrided.texCoords[i].dwStride = D3DDrawPrimStrideData->textureCoords[i].dwStride;
4092 /* WineD3D doesn't need the FVF here */
4093 EnterCriticalSection(&ddraw_cs);
4094 IWineD3DDevice_SetPrimitiveType(This->wineD3DDevice, PrimitiveType);
4095 hr = IWineD3DDevice_DrawIndexedPrimitiveStrided(This->wineD3DDevice,
4096 IndexCount, &WineD3DStrided, VertexCount, Indices, WINED3DFMT_R16_UINT);
4097 LeaveCriticalSection(&ddraw_cs);
4101 static HRESULT WINAPI
4102 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUSetup(IDirect3DDevice7 *iface,
4103 D3DPRIMITIVETYPE PrimitiveType,
4105 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
4111 return IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided(iface, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Indices, IndexCount, Flags);
4114 static HRESULT WINAPI
4115 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUPreserve(IDirect3DDevice7 *iface,
4116 D3DPRIMITIVETYPE PrimitiveType,
4118 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
4127 old_fpucw = d3d_fpu_setup();
4128 hr = IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided(iface, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Indices, IndexCount, Flags);
4129 set_fpu_control_word(old_fpucw);
4134 static HRESULT WINAPI
4135 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveStrided(IDirect3DDevice3 *iface,
4136 D3DPRIMITIVETYPE PrimitiveType,
4138 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
4144 IDirect3DDeviceImpl *This = device_from_device3(iface);
4145 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", iface, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Indices, IndexCount, Flags);
4146 return IDirect3DDevice7_DrawIndexedPrimitiveStrided((IDirect3DDevice7 *)This, PrimitiveType,
4147 VertexType, D3DDrawPrimStrideData, VertexCount, Indices, IndexCount, Flags);
4150 /*****************************************************************************
4151 * IDirect3DDevice7::DrawPrimitiveVB
4153 * Draws primitives from a vertex buffer to the screen.
4158 * PrimitiveType: Type of primitive to be rendered.
4159 * D3DVertexBuf: Source Vertex Buffer
4160 * StartVertex: Index of the first vertex from the buffer to be rendered
4161 * NumVertices: Number of vertices to be rendered
4162 * Flags: Can be D3DDP_WAIT to wait until rendering has finished
4166 * DDERR_INVALIDPARAMS if D3DVertexBuf is NULL
4168 *****************************************************************************/
4170 IDirect3DDeviceImpl_7_DrawPrimitiveVB(IDirect3DDevice7 *iface,
4171 D3DPRIMITIVETYPE PrimitiveType,
4172 IDirect3DVertexBuffer7 *D3DVertexBuf,
4177 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
4178 IDirect3DVertexBufferImpl *vb = (IDirect3DVertexBufferImpl *)D3DVertexBuf;
4182 TRACE("(%p)->(%08x,%p,%08x,%08x,%08x)\n", This, PrimitiveType, D3DVertexBuf, StartVertex, NumVertices, Flags);
4187 ERR("(%p) No Vertex buffer specified\n", This);
4188 return DDERR_INVALIDPARAMS;
4190 stride = get_flexible_vertex_size(vb->fvf);
4192 EnterCriticalSection(&ddraw_cs);
4193 hr = IWineD3DDevice_SetVertexDeclaration(This->wineD3DDevice,
4194 vb->wineD3DVertexDeclaration);
4197 ERR(" (%p) Setting the FVF failed, hr = %x!\n", This, hr);
4198 LeaveCriticalSection(&ddraw_cs);
4202 /* Set the vertex stream source */
4203 hr = IWineD3DDevice_SetStreamSource(This->wineD3DDevice,
4204 0 /* StreamNumber */,
4205 vb->wineD3DVertexBuffer,
4206 0 /* StartVertex - we pass this to DrawPrimitive */,
4210 ERR("(%p) IDirect3DDevice::SetStreamSource failed with hr = %08x\n", This, hr);
4211 LeaveCriticalSection(&ddraw_cs);
4215 /* Now draw the primitives */
4216 IWineD3DDevice_SetPrimitiveType(This->wineD3DDevice, PrimitiveType);
4217 hr = IWineD3DDevice_DrawPrimitive(This->wineD3DDevice, StartVertex, NumVertices);
4218 LeaveCriticalSection(&ddraw_cs);
4222 static HRESULT WINAPI
4223 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUSetup(IDirect3DDevice7 *iface,
4224 D3DPRIMITIVETYPE PrimitiveType,
4225 IDirect3DVertexBuffer7 *D3DVertexBuf,
4230 return IDirect3DDeviceImpl_7_DrawPrimitiveVB(iface, PrimitiveType, D3DVertexBuf, StartVertex, NumVertices, Flags);
4233 static HRESULT WINAPI
4234 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUPreserve(IDirect3DDevice7 *iface,
4235 D3DPRIMITIVETYPE PrimitiveType,
4236 IDirect3DVertexBuffer7 *D3DVertexBuf,
4244 old_fpucw = d3d_fpu_setup();
4245 hr = IDirect3DDeviceImpl_7_DrawPrimitiveVB(iface, PrimitiveType, D3DVertexBuf, StartVertex, NumVertices, Flags);
4246 set_fpu_control_word(old_fpucw);
4251 static HRESULT WINAPI
4252 Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveVB(IDirect3DDevice3 *iface,
4253 D3DPRIMITIVETYPE PrimitiveType,
4254 IDirect3DVertexBuffer *D3DVertexBuf,
4259 IDirect3DDeviceImpl *This = device_from_device3(iface);
4260 IDirect3DVertexBufferImpl *vb = D3DVertexBuf ? vb_from_vb1(D3DVertexBuf) : NULL;
4261 TRACE_(ddraw_thunk)("(%p)->(%08x,%p,%08x,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, vb, StartVertex, NumVertices, Flags);
4262 return IDirect3DDevice7_DrawPrimitiveVB((IDirect3DDevice7 *)This, PrimitiveType,
4263 (IDirect3DVertexBuffer7 *)vb, StartVertex, NumVertices, Flags);
4267 /*****************************************************************************
4268 * IDirect3DDevice7::DrawIndexedPrimitiveVB
4270 * Draws primitives from a vertex buffer to the screen
4273 * PrimitiveType: Type of primitive to be rendered.
4274 * D3DVertexBuf: Source Vertex Buffer
4275 * StartVertex: Index of the first vertex from the buffer to be rendered
4276 * NumVertices: Number of vertices to be rendered
4277 * Indices: Array of DWORDs used to index into the Vertices
4278 * IndexCount: Number of indices in Indices
4279 * Flags: Can be D3DDP_WAIT to wait until rendering has finished
4283 *****************************************************************************/
4285 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB(IDirect3DDevice7 *iface,
4286 D3DPRIMITIVETYPE PrimitiveType,
4287 IDirect3DVertexBuffer7 *D3DVertexBuf,
4294 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
4295 IDirect3DVertexBufferImpl *vb = (IDirect3DVertexBufferImpl *)D3DVertexBuf;
4296 DWORD stride = get_flexible_vertex_size(vb->fvf);
4297 WORD *LockedIndices;
4299 WINED3DBUFFER_DESC desc;
4301 TRACE("(%p)->(%08x,%p,%d,%d,%p,%d,%08x)\n", This, PrimitiveType, vb, StartVertex, NumVertices, Indices, IndexCount, Flags);
4304 * 1) Upload the Indices to the index buffer
4305 * 2) Set the index source
4306 * 3) Set the Vertex Buffer as the Stream source
4307 * 4) Call IWineD3DDevice::DrawIndexedPrimitive
4310 EnterCriticalSection(&ddraw_cs);
4312 hr = IWineD3DDevice_SetVertexDeclaration(This->wineD3DDevice,
4313 vb->wineD3DVertexDeclaration);
4316 ERR(" (%p) Setting the FVF failed, hr = %x!\n", This, hr);
4317 LeaveCriticalSection(&ddraw_cs);
4321 /* check that the buffer is large enough to hold the indices,
4322 * reallocate if necessary.
4324 hr = IWineD3DBuffer_GetDesc(This->indexbuffer, &desc);
4325 if(desc.Size < IndexCount * sizeof(WORD))
4327 UINT size = max(desc.Size * 2, IndexCount * sizeof(WORD));
4328 IWineD3DBuffer *buffer;
4331 TRACE("Growing index buffer to %u bytes\n", size);
4333 IWineD3DBuffer_GetParent(This->indexbuffer, &parent);
4334 hr = IWineD3DDevice_CreateIndexBuffer(This->wineD3DDevice, size,
4335 WINED3DUSAGE_DYNAMIC /* Usage */, WINED3DPOOL_DEFAULT, &buffer, parent,
4336 &ddraw_null_wined3d_parent_ops);
4339 ERR("(%p) IWineD3DDevice::CreateIndexBuffer failed with hr = %08x\n", This, hr);
4340 IParent_Release(parent);
4341 LeaveCriticalSection(&ddraw_cs);
4345 IWineD3DBuffer_Release(This->indexbuffer);
4346 This->indexbuffer = buffer;
4348 ((IParentImpl *)parent)->child = (IUnknown *)buffer;
4349 IParent_Release(parent);
4352 /* copy the index stream into the index buffer.
4353 * A new IWineD3DDevice method could be created
4354 * which takes an user pointer containing the indices
4355 * or a SetData-Method for the index buffer, which
4356 * overrides the index buffer data with our pointer.
4358 hr = IWineD3DBuffer_Map(This->indexbuffer,
4359 0 /* OffSetToLock */,
4360 IndexCount * sizeof(WORD),
4361 (BYTE **) &LockedIndices,
4365 ERR("(%p) IWineD3DBuffer::Map failed with hr = %08x\n", This, hr);
4366 LeaveCriticalSection(&ddraw_cs);
4369 memcpy(LockedIndices, Indices, IndexCount * sizeof(WORD));
4370 hr = IWineD3DBuffer_Unmap(This->indexbuffer);
4373 ERR("(%p) IWineD3DBuffer::Unmap failed with hr = %08x\n", This, hr);
4374 LeaveCriticalSection(&ddraw_cs);
4378 /* Set the index stream */
4379 IWineD3DDevice_SetBaseVertexIndex(This->wineD3DDevice, StartVertex);
4380 hr = IWineD3DDevice_SetIndexBuffer(This->wineD3DDevice, This->indexbuffer,
4381 WINED3DFMT_R16_UINT);
4383 /* Set the vertex stream source */
4384 hr = IWineD3DDevice_SetStreamSource(This->wineD3DDevice,
4385 0 /* StreamNumber */,
4386 vb->wineD3DVertexBuffer,
4387 0 /* offset, we pass this to DrawIndexedPrimitive */,
4391 ERR("(%p) IDirect3DDevice::SetStreamSource failed with hr = %08x\n", This, hr);
4392 LeaveCriticalSection(&ddraw_cs);
4397 IWineD3DDevice_SetPrimitiveType(This->wineD3DDevice, PrimitiveType);
4398 hr = IWineD3DDevice_DrawIndexedPrimitive(This->wineD3DDevice, 0 /* StartIndex */, IndexCount);
4400 LeaveCriticalSection(&ddraw_cs);
4404 static HRESULT WINAPI
4405 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUSetup(IDirect3DDevice7 *iface,
4406 D3DPRIMITIVETYPE PrimitiveType,
4407 IDirect3DVertexBuffer7 *D3DVertexBuf,
4414 return IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB(iface, PrimitiveType, D3DVertexBuf, StartVertex, NumVertices, Indices, IndexCount, Flags);
4417 static HRESULT WINAPI
4418 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUPreserve(IDirect3DDevice7 *iface,
4419 D3DPRIMITIVETYPE PrimitiveType,
4420 IDirect3DVertexBuffer7 *D3DVertexBuf,
4430 old_fpucw = d3d_fpu_setup();
4431 hr = IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB(iface, PrimitiveType, D3DVertexBuf, StartVertex, NumVertices, Indices, IndexCount, Flags);
4432 set_fpu_control_word(old_fpucw);
4437 static HRESULT WINAPI
4438 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveVB(IDirect3DDevice3 *iface,
4439 D3DPRIMITIVETYPE PrimitiveType,
4440 IDirect3DVertexBuffer *D3DVertexBuf,
4445 IDirect3DDeviceImpl *This = device_from_device3(iface);
4446 IDirect3DVertexBufferImpl *VB = vb_from_vb1(D3DVertexBuf);
4447 TRACE_(ddraw_thunk)("(%p)->(%08x,%p,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, VB, Indices, IndexCount, Flags);
4449 return IDirect3DDevice7_DrawIndexedPrimitiveVB((IDirect3DDevice7 *)This, PrimitiveType,
4450 (IDirect3DVertexBuffer7 *)VB, 0, IndexCount, Indices, IndexCount, Flags);
4453 /*****************************************************************************
4454 * IDirect3DDevice7::ComputeSphereVisibility
4456 * Calculates the visibility of spheres in the current viewport. The spheres
4457 * are passed in the Centers and Radii arrays, the results are passed back
4458 * in the ReturnValues array. Return values are either completely visible,
4459 * partially visible or completely invisible.
4460 * The return value consist of a combination of D3DCLIP_* flags, or it's
4461 * 0 if the sphere is completely visible(according to the SDK, not checked)
4466 * Centers: Array containing the sphere centers
4467 * Radii: Array containing the sphere radii
4468 * NumSpheres: The number of centers and radii in the arrays
4470 * ReturnValues: Array to write the results to
4474 * (DDERR_INVALIDPARAMS if Centers, Radii or ReturnValues are NULL)
4475 * (D3DERR_INVALIDMATRIX if the combined world, view and proj matrix
4478 *****************************************************************************/
4480 static DWORD in_plane(UINT plane, D3DVECTOR normal, D3DVALUE origin_plane, D3DVECTOR center, D3DVALUE radius)
4482 float distance, norm;
4484 norm = sqrt( normal.u1.x * normal.u1.x + normal.u2.y * normal.u2.y + normal.u3.z * normal.u3.z );
4485 distance = ( origin_plane + normal.u1.x * center.u1.x + normal.u2.y * center.u2.y + normal.u3.z * center.u3.z ) / norm;
4487 if ( fabs( distance ) < radius ) return D3DSTATUS_CLIPUNIONLEFT << plane;
4488 if ( distance < -radius ) return (D3DSTATUS_CLIPUNIONLEFT | D3DSTATUS_CLIPINTERSECTIONLEFT) << plane;
4492 static HRESULT WINAPI
4493 IDirect3DDeviceImpl_7_ComputeSphereVisibility(IDirect3DDevice7 *iface,
4498 DWORD *ReturnValues)
4501 D3DVALUE origin_plane[6];
4506 TRACE("(%p)->(%p,%p,%08x,%08x,%p)\n", iface, Centers, Radii, NumSpheres, Flags, ReturnValues);
4508 hr = IDirect3DDeviceImpl_7_GetTransform(iface, D3DTRANSFORMSTATE_WORLD, &m);
4509 if ( hr != DD_OK ) return DDERR_INVALIDPARAMS;
4510 hr = IDirect3DDeviceImpl_7_GetTransform(iface, D3DTRANSFORMSTATE_VIEW, &temp);
4511 if ( hr != DD_OK ) return DDERR_INVALIDPARAMS;
4512 multiply_matrix_D3D_way(&m, &m, &temp);
4514 hr = IDirect3DDeviceImpl_7_GetTransform(iface, D3DTRANSFORMSTATE_PROJECTION, &temp);
4515 if ( hr != DD_OK ) return DDERR_INVALIDPARAMS;
4516 multiply_matrix_D3D_way(&m, &m, &temp);
4519 vec[0].u1.x = m._14 + m._11;
4520 vec[0].u2.y = m._24 + m._21;
4521 vec[0].u3.z = m._34 + m._31;
4522 origin_plane[0] = m._44 + m._41;
4525 vec[1].u1.x = m._14 - m._11;
4526 vec[1].u2.y = m._24 - m._21;
4527 vec[1].u3.z = m._34 - m._31;
4528 origin_plane[1] = m._44 - m._41;
4531 vec[2].u1.x = m._14 - m._12;
4532 vec[2].u2.y = m._24 - m._22;
4533 vec[2].u3.z = m._34 - m._32;
4534 origin_plane[2] = m._44 - m._42;
4537 vec[3].u1.x = m._14 + m._12;
4538 vec[3].u2.y = m._24 + m._22;
4539 vec[3].u3.z = m._34 + m._32;
4540 origin_plane[3] = m._44 + m._42;
4543 vec[4].u1.x = m._13;
4544 vec[4].u2.y = m._23;
4545 vec[4].u3.z = m._33;
4546 origin_plane[4] = m._43;
4549 vec[5].u1.x = m._14 - m._13;
4550 vec[5].u2.y = m._24 - m._23;
4551 vec[5].u3.z = m._34 - m._33;
4552 origin_plane[5] = m._44 - m._43;
4554 for(i=0; i<NumSpheres; i++)
4556 ReturnValues[i] = 0;
4557 for(j=0; j<6; j++) ReturnValues[i] |= in_plane(j, vec[j], origin_plane[j], Centers[i], Radii[i]);
4563 static HRESULT WINAPI
4564 Thunk_IDirect3DDeviceImpl_3_ComputeSphereVisibility(IDirect3DDevice3 *iface,
4569 DWORD *ReturnValues)
4571 IDirect3DDeviceImpl *This = device_from_device3(iface);
4572 TRACE_(ddraw_thunk)("(%p)->(%p,%p,%08x,%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, Centers, Radii, NumSpheres, Flags, ReturnValues);
4573 return IDirect3DDevice7_ComputeSphereVisibility((IDirect3DDevice7 *)This,
4574 Centers, Radii, NumSpheres, Flags, ReturnValues);
4577 /*****************************************************************************
4578 * IDirect3DDevice7::GetTexture
4580 * Returns the texture interface handle assigned to a texture stage.
4581 * The returned texture is AddRefed. This is taken from old ddraw,
4582 * not checked in Windows.
4587 * Stage: Texture stage to read the texture from
4588 * Texture: Address to store the interface pointer at
4592 * DDERR_INVALIDPARAMS if Texture is NULL
4593 * For details, see IWineD3DDevice::GetTexture
4595 *****************************************************************************/
4597 IDirect3DDeviceImpl_7_GetTexture(IDirect3DDevice7 *iface,
4599 IDirectDrawSurface7 **Texture)
4601 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
4602 IWineD3DBaseTexture *Surf;
4604 TRACE("(%p)->(%d,%p): Relay\n", This, Stage, Texture);
4608 TRACE("Texture == NULL, failing with DDERR_INVALIDPARAMS\n");
4609 return DDERR_INVALIDPARAMS;
4612 EnterCriticalSection(&ddraw_cs);
4613 hr = IWineD3DDevice_GetTexture(This->wineD3DDevice, Stage, &Surf);
4614 if( (hr != D3D_OK) || (!Surf) )
4617 LeaveCriticalSection(&ddraw_cs);
4621 /* GetParent AddRef()s, which is perfectly OK.
4622 * We have passed the IDirectDrawSurface7 interface to WineD3D, so that's OK too.
4624 hr = IWineD3DBaseTexture_GetParent(Surf,
4625 (IUnknown **) Texture);
4626 LeaveCriticalSection(&ddraw_cs);
4630 static HRESULT WINAPI
4631 IDirect3DDeviceImpl_7_GetTexture_FPUSetup(IDirect3DDevice7 *iface,
4633 IDirectDrawSurface7 **Texture)
4635 return IDirect3DDeviceImpl_7_GetTexture(iface, Stage, Texture);
4638 static HRESULT WINAPI
4639 IDirect3DDeviceImpl_7_GetTexture_FPUPreserve(IDirect3DDevice7 *iface,
4641 IDirectDrawSurface7 **Texture)
4646 old_fpucw = d3d_fpu_setup();
4647 hr = IDirect3DDeviceImpl_7_GetTexture(iface, Stage, Texture);
4648 set_fpu_control_word(old_fpucw);
4653 static HRESULT WINAPI
4654 Thunk_IDirect3DDeviceImpl_3_GetTexture(IDirect3DDevice3 *iface,
4656 IDirect3DTexture2 **Texture2)
4658 IDirect3DDeviceImpl *This = device_from_device3(iface);
4660 IDirectDrawSurface7 *ret_val;
4662 TRACE_(ddraw_thunk)("(%p)->(%d,%p) thunking to IDirect3DDevice7 interface.\n", This, Stage, Texture2);
4663 ret = IDirect3DDevice7_GetTexture((IDirect3DDevice7 *)This, Stage, &ret_val);
4665 *Texture2 = ret_val ? (IDirect3DTexture2 *)&((IDirectDrawSurfaceImpl *)ret_val)->IDirect3DTexture2_vtbl : NULL;
4667 TRACE_(ddraw_thunk)(" returning interface %p.\n", *Texture2);
4672 /*****************************************************************************
4673 * IDirect3DDevice7::SetTexture
4675 * Assigns a texture to a texture stage. Is the texture AddRef-ed?
4680 * Stage: The stage to assign the texture to
4681 * Texture: Interface pointer to the texture surface
4685 * For details, see IWineD3DDevice::SetTexture
4687 *****************************************************************************/
4689 IDirect3DDeviceImpl_7_SetTexture(IDirect3DDevice7 *iface,
4691 IDirectDrawSurface7 *Texture)
4693 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
4694 IDirectDrawSurfaceImpl *surf = (IDirectDrawSurfaceImpl *)Texture;
4696 TRACE("(%p)->(%08x,%p): Relay!\n", This, Stage, surf);
4698 /* Texture may be NULL here */
4699 EnterCriticalSection(&ddraw_cs);
4700 hr = IWineD3DDevice_SetTexture(This->wineD3DDevice,
4702 surf ? surf->wineD3DTexture : NULL);
4703 LeaveCriticalSection(&ddraw_cs);
4707 static HRESULT WINAPI
4708 IDirect3DDeviceImpl_7_SetTexture_FPUSetup(IDirect3DDevice7 *iface,
4710 IDirectDrawSurface7 *Texture)
4712 return IDirect3DDeviceImpl_7_SetTexture(iface, Stage, Texture);
4715 static HRESULT WINAPI
4716 IDirect3DDeviceImpl_7_SetTexture_FPUPreserve(IDirect3DDevice7 *iface,
4718 IDirectDrawSurface7 *Texture)
4723 old_fpucw = d3d_fpu_setup();
4724 hr = IDirect3DDeviceImpl_7_SetTexture(iface, Stage, Texture);
4725 set_fpu_control_word(old_fpucw);
4730 static HRESULT WINAPI
4731 IDirect3DDeviceImpl_3_SetTexture(IDirect3DDevice3 *iface,
4733 IDirect3DTexture2 *Texture2)
4735 IDirect3DDeviceImpl *This = device_from_device3(iface);
4736 IDirectDrawSurfaceImpl *tex = Texture2 ? surface_from_texture2(Texture2) : NULL;
4739 TRACE("(%p)->(%d,%p)\n", This, Stage, tex);
4741 EnterCriticalSection(&ddraw_cs);
4743 if (This->legacyTextureBlending)
4744 IDirect3DDevice3_GetRenderState(iface, D3DRENDERSTATE_TEXTUREMAPBLEND, &texmapblend);
4746 hr = IDirect3DDevice7_SetTexture((IDirect3DDevice7 *)This, Stage, (IDirectDrawSurface7 *)tex);
4748 if (This->legacyTextureBlending && texmapblend == D3DTBLEND_MODULATE)
4750 /* This fixup is required by the way D3DTBLEND_MODULATE maps to texture stage states.
4751 See IDirect3DDeviceImpl_3_SetRenderState for details. */
4752 BOOL tex_alpha = FALSE;
4753 IWineD3DBaseTexture *tex = NULL;
4754 WINED3DSURFACE_DESC desc;
4755 DDPIXELFORMAT ddfmt;
4758 result = IWineD3DDevice_GetTexture(This->wineD3DDevice,
4762 if(result == WINED3D_OK && tex)
4764 memset(&desc, 0, sizeof(desc));
4765 result = IWineD3DTexture_GetLevelDesc((IWineD3DTexture*) tex, 0, &desc);
4766 if (SUCCEEDED(result))
4768 ddfmt.dwSize = sizeof(ddfmt);
4769 PixelFormat_WineD3DtoDD(&ddfmt, desc.format);
4770 if (ddfmt.u5.dwRGBAlphaBitMask) tex_alpha = TRUE;
4773 IWineD3DBaseTexture_Release(tex);
4776 /* Arg 1/2 are already set to WINED3DTA_TEXTURE/WINED3DTA_CURRENT in case of D3DTBLEND_MODULATE */
4778 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAOP, WINED3DTOP_SELECTARG1);
4780 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAOP, WINED3DTOP_SELECTARG2);
4783 LeaveCriticalSection(&ddraw_cs);
4788 static const struct tss_lookup
4795 {FALSE, WINED3DTSS_FORCE_DWORD}, /* 0, unused */
4796 {FALSE, WINED3DTSS_COLOROP}, /* 1, D3DTSS_COLOROP */
4797 {FALSE, WINED3DTSS_COLORARG1}, /* 2, D3DTSS_COLORARG1 */
4798 {FALSE, WINED3DTSS_COLORARG2}, /* 3, D3DTSS_COLORARG2 */
4799 {FALSE, WINED3DTSS_ALPHAOP}, /* 4, D3DTSS_ALPHAOP */
4800 {FALSE, WINED3DTSS_ALPHAARG1}, /* 5, D3DTSS_ALPHAARG1 */
4801 {FALSE, WINED3DTSS_ALPHAARG2}, /* 6, D3DTSS_ALPHAARG2 */
4802 {FALSE, WINED3DTSS_BUMPENVMAT00}, /* 7, D3DTSS_BUMPENVMAT00 */
4803 {FALSE, WINED3DTSS_BUMPENVMAT01}, /* 8, D3DTSS_BUMPENVMAT01 */
4804 {FALSE, WINED3DTSS_BUMPENVMAT10}, /* 9, D3DTSS_BUMPENVMAT10 */
4805 {FALSE, WINED3DTSS_BUMPENVMAT11}, /* 10, D3DTSS_BUMPENVMAT11 */
4806 {FALSE, WINED3DTSS_TEXCOORDINDEX}, /* 11, D3DTSS_TEXCOORDINDEX */
4807 {TRUE, WINED3DSAMP_ADDRESSU}, /* 12, D3DTSS_ADDRESS */
4808 {TRUE, WINED3DSAMP_ADDRESSU}, /* 13, D3DTSS_ADDRESSU */
4809 {TRUE, WINED3DSAMP_ADDRESSV}, /* 14, D3DTSS_ADDRESSV */
4810 {TRUE, WINED3DSAMP_BORDERCOLOR}, /* 15, D3DTSS_BORDERCOLOR */
4811 {TRUE, WINED3DSAMP_MAGFILTER}, /* 16, D3DTSS_MAGFILTER */
4812 {TRUE, WINED3DSAMP_MINFILTER}, /* 17, D3DTSS_MINFILTER */
4813 {TRUE, WINED3DSAMP_MIPFILTER}, /* 18, D3DTSS_MIPFILTER */
4814 {TRUE, WINED3DSAMP_MIPMAPLODBIAS}, /* 19, D3DTSS_MIPMAPLODBIAS */
4815 {TRUE, WINED3DSAMP_MAXMIPLEVEL}, /* 20, D3DTSS_MAXMIPLEVEL */
4816 {TRUE, WINED3DSAMP_MAXANISOTROPY}, /* 21, D3DTSS_MAXANISOTROPY */
4817 {FALSE, WINED3DTSS_BUMPENVLSCALE}, /* 22, D3DTSS_BUMPENVLSCALE */
4818 {FALSE, WINED3DTSS_BUMPENVLOFFSET}, /* 23, D3DTSS_BUMPENVLOFFSET */
4819 {FALSE, WINED3DTSS_TEXTURETRANSFORMFLAGS}, /* 24, D3DTSS_TEXTURETRANSFORMFLAGS */
4822 /*****************************************************************************
4823 * IDirect3DDevice7::GetTextureStageState
4825 * Retrieves a state from a texture stage.
4830 * Stage: The stage to retrieve the state from
4831 * TexStageStateType: The state type to retrieve
4832 * State: Address to store the state's value at
4836 * DDERR_INVALIDPARAMS if State is NULL
4837 * For details, see IWineD3DDevice::GetTextureStageState
4839 *****************************************************************************/
4841 IDirect3DDeviceImpl_7_GetTextureStageState(IDirect3DDevice7 *iface,
4843 D3DTEXTURESTAGESTATETYPE TexStageStateType,
4846 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
4848 const struct tss_lookup *l = &tss_lookup[TexStageStateType];
4849 TRACE("(%p)->(%08x,%08x,%p): Relay!\n", This, Stage, TexStageStateType, State);
4852 return DDERR_INVALIDPARAMS;
4854 if (TexStageStateType > D3DTSS_TEXTURETRANSFORMFLAGS)
4856 WARN("Invalid TexStageStateType %#x passed.\n", TexStageStateType);
4861 EnterCriticalSection(&ddraw_cs);
4863 if (l->sampler_state)
4865 hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice, Stage, l->state, State);
4867 switch(TexStageStateType)
4869 /* Mipfilter is a sampler state with different values */
4870 case D3DTSS_MIPFILTER:
4874 case WINED3DTEXF_NONE: *State = D3DTFP_NONE; break;
4875 case WINED3DTEXF_POINT: *State = D3DTFP_POINT; break;
4876 case WINED3DTEXF_LINEAR: *State = D3DTFP_LINEAR; break;
4878 ERR("Unexpected mipfilter value %#x\n", *State);
4879 *State = D3DTFP_NONE;
4885 /* Magfilter has slightly different values */
4886 case D3DTSS_MAGFILTER:
4890 case WINED3DTEXF_POINT: *State = D3DTFG_POINT; break;
4891 case WINED3DTEXF_LINEAR: *State = D3DTFG_LINEAR; break;
4892 case WINED3DTEXF_ANISOTROPIC: *State = D3DTFG_ANISOTROPIC; break;
4893 case WINED3DTEXF_FLATCUBIC: *State = D3DTFG_FLATCUBIC; break;
4894 case WINED3DTEXF_GAUSSIANCUBIC: *State = D3DTFG_GAUSSIANCUBIC; break;
4896 ERR("Unexpected wined3d mag filter value %#x\n", *State);
4897 *State = D3DTFG_POINT;
4909 hr = IWineD3DDevice_GetTextureStageState(This->wineD3DDevice, Stage, l->state, State);
4912 LeaveCriticalSection(&ddraw_cs);
4916 static HRESULT WINAPI
4917 IDirect3DDeviceImpl_7_GetTextureStageState_FPUSetup(IDirect3DDevice7 *iface,
4919 D3DTEXTURESTAGESTATETYPE TexStageStateType,
4922 return IDirect3DDeviceImpl_7_GetTextureStageState(iface, Stage, TexStageStateType, State);
4925 static HRESULT WINAPI
4926 IDirect3DDeviceImpl_7_GetTextureStageState_FPUPreserve(IDirect3DDevice7 *iface,
4928 D3DTEXTURESTAGESTATETYPE TexStageStateType,
4934 old_fpucw = d3d_fpu_setup();
4935 hr = IDirect3DDeviceImpl_7_GetTextureStageState(iface, Stage, TexStageStateType, State);
4936 set_fpu_control_word(old_fpucw);
4941 static HRESULT WINAPI
4942 Thunk_IDirect3DDeviceImpl_3_GetTextureStageState(IDirect3DDevice3 *iface,
4944 D3DTEXTURESTAGESTATETYPE TexStageStateType,
4947 IDirect3DDeviceImpl *This = device_from_device3(iface);
4948 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, Stage, TexStageStateType, State);
4949 return IDirect3DDevice7_GetTextureStageState((IDirect3DDevice7 *)This, Stage, TexStageStateType, State);
4952 /*****************************************************************************
4953 * IDirect3DDevice7::SetTextureStageState
4955 * Sets a texture stage state. Some stage types need to be handled specially,
4956 * because they do not exist in WineD3D and were moved to another place
4961 * Stage: The stage to modify
4962 * TexStageStateType: The state to change
4963 * State: The new value for the state
4967 * For details, see IWineD3DDevice::SetTextureStageState
4969 *****************************************************************************/
4971 IDirect3DDeviceImpl_7_SetTextureStageState(IDirect3DDevice7 *iface,
4973 D3DTEXTURESTAGESTATETYPE TexStageStateType,
4976 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
4977 const struct tss_lookup *l = &tss_lookup[TexStageStateType];
4979 TRACE("(%p)->(%08x,%08x,%08x): Relay!\n", This, Stage, TexStageStateType, State);
4981 if (TexStageStateType > D3DTSS_TEXTURETRANSFORMFLAGS)
4983 WARN("Invalid TexStageStateType %#x passed.\n", TexStageStateType);
4987 EnterCriticalSection(&ddraw_cs);
4989 if (l->sampler_state)
4991 switch(TexStageStateType)
4993 /* Mipfilter is a sampler state with different values */
4994 case D3DTSS_MIPFILTER:
4998 case D3DTFP_NONE: State = WINED3DTEXF_NONE; break;
4999 case D3DTFP_POINT: State = WINED3DTEXF_POINT; break;
5000 case 0: /* Unchecked */
5001 case D3DTFP_LINEAR: State = WINED3DTEXF_LINEAR; break;
5003 ERR("Unexpected mipfilter value %d\n", State);
5004 State = WINED3DTEXF_NONE;
5010 /* Magfilter has slightly different values */
5011 case D3DTSS_MAGFILTER:
5015 case D3DTFG_POINT: State = WINED3DTEXF_POINT; break;
5016 case D3DTFG_LINEAR: State = WINED3DTEXF_LINEAR; break;
5017 case D3DTFG_FLATCUBIC: State = WINED3DTEXF_FLATCUBIC; break;
5018 case D3DTFG_GAUSSIANCUBIC: State = WINED3DTEXF_GAUSSIANCUBIC; break;
5019 case D3DTFG_ANISOTROPIC: State = WINED3DTEXF_ANISOTROPIC; break;
5021 ERR("Unexpected d3d7 mag filter type %d\n", State);
5022 State = WINED3DTEXF_POINT;
5028 case D3DTSS_ADDRESS:
5029 IWineD3DDevice_SetSamplerState(This->wineD3DDevice, Stage, WINED3DSAMP_ADDRESSV, State);
5036 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice, Stage, l->state, State);
5040 hr = IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, Stage, l->state, State);
5043 LeaveCriticalSection(&ddraw_cs);
5047 static HRESULT WINAPI
5048 IDirect3DDeviceImpl_7_SetTextureStageState_FPUSetup(IDirect3DDevice7 *iface,
5050 D3DTEXTURESTAGESTATETYPE TexStageStateType,
5053 return IDirect3DDeviceImpl_7_SetTextureStageState(iface, Stage, TexStageStateType, State);
5056 static HRESULT WINAPI
5057 IDirect3DDeviceImpl_7_SetTextureStageState_FPUPreserve(IDirect3DDevice7 *iface,
5059 D3DTEXTURESTAGESTATETYPE TexStageStateType,
5065 old_fpucw = d3d_fpu_setup();
5066 hr = IDirect3DDeviceImpl_7_SetTextureStageState(iface, Stage, TexStageStateType, State);
5067 set_fpu_control_word(old_fpucw);
5072 static HRESULT WINAPI
5073 Thunk_IDirect3DDeviceImpl_3_SetTextureStageState(IDirect3DDevice3 *iface,
5075 D3DTEXTURESTAGESTATETYPE TexStageStateType,
5078 IDirect3DDeviceImpl *This = device_from_device3(iface);
5079 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, Stage, TexStageStateType, State);
5080 return IDirect3DDevice7_SetTextureStageState((IDirect3DDevice7 *)This, Stage, TexStageStateType, State);
5083 /*****************************************************************************
5084 * IDirect3DDevice7::ValidateDevice
5086 * SDK: "Reports the device's ability to render the currently set
5087 * texture-blending operations in a single pass". Whatever that means
5093 * NumPasses: Address to write the number of necessary passes for the
5094 * desired effect to.
5098 * See IWineD3DDevice::ValidateDevice for more details
5100 *****************************************************************************/
5102 IDirect3DDeviceImpl_7_ValidateDevice(IDirect3DDevice7 *iface,
5105 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5107 TRACE("(%p)->(%p): Relay\n", This, NumPasses);
5109 EnterCriticalSection(&ddraw_cs);
5110 hr = IWineD3DDevice_ValidateDevice(This->wineD3DDevice, NumPasses);
5111 LeaveCriticalSection(&ddraw_cs);
5115 static HRESULT WINAPI
5116 IDirect3DDeviceImpl_7_ValidateDevice_FPUSetup(IDirect3DDevice7 *iface,
5119 return IDirect3DDeviceImpl_7_ValidateDevice(iface, NumPasses);
5122 static HRESULT WINAPI
5123 IDirect3DDeviceImpl_7_ValidateDevice_FPUPreserve(IDirect3DDevice7 *iface,
5129 old_fpucw = d3d_fpu_setup();
5130 hr = IDirect3DDeviceImpl_7_ValidateDevice(iface, NumPasses);
5131 set_fpu_control_word(old_fpucw);
5136 static HRESULT WINAPI
5137 Thunk_IDirect3DDeviceImpl_3_ValidateDevice(IDirect3DDevice3 *iface,
5140 IDirect3DDeviceImpl *This = device_from_device3(iface);
5141 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, Passes);
5142 return IDirect3DDevice7_ValidateDevice((IDirect3DDevice7 *)This, Passes);
5145 /*****************************************************************************
5146 * IDirect3DDevice7::Clear
5148 * Fills the render target, the z buffer and the stencil buffer with a
5149 * clear color / value
5154 * Count: Number of rectangles in Rects must be 0 if Rects is NULL
5155 * Rects: Rectangles to clear. If NULL, the whole surface is cleared
5156 * Flags: Some flags, as usual
5157 * Color: Clear color for the render target
5158 * Z: Clear value for the Z buffer
5159 * Stencil: Clear value to store in each stencil buffer entry
5163 * For details, see IWineD3DDevice::Clear
5165 *****************************************************************************/
5167 IDirect3DDeviceImpl_7_Clear(IDirect3DDevice7 *iface,
5175 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5177 TRACE("(%p)->(%08x,%p,%08x,%08x,%f,%08x): Relay\n", This, Count, Rects, Flags, Color, Z, Stencil);
5179 /* Note; D3DRECT is compatible with WINED3DRECT */
5180 EnterCriticalSection(&ddraw_cs);
5181 hr = IWineD3DDevice_Clear(This->wineD3DDevice, Count, (WINED3DRECT*) Rects, Flags, Color, Z, Stencil);
5182 LeaveCriticalSection(&ddraw_cs);
5186 static HRESULT WINAPI
5187 IDirect3DDeviceImpl_7_Clear_FPUSetup(IDirect3DDevice7 *iface,
5195 return IDirect3DDeviceImpl_7_Clear(iface, Count, Rects, Flags, Color, Z, Stencil);
5198 static HRESULT WINAPI
5199 IDirect3DDeviceImpl_7_Clear_FPUPreserve(IDirect3DDevice7 *iface,
5210 old_fpucw = d3d_fpu_setup();
5211 hr = IDirect3DDeviceImpl_7_Clear(iface, Count, Rects, Flags, Color, Z, Stencil);
5212 set_fpu_control_word(old_fpucw);
5217 /*****************************************************************************
5218 * IDirect3DDevice7::SetViewport
5220 * Sets the current viewport.
5222 * Version 7 only, but IDirect3DViewport uses this call for older
5226 * Data: The new viewport to set
5230 * DDERR_INVALIDPARAMS if Data is NULL
5231 * For more details, see IWineDDDevice::SetViewport
5233 *****************************************************************************/
5235 IDirect3DDeviceImpl_7_SetViewport(IDirect3DDevice7 *iface,
5238 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5240 TRACE("(%p)->(%p) Relay!\n", This, Data);
5243 return DDERR_INVALIDPARAMS;
5245 /* Note: D3DVIEWPORT7 is compatible with WINED3DVIEWPORT */
5246 EnterCriticalSection(&ddraw_cs);
5247 hr = IWineD3DDevice_SetViewport(This->wineD3DDevice,
5248 (WINED3DVIEWPORT*) Data);
5249 LeaveCriticalSection(&ddraw_cs);
5253 static HRESULT WINAPI
5254 IDirect3DDeviceImpl_7_SetViewport_FPUSetup(IDirect3DDevice7 *iface,
5257 return IDirect3DDeviceImpl_7_SetViewport(iface, Data);
5260 static HRESULT WINAPI
5261 IDirect3DDeviceImpl_7_SetViewport_FPUPreserve(IDirect3DDevice7 *iface,
5267 old_fpucw = d3d_fpu_setup();
5268 hr = IDirect3DDeviceImpl_7_SetViewport(iface, Data);
5269 set_fpu_control_word(old_fpucw);
5274 /*****************************************************************************
5275 * IDirect3DDevice::GetViewport
5277 * Returns the current viewport
5282 * Data: D3D7Viewport structure to write the viewport information to
5286 * DDERR_INVALIDPARAMS if Data is NULL
5287 * For more details, see IWineD3DDevice::GetViewport
5289 *****************************************************************************/
5291 IDirect3DDeviceImpl_7_GetViewport(IDirect3DDevice7 *iface,
5294 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5296 TRACE("(%p)->(%p) Relay!\n", This, Data);
5299 return DDERR_INVALIDPARAMS;
5301 /* Note: D3DVIEWPORT7 is compatible with WINED3DVIEWPORT */
5302 EnterCriticalSection(&ddraw_cs);
5303 hr = IWineD3DDevice_GetViewport(This->wineD3DDevice,
5304 (WINED3DVIEWPORT*) Data);
5306 LeaveCriticalSection(&ddraw_cs);
5307 return hr_ddraw_from_wined3d(hr);
5310 static HRESULT WINAPI
5311 IDirect3DDeviceImpl_7_GetViewport_FPUSetup(IDirect3DDevice7 *iface,
5314 return IDirect3DDeviceImpl_7_GetViewport(iface, Data);
5317 static HRESULT WINAPI
5318 IDirect3DDeviceImpl_7_GetViewport_FPUPreserve(IDirect3DDevice7 *iface,
5324 old_fpucw = d3d_fpu_setup();
5325 hr = IDirect3DDeviceImpl_7_GetViewport(iface, Data);
5326 set_fpu_control_word(old_fpucw);
5331 /*****************************************************************************
5332 * IDirect3DDevice7::SetMaterial
5339 * Mat: The material to set
5343 * DDERR_INVALIDPARAMS if Mat is NULL.
5344 * For more details, see IWineD3DDevice::SetMaterial
5346 *****************************************************************************/
5348 IDirect3DDeviceImpl_7_SetMaterial(IDirect3DDevice7 *iface,
5351 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5353 TRACE("(%p)->(%p): Relay!\n", This, Mat);
5355 if (!Mat) return DDERR_INVALIDPARAMS;
5356 /* Note: D3DMATERIAL7 is compatible with WINED3DMATERIAL */
5357 EnterCriticalSection(&ddraw_cs);
5358 hr = IWineD3DDevice_SetMaterial(This->wineD3DDevice,
5359 (WINED3DMATERIAL*) Mat);
5360 LeaveCriticalSection(&ddraw_cs);
5361 return hr_ddraw_from_wined3d(hr);
5364 static HRESULT WINAPI
5365 IDirect3DDeviceImpl_7_SetMaterial_FPUSetup(IDirect3DDevice7 *iface,
5368 return IDirect3DDeviceImpl_7_SetMaterial(iface, Mat);
5371 static HRESULT WINAPI
5372 IDirect3DDeviceImpl_7_SetMaterial_FPUPreserve(IDirect3DDevice7 *iface,
5378 old_fpucw = d3d_fpu_setup();
5379 hr = IDirect3DDeviceImpl_7_SetMaterial(iface, Mat);
5380 set_fpu_control_word(old_fpucw);
5385 /*****************************************************************************
5386 * IDirect3DDevice7::GetMaterial
5388 * Returns the current material
5393 * Mat: D3DMATERIAL7 structure to write the material parameters to
5397 * DDERR_INVALIDPARAMS if Mat is NULL
5398 * For more details, see IWineD3DDevice::GetMaterial
5400 *****************************************************************************/
5402 IDirect3DDeviceImpl_7_GetMaterial(IDirect3DDevice7 *iface,
5405 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5407 TRACE("(%p)->(%p): Relay!\n", This, Mat);
5409 EnterCriticalSection(&ddraw_cs);
5410 /* Note: D3DMATERIAL7 is compatible with WINED3DMATERIAL */
5411 hr = IWineD3DDevice_GetMaterial(This->wineD3DDevice,
5412 (WINED3DMATERIAL*) Mat);
5413 LeaveCriticalSection(&ddraw_cs);
5414 return hr_ddraw_from_wined3d(hr);
5417 static HRESULT WINAPI
5418 IDirect3DDeviceImpl_7_GetMaterial_FPUSetup(IDirect3DDevice7 *iface,
5421 return IDirect3DDeviceImpl_7_GetMaterial(iface, Mat);
5424 static HRESULT WINAPI
5425 IDirect3DDeviceImpl_7_GetMaterial_FPUPreserve(IDirect3DDevice7 *iface,
5431 old_fpucw = d3d_fpu_setup();
5432 hr = IDirect3DDeviceImpl_7_GetMaterial(iface, Mat);
5433 set_fpu_control_word(old_fpucw);
5438 /*****************************************************************************
5439 * IDirect3DDevice7::SetLight
5441 * Assigns a light to a light index, but doesn't activate it yet.
5443 * Version 7, IDirect3DLight uses this method for older versions
5446 * LightIndex: The index of the new light
5447 * Light: A D3DLIGHT7 structure describing the light
5451 * For more details, see IWineD3DDevice::SetLight
5453 *****************************************************************************/
5455 IDirect3DDeviceImpl_7_SetLight(IDirect3DDevice7 *iface,
5459 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5461 TRACE("(%p)->(%08x,%p): Relay!\n", This, LightIndex, Light);
5463 EnterCriticalSection(&ddraw_cs);
5464 /* Note: D3DLIGHT7 is compatible with WINED3DLIGHT */
5465 hr = IWineD3DDevice_SetLight(This->wineD3DDevice,
5467 (WINED3DLIGHT*) Light);
5468 LeaveCriticalSection(&ddraw_cs);
5469 return hr_ddraw_from_wined3d(hr);
5472 static HRESULT WINAPI
5473 IDirect3DDeviceImpl_7_SetLight_FPUSetup(IDirect3DDevice7 *iface,
5477 return IDirect3DDeviceImpl_7_SetLight(iface, LightIndex, Light);
5480 static HRESULT WINAPI
5481 IDirect3DDeviceImpl_7_SetLight_FPUPreserve(IDirect3DDevice7 *iface,
5488 old_fpucw = d3d_fpu_setup();
5489 hr = IDirect3DDeviceImpl_7_SetLight(iface, LightIndex, Light);
5490 set_fpu_control_word(old_fpucw);
5495 /*****************************************************************************
5496 * IDirect3DDevice7::GetLight
5498 * Returns the light assigned to a light index
5501 * Light: Structure to write the light information to
5505 * DDERR_INVALIDPARAMS if Light is NULL
5506 * For details, see IWineD3DDevice::GetLight
5508 *****************************************************************************/
5510 IDirect3DDeviceImpl_7_GetLight(IDirect3DDevice7 *iface,
5514 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5516 TRACE("(%p)->(%08x,%p): Relay!\n", This, LightIndex, Light);
5518 EnterCriticalSection(&ddraw_cs);
5519 /* Note: D3DLIGHT7 is compatible with WINED3DLIGHT */
5520 rc = IWineD3DDevice_GetLight(This->wineD3DDevice,
5522 (WINED3DLIGHT*) Light);
5524 /* Translate the result. WineD3D returns other values than D3D7 */
5525 LeaveCriticalSection(&ddraw_cs);
5526 return hr_ddraw_from_wined3d(rc);
5529 static HRESULT WINAPI
5530 IDirect3DDeviceImpl_7_GetLight_FPUSetup(IDirect3DDevice7 *iface,
5534 return IDirect3DDeviceImpl_7_GetLight(iface, LightIndex, Light);
5537 static HRESULT WINAPI
5538 IDirect3DDeviceImpl_7_GetLight_FPUPreserve(IDirect3DDevice7 *iface,
5545 old_fpucw = d3d_fpu_setup();
5546 hr = IDirect3DDeviceImpl_7_GetLight(iface, LightIndex, Light);
5547 set_fpu_control_word(old_fpucw);
5552 /*****************************************************************************
5553 * IDirect3DDevice7::BeginStateBlock
5555 * Begins recording to a stateblock
5561 * For details see IWineD3DDevice::BeginStateBlock
5563 *****************************************************************************/
5565 IDirect3DDeviceImpl_7_BeginStateBlock(IDirect3DDevice7 *iface)
5567 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5569 TRACE("(%p)->(): Relay!\n", This);
5571 EnterCriticalSection(&ddraw_cs);
5572 hr = IWineD3DDevice_BeginStateBlock(This->wineD3DDevice);
5573 LeaveCriticalSection(&ddraw_cs);
5574 return hr_ddraw_from_wined3d(hr);
5577 static HRESULT WINAPI
5578 IDirect3DDeviceImpl_7_BeginStateBlock_FPUSetup(IDirect3DDevice7 *iface)
5580 return IDirect3DDeviceImpl_7_BeginStateBlock(iface);
5583 static HRESULT WINAPI
5584 IDirect3DDeviceImpl_7_BeginStateBlock_FPUPreserve(IDirect3DDevice7 *iface)
5589 old_fpucw = d3d_fpu_setup();
5590 hr = IDirect3DDeviceImpl_7_BeginStateBlock(iface);
5591 set_fpu_control_word(old_fpucw);
5596 /*****************************************************************************
5597 * IDirect3DDevice7::EndStateBlock
5599 * Stops recording to a state block and returns the created stateblock
5605 * BlockHandle: Address to store the stateblock's handle to
5609 * DDERR_INVALIDPARAMS if BlockHandle is NULL
5610 * See IWineD3DDevice::EndStateBlock for more details
5612 *****************************************************************************/
5614 IDirect3DDeviceImpl_7_EndStateBlock(IDirect3DDevice7 *iface,
5617 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5619 TRACE("(%p)->(%p): Relay!\n", This, BlockHandle);
5623 WARN("BlockHandle == NULL, returning DDERR_INVALIDPARAMS\n");
5624 return DDERR_INVALIDPARAMS;
5627 EnterCriticalSection(&ddraw_cs);
5628 *BlockHandle = IDirect3DDeviceImpl_CreateHandle(This);
5631 ERR("Cannot get a handle number for the stateblock\n");
5632 LeaveCriticalSection(&ddraw_cs);
5633 return DDERR_OUTOFMEMORY;
5635 This->Handles[*BlockHandle - 1].type = DDrawHandle_StateBlock;
5636 hr = IWineD3DDevice_EndStateBlock(This->wineD3DDevice,
5637 (IWineD3DStateBlock **) &This->Handles[*BlockHandle - 1].ptr);
5638 LeaveCriticalSection(&ddraw_cs);
5639 return hr_ddraw_from_wined3d(hr);
5642 static HRESULT WINAPI
5643 IDirect3DDeviceImpl_7_EndStateBlock_FPUSetup(IDirect3DDevice7 *iface,
5646 return IDirect3DDeviceImpl_7_EndStateBlock(iface, BlockHandle);
5649 static HRESULT WINAPI
5650 IDirect3DDeviceImpl_7_EndStateBlock_FPUPreserve(IDirect3DDevice7 *iface,
5656 old_fpucw = d3d_fpu_setup();
5657 hr = IDirect3DDeviceImpl_7_EndStateBlock(iface, BlockHandle);
5658 set_fpu_control_word(old_fpucw);
5663 /*****************************************************************************
5664 * IDirect3DDevice7::PreLoad
5666 * Allows the app to signal that a texture will be used soon, to allow
5667 * the Direct3DDevice to load it to the video card in the meantime.
5672 * Texture: The texture to preload
5676 * DDERR_INVALIDPARAMS if Texture is NULL
5677 * See IWineD3DSurface::PreLoad for details
5679 *****************************************************************************/
5681 IDirect3DDeviceImpl_7_PreLoad(IDirect3DDevice7 *iface,
5682 IDirectDrawSurface7 *Texture)
5684 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5685 IDirectDrawSurfaceImpl *surf = (IDirectDrawSurfaceImpl *)Texture;
5687 TRACE("(%p)->(%p): Relay!\n", This, surf);
5690 return DDERR_INVALIDPARAMS;
5692 EnterCriticalSection(&ddraw_cs);
5693 IWineD3DSurface_PreLoad(surf->WineD3DSurface);
5694 LeaveCriticalSection(&ddraw_cs);
5698 static HRESULT WINAPI
5699 IDirect3DDeviceImpl_7_PreLoad_FPUSetup(IDirect3DDevice7 *iface,
5700 IDirectDrawSurface7 *Texture)
5702 return IDirect3DDeviceImpl_7_PreLoad(iface, Texture);
5705 static HRESULT WINAPI
5706 IDirect3DDeviceImpl_7_PreLoad_FPUPreserve(IDirect3DDevice7 *iface,
5707 IDirectDrawSurface7 *Texture)
5712 old_fpucw = d3d_fpu_setup();
5713 hr = IDirect3DDeviceImpl_7_PreLoad(iface, Texture);
5714 set_fpu_control_word(old_fpucw);
5719 /*****************************************************************************
5720 * IDirect3DDevice7::ApplyStateBlock
5722 * Activates the state stored in a state block handle.
5725 * BlockHandle: The stateblock handle to activate
5729 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is NULL
5731 *****************************************************************************/
5733 IDirect3DDeviceImpl_7_ApplyStateBlock(IDirect3DDevice7 *iface,
5736 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5738 TRACE("(%p)->(%08x): Relay!\n", This, BlockHandle);
5740 EnterCriticalSection(&ddraw_cs);
5741 if(!BlockHandle || BlockHandle > This->numHandles)
5743 WARN("Out of range handle %d, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle);
5744 LeaveCriticalSection(&ddraw_cs);
5745 return D3DERR_INVALIDSTATEBLOCK;
5747 if(This->Handles[BlockHandle - 1].type != DDrawHandle_StateBlock)
5749 WARN("Handle %d is not a stateblock, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle);
5750 LeaveCriticalSection(&ddraw_cs);
5751 return D3DERR_INVALIDSTATEBLOCK;
5754 hr = IWineD3DStateBlock_Apply((IWineD3DStateBlock *) This->Handles[BlockHandle - 1].ptr);
5755 LeaveCriticalSection(&ddraw_cs);
5756 return hr_ddraw_from_wined3d(hr);
5759 static HRESULT WINAPI
5760 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUSetup(IDirect3DDevice7 *iface,
5763 return IDirect3DDeviceImpl_7_ApplyStateBlock(iface, BlockHandle);
5766 static HRESULT WINAPI
5767 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUPreserve(IDirect3DDevice7 *iface,
5773 old_fpucw = d3d_fpu_setup();
5774 hr = IDirect3DDeviceImpl_7_ApplyStateBlock(iface, BlockHandle);
5775 set_fpu_control_word(old_fpucw);
5780 /*****************************************************************************
5781 * IDirect3DDevice7::CaptureStateBlock
5783 * Updates a stateblock's values to the values currently set for the device
5788 * BlockHandle: Stateblock to update
5792 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is NULL
5793 * See IWineD3DDevice::CaptureStateBlock for more details
5795 *****************************************************************************/
5797 IDirect3DDeviceImpl_7_CaptureStateBlock(IDirect3DDevice7 *iface,
5800 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5802 TRACE("(%p)->(%08x): Relay!\n", This, BlockHandle);
5804 EnterCriticalSection(&ddraw_cs);
5805 if(BlockHandle == 0 || BlockHandle > This->numHandles)
5807 WARN("Out of range handle %d, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle);
5808 LeaveCriticalSection(&ddraw_cs);
5809 return D3DERR_INVALIDSTATEBLOCK;
5811 if(This->Handles[BlockHandle - 1].type != DDrawHandle_StateBlock)
5813 WARN("Handle %d is not a stateblock, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle);
5814 LeaveCriticalSection(&ddraw_cs);
5815 return D3DERR_INVALIDSTATEBLOCK;
5818 hr = IWineD3DStateBlock_Capture((IWineD3DStateBlock *) This->Handles[BlockHandle - 1].ptr);
5819 LeaveCriticalSection(&ddraw_cs);
5820 return hr_ddraw_from_wined3d(hr);
5823 static HRESULT WINAPI
5824 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUSetup(IDirect3DDevice7 *iface,
5827 return IDirect3DDeviceImpl_7_CaptureStateBlock(iface, BlockHandle);
5830 static HRESULT WINAPI
5831 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUPreserve(IDirect3DDevice7 *iface,
5837 old_fpucw = d3d_fpu_setup();
5838 hr = IDirect3DDeviceImpl_7_CaptureStateBlock(iface, BlockHandle);
5839 set_fpu_control_word(old_fpucw);
5844 /*****************************************************************************
5845 * IDirect3DDevice7::DeleteStateBlock
5847 * Deletes a stateblock handle. This means releasing the WineD3DStateBlock
5852 * BlockHandle: Stateblock handle to delete
5856 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is 0
5858 *****************************************************************************/
5860 IDirect3DDeviceImpl_7_DeleteStateBlock(IDirect3DDevice7 *iface,
5863 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5865 TRACE("(%p)->(%08x): Relay!\n", This, BlockHandle);
5867 EnterCriticalSection(&ddraw_cs);
5868 if(BlockHandle == 0 || BlockHandle > This->numHandles)
5870 WARN("Out of range handle %d, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle);
5871 LeaveCriticalSection(&ddraw_cs);
5872 return D3DERR_INVALIDSTATEBLOCK;
5874 if(This->Handles[BlockHandle - 1].type != DDrawHandle_StateBlock)
5876 WARN("Handle %d is not a stateblock, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle);
5877 LeaveCriticalSection(&ddraw_cs);
5878 return D3DERR_INVALIDSTATEBLOCK;
5881 ref = IWineD3DStateBlock_Release((IWineD3DStateBlock *) This->Handles[BlockHandle - 1].ptr);
5884 ERR("Something is still holding the stateblock %p(Handle %d). Ref = %d\n", This->Handles[BlockHandle - 1].ptr, BlockHandle, ref);
5886 This->Handles[BlockHandle - 1].ptr = NULL;
5887 This->Handles[BlockHandle - 1].type = DDrawHandle_Unknown;
5889 LeaveCriticalSection(&ddraw_cs);
5893 static HRESULT WINAPI
5894 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUSetup(IDirect3DDevice7 *iface,
5897 return IDirect3DDeviceImpl_7_DeleteStateBlock(iface, BlockHandle);
5900 static HRESULT WINAPI
5901 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUPreserve(IDirect3DDevice7 *iface,
5907 old_fpucw = d3d_fpu_setup();
5908 hr = IDirect3DDeviceImpl_7_DeleteStateBlock(iface, BlockHandle);
5909 set_fpu_control_word(old_fpucw);
5914 /*****************************************************************************
5915 * IDirect3DDevice7::CreateStateBlock
5917 * Creates a new state block handle.
5922 * Type: The state block type
5923 * BlockHandle: Address to write the created handle to
5927 * DDERR_INVALIDPARAMS if BlockHandle is NULL
5929 *****************************************************************************/
5931 IDirect3DDeviceImpl_7_CreateStateBlock(IDirect3DDevice7 *iface,
5932 D3DSTATEBLOCKTYPE Type,
5935 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5937 TRACE("(%p)->(%08x,%p)!\n", This, Type, BlockHandle);
5941 WARN("BlockHandle == NULL, returning DDERR_INVALIDPARAMS\n");
5942 return DDERR_INVALIDPARAMS;
5944 if(Type != D3DSBT_ALL && Type != D3DSBT_PIXELSTATE &&
5945 Type != D3DSBT_VERTEXSTATE ) {
5946 WARN("Unexpected stateblock type, returning DDERR_INVALIDPARAMS\n");
5947 return DDERR_INVALIDPARAMS;
5950 EnterCriticalSection(&ddraw_cs);
5951 *BlockHandle = IDirect3DDeviceImpl_CreateHandle(This);
5954 ERR("Cannot get a handle number for the stateblock\n");
5955 LeaveCriticalSection(&ddraw_cs);
5956 return DDERR_OUTOFMEMORY;
5958 This->Handles[*BlockHandle - 1].type = DDrawHandle_StateBlock;
5960 /* The D3DSTATEBLOCKTYPE enum is fine here */
5961 hr = IWineD3DDevice_CreateStateBlock(This->wineD3DDevice,
5963 (IWineD3DStateBlock **) &This->Handles[*BlockHandle - 1].ptr,
5964 NULL /* Parent, hope that works */);
5965 LeaveCriticalSection(&ddraw_cs);
5966 return hr_ddraw_from_wined3d(hr);
5969 static HRESULT WINAPI
5970 IDirect3DDeviceImpl_7_CreateStateBlock_FPUSetup(IDirect3DDevice7 *iface,
5971 D3DSTATEBLOCKTYPE Type,
5974 return IDirect3DDeviceImpl_7_CreateStateBlock(iface, Type, BlockHandle);
5977 static HRESULT WINAPI
5978 IDirect3DDeviceImpl_7_CreateStateBlock_FPUPreserve(IDirect3DDevice7 *iface,
5979 D3DSTATEBLOCKTYPE Type,
5985 old_fpucw = d3d_fpu_setup();
5986 hr =IDirect3DDeviceImpl_7_CreateStateBlock(iface, Type, BlockHandle);
5987 set_fpu_control_word(old_fpucw);
5992 /* Helper function for IDirect3DDeviceImpl_7_Load. */
5993 static BOOL is_mip_level_subset(IDirectDrawSurfaceImpl *dest,
5994 IDirectDrawSurfaceImpl *src)
5996 IDirectDrawSurfaceImpl *src_level, *dest_level;
5997 IDirectDrawSurface7 *temp;
5998 DDSURFACEDESC2 ddsd;
5999 BOOL levelFound; /* at least one suitable sublevel in dest found */
6001 /* To satisfy "destination is mip level subset of source" criteria (regular texture counts as 1 level),
6002 * 1) there must be at least one mip level in destination that matched dimensions of some mip level in source and
6003 * 2) there must be no destination levels that don't match any levels in source. Otherwise it's INVALIDPARAMS.
6010 for (;src_level && dest_level;)
6012 if (src_level->surface_desc.dwWidth == dest_level->surface_desc.dwWidth &&
6013 src_level->surface_desc.dwHeight == dest_level->surface_desc.dwHeight)
6017 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
6018 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_MIPMAPSUBLEVEL;
6019 IDirectDrawSurface7_GetAttachedSurface((IDirectDrawSurface7 *)dest_level, &ddsd.ddsCaps, &temp);
6021 if (dest_level != dest) IDirectDrawSurface7_Release((IDirectDrawSurface7 *)dest_level);
6023 dest_level = (IDirectDrawSurfaceImpl *)temp;
6026 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
6027 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_MIPMAPSUBLEVEL;
6028 IDirectDrawSurface7_GetAttachedSurface((IDirectDrawSurface7 *)src_level, &ddsd.ddsCaps, &temp);
6030 if (src_level != src) IDirectDrawSurface7_Release((IDirectDrawSurface7 *)src_level);
6032 src_level = (IDirectDrawSurfaceImpl *)temp;
6035 if (src_level && src_level != src) IDirectDrawSurface7_Release((IDirectDrawSurface7 *)src_level);
6036 if (dest_level && dest_level != dest) IDirectDrawSurface7_Release((IDirectDrawSurface7 *)dest_level);
6038 return !dest_level && levelFound;
6041 /* Helper function for IDirect3DDeviceImpl_7_Load. */
6042 static void copy_mipmap_chain(IDirect3DDeviceImpl *device,
6043 IDirectDrawSurfaceImpl *dest,
6044 IDirectDrawSurfaceImpl *src,
6045 const POINT *DestPoint,
6046 const RECT *SrcRect)
6048 IDirectDrawSurfaceImpl *src_level, *dest_level;
6049 IDirectDrawSurface7 *temp;
6050 DDSURFACEDESC2 ddsd;
6054 IDirectDrawPalette *pal = NULL, *pal_src = NULL;
6057 BOOL palette_missing = FALSE;
6059 /* Copy palette, if possible. */
6060 IDirectDrawSurface7_GetPalette((IDirectDrawSurface7 *)src, &pal_src);
6061 IDirectDrawSurface7_GetPalette((IDirectDrawSurface7 *)dest, &pal);
6063 if (pal_src != NULL && pal != NULL)
6065 PALETTEENTRY palent[256];
6067 IDirectDrawPalette_GetEntries(pal_src, 0, 0, 256, palent);
6068 IDirectDrawPalette_SetEntries(pal, 0, 0, 256, palent);
6071 if (dest->surface_desc.u4.ddpfPixelFormat.dwFlags & (DDPF_PALETTEINDEXED1 | DDPF_PALETTEINDEXED2 |
6072 DDPF_PALETTEINDEXED4 | DDPF_PALETTEINDEXED8 | DDPF_PALETTEINDEXEDTO8) && !pal)
6074 palette_missing = TRUE;
6077 if (pal) IDirectDrawPalette_Release(pal);
6078 if (pal_src) IDirectDrawPalette_Release(pal_src);
6080 /* Copy colorkeys, if present. */
6081 for (ckeyflag = DDCKEY_DESTBLT; ckeyflag <= DDCKEY_SRCOVERLAY; ckeyflag <<= 1)
6083 hr = IDirectDrawSurface7_GetColorKey((IDirectDrawSurface7 *)src, ckeyflag, &ddckey);
6087 IDirectDrawSurface7_SetColorKey((IDirectDrawSurface7 *)dest, ckeyflag, &ddckey);
6097 for (;src_level && dest_level;)
6099 if (src_level->surface_desc.dwWidth == dest_level->surface_desc.dwWidth &&
6100 src_level->surface_desc.dwHeight == dest_level->surface_desc.dwHeight)
6102 /* Try UpdateSurface that may perform a more direct opengl loading. But skip this if destination is paletted texture and has no palette.
6103 * Some games like Sacrifice set palette after Load, and it is a waste of effort to try to load texture without palette and generates
6104 * warnings in wined3d. */
6105 if (!palette_missing)
6106 hr = IWineD3DDevice_UpdateSurface(device->wineD3DDevice, src_level->WineD3DSurface, &rect, dest_level->WineD3DSurface,
6109 if (palette_missing || FAILED(hr))
6111 /* UpdateSurface may fail e.g. if dest is in system memory. Fall back to BltFast that is less strict. */
6112 IWineD3DSurface_BltFast(dest_level->WineD3DSurface,
6114 src_level->WineD3DSurface, &rect, 0);
6117 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
6118 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_MIPMAPSUBLEVEL;
6119 IDirectDrawSurface7_GetAttachedSurface((IDirectDrawSurface7 *)dest_level, &ddsd.ddsCaps, &temp);
6121 if (dest_level != dest) IDirectDrawSurface7_Release((IDirectDrawSurface7 *)dest_level);
6123 dest_level = (IDirectDrawSurfaceImpl *)temp;
6126 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
6127 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_MIPMAPSUBLEVEL;
6128 IDirectDrawSurface7_GetAttachedSurface((IDirectDrawSurface7 *)src_level, &ddsd.ddsCaps, &temp);
6130 if (src_level != src) IDirectDrawSurface7_Release((IDirectDrawSurface7 *)src_level);
6132 src_level = (IDirectDrawSurfaceImpl *)temp;
6139 rect.right = (rect.right + 1) / 2;
6140 rect.bottom = (rect.bottom + 1) / 2;
6143 if (src_level && src_level != src) IDirectDrawSurface7_Release((IDirectDrawSurface7 *)src_level);
6144 if (dest_level && dest_level != dest) IDirectDrawSurface7_Release((IDirectDrawSurface7 *)dest_level);
6147 /*****************************************************************************
6148 * IDirect3DDevice7::Load
6150 * Loads a rectangular area from the source into the destination texture.
6151 * It can also copy the source to the faces of a cubic environment map
6156 * DestTex: Destination texture
6157 * DestPoint: Point in the destination where the source image should be
6159 * SrcTex: Source texture
6160 * SrcRect: Source rectangle
6161 * Flags: Cubemap faces to load (DDSCAPS2_CUBEMAP_ALLFACES, DDSCAPS2_CUBEMAP_POSITIVEX,
6162 * DDSCAPS2_CUBEMAP_NEGATIVEX, DDSCAPS2_CUBEMAP_POSITIVEY, DDSCAPS2_CUBEMAP_NEGATIVEY,
6163 * DDSCAPS2_CUBEMAP_POSITIVEZ, DDSCAPS2_CUBEMAP_NEGATIVEZ)
6167 * DDERR_INVALIDPARAMS if DestTex or SrcTex are NULL, broken coordinates or anything unexpected.
6170 *****************************************************************************/
6173 IDirect3DDeviceImpl_7_Load(IDirect3DDevice7 *iface,
6174 IDirectDrawSurface7 *DestTex,
6176 IDirectDrawSurface7 *SrcTex,
6180 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
6181 IDirectDrawSurfaceImpl *dest = (IDirectDrawSurfaceImpl *)DestTex;
6182 IDirectDrawSurfaceImpl *src = (IDirectDrawSurfaceImpl *)SrcTex;
6185 TRACE("(%p)->(%p,%p,%p,%p,%08x)\n", This, dest, DestPoint, src, SrcRect, Flags);
6187 if( (!src) || (!dest) )
6188 return DDERR_INVALIDPARAMS;
6190 EnterCriticalSection(&ddraw_cs);
6192 if (SrcRect) srcrect = *SrcRect;
6195 srcrect.left = srcrect.top = 0;
6196 srcrect.right = src->surface_desc.dwWidth;
6197 srcrect.bottom = src->surface_desc.dwHeight;
6200 if (DestPoint) destpoint = *DestPoint;
6203 destpoint.x = destpoint.y = 0;
6205 /* Check bad dimensions. DestPoint is validated against src, not dest, because
6206 * destination can be a subset of mip levels, in which case actual coordinates used
6207 * for it may be divided. If any dimension of dest is larger than source, it can't be
6208 * mip level subset, so an error can be returned early.
6210 if (srcrect.left >= srcrect.right || srcrect.top >= srcrect.bottom ||
6211 srcrect.right > src->surface_desc.dwWidth ||
6212 srcrect.bottom > src->surface_desc.dwHeight ||
6213 destpoint.x + srcrect.right - srcrect.left > src->surface_desc.dwWidth ||
6214 destpoint.y + srcrect.bottom - srcrect.top > src->surface_desc.dwHeight ||
6215 dest->surface_desc.dwWidth > src->surface_desc.dwWidth ||
6216 dest->surface_desc.dwHeight > src->surface_desc.dwHeight)
6218 LeaveCriticalSection(&ddraw_cs);
6219 return DDERR_INVALIDPARAMS;
6222 /* Must be top level surfaces. */
6223 if (src->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_MIPMAPSUBLEVEL ||
6224 dest->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_MIPMAPSUBLEVEL)
6226 LeaveCriticalSection(&ddraw_cs);
6227 return DDERR_INVALIDPARAMS;
6230 if (src->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP)
6232 DWORD src_face_flag, dest_face_flag;
6233 IDirectDrawSurfaceImpl *src_face, *dest_face;
6234 IDirectDrawSurface7 *temp;
6235 DDSURFACEDESC2 ddsd;
6238 if (!(dest->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP))
6240 LeaveCriticalSection(&ddraw_cs);
6241 return DDERR_INVALIDPARAMS;
6244 /* Iterate through cube faces 2 times. First time is just to check INVALIDPARAMS conditions, second
6245 * time it's actual surface loading. */
6246 for (i = 0; i < 2; i++)
6251 for (;dest_face && src_face;)
6253 src_face_flag = src_face->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP_ALLFACES;
6254 dest_face_flag = dest_face->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP_ALLFACES;
6256 if (src_face_flag == dest_face_flag)
6260 /* Destination mip levels must be subset of source mip levels. */
6261 if (!is_mip_level_subset(dest_face, src_face))
6263 LeaveCriticalSection(&ddraw_cs);
6264 return DDERR_INVALIDPARAMS;
6267 else if (Flags & dest_face_flag)
6269 copy_mipmap_chain(This, dest_face, src_face, &destpoint, &srcrect);
6272 if (src_face_flag < DDSCAPS2_CUBEMAP_NEGATIVEZ)
6274 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
6275 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | (src_face_flag << 1);
6276 IDirectDrawSurface7_GetAttachedSurface((IDirectDrawSurface7 *)src, &ddsd.ddsCaps, &temp);
6278 if (src_face != src) IDirectDrawSurface7_Release((IDirectDrawSurface7 *)src_face);
6280 src_face = (IDirectDrawSurfaceImpl *)temp;
6284 if (src_face != src) IDirectDrawSurface7_Release((IDirectDrawSurface7 *)src_face);
6290 if (dest_face_flag < DDSCAPS2_CUBEMAP_NEGATIVEZ)
6292 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
6293 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | (dest_face_flag << 1);
6294 IDirectDrawSurface7_GetAttachedSurface((IDirectDrawSurface7 *)dest, &ddsd.ddsCaps, &temp);
6296 if (dest_face != dest) IDirectDrawSurface7_Release((IDirectDrawSurface7 *)dest_face);
6298 dest_face = (IDirectDrawSurfaceImpl *)temp;
6302 if (dest_face != dest) IDirectDrawSurface7_Release((IDirectDrawSurface7 *)dest_face);
6310 /* Native returns error if src faces are not subset of dest faces. */
6313 LeaveCriticalSection(&ddraw_cs);
6314 return DDERR_INVALIDPARAMS;
6319 LeaveCriticalSection(&ddraw_cs);
6322 else if (dest->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP)
6324 LeaveCriticalSection(&ddraw_cs);
6325 return DDERR_INVALIDPARAMS;
6328 /* Handle non cube map textures. */
6330 /* Destination mip levels must be subset of source mip levels. */
6331 if (!is_mip_level_subset(dest, src))
6333 LeaveCriticalSection(&ddraw_cs);
6334 return DDERR_INVALIDPARAMS;
6337 copy_mipmap_chain(This, dest, src, &destpoint, &srcrect);
6339 LeaveCriticalSection(&ddraw_cs);
6343 static HRESULT WINAPI
6344 IDirect3DDeviceImpl_7_Load_FPUSetup(IDirect3DDevice7 *iface,
6345 IDirectDrawSurface7 *DestTex,
6347 IDirectDrawSurface7 *SrcTex,
6351 return IDirect3DDeviceImpl_7_Load(iface, DestTex, DestPoint, SrcTex, SrcRect, Flags);
6354 static HRESULT WINAPI
6355 IDirect3DDeviceImpl_7_Load_FPUPreserve(IDirect3DDevice7 *iface,
6356 IDirectDrawSurface7 *DestTex,
6358 IDirectDrawSurface7 *SrcTex,
6365 old_fpucw = d3d_fpu_setup();
6366 hr = IDirect3DDeviceImpl_7_Load(iface, DestTex, DestPoint, SrcTex, SrcRect, Flags);
6367 set_fpu_control_word(old_fpucw);
6372 /*****************************************************************************
6373 * IDirect3DDevice7::LightEnable
6375 * Enables or disables a light
6377 * Version 7, IDirect3DLight uses this method too.
6380 * LightIndex: The index of the light to enable / disable
6381 * Enable: Enable or disable the light
6385 * For more details, see IWineD3DDevice::SetLightEnable
6387 *****************************************************************************/
6389 IDirect3DDeviceImpl_7_LightEnable(IDirect3DDevice7 *iface,
6393 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
6395 TRACE("(%p)->(%08x,%d): Relay!\n", This, LightIndex, Enable);
6397 EnterCriticalSection(&ddraw_cs);
6398 hr = IWineD3DDevice_SetLightEnable(This->wineD3DDevice, LightIndex, Enable);
6399 LeaveCriticalSection(&ddraw_cs);
6400 return hr_ddraw_from_wined3d(hr);
6403 static HRESULT WINAPI
6404 IDirect3DDeviceImpl_7_LightEnable_FPUSetup(IDirect3DDevice7 *iface,
6408 return IDirect3DDeviceImpl_7_LightEnable(iface, LightIndex, Enable);
6411 static HRESULT WINAPI
6412 IDirect3DDeviceImpl_7_LightEnable_FPUPreserve(IDirect3DDevice7 *iface,
6419 old_fpucw = d3d_fpu_setup();
6420 hr = IDirect3DDeviceImpl_7_LightEnable(iface, LightIndex, Enable);
6421 set_fpu_control_word(old_fpucw);
6426 /*****************************************************************************
6427 * IDirect3DDevice7::GetLightEnable
6429 * Retrieves if the light with the given index is enabled or not
6434 * LightIndex: Index of desired light
6435 * Enable: Pointer to a BOOL which contains the result
6439 * DDERR_INVALIDPARAMS if Enable is NULL
6440 * See IWineD3DDevice::GetLightEnable for more details
6442 *****************************************************************************/
6444 IDirect3DDeviceImpl_7_GetLightEnable(IDirect3DDevice7 *iface,
6448 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
6450 TRACE("(%p)->(%08x,%p): Relay\n", This, LightIndex, Enable);
6453 return DDERR_INVALIDPARAMS;
6455 EnterCriticalSection(&ddraw_cs);
6456 hr = IWineD3DDevice_GetLightEnable(This->wineD3DDevice, LightIndex, Enable);
6457 LeaveCriticalSection(&ddraw_cs);
6458 return hr_ddraw_from_wined3d(hr);
6461 static HRESULT WINAPI
6462 IDirect3DDeviceImpl_7_GetLightEnable_FPUSetup(IDirect3DDevice7 *iface,
6466 return IDirect3DDeviceImpl_7_GetLightEnable(iface, LightIndex, Enable);
6469 static HRESULT WINAPI
6470 IDirect3DDeviceImpl_7_GetLightEnable_FPUPreserve(IDirect3DDevice7 *iface,
6477 old_fpucw = d3d_fpu_setup();
6478 hr = IDirect3DDeviceImpl_7_GetLightEnable(iface, LightIndex, Enable);
6479 set_fpu_control_word(old_fpucw);
6484 /*****************************************************************************
6485 * IDirect3DDevice7::SetClipPlane
6487 * Sets custom clipping plane
6492 * Index: The index of the clipping plane
6493 * PlaneEquation: An equation defining the clipping plane
6497 * DDERR_INVALIDPARAMS if PlaneEquation is NULL
6498 * See IWineD3DDevice::SetClipPlane for more details
6500 *****************************************************************************/
6502 IDirect3DDeviceImpl_7_SetClipPlane(IDirect3DDevice7 *iface,
6504 D3DVALUE* PlaneEquation)
6506 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
6508 TRACE("(%p)->(%08x,%p): Relay!\n", This, Index, PlaneEquation);
6511 return DDERR_INVALIDPARAMS;
6513 EnterCriticalSection(&ddraw_cs);
6514 hr = IWineD3DDevice_SetClipPlane(This->wineD3DDevice, Index, PlaneEquation);
6515 LeaveCriticalSection(&ddraw_cs);
6519 static HRESULT WINAPI
6520 IDirect3DDeviceImpl_7_SetClipPlane_FPUSetup(IDirect3DDevice7 *iface,
6522 D3DVALUE* PlaneEquation)
6524 return IDirect3DDeviceImpl_7_SetClipPlane(iface, Index, PlaneEquation);
6527 static HRESULT WINAPI
6528 IDirect3DDeviceImpl_7_SetClipPlane_FPUPreserve(IDirect3DDevice7 *iface,
6530 D3DVALUE* PlaneEquation)
6535 old_fpucw = d3d_fpu_setup();
6536 hr = IDirect3DDeviceImpl_7_SetClipPlane(iface, Index, PlaneEquation);
6537 set_fpu_control_word(old_fpucw);
6542 /*****************************************************************************
6543 * IDirect3DDevice7::GetClipPlane
6545 * Returns the clipping plane with a specific index
6548 * Index: The index of the desired plane
6549 * PlaneEquation: Address to store the plane equation to
6553 * DDERR_INVALIDPARAMS if PlaneEquation is NULL
6554 * See IWineD3DDevice::GetClipPlane for more details
6556 *****************************************************************************/
6558 IDirect3DDeviceImpl_7_GetClipPlane(IDirect3DDevice7 *iface,
6560 D3DVALUE* PlaneEquation)
6562 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
6564 TRACE("(%p)->(%d,%p): Relay!\n", This, Index, PlaneEquation);
6567 return DDERR_INVALIDPARAMS;
6569 EnterCriticalSection(&ddraw_cs);
6570 hr = IWineD3DDevice_GetClipPlane(This->wineD3DDevice, Index, PlaneEquation);
6571 LeaveCriticalSection(&ddraw_cs);
6575 static HRESULT WINAPI
6576 IDirect3DDeviceImpl_7_GetClipPlane_FPUSetup(IDirect3DDevice7 *iface,
6578 D3DVALUE* PlaneEquation)
6580 return IDirect3DDeviceImpl_7_GetClipPlane(iface, Index, PlaneEquation);
6583 static HRESULT WINAPI
6584 IDirect3DDeviceImpl_7_GetClipPlane_FPUPreserve(IDirect3DDevice7 *iface,
6586 D3DVALUE* PlaneEquation)
6591 old_fpucw = d3d_fpu_setup();
6592 hr = IDirect3DDeviceImpl_7_GetClipPlane(iface, Index, PlaneEquation);
6593 set_fpu_control_word(old_fpucw);
6598 /*****************************************************************************
6599 * IDirect3DDevice7::GetInfo
6601 * Retrieves some information about the device. The DirectX sdk says that
6602 * this version returns S_FALSE for all retail builds of DirectX, that's what
6603 * this implementation does.
6606 * DevInfoID: Information type requested
6607 * DevInfoStruct: Pointer to a structure to store the info to
6608 * Size: Size of the structure
6611 * S_FALSE, because it's a non-debug driver
6613 *****************************************************************************/
6614 static HRESULT WINAPI
6615 IDirect3DDeviceImpl_7_GetInfo(IDirect3DDevice7 *iface,
6617 void *DevInfoStruct,
6620 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
6621 TRACE("(%p)->(%08x,%p,%08x)\n", This, DevInfoID, DevInfoStruct, Size);
6625 TRACE(" info requested : ");
6628 case D3DDEVINFOID_TEXTUREMANAGER: TRACE("D3DDEVINFOID_TEXTUREMANAGER\n"); break;
6629 case D3DDEVINFOID_D3DTEXTUREMANAGER: TRACE("D3DDEVINFOID_D3DTEXTUREMANAGER\n"); break;
6630 case D3DDEVINFOID_TEXTURING: TRACE("D3DDEVINFOID_TEXTURING\n"); break;
6631 default: ERR(" invalid flag !!!\n"); return DDERR_INVALIDPARAMS;
6635 return S_FALSE; /* According to MSDN, this is valid for a non-debug driver */
6638 /* For performance optimization, devices created in FPUSETUP and FPUPRESERVE modes
6639 * have separate vtables. Simple functions where this doesn't matter like GetDirect3D
6640 * are not duplicated.
6642 * Device created with DDSCL_FPUSETUP (d3d7 default) - device methods assume that FPU
6643 * has already been setup for optimal d3d operation.
6645 * Device created with DDSCL_FPUPRESERVE - resets and restores FPU mode when necessary in
6646 * d3d calls (FPU may be in a mode non-suitable for d3d when the app calls d3d). Required
6647 * by Sacrifice (game). */
6648 const IDirect3DDevice7Vtbl IDirect3DDevice7_FPUSetup_Vtbl =
6650 /*** IUnknown Methods ***/
6651 IDirect3DDeviceImpl_7_QueryInterface,
6652 IDirect3DDeviceImpl_7_AddRef,
6653 IDirect3DDeviceImpl_7_Release,
6654 /*** IDirect3DDevice7 ***/
6655 IDirect3DDeviceImpl_7_GetCaps_FPUSetup,
6656 IDirect3DDeviceImpl_7_EnumTextureFormats_FPUSetup,
6657 IDirect3DDeviceImpl_7_BeginScene_FPUSetup,
6658 IDirect3DDeviceImpl_7_EndScene_FPUSetup,
6659 IDirect3DDeviceImpl_7_GetDirect3D,
6660 IDirect3DDeviceImpl_7_SetRenderTarget_FPUSetup,
6661 IDirect3DDeviceImpl_7_GetRenderTarget,
6662 IDirect3DDeviceImpl_7_Clear_FPUSetup,
6663 IDirect3DDeviceImpl_7_SetTransform_FPUSetup,
6664 IDirect3DDeviceImpl_7_GetTransform_FPUSetup,
6665 IDirect3DDeviceImpl_7_SetViewport_FPUSetup,
6666 IDirect3DDeviceImpl_7_MultiplyTransform_FPUSetup,
6667 IDirect3DDeviceImpl_7_GetViewport_FPUSetup,
6668 IDirect3DDeviceImpl_7_SetMaterial_FPUSetup,
6669 IDirect3DDeviceImpl_7_GetMaterial_FPUSetup,
6670 IDirect3DDeviceImpl_7_SetLight_FPUSetup,
6671 IDirect3DDeviceImpl_7_GetLight_FPUSetup,
6672 IDirect3DDeviceImpl_7_SetRenderState_FPUSetup,
6673 IDirect3DDeviceImpl_7_GetRenderState_FPUSetup,
6674 IDirect3DDeviceImpl_7_BeginStateBlock_FPUSetup,
6675 IDirect3DDeviceImpl_7_EndStateBlock_FPUSetup,
6676 IDirect3DDeviceImpl_7_PreLoad_FPUSetup,
6677 IDirect3DDeviceImpl_7_DrawPrimitive_FPUSetup,
6678 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUSetup,
6679 IDirect3DDeviceImpl_7_SetClipStatus,
6680 IDirect3DDeviceImpl_7_GetClipStatus,
6681 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUSetup,
6682 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUSetup,
6683 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUSetup,
6684 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUSetup,
6685 IDirect3DDeviceImpl_7_ComputeSphereVisibility,
6686 IDirect3DDeviceImpl_7_GetTexture_FPUSetup,
6687 IDirect3DDeviceImpl_7_SetTexture_FPUSetup,
6688 IDirect3DDeviceImpl_7_GetTextureStageState_FPUSetup,
6689 IDirect3DDeviceImpl_7_SetTextureStageState_FPUSetup,
6690 IDirect3DDeviceImpl_7_ValidateDevice_FPUSetup,
6691 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUSetup,
6692 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUSetup,
6693 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUSetup,
6694 IDirect3DDeviceImpl_7_CreateStateBlock_FPUSetup,
6695 IDirect3DDeviceImpl_7_Load_FPUSetup,
6696 IDirect3DDeviceImpl_7_LightEnable_FPUSetup,
6697 IDirect3DDeviceImpl_7_GetLightEnable_FPUSetup,
6698 IDirect3DDeviceImpl_7_SetClipPlane_FPUSetup,
6699 IDirect3DDeviceImpl_7_GetClipPlane_FPUSetup,
6700 IDirect3DDeviceImpl_7_GetInfo
6703 const IDirect3DDevice7Vtbl IDirect3DDevice7_FPUPreserve_Vtbl =
6705 /*** IUnknown Methods ***/
6706 IDirect3DDeviceImpl_7_QueryInterface,
6707 IDirect3DDeviceImpl_7_AddRef,
6708 IDirect3DDeviceImpl_7_Release,
6709 /*** IDirect3DDevice7 ***/
6710 IDirect3DDeviceImpl_7_GetCaps_FPUPreserve,
6711 IDirect3DDeviceImpl_7_EnumTextureFormats_FPUPreserve,
6712 IDirect3DDeviceImpl_7_BeginScene_FPUPreserve,
6713 IDirect3DDeviceImpl_7_EndScene_FPUPreserve,
6714 IDirect3DDeviceImpl_7_GetDirect3D,
6715 IDirect3DDeviceImpl_7_SetRenderTarget_FPUPreserve,
6716 IDirect3DDeviceImpl_7_GetRenderTarget,
6717 IDirect3DDeviceImpl_7_Clear_FPUPreserve,
6718 IDirect3DDeviceImpl_7_SetTransform_FPUPreserve,
6719 IDirect3DDeviceImpl_7_GetTransform_FPUPreserve,
6720 IDirect3DDeviceImpl_7_SetViewport_FPUPreserve,
6721 IDirect3DDeviceImpl_7_MultiplyTransform_FPUPreserve,
6722 IDirect3DDeviceImpl_7_GetViewport_FPUPreserve,
6723 IDirect3DDeviceImpl_7_SetMaterial_FPUPreserve,
6724 IDirect3DDeviceImpl_7_GetMaterial_FPUPreserve,
6725 IDirect3DDeviceImpl_7_SetLight_FPUPreserve,
6726 IDirect3DDeviceImpl_7_GetLight_FPUPreserve,
6727 IDirect3DDeviceImpl_7_SetRenderState_FPUPreserve,
6728 IDirect3DDeviceImpl_7_GetRenderState_FPUPreserve,
6729 IDirect3DDeviceImpl_7_BeginStateBlock_FPUPreserve,
6730 IDirect3DDeviceImpl_7_EndStateBlock_FPUPreserve,
6731 IDirect3DDeviceImpl_7_PreLoad_FPUPreserve,
6732 IDirect3DDeviceImpl_7_DrawPrimitive_FPUPreserve,
6733 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUPreserve,
6734 IDirect3DDeviceImpl_7_SetClipStatus,
6735 IDirect3DDeviceImpl_7_GetClipStatus,
6736 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUPreserve,
6737 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUPreserve,
6738 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUPreserve,
6739 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUPreserve,
6740 IDirect3DDeviceImpl_7_ComputeSphereVisibility,
6741 IDirect3DDeviceImpl_7_GetTexture_FPUPreserve,
6742 IDirect3DDeviceImpl_7_SetTexture_FPUPreserve,
6743 IDirect3DDeviceImpl_7_GetTextureStageState_FPUPreserve,
6744 IDirect3DDeviceImpl_7_SetTextureStageState_FPUPreserve,
6745 IDirect3DDeviceImpl_7_ValidateDevice_FPUPreserve,
6746 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUPreserve,
6747 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUPreserve,
6748 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUPreserve,
6749 IDirect3DDeviceImpl_7_CreateStateBlock_FPUPreserve,
6750 IDirect3DDeviceImpl_7_Load_FPUPreserve,
6751 IDirect3DDeviceImpl_7_LightEnable_FPUPreserve,
6752 IDirect3DDeviceImpl_7_GetLightEnable_FPUPreserve,
6753 IDirect3DDeviceImpl_7_SetClipPlane_FPUPreserve,
6754 IDirect3DDeviceImpl_7_GetClipPlane_FPUPreserve,
6755 IDirect3DDeviceImpl_7_GetInfo
6758 const IDirect3DDevice3Vtbl IDirect3DDevice3_Vtbl =
6760 /*** IUnknown Methods ***/
6761 Thunk_IDirect3DDeviceImpl_3_QueryInterface,
6762 Thunk_IDirect3DDeviceImpl_3_AddRef,
6763 Thunk_IDirect3DDeviceImpl_3_Release,
6764 /*** IDirect3DDevice3 ***/
6765 IDirect3DDeviceImpl_3_GetCaps,
6766 IDirect3DDeviceImpl_3_GetStats,
6767 IDirect3DDeviceImpl_3_AddViewport,
6768 IDirect3DDeviceImpl_3_DeleteViewport,
6769 IDirect3DDeviceImpl_3_NextViewport,
6770 Thunk_IDirect3DDeviceImpl_3_EnumTextureFormats,
6771 Thunk_IDirect3DDeviceImpl_3_BeginScene,
6772 Thunk_IDirect3DDeviceImpl_3_EndScene,
6773 Thunk_IDirect3DDeviceImpl_3_GetDirect3D,
6774 IDirect3DDeviceImpl_3_SetCurrentViewport,
6775 IDirect3DDeviceImpl_3_GetCurrentViewport,
6776 Thunk_IDirect3DDeviceImpl_3_SetRenderTarget,
6777 Thunk_IDirect3DDeviceImpl_3_GetRenderTarget,
6778 IDirect3DDeviceImpl_3_Begin,
6779 IDirect3DDeviceImpl_3_BeginIndexed,
6780 IDirect3DDeviceImpl_3_Vertex,
6781 IDirect3DDeviceImpl_3_Index,
6782 IDirect3DDeviceImpl_3_End,
6783 IDirect3DDeviceImpl_3_GetRenderState,
6784 IDirect3DDeviceImpl_3_SetRenderState,
6785 IDirect3DDeviceImpl_3_GetLightState,
6786 IDirect3DDeviceImpl_3_SetLightState,
6787 Thunk_IDirect3DDeviceImpl_3_SetTransform,
6788 Thunk_IDirect3DDeviceImpl_3_GetTransform,
6789 Thunk_IDirect3DDeviceImpl_3_MultiplyTransform,
6790 Thunk_IDirect3DDeviceImpl_3_DrawPrimitive,
6791 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitive,
6792 Thunk_IDirect3DDeviceImpl_3_SetClipStatus,
6793 Thunk_IDirect3DDeviceImpl_3_GetClipStatus,
6794 Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveStrided,
6795 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveStrided,
6796 Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveVB,
6797 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveVB,
6798 Thunk_IDirect3DDeviceImpl_3_ComputeSphereVisibility,
6799 Thunk_IDirect3DDeviceImpl_3_GetTexture,
6800 IDirect3DDeviceImpl_3_SetTexture,
6801 Thunk_IDirect3DDeviceImpl_3_GetTextureStageState,
6802 Thunk_IDirect3DDeviceImpl_3_SetTextureStageState,
6803 Thunk_IDirect3DDeviceImpl_3_ValidateDevice
6806 const IDirect3DDevice2Vtbl IDirect3DDevice2_Vtbl =
6808 /*** IUnknown Methods ***/
6809 Thunk_IDirect3DDeviceImpl_2_QueryInterface,
6810 Thunk_IDirect3DDeviceImpl_2_AddRef,
6811 Thunk_IDirect3DDeviceImpl_2_Release,
6812 /*** IDirect3DDevice2 ***/
6813 Thunk_IDirect3DDeviceImpl_2_GetCaps,
6814 IDirect3DDeviceImpl_2_SwapTextureHandles,
6815 Thunk_IDirect3DDeviceImpl_2_GetStats,
6816 Thunk_IDirect3DDeviceImpl_2_AddViewport,
6817 Thunk_IDirect3DDeviceImpl_2_DeleteViewport,
6818 Thunk_IDirect3DDeviceImpl_2_NextViewport,
6819 IDirect3DDeviceImpl_2_EnumTextureFormats,
6820 Thunk_IDirect3DDeviceImpl_2_BeginScene,
6821 Thunk_IDirect3DDeviceImpl_2_EndScene,
6822 Thunk_IDirect3DDeviceImpl_2_GetDirect3D,
6823 Thunk_IDirect3DDeviceImpl_2_SetCurrentViewport,
6824 Thunk_IDirect3DDeviceImpl_2_GetCurrentViewport,
6825 Thunk_IDirect3DDeviceImpl_2_SetRenderTarget,
6826 Thunk_IDirect3DDeviceImpl_2_GetRenderTarget,
6827 Thunk_IDirect3DDeviceImpl_2_Begin,
6828 Thunk_IDirect3DDeviceImpl_2_BeginIndexed,
6829 Thunk_IDirect3DDeviceImpl_2_Vertex,
6830 Thunk_IDirect3DDeviceImpl_2_Index,
6831 Thunk_IDirect3DDeviceImpl_2_End,
6832 Thunk_IDirect3DDeviceImpl_2_GetRenderState,
6833 Thunk_IDirect3DDeviceImpl_2_SetRenderState,
6834 Thunk_IDirect3DDeviceImpl_2_GetLightState,
6835 Thunk_IDirect3DDeviceImpl_2_SetLightState,
6836 Thunk_IDirect3DDeviceImpl_2_SetTransform,
6837 Thunk_IDirect3DDeviceImpl_2_GetTransform,
6838 Thunk_IDirect3DDeviceImpl_2_MultiplyTransform,
6839 Thunk_IDirect3DDeviceImpl_2_DrawPrimitive,
6840 Thunk_IDirect3DDeviceImpl_2_DrawIndexedPrimitive,
6841 Thunk_IDirect3DDeviceImpl_2_SetClipStatus,
6842 Thunk_IDirect3DDeviceImpl_2_GetClipStatus
6845 const IDirect3DDeviceVtbl IDirect3DDevice1_Vtbl =
6847 /*** IUnknown Methods ***/
6848 Thunk_IDirect3DDeviceImpl_1_QueryInterface,
6849 Thunk_IDirect3DDeviceImpl_1_AddRef,
6850 Thunk_IDirect3DDeviceImpl_1_Release,
6851 /*** IDirect3DDevice1 ***/
6852 IDirect3DDeviceImpl_1_Initialize,
6853 Thunk_IDirect3DDeviceImpl_1_GetCaps,
6854 Thunk_IDirect3DDeviceImpl_1_SwapTextureHandles,
6855 IDirect3DDeviceImpl_1_CreateExecuteBuffer,
6856 Thunk_IDirect3DDeviceImpl_1_GetStats,
6857 IDirect3DDeviceImpl_1_Execute,
6858 Thunk_IDirect3DDeviceImpl_1_AddViewport,
6859 Thunk_IDirect3DDeviceImpl_1_DeleteViewport,
6860 Thunk_IDirect3DDeviceImpl_1_NextViewport,
6861 IDirect3DDeviceImpl_1_Pick,
6862 IDirect3DDeviceImpl_1_GetPickRecords,
6863 Thunk_IDirect3DDeviceImpl_1_EnumTextureFormats,
6864 IDirect3DDeviceImpl_1_CreateMatrix,
6865 IDirect3DDeviceImpl_1_SetMatrix,
6866 IDirect3DDeviceImpl_1_GetMatrix,
6867 IDirect3DDeviceImpl_1_DeleteMatrix,
6868 Thunk_IDirect3DDeviceImpl_1_BeginScene,
6869 Thunk_IDirect3DDeviceImpl_1_EndScene,
6870 Thunk_IDirect3DDeviceImpl_1_GetDirect3D
6873 /*****************************************************************************
6874 * IDirect3DDeviceImpl_CreateHandle
6876 * Not called from the VTable
6878 * Some older interface versions operate with handles, which are basically
6879 * DWORDs which identify an interface, for example
6880 * IDirect3DDevice::SetRenderState with DIRECT3DRENDERSTATE_TEXTUREHANDLE
6882 * Those handle could be just casts to the interface pointers or vice versa,
6883 * but that is not 64 bit safe and would mean blindly derefering a DWORD
6884 * passed by the app. Instead there is a dynamic array in the device which
6885 * keeps a DWORD to pointer information and a type for the handle.
6887 * Basically this array only grows, when a handle is freed its pointer is
6888 * just set to NULL. There will be much more reads from the array than
6889 * insertion operations, so a dynamic array is fine.
6892 * This: D3DDevice implementation for which this handle should be created
6895 * A free handle on success
6898 *****************************************************************************/
6900 IDirect3DDeviceImpl_CreateHandle(IDirect3DDeviceImpl *This)
6903 struct HandleEntry *oldHandles = This->Handles;
6905 TRACE("(%p)\n", This);
6907 for(i = 0; i < This->numHandles; i++)
6909 if(This->Handles[i].ptr == NULL &&
6910 This->Handles[i].type == DDrawHandle_Unknown)
6912 TRACE("Reusing freed handle %d\n", i + 1);
6917 TRACE("Growing the handle array\n");
6920 This->Handles = HeapAlloc(GetProcessHeap(), 0, sizeof(struct HandleEntry) * This->numHandles);
6923 ERR("Out of memory\n");
6924 This->Handles = oldHandles;
6930 memcpy(This->Handles, oldHandles, (This->numHandles - 1) * sizeof(struct HandleEntry));
6931 HeapFree(GetProcessHeap(), 0, oldHandles);
6934 TRACE("Returning %d\n", This->numHandles);
6935 return This->numHandles;
6938 /*****************************************************************************
6939 * IDirect3DDeviceImpl_UpdateDepthStencil
6941 * Checks the current render target for attached depth stencils and sets the
6942 * WineD3D depth stencil accordingly.
6945 * The depth stencil state to set if creating the device
6947 *****************************************************************************/
6949 IDirect3DDeviceImpl_UpdateDepthStencil(IDirect3DDeviceImpl *This)
6951 IDirectDrawSurface7 *depthStencil = NULL;
6952 IDirectDrawSurfaceImpl *dsi;
6953 static DDSCAPS2 depthcaps = { DDSCAPS_ZBUFFER, 0, 0, 0 };
6955 IDirectDrawSurface7_GetAttachedSurface((IDirectDrawSurface7 *)This->target, &depthcaps, &depthStencil);
6958 TRACE("Setting wined3d depth stencil to NULL\n");
6959 IWineD3DDevice_SetDepthStencilSurface(This->wineD3DDevice,
6961 return WINED3DZB_FALSE;
6964 dsi = (IDirectDrawSurfaceImpl *)depthStencil;
6965 TRACE("Setting wined3d depth stencil to %p (wined3d %p)\n", dsi, dsi->WineD3DSurface);
6966 IWineD3DDevice_SetDepthStencilSurface(This->wineD3DDevice,
6967 dsi->WineD3DSurface);
6969 IDirectDrawSurface7_Release(depthStencil);
6970 return WINED3DZB_TRUE;