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"
33 #include "ddraw_private.h"
35 WINE_DEFAULT_DEBUG_CHANNEL(ddraw
);
38 const GUID IID_D3DDEVICE_WineD3D
= {
42 { 0xb7,0x98,0xc6,0x8a,0x77,0x2d,0x72,0x2a }
45 static inline void set_fpu_control_word(WORD fpucw
)
47 #if defined(__i386__) && defined(__GNUC__)
48 __asm__
volatile ("fldcw %0" : : "m" (fpucw
));
49 #elif defined(__i386__) && defined(_MSC_VER)
54 static inline WORD
d3d_fpu_setup(void)
58 #if defined(__i386__) && defined(__GNUC__)
59 __asm__
volatile ("fnstcw %0" : "=m" (oldcw
));
60 #elif defined(__i386__) && defined(_MSC_VER)
63 static BOOL warned
= FALSE
;
66 FIXME("FPUPRESERVE not implemented for this platform / compiler\n");
72 set_fpu_control_word(0x37f);
77 /*****************************************************************************
78 * IUnknown Methods. Common for Version 1, 2, 3 and 7
79 *****************************************************************************/
81 /*****************************************************************************
82 * IDirect3DDevice7::QueryInterface
84 * Used to query other interfaces from a Direct3DDevice interface.
85 * It can return interface pointers to all Direct3DDevice versions as well
86 * as IDirectDraw and IDirect3D. For a link to QueryInterface
87 * rules see ddraw.c, IDirectDraw7::QueryInterface
89 * Exists in Version 1, 2, 3 and 7
92 * refiid: Interface ID queried for
93 * obj: Used to return the interface pointer
96 * D3D_OK or E_NOINTERFACE
98 *****************************************************************************/
100 IDirect3DDeviceImpl_7_QueryInterface(IDirect3DDevice7
*iface
,
104 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
106 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(refiid
), obj
);
108 /* According to COM docs, if the QueryInterface fails, obj should be set to NULL */
112 return DDERR_INVALIDPARAMS
;
114 if ( IsEqualGUID( &IID_IUnknown
, refiid
) )
119 /* Check DirectDraw Interfaces. */
120 else if( IsEqualGUID( &IID_IDirectDraw7
, refiid
) )
122 *obj
= &This
->ddraw
->IDirectDraw7_iface
;
123 TRACE("(%p) Returning IDirectDraw7 interface at %p\n", This
, *obj
);
125 else if ( IsEqualGUID( &IID_IDirectDraw4
, refiid
) )
127 *obj
= &This
->ddraw
->IDirectDraw4_iface
;
128 TRACE("(%p) Returning IDirectDraw4 interface at %p\n", This
, *obj
);
130 else if ( IsEqualGUID( &IID_IDirectDraw2
, refiid
) )
132 *obj
= &This
->ddraw
->IDirectDraw2_iface
;
133 TRACE("(%p) Returning IDirectDraw2 interface at %p\n", This
, *obj
);
135 else if( IsEqualGUID( &IID_IDirectDraw
, refiid
) )
137 *obj
= &This
->ddraw
->IDirectDraw_iface
;
138 TRACE("(%p) Returning IDirectDraw interface at %p\n", This
, *obj
);
142 else if ( IsEqualGUID( &IID_IDirect3D
, refiid
) )
144 *obj
= &This
->ddraw
->IDirect3D_iface
;
145 TRACE("(%p) Returning IDirect3D interface at %p\n", This
, *obj
);
147 else if ( IsEqualGUID( &IID_IDirect3D2
, refiid
) )
149 *obj
= &This
->ddraw
->IDirect3D2_iface
;
150 TRACE("(%p) Returning IDirect3D2 interface at %p\n", This
, *obj
);
152 else if ( IsEqualGUID( &IID_IDirect3D3
, refiid
) )
154 *obj
= &This
->ddraw
->IDirect3D3_iface
;
155 TRACE("(%p) Returning IDirect3D3 interface at %p\n", This
, *obj
);
157 else if ( IsEqualGUID( &IID_IDirect3D7
, refiid
) )
159 *obj
= &This
->ddraw
->IDirect3D7_iface
;
160 TRACE("(%p) Returning IDirect3D7 interface at %p\n", This
, *obj
);
164 else if ( IsEqualGUID( &IID_IDirect3DDevice
, refiid
) )
166 *obj
= &This
->IDirect3DDevice_vtbl
;
167 TRACE("(%p) Returning IDirect3DDevice interface at %p\n", This
, *obj
);
169 else if ( IsEqualGUID( &IID_IDirect3DDevice2
, refiid
) ) {
170 *obj
= &This
->IDirect3DDevice2_vtbl
;
171 TRACE("(%p) Returning IDirect3DDevice2 interface at %p\n", This
, *obj
);
173 else if ( IsEqualGUID( &IID_IDirect3DDevice3
, refiid
) ) {
174 *obj
= &This
->IDirect3DDevice3_vtbl
;
175 TRACE("(%p) Returning IDirect3DDevice3 interface at %p\n", This
, *obj
);
177 else if ( IsEqualGUID( &IID_IDirect3DDevice7
, refiid
) ) {
179 TRACE("(%p) Returning IDirect3DDevice7 interface at %p\n", This
, *obj
);
182 /* Unknown interface */
185 ERR("(%p)->(%s, %p): No interface found\n", This
, debugstr_guid(refiid
), obj
);
186 return E_NOINTERFACE
;
189 /* AddRef the returned interface */
190 IUnknown_AddRef( (IUnknown
*) *obj
);
194 static HRESULT WINAPI
IDirect3DDeviceImpl_3_QueryInterface(IDirect3DDevice3
*iface
, REFIID riid
,
197 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), obj
);
199 return IDirect3DDevice7_QueryInterface((IDirect3DDevice7
*)device_from_device3(iface
), riid
, obj
);
202 static HRESULT WINAPI
IDirect3DDeviceImpl_2_QueryInterface(IDirect3DDevice2
*iface
, REFIID riid
,
205 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), obj
);
207 return IDirect3DDevice7_QueryInterface((IDirect3DDevice7
*)device_from_device2(iface
), riid
, obj
);
210 static HRESULT WINAPI
IDirect3DDeviceImpl_1_QueryInterface(IDirect3DDevice
*iface
, REFIID riid
,
213 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), obp
);
215 return IDirect3DDevice7_QueryInterface((IDirect3DDevice7
*)device_from_device1(iface
), riid
, obp
);
218 /*****************************************************************************
219 * IDirect3DDevice7::AddRef
221 * Increases the refcount....
222 * The most exciting Method, definitely
224 * Exists in Version 1, 2, 3 and 7
229 *****************************************************************************/
231 IDirect3DDeviceImpl_7_AddRef(IDirect3DDevice7
*iface
)
233 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
234 ULONG ref
= InterlockedIncrement(&This
->ref
);
236 TRACE("%p increasing refcount to %u.\n", This
, ref
);
241 static ULONG WINAPI
IDirect3DDeviceImpl_3_AddRef(IDirect3DDevice3
*iface
)
243 TRACE("iface %p.\n", iface
);
245 return IDirect3DDevice7_AddRef((IDirect3DDevice7
*)device_from_device3(iface
));
248 static ULONG WINAPI
IDirect3DDeviceImpl_2_AddRef(IDirect3DDevice2
*iface
)
250 TRACE("iface %p.\n", iface
);
252 return IDirect3DDevice7_AddRef((IDirect3DDevice7
*)device_from_device2(iface
));
255 static ULONG WINAPI
IDirect3DDeviceImpl_1_AddRef(IDirect3DDevice
*iface
)
257 TRACE("iface %p.\n", iface
);
259 return IDirect3DDevice7_AddRef((IDirect3DDevice7
*)device_from_device1(iface
));
262 /*****************************************************************************
263 * IDirect3DDevice7::Release
265 * Decreases the refcount of the interface
266 * When the refcount is reduced to 0, the object is destroyed.
268 * Exists in Version 1, 2, 3 and 7
273 *****************************************************************************/
275 IDirect3DDeviceImpl_7_Release(IDirect3DDevice7
*iface
)
277 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
278 ULONG ref
= InterlockedDecrement(&This
->ref
);
280 TRACE("%p decreasing refcount to %u.\n", This
, ref
);
282 /* This method doesn't destroy the WineD3DDevice, because it's still in use for
283 * 2D rendering. IDirectDrawSurface7::Release will destroy the WineD3DDevice
284 * when the render target is released
290 EnterCriticalSection(&ddraw_cs
);
292 /* There is no need to unset any resources here, wined3d will take
293 * care of that on Uninit3D(). */
295 /* Free the index buffer. */
296 wined3d_buffer_decref(This
->indexbuffer
);
298 /* Set the device up to render to the front buffer since the back
299 * buffer will vanish soon. */
300 IWineD3DDevice_SetRenderTarget(This
->wineD3DDevice
, 0,
301 This
->ddraw
->d3d_target
->WineD3DSurface
, TRUE
);
303 /* Release the WineD3DDevice. This won't destroy it */
304 if(IWineD3DDevice_Release(This
->wineD3DDevice
) <= 0)
306 ERR(" (%p) The wineD3D device %p was destroyed unexpectedly. Prepare for trouble\n", This
, This
->wineD3DDevice
);
309 /* The texture handles should be unset by now, but there might be some bits
310 * missing in our reference counting(needs test). Do a sanity check. */
311 for (i
= 0; i
< This
->handle_table
.entry_count
; ++i
)
313 struct ddraw_handle_entry
*entry
= &This
->handle_table
.entries
[i
];
317 case DDRAW_HANDLE_FREE
:
320 case DDRAW_HANDLE_MATERIAL
:
322 IDirect3DMaterialImpl
*m
= entry
->object
;
323 FIXME("Material handle %#x (%p) not unset properly.\n", i
+ 1, m
);
328 case DDRAW_HANDLE_MATRIX
:
330 /* No FIXME here because this might happen because of sloppy applications. */
331 WARN("Leftover matrix handle %#x (%p), deleting.\n", i
+ 1, entry
->object
);
332 IDirect3DDevice_DeleteMatrix((IDirect3DDevice
*)&This
->IDirect3DDevice_vtbl
, i
+ 1);
336 case DDRAW_HANDLE_STATEBLOCK
:
338 /* No FIXME here because this might happen because of sloppy applications. */
339 WARN("Leftover stateblock handle %#x (%p), deleting.\n", i
+ 1, entry
->object
);
340 IDirect3DDevice7_DeleteStateBlock(iface
, i
+ 1);
344 case DDRAW_HANDLE_SURFACE
:
346 IDirectDrawSurfaceImpl
*surf
= entry
->object
;
347 FIXME("Texture handle %#x (%p) not unset properly.\n", i
+ 1, surf
);
353 FIXME("Handle %#x (%p) has unknown type %#x.\n", i
+ 1, entry
->object
, entry
->type
);
358 ddraw_handle_table_destroy(&This
->handle_table
);
360 TRACE("Releasing target %p %p\n", This
->target
, This
->ddraw
->d3d_target
);
361 /* Release the render target and the WineD3D render target
362 * (See IDirect3D7::CreateDevice for more comments on this)
364 IDirectDrawSurface7_Release((IDirectDrawSurface7
*)This
->target
);
365 IDirectDrawSurface7_Release((IDirectDrawSurface7
*)This
->ddraw
->d3d_target
);
366 TRACE("Target release done\n");
368 This
->ddraw
->d3ddevice
= NULL
;
370 /* Now free the structure */
371 HeapFree(GetProcessHeap(), 0, This
);
372 LeaveCriticalSection(&ddraw_cs
);
379 static ULONG WINAPI
IDirect3DDeviceImpl_3_Release(IDirect3DDevice3
*iface
)
381 TRACE("iface %p.\n", iface
);
383 return IDirect3DDevice7_Release((IDirect3DDevice7
*)device_from_device3(iface
));
386 static ULONG WINAPI
IDirect3DDeviceImpl_2_Release(IDirect3DDevice2
*iface
)
388 TRACE("iface %p.\n", iface
);
390 return IDirect3DDevice7_Release((IDirect3DDevice7
*)device_from_device2(iface
));
393 static ULONG WINAPI
IDirect3DDeviceImpl_1_Release(IDirect3DDevice
*iface
)
395 TRACE("iface %p.\n", iface
);
397 return IDirect3DDevice7_Release((IDirect3DDevice7
*)device_from_device1(iface
));
400 /*****************************************************************************
401 * IDirect3DDevice Methods
402 *****************************************************************************/
404 /*****************************************************************************
405 * IDirect3DDevice::Initialize
407 * Initializes a Direct3DDevice. This implementation is a no-op, as all
408 * initialization is done at create time.
410 * Exists in Version 1
413 * No idea what they mean, as the MSDN page is gone
417 *****************************************************************************/
418 static HRESULT WINAPI
419 IDirect3DDeviceImpl_1_Initialize(IDirect3DDevice
*iface
,
420 IDirect3D
*Direct3D
, GUID
*guid
,
423 /* It shouldn't be crucial, but print a FIXME, I'm interested if
424 * any game calls it and when. */
425 FIXME("iface %p, d3d %p, guid %s, device_desc %p nop!\n",
426 iface
, Direct3D
, debugstr_guid(guid
), Desc
);
431 /*****************************************************************************
432 * IDirect3DDevice7::GetCaps
434 * Retrieves the device's capabilities
436 * This implementation is used for Version 7 only, the older versions have
437 * their own implementation.
440 * Desc: Pointer to a D3DDEVICEDESC7 structure to fill
444 * D3DERR_* if a problem occurs. See WineD3D
446 *****************************************************************************/
448 IDirect3DDeviceImpl_7_GetCaps(IDirect3DDevice7
*iface
,
449 D3DDEVICEDESC7
*Desc
)
451 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
452 D3DDEVICEDESC OldDesc
;
454 TRACE("iface %p, device_desc %p.\n", iface
, Desc
);
456 /* Call the same function used by IDirect3D, this saves code */
457 return IDirect3DImpl_GetCaps(This
->ddraw
->wineD3D
, &OldDesc
, Desc
);
460 static HRESULT WINAPI
461 IDirect3DDeviceImpl_7_GetCaps_FPUSetup(IDirect3DDevice7
*iface
,
462 D3DDEVICEDESC7
*Desc
)
464 return IDirect3DDeviceImpl_7_GetCaps(iface
, Desc
);
467 static HRESULT WINAPI
468 IDirect3DDeviceImpl_7_GetCaps_FPUPreserve(IDirect3DDevice7
*iface
,
469 D3DDEVICEDESC7
*Desc
)
474 old_fpucw
= d3d_fpu_setup();
475 hr
= IDirect3DDeviceImpl_7_GetCaps(iface
, Desc
);
476 set_fpu_control_word(old_fpucw
);
480 /*****************************************************************************
481 * IDirect3DDevice3::GetCaps
483 * Retrieves the capabilities of the hardware device and the emulation
484 * device. For Wine, hardware and emulation are the same (it's all HW).
486 * This implementation is used for Version 1, 2, and 3. Version 7 has its own
489 * HWDesc: Structure to fill with the HW caps
490 * HelDesc: Structure to fill with the hardware emulation caps
494 * D3DERR_* if a problem occurs. See WineD3D
496 *****************************************************************************/
497 static HRESULT WINAPI
498 IDirect3DDeviceImpl_3_GetCaps(IDirect3DDevice3
*iface
,
499 D3DDEVICEDESC
*HWDesc
,
500 D3DDEVICEDESC
*HelDesc
)
502 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
503 D3DDEVICEDESC7 newDesc
;
506 TRACE("iface %p, hw_desc %p, hel_desc %p.\n", iface
, HWDesc
, HelDesc
);
508 hr
= IDirect3DImpl_GetCaps(This
->ddraw
->wineD3D
, HWDesc
, &newDesc
);
509 if(hr
!= D3D_OK
) return hr
;
515 static HRESULT WINAPI
IDirect3DDeviceImpl_2_GetCaps(IDirect3DDevice2
*iface
,
516 D3DDEVICEDESC
*D3DHWDevDesc
, D3DDEVICEDESC
*D3DHELDevDesc
)
518 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
519 TRACE("iface %p, hw_desc %p, hel_desc %p.\n", iface
, D3DHWDevDesc
, D3DHELDevDesc
);
520 return IDirect3DDevice3_GetCaps((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
, D3DHWDevDesc
, D3DHELDevDesc
);
523 static HRESULT WINAPI
IDirect3DDeviceImpl_1_GetCaps(IDirect3DDevice
*iface
,
524 D3DDEVICEDESC
*D3DHWDevDesc
, D3DDEVICEDESC
*D3DHELDevDesc
)
526 IDirect3DDeviceImpl
*This
= device_from_device1(iface
);
527 TRACE("iface %p, hw_desc %p, hel_desc %p.\n", iface
, D3DHWDevDesc
, D3DHELDevDesc
);
528 return IDirect3DDevice3_GetCaps((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
, D3DHWDevDesc
, D3DHELDevDesc
);
531 /*****************************************************************************
532 * IDirect3DDevice2::SwapTextureHandles
534 * Swaps the texture handles of 2 Texture interfaces. Version 1 and 2
537 * Tex1, Tex2: The 2 Textures to swap
542 *****************************************************************************/
543 static HRESULT WINAPI
544 IDirect3DDeviceImpl_2_SwapTextureHandles(IDirect3DDevice2
*iface
,
545 IDirect3DTexture2
*Tex1
,
546 IDirect3DTexture2
*Tex2
)
548 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
549 IDirectDrawSurfaceImpl
*surf1
= surface_from_texture2(Tex1
);
550 IDirectDrawSurfaceImpl
*surf2
= surface_from_texture2(Tex2
);
553 TRACE("iface %p, tex1 %p, tex2 %p.\n", iface
, Tex1
, Tex2
);
555 EnterCriticalSection(&ddraw_cs
);
557 h1
= surf1
->Handle
- 1;
558 h2
= surf2
->Handle
- 1;
559 This
->handle_table
.entries
[h1
].object
= surf2
;
560 This
->handle_table
.entries
[h2
].object
= surf1
;
561 surf2
->Handle
= h1
+ 1;
562 surf1
->Handle
= h2
+ 1;
564 LeaveCriticalSection(&ddraw_cs
);
569 static HRESULT WINAPI
IDirect3DDeviceImpl_1_SwapTextureHandles(IDirect3DDevice
*iface
,
570 IDirect3DTexture
*D3DTex1
, IDirect3DTexture
*D3DTex2
)
572 IDirect3DDeviceImpl
*This
= device_from_device1(iface
);
573 IDirectDrawSurfaceImpl
*surf1
= surface_from_texture1(D3DTex1
);
574 IDirectDrawSurfaceImpl
*surf2
= surface_from_texture1(D3DTex2
);
575 IDirect3DTexture2
*t1
= surf1
? (IDirect3DTexture2
*)&surf1
->IDirect3DTexture2_vtbl
: NULL
;
576 IDirect3DTexture2
*t2
= surf2
? (IDirect3DTexture2
*)&surf2
->IDirect3DTexture2_vtbl
: NULL
;
578 TRACE("iface %p, tex1 %p, tex2 %p.\n", iface
, D3DTex1
, D3DTex2
);
580 return IDirect3DDevice2_SwapTextureHandles((IDirect3DDevice2
*)&This
->IDirect3DDevice2_vtbl
, t1
, t2
);
583 /*****************************************************************************
584 * IDirect3DDevice3::GetStats
586 * This method seems to retrieve some stats from the device.
587 * The MSDN documentation doesn't exist any more, but the D3DSTATS
588 * structure suggests that the amount of drawn primitives and processed
589 * vertices is returned.
591 * Exists in Version 1, 2 and 3
594 * Stats: Pointer to a D3DSTATS structure to be filled
598 * DDERR_INVALIDPARAMS if Stats == NULL
600 *****************************************************************************/
601 static HRESULT WINAPI
602 IDirect3DDeviceImpl_3_GetStats(IDirect3DDevice3
*iface
,
605 FIXME("iface %p, stats %p stub!\n", iface
, Stats
);
608 return DDERR_INVALIDPARAMS
;
610 /* Fill the Stats with 0 */
611 Stats
->dwTrianglesDrawn
= 0;
612 Stats
->dwLinesDrawn
= 0;
613 Stats
->dwPointsDrawn
= 0;
614 Stats
->dwSpansDrawn
= 0;
615 Stats
->dwVerticesProcessed
= 0;
620 static HRESULT WINAPI
IDirect3DDeviceImpl_2_GetStats(IDirect3DDevice2
*iface
, D3DSTATS
*Stats
)
622 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
624 TRACE("iface %p, stats %p.\n", iface
, Stats
);
626 return IDirect3DDevice3_GetStats((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
, Stats
);
629 static HRESULT WINAPI
IDirect3DDeviceImpl_1_GetStats(IDirect3DDevice
*iface
, D3DSTATS
*Stats
)
631 IDirect3DDeviceImpl
*This
= device_from_device1(iface
);
633 TRACE("iface %p, stats %p.\n", iface
, Stats
);
635 return IDirect3DDevice3_GetStats((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
, Stats
);
638 /*****************************************************************************
639 * IDirect3DDevice::CreateExecuteBuffer
641 * Creates an IDirect3DExecuteBuffer, used for rendering with a
647 * Desc: Buffer description
648 * ExecuteBuffer: Address to return the Interface pointer at
649 * UnkOuter: Must be NULL. Basically for aggregation, which ddraw doesn't
653 * CLASS_E_NOAGGREGATION if UnkOuter != NULL
654 * DDERR_OUTOFMEMORY if we ran out of memory
657 *****************************************************************************/
658 static HRESULT WINAPI
659 IDirect3DDeviceImpl_1_CreateExecuteBuffer(IDirect3DDevice
*iface
,
660 D3DEXECUTEBUFFERDESC
*Desc
,
661 IDirect3DExecuteBuffer
**ExecuteBuffer
,
664 IDirect3DDeviceImpl
*This
= device_from_device1(iface
);
665 IDirect3DExecuteBufferImpl
* object
;
668 TRACE("iface %p, buffer_desc %p, buffer %p, outer_unknown %p.\n",
669 iface
, Desc
, ExecuteBuffer
, UnkOuter
);
672 return CLASS_E_NOAGGREGATION
;
674 /* Allocate the new Execute Buffer */
675 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirect3DExecuteBufferImpl
));
678 ERR("Out of memory when allocating a IDirect3DExecuteBufferImpl structure\n");
679 return DDERR_OUTOFMEMORY
;
682 hr
= d3d_execute_buffer_init(object
, This
, Desc
);
685 WARN("Failed to initialize execute buffer, hr %#x.\n", hr
);
686 HeapFree(GetProcessHeap(), 0, object
);
690 *ExecuteBuffer
= (IDirect3DExecuteBuffer
*)object
;
692 TRACE(" Returning IDirect3DExecuteBuffer at %p, implementation is at %p\n", *ExecuteBuffer
, object
);
697 /*****************************************************************************
698 * IDirect3DDevice::Execute
700 * Executes all the stuff in an execute buffer.
703 * ExecuteBuffer: The buffer to execute
704 * Viewport: The viewport used for rendering
708 * DDERR_INVALIDPARAMS if ExecuteBuffer == NULL
711 *****************************************************************************/
712 static HRESULT WINAPI
713 IDirect3DDeviceImpl_1_Execute(IDirect3DDevice
*iface
,
714 IDirect3DExecuteBuffer
*ExecuteBuffer
,
715 IDirect3DViewport
*Viewport
,
718 IDirect3DDeviceImpl
*This
= device_from_device1(iface
);
719 IDirect3DExecuteBufferImpl
*Direct3DExecuteBufferImpl
= (IDirect3DExecuteBufferImpl
*)ExecuteBuffer
;
720 IDirect3DViewportImpl
*Direct3DViewportImpl
= (IDirect3DViewportImpl
*)Viewport
;
722 TRACE("iface %p, buffer %p, viewport %p, flags %#x.\n", iface
, ExecuteBuffer
, Viewport
, Flags
);
724 if(!Direct3DExecuteBufferImpl
)
725 return DDERR_INVALIDPARAMS
;
728 EnterCriticalSection(&ddraw_cs
);
729 IDirect3DExecuteBufferImpl_Execute(Direct3DExecuteBufferImpl
, This
, Direct3DViewportImpl
);
730 LeaveCriticalSection(&ddraw_cs
);
735 /*****************************************************************************
736 * IDirect3DDevice3::AddViewport
738 * Add a Direct3DViewport to the device's viewport list. These viewports
739 * are wrapped to IDirect3DDevice7 viewports in viewport.c
741 * Exists in Version 1, 2 and 3. Note that IDirect3DViewport 1, 2 and 3
742 * are the same interfaces.
745 * Viewport: The viewport to add
748 * DDERR_INVALIDPARAMS if Viewport == NULL
751 *****************************************************************************/
752 static HRESULT WINAPI
753 IDirect3DDeviceImpl_3_AddViewport(IDirect3DDevice3
*iface
,
754 IDirect3DViewport3
*Viewport
)
756 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
757 IDirect3DViewportImpl
*vp
= (IDirect3DViewportImpl
*)Viewport
;
759 TRACE("iface %p, viewport %p.\n", iface
, Viewport
);
763 return DDERR_INVALIDPARAMS
;
765 EnterCriticalSection(&ddraw_cs
);
766 vp
->next
= This
->viewport_list
;
767 This
->viewport_list
= vp
;
768 vp
->active_device
= This
; /* Viewport must be usable for Clear() after AddViewport,
769 so set active_device here. */
770 LeaveCriticalSection(&ddraw_cs
);
775 static HRESULT WINAPI
IDirect3DDeviceImpl_2_AddViewport(IDirect3DDevice2
*iface
,
776 IDirect3DViewport2
*Direct3DViewport2
)
778 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
779 IDirect3DViewportImpl
*vp
= (IDirect3DViewportImpl
*)Direct3DViewport2
;
781 TRACE("iface %p, viewport %p.\n", iface
, Direct3DViewport2
);
783 return IDirect3DDevice3_AddViewport((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
, (IDirect3DViewport3
*)vp
);
786 static HRESULT WINAPI
IDirect3DDeviceImpl_1_AddViewport(IDirect3DDevice
*iface
,
787 IDirect3DViewport
*Direct3DViewport
)
789 IDirect3DDeviceImpl
*This
= device_from_device1(iface
);
790 IDirect3DViewportImpl
*vp
= (IDirect3DViewportImpl
*)Direct3DViewport
;
792 TRACE("iface %p, viewport %p.\n", iface
, Direct3DViewport
);
794 return IDirect3DDevice3_AddViewport((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
, (IDirect3DViewport3
*)vp
);
797 /*****************************************************************************
798 * IDirect3DDevice3::DeleteViewport
800 * Deletes a Direct3DViewport from the device's viewport list.
802 * Exists in Version 1, 2 and 3. Note that all Viewport interface versions
806 * Viewport: The viewport to delete
810 * DDERR_INVALIDPARAMS if the viewport wasn't found in the list
812 *****************************************************************************/
813 static HRESULT WINAPI
814 IDirect3DDeviceImpl_3_DeleteViewport(IDirect3DDevice3
*iface
,
815 IDirect3DViewport3
*Viewport
)
817 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
818 IDirect3DViewportImpl
*vp
= (IDirect3DViewportImpl
*) Viewport
;
819 IDirect3DViewportImpl
*cur_viewport
, *prev_viewport
= NULL
;
821 TRACE("iface %p, viewport %p.\n", iface
, Viewport
);
823 EnterCriticalSection(&ddraw_cs
);
824 cur_viewport
= This
->viewport_list
;
825 while (cur_viewport
!= NULL
)
827 if (cur_viewport
== vp
)
829 if (prev_viewport
== NULL
) This
->viewport_list
= cur_viewport
->next
;
830 else prev_viewport
->next
= cur_viewport
->next
;
831 /* TODO : add desactivate of the viewport and all associated lights... */
832 LeaveCriticalSection(&ddraw_cs
);
835 prev_viewport
= cur_viewport
;
836 cur_viewport
= cur_viewport
->next
;
839 LeaveCriticalSection(&ddraw_cs
);
840 return DDERR_INVALIDPARAMS
;
843 static HRESULT WINAPI
IDirect3DDeviceImpl_2_DeleteViewport(IDirect3DDevice2
*iface
,
844 IDirect3DViewport2
*Direct3DViewport2
)
846 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
847 IDirect3DViewportImpl
*vp
= (IDirect3DViewportImpl
*)Direct3DViewport2
;
849 TRACE("iface %p, viewport %p.\n", iface
, Direct3DViewport2
);
851 return IDirect3DDevice3_DeleteViewport((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
, (IDirect3DViewport3
*)vp
);
854 static HRESULT WINAPI
IDirect3DDeviceImpl_1_DeleteViewport(IDirect3DDevice
*iface
,
855 IDirect3DViewport
*Direct3DViewport
)
857 IDirect3DDeviceImpl
*This
= device_from_device1(iface
);
858 IDirect3DViewportImpl
*vp
= (IDirect3DViewportImpl
*)Direct3DViewport
;
860 TRACE("iface %p, viewport %p.\n", iface
, Direct3DViewport
);
862 return IDirect3DDevice3_DeleteViewport((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
, (IDirect3DViewport3
*)vp
);
865 /*****************************************************************************
866 * IDirect3DDevice3::NextViewport
868 * Returns a viewport from the viewport list, depending on the
869 * passed viewport and the flags.
871 * Exists in Version 1, 2 and 3. Note that all Viewport interface versions
875 * Viewport: Viewport to use for beginning the search
876 * Flags: D3DNEXT_NEXT, D3DNEXT_HEAD or D3DNEXT_TAIL
880 * DDERR_INVALIDPARAMS if the flags were wrong, or Viewport was NULL
882 *****************************************************************************/
883 static HRESULT WINAPI
884 IDirect3DDeviceImpl_3_NextViewport(IDirect3DDevice3
*iface
,
885 IDirect3DViewport3
*Viewport3
,
886 IDirect3DViewport3
**lplpDirect3DViewport3
,
889 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
890 IDirect3DViewportImpl
*vp
= (IDirect3DViewportImpl
*)Viewport3
;
891 IDirect3DViewportImpl
*res
= NULL
;
893 TRACE("iface %p, viewport %p, next %p, flags %#x.\n",
894 iface
, Viewport3
, lplpDirect3DViewport3
, Flags
);
898 *lplpDirect3DViewport3
= NULL
;
899 return DDERR_INVALIDPARAMS
;
903 EnterCriticalSection(&ddraw_cs
);
913 res
= This
->viewport_list
;
918 IDirect3DViewportImpl
*cur_viewport
= This
->viewport_list
;
919 if (cur_viewport
!= NULL
)
921 while (cur_viewport
->next
!= NULL
) cur_viewport
= cur_viewport
->next
;
927 *lplpDirect3DViewport3
= NULL
;
928 LeaveCriticalSection(&ddraw_cs
);
929 return DDERR_INVALIDPARAMS
;
932 *lplpDirect3DViewport3
= (IDirect3DViewport3
*)res
;
933 LeaveCriticalSection(&ddraw_cs
);
937 static HRESULT WINAPI
IDirect3DDeviceImpl_2_NextViewport(IDirect3DDevice2
*iface
,
938 IDirect3DViewport2
*Viewport2
, IDirect3DViewport2
**lplpDirect3DViewport2
, DWORD Flags
)
940 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
941 IDirect3DViewportImpl
*vp
= (IDirect3DViewportImpl
*)Viewport2
;
942 IDirect3DViewport3
*res
;
945 TRACE("iface %p, viewport %p, next %p, flags %#x.\n",
946 iface
, Viewport2
, lplpDirect3DViewport2
, Flags
);
948 hr
= IDirect3DDevice3_NextViewport((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
,
949 (IDirect3DViewport3
*)vp
, &res
, Flags
);
950 *lplpDirect3DViewport2
= (IDirect3DViewport2
*)res
;
954 static HRESULT WINAPI
IDirect3DDeviceImpl_1_NextViewport(IDirect3DDevice
*iface
,
955 IDirect3DViewport
*Viewport
, IDirect3DViewport
**lplpDirect3DViewport
, DWORD Flags
)
957 IDirect3DDeviceImpl
*This
= device_from_device1(iface
);
958 IDirect3DViewportImpl
*vp
= (IDirect3DViewportImpl
*)Viewport
;
959 IDirect3DViewport3
*res
;
962 TRACE("iface %p, viewport %p, next %p, flags %#x.\n",
963 iface
, Viewport
, lplpDirect3DViewport
, Flags
);
965 hr
= IDirect3DDevice3_NextViewport((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
,
966 (IDirect3DViewport3
*)vp
, &res
, Flags
);
967 *lplpDirect3DViewport
= (IDirect3DViewport
*)res
;
971 /*****************************************************************************
972 * IDirect3DDevice::Pick
974 * Executes an execute buffer without performing rendering. Instead, a
975 * list of primitives that intersect with (x1,y1) of the passed rectangle
976 * is created. IDirect3DDevice::GetPickRecords can be used to retrieve
982 * ExecuteBuffer: Buffer to execute
983 * Viewport: Viewport to use for execution
984 * Flags: None are defined, according to the SDK
985 * Rect: Specifies the coordinates to be picked. Only x1 and y2 are used,
986 * x2 and y2 are ignored.
989 * D3D_OK because it's a stub
991 *****************************************************************************/
992 static HRESULT WINAPI
993 IDirect3DDeviceImpl_1_Pick(IDirect3DDevice
*iface
,
994 IDirect3DExecuteBuffer
*ExecuteBuffer
,
995 IDirect3DViewport
*Viewport
,
999 FIXME("iface %p, buffer %p, viewport %p, flags %#x, rect %s stub!\n",
1000 iface
, ExecuteBuffer
, Viewport
, Flags
, wine_dbgstr_rect((RECT
*)Rect
));
1005 /*****************************************************************************
1006 * IDirect3DDevice::GetPickRecords
1008 * Retrieves the pick records generated by IDirect3DDevice::GetPickRecords
1013 * Count: Pointer to a DWORD containing the numbers of pick records to
1015 * D3DPickRec: Address to store the resulting D3DPICKRECORD array.
1018 * D3D_OK, because it's a stub
1020 *****************************************************************************/
1021 static HRESULT WINAPI
1022 IDirect3DDeviceImpl_1_GetPickRecords(IDirect3DDevice
*iface
,
1024 D3DPICKRECORD
*D3DPickRec
)
1026 FIXME("iface %p, count %p, records %p stub!\n", iface
, Count
, D3DPickRec
);
1031 /*****************************************************************************
1032 * IDirect3DDevice7::EnumTextureformats
1034 * Enumerates the supported texture formats. It has a list of all possible
1035 * formats and calls IWineD3D::CheckDeviceFormat for each format to see if
1036 * WineD3D supports it. If so, then it is passed to the app.
1038 * This is for Version 7 and 3, older versions have a different
1039 * callback function and their own implementation
1042 * Callback: Callback to call for each enumerated format
1043 * Arg: Argument to pass to the callback
1047 * DDERR_INVALIDPARAMS if Callback == NULL
1049 *****************************************************************************/
1051 IDirect3DDeviceImpl_7_EnumTextureFormats(IDirect3DDevice7
*iface
,
1052 LPD3DENUMPIXELFORMATSCALLBACK Callback
,
1055 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
1057 WINED3DDISPLAYMODE mode
;
1060 static const enum wined3d_format_id FormatList
[] =
1063 WINED3DFMT_B8G8R8A8_UNORM
,
1064 WINED3DFMT_B8G8R8X8_UNORM
,
1066 WINED3DFMT_B8G8R8_UNORM
,
1068 WINED3DFMT_B5G5R5A1_UNORM
,
1069 WINED3DFMT_B4G4R4A4_UNORM
,
1070 WINED3DFMT_B5G6R5_UNORM
,
1071 WINED3DFMT_B5G5R5X1_UNORM
,
1073 WINED3DFMT_B2G3R3_UNORM
,
1081 static const enum wined3d_format_id BumpFormatList
[] =
1083 WINED3DFMT_R8G8_SNORM
,
1084 WINED3DFMT_R5G5_SNORM_L6_UNORM
,
1085 WINED3DFMT_R8G8_SNORM_L8X8_UNORM
,
1086 WINED3DFMT_R16G16_SNORM
,
1087 WINED3DFMT_R10G11B11_SNORM
,
1088 WINED3DFMT_R10G10B10_SNORM_A2_UNORM
1091 TRACE("iface %p, callback %p, context %p.\n", iface
, Callback
, Arg
);
1094 return DDERR_INVALIDPARAMS
;
1096 EnterCriticalSection(&ddraw_cs
);
1098 memset(&mode
, 0, sizeof(mode
));
1099 hr
= IWineD3DDevice_GetDisplayMode(This
->ddraw
->wineD3DDevice
,
1103 LeaveCriticalSection(&ddraw_cs
);
1104 WARN("Cannot get the current adapter format\n");
1108 for (i
= 0; i
< sizeof(FormatList
) / sizeof(*FormatList
); ++i
)
1110 hr
= wined3d_check_device_format(This
->ddraw
->wineD3D
, WINED3DADAPTER_DEFAULT
, WINED3DDEVTYPE_HAL
,
1111 mode
.Format
, 0, WINED3DRTYPE_TEXTURE
, FormatList
[i
], SURFACE_OPENGL
);
1114 DDPIXELFORMAT pformat
;
1116 memset(&pformat
, 0, sizeof(pformat
));
1117 pformat
.dwSize
= sizeof(pformat
);
1118 PixelFormat_WineD3DtoDD(&pformat
, FormatList
[i
]);
1120 TRACE("Enumerating WineD3DFormat %d\n", FormatList
[i
]);
1121 hr
= Callback(&pformat
, Arg
);
1122 if(hr
!= DDENUMRET_OK
)
1124 TRACE("Format enumeration cancelled by application\n");
1125 LeaveCriticalSection(&ddraw_cs
);
1131 for (i
= 0; i
< sizeof(BumpFormatList
) / sizeof(*BumpFormatList
); ++i
)
1133 hr
= wined3d_check_device_format(This
->ddraw
->wineD3D
, WINED3DADAPTER_DEFAULT
,
1134 WINED3DDEVTYPE_HAL
, mode
.Format
, WINED3DUSAGE_QUERY_LEGACYBUMPMAP
,
1135 WINED3DRTYPE_TEXTURE
, BumpFormatList
[i
], SURFACE_OPENGL
);
1138 DDPIXELFORMAT pformat
;
1140 memset(&pformat
, 0, sizeof(pformat
));
1141 pformat
.dwSize
= sizeof(pformat
);
1142 PixelFormat_WineD3DtoDD(&pformat
, BumpFormatList
[i
]);
1144 TRACE("Enumerating WineD3DFormat %d\n", BumpFormatList
[i
]);
1145 hr
= Callback(&pformat
, Arg
);
1146 if(hr
!= DDENUMRET_OK
)
1148 TRACE("Format enumeration cancelled by application\n");
1149 LeaveCriticalSection(&ddraw_cs
);
1154 TRACE("End of enumeration\n");
1155 LeaveCriticalSection(&ddraw_cs
);
1159 static HRESULT WINAPI
1160 IDirect3DDeviceImpl_7_EnumTextureFormats_FPUSetup(IDirect3DDevice7
*iface
,
1161 LPD3DENUMPIXELFORMATSCALLBACK Callback
,
1164 return IDirect3DDeviceImpl_7_EnumTextureFormats(iface
, Callback
, Arg
);
1167 static HRESULT WINAPI
1168 IDirect3DDeviceImpl_7_EnumTextureFormats_FPUPreserve(IDirect3DDevice7
*iface
,
1169 LPD3DENUMPIXELFORMATSCALLBACK Callback
,
1175 old_fpucw
= d3d_fpu_setup();
1176 hr
= IDirect3DDeviceImpl_7_EnumTextureFormats(iface
, Callback
, Arg
);
1177 set_fpu_control_word(old_fpucw
);
1182 static HRESULT WINAPI
IDirect3DDeviceImpl_3_EnumTextureFormats(IDirect3DDevice3
*iface
,
1183 LPD3DENUMPIXELFORMATSCALLBACK Callback
, void *Arg
)
1185 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
1187 TRACE("iface %p, callback %p, context %p.\n", iface
, Callback
, Arg
);
1189 return IDirect3DDevice7_EnumTextureFormats((IDirect3DDevice7
*)This
, Callback
, Arg
);
1192 /*****************************************************************************
1193 * IDirect3DDevice2::EnumTextureformats
1195 * EnumTextureFormats for Version 1 and 2, see
1196 * IDirect3DDevice7::EnumTexureFormats for a more detailed description.
1198 * This version has a different callback and does not enumerate FourCC
1201 *****************************************************************************/
1202 static HRESULT WINAPI
1203 IDirect3DDeviceImpl_2_EnumTextureFormats(IDirect3DDevice2
*iface
,
1204 LPD3DENUMTEXTUREFORMATSCALLBACK Callback
,
1207 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
1210 WINED3DDISPLAYMODE mode
;
1212 static const enum wined3d_format_id FormatList
[] =
1215 WINED3DFMT_B8G8R8A8_UNORM
,
1216 WINED3DFMT_B8G8R8X8_UNORM
,
1218 WINED3DFMT_B8G8R8_UNORM
,
1220 WINED3DFMT_B5G5R5A1_UNORM
,
1221 WINED3DFMT_B4G4R4A4_UNORM
,
1222 WINED3DFMT_B5G6R5_UNORM
,
1223 WINED3DFMT_B5G5R5X1_UNORM
,
1225 WINED3DFMT_B2G3R3_UNORM
,
1227 /* FOURCC codes - Not in this version*/
1230 TRACE("iface %p, callback %p, context %p.\n", iface
, Callback
, Arg
);
1233 return DDERR_INVALIDPARAMS
;
1235 EnterCriticalSection(&ddraw_cs
);
1237 memset(&mode
, 0, sizeof(mode
));
1238 hr
= IWineD3DDevice_GetDisplayMode(This
->ddraw
->wineD3DDevice
,
1242 LeaveCriticalSection(&ddraw_cs
);
1243 WARN("Cannot get the current adapter format\n");
1247 for (i
= 0; i
< sizeof(FormatList
) / sizeof(*FormatList
); ++i
)
1249 hr
= wined3d_check_device_format(This
->ddraw
->wineD3D
, 0, WINED3DDEVTYPE_HAL
,
1250 mode
.Format
, 0, WINED3DRTYPE_TEXTURE
, FormatList
[i
], SURFACE_OPENGL
);
1253 DDSURFACEDESC sdesc
;
1255 memset(&sdesc
, 0, sizeof(sdesc
));
1256 sdesc
.dwSize
= sizeof(sdesc
);
1257 sdesc
.dwFlags
= DDSD_PIXELFORMAT
| DDSD_CAPS
;
1258 sdesc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
1259 sdesc
.ddpfPixelFormat
.dwSize
= sizeof(sdesc
.ddpfPixelFormat
);
1260 PixelFormat_WineD3DtoDD(&sdesc
.ddpfPixelFormat
, FormatList
[i
]);
1262 TRACE("Enumerating WineD3DFormat %d\n", FormatList
[i
]);
1263 hr
= Callback(&sdesc
, Arg
);
1264 if(hr
!= DDENUMRET_OK
)
1266 TRACE("Format enumeration cancelled by application\n");
1267 LeaveCriticalSection(&ddraw_cs
);
1272 TRACE("End of enumeration\n");
1273 LeaveCriticalSection(&ddraw_cs
);
1277 static HRESULT WINAPI
IDirect3DDeviceImpl_1_EnumTextureFormats(IDirect3DDevice
*iface
,
1278 LPD3DENUMTEXTUREFORMATSCALLBACK Callback
, void *Arg
)
1280 IDirect3DDeviceImpl
*This
= device_from_device1(iface
);
1282 TRACE("iface %p, callback %p, context %p.\n", iface
, Callback
, Arg
);
1284 return IDirect3DDevice2_EnumTextureFormats((IDirect3DDevice2
*)&This
->IDirect3DDevice2_vtbl
, Callback
, Arg
);
1287 /*****************************************************************************
1288 * IDirect3DDevice::CreateMatrix
1290 * Creates a matrix handle. A handle is created and memory for a D3DMATRIX is
1291 * allocated for the handle.
1296 * D3DMatHandle: Address to return the handle at
1300 * DDERR_INVALIDPARAMS if D3DMatHandle = NULL
1302 *****************************************************************************/
1303 static HRESULT WINAPI
1304 IDirect3DDeviceImpl_1_CreateMatrix(IDirect3DDevice
*iface
, D3DMATRIXHANDLE
*D3DMatHandle
)
1306 IDirect3DDeviceImpl
*This
= device_from_device1(iface
);
1310 TRACE("iface %p, matrix_handle %p.\n", iface
, D3DMatHandle
);
1313 return DDERR_INVALIDPARAMS
;
1315 Matrix
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(D3DMATRIX
));
1318 ERR("Out of memory when allocating a D3DMATRIX\n");
1319 return DDERR_OUTOFMEMORY
;
1322 EnterCriticalSection(&ddraw_cs
);
1324 h
= ddraw_allocate_handle(&This
->handle_table
, Matrix
, DDRAW_HANDLE_MATRIX
);
1325 if (h
== DDRAW_INVALID_HANDLE
)
1327 ERR("Failed to allocate a matrix handle.\n");
1328 HeapFree(GetProcessHeap(), 0, Matrix
);
1329 LeaveCriticalSection(&ddraw_cs
);
1330 return DDERR_OUTOFMEMORY
;
1333 *D3DMatHandle
= h
+ 1;
1335 TRACE(" returning matrix handle %d\n", *D3DMatHandle
);
1337 LeaveCriticalSection(&ddraw_cs
);
1341 /*****************************************************************************
1342 * IDirect3DDevice::SetMatrix
1344 * Sets a matrix for a matrix handle. The matrix is copied into the memory
1345 * allocated for the handle
1350 * D3DMatHandle: Handle to set the matrix to
1351 * D3DMatrix: Matrix to set
1355 * DDERR_INVALIDPARAMS if the handle of the matrix is invalid or the matrix
1358 *****************************************************************************/
1359 static HRESULT WINAPI
1360 IDirect3DDeviceImpl_1_SetMatrix(IDirect3DDevice
*iface
,
1361 D3DMATRIXHANDLE D3DMatHandle
,
1362 D3DMATRIX
*D3DMatrix
)
1364 IDirect3DDeviceImpl
*This
= device_from_device1(iface
);
1367 TRACE("iface %p, matrix_handle %#x, matrix %p.\n", iface
, D3DMatHandle
, D3DMatrix
);
1369 if (!D3DMatrix
) return DDERR_INVALIDPARAMS
;
1371 EnterCriticalSection(&ddraw_cs
);
1373 m
= ddraw_get_object(&This
->handle_table
, D3DMatHandle
- 1, DDRAW_HANDLE_MATRIX
);
1376 WARN("Invalid matrix handle.\n");
1377 LeaveCriticalSection(&ddraw_cs
);
1378 return DDERR_INVALIDPARAMS
;
1381 if (TRACE_ON(ddraw
))
1382 dump_D3DMATRIX(D3DMatrix
);
1386 if(This
->world
== D3DMatHandle
)
1388 IWineD3DDevice_SetTransform(This
->wineD3DDevice
,
1389 WINED3DTS_WORLDMATRIX(0),
1390 (WINED3DMATRIX
*) D3DMatrix
);
1392 if(This
->view
== D3DMatHandle
)
1394 IWineD3DDevice_SetTransform(This
->wineD3DDevice
,
1396 (WINED3DMATRIX
*) D3DMatrix
);
1398 if(This
->proj
== D3DMatHandle
)
1400 IWineD3DDevice_SetTransform(This
->wineD3DDevice
,
1401 WINED3DTS_PROJECTION
,
1402 (WINED3DMATRIX
*) D3DMatrix
);
1405 LeaveCriticalSection(&ddraw_cs
);
1409 /*****************************************************************************
1410 * IDirect3DDevice::GetMatrix
1412 * Returns the content of a D3DMATRIX handle
1417 * D3DMatHandle: Matrix handle to read the content from
1418 * D3DMatrix: Address to store the content at
1422 * DDERR_INVALIDPARAMS if D3DMatHandle is invalid or D3DMatrix is NULL
1424 *****************************************************************************/
1425 static HRESULT WINAPI
1426 IDirect3DDeviceImpl_1_GetMatrix(IDirect3DDevice
*iface
,
1427 D3DMATRIXHANDLE D3DMatHandle
,
1428 D3DMATRIX
*D3DMatrix
)
1430 IDirect3DDeviceImpl
*This
= device_from_device1(iface
);
1433 TRACE("iface %p, matrix_handle %#x, matrix %p.\n", iface
, D3DMatHandle
, D3DMatrix
);
1435 if (!D3DMatrix
) return DDERR_INVALIDPARAMS
;
1437 EnterCriticalSection(&ddraw_cs
);
1439 m
= ddraw_get_object(&This
->handle_table
, D3DMatHandle
- 1, DDRAW_HANDLE_MATRIX
);
1442 WARN("Invalid matrix handle.\n");
1443 LeaveCriticalSection(&ddraw_cs
);
1444 return DDERR_INVALIDPARAMS
;
1449 LeaveCriticalSection(&ddraw_cs
);
1453 /*****************************************************************************
1454 * IDirect3DDevice::DeleteMatrix
1456 * Destroys a Matrix handle. Frees the memory and unsets the handle data
1461 * D3DMatHandle: Handle to destroy
1465 * DDERR_INVALIDPARAMS if D3DMatHandle is invalid
1467 *****************************************************************************/
1468 static HRESULT WINAPI
1469 IDirect3DDeviceImpl_1_DeleteMatrix(IDirect3DDevice
*iface
,
1470 D3DMATRIXHANDLE D3DMatHandle
)
1472 IDirect3DDeviceImpl
*This
= device_from_device1(iface
);
1475 TRACE("iface %p, matrix_handle %#x.\n", iface
, D3DMatHandle
);
1477 EnterCriticalSection(&ddraw_cs
);
1479 m
= ddraw_free_handle(&This
->handle_table
, D3DMatHandle
- 1, DDRAW_HANDLE_MATRIX
);
1482 WARN("Invalid matrix handle.\n");
1483 LeaveCriticalSection(&ddraw_cs
);
1484 return DDERR_INVALIDPARAMS
;
1487 LeaveCriticalSection(&ddraw_cs
);
1489 HeapFree(GetProcessHeap(), 0, m
);
1494 /*****************************************************************************
1495 * IDirect3DDevice7::BeginScene
1497 * This method must be called before any rendering is performed.
1498 * IDirect3DDevice::EndScene has to be called after the scene is complete
1500 * Version 1, 2, 3 and 7
1503 * D3D_OK on success, for details see IWineD3DDevice::BeginScene
1504 * D3DERR_SCENE_IN_SCENE if WineD3D returns an error(Only in case of an already
1507 *****************************************************************************/
1509 IDirect3DDeviceImpl_7_BeginScene(IDirect3DDevice7
*iface
)
1511 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
1514 TRACE("iface %p.\n", iface
);
1516 EnterCriticalSection(&ddraw_cs
);
1517 hr
= IWineD3DDevice_BeginScene(This
->wineD3DDevice
);
1518 LeaveCriticalSection(&ddraw_cs
);
1519 if(hr
== WINED3D_OK
) return D3D_OK
;
1520 else return D3DERR_SCENE_IN_SCENE
; /* TODO: Other possible causes of failure */
1523 static HRESULT WINAPI
1524 IDirect3DDeviceImpl_7_BeginScene_FPUSetup(IDirect3DDevice7
*iface
)
1526 return IDirect3DDeviceImpl_7_BeginScene(iface
);
1529 static HRESULT WINAPI
1530 IDirect3DDeviceImpl_7_BeginScene_FPUPreserve(IDirect3DDevice7
*iface
)
1535 old_fpucw
= d3d_fpu_setup();
1536 hr
= IDirect3DDeviceImpl_7_BeginScene(iface
);
1537 set_fpu_control_word(old_fpucw
);
1542 static HRESULT WINAPI
IDirect3DDeviceImpl_3_BeginScene(IDirect3DDevice3
*iface
)
1544 TRACE("iface %p.\n", iface
);
1546 return IDirect3DDevice7_BeginScene((IDirect3DDevice7
*)device_from_device3(iface
));
1549 static HRESULT WINAPI
IDirect3DDeviceImpl_2_BeginScene(IDirect3DDevice2
*iface
)
1551 TRACE("iface %p.\n", iface
);
1553 return IDirect3DDevice7_BeginScene((IDirect3DDevice7
*)device_from_device2(iface
));
1556 static HRESULT WINAPI
IDirect3DDeviceImpl_1_BeginScene(IDirect3DDevice
*iface
)
1558 TRACE("iface %p.\n", iface
);
1560 return IDirect3DDevice7_BeginScene((IDirect3DDevice7
*)device_from_device1(iface
));
1563 /*****************************************************************************
1564 * IDirect3DDevice7::EndScene
1566 * Ends a scene that has been begun with IDirect3DDevice7::BeginScene.
1567 * This method must be called after rendering is finished.
1569 * Version 1, 2, 3 and 7
1572 * D3D_OK on success, for details see IWineD3DDevice::EndScene
1573 * D3DERR_SCENE_NOT_IN_SCENE is returned if WineD3D returns an error. It does
1574 * that only if the scene was already ended.
1576 *****************************************************************************/
1578 IDirect3DDeviceImpl_7_EndScene(IDirect3DDevice7
*iface
)
1580 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
1583 TRACE("iface %p.\n", iface
);
1585 EnterCriticalSection(&ddraw_cs
);
1586 hr
= IWineD3DDevice_EndScene(This
->wineD3DDevice
);
1587 LeaveCriticalSection(&ddraw_cs
);
1588 if(hr
== WINED3D_OK
) return D3D_OK
;
1589 else return D3DERR_SCENE_NOT_IN_SCENE
;
1592 static HRESULT WINAPI DECLSPEC_HOTPATCH
1593 IDirect3DDeviceImpl_7_EndScene_FPUSetup(IDirect3DDevice7
*iface
)
1595 return IDirect3DDeviceImpl_7_EndScene(iface
);
1598 static HRESULT WINAPI DECLSPEC_HOTPATCH
1599 IDirect3DDeviceImpl_7_EndScene_FPUPreserve(IDirect3DDevice7
*iface
)
1604 old_fpucw
= d3d_fpu_setup();
1605 hr
= IDirect3DDeviceImpl_7_EndScene(iface
);
1606 set_fpu_control_word(old_fpucw
);
1611 static HRESULT WINAPI DECLSPEC_HOTPATCH
IDirect3DDeviceImpl_3_EndScene(IDirect3DDevice3
*iface
)
1613 TRACE("iface %p.\n", iface
);
1615 return IDirect3DDevice7_EndScene((IDirect3DDevice7
*)device_from_device3(iface
));
1618 static HRESULT WINAPI DECLSPEC_HOTPATCH
IDirect3DDeviceImpl_2_EndScene(IDirect3DDevice2
*iface
)
1620 TRACE("iface %p.\n", iface
);
1622 return IDirect3DDevice7_EndScene((IDirect3DDevice7
*)device_from_device2(iface
));
1625 static HRESULT WINAPI DECLSPEC_HOTPATCH
IDirect3DDeviceImpl_1_EndScene(IDirect3DDevice
*iface
)
1627 TRACE("iface %p.\n", iface
);
1629 return IDirect3DDevice7_EndScene((IDirect3DDevice7
*)device_from_device1(iface
));
1632 /*****************************************************************************
1633 * IDirect3DDevice7::GetDirect3D
1635 * Returns the IDirect3D(= interface to the DirectDraw object) used to create
1639 * Direct3D7: Address to store the interface pointer at
1643 * DDERR_INVALIDPARAMS if Direct3D7 == NULL
1645 *****************************************************************************/
1646 static HRESULT WINAPI
1647 IDirect3DDeviceImpl_7_GetDirect3D(IDirect3DDevice7
*iface
,
1648 IDirect3D7
**Direct3D7
)
1650 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
1652 TRACE("iface %p, d3d %p.\n", iface
, Direct3D7
);
1655 return DDERR_INVALIDPARAMS
;
1657 *Direct3D7
= &This
->ddraw
->IDirect3D7_iface
;
1658 IDirect3D7_AddRef(*Direct3D7
);
1660 TRACE(" returning interface %p\n", *Direct3D7
);
1664 static HRESULT WINAPI
IDirect3DDeviceImpl_3_GetDirect3D(IDirect3DDevice3
*iface
,
1665 IDirect3D3
**Direct3D3
)
1667 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
1669 TRACE("iface %p, d3d %p.\n", iface
, Direct3D3
);
1672 return DDERR_INVALIDPARAMS
;
1674 IDirect3D3_AddRef(&This
->ddraw
->IDirect3D3_iface
);
1675 *Direct3D3
= &This
->ddraw
->IDirect3D3_iface
;
1676 TRACE(" returning interface %p\n", *Direct3D3
);
1680 static HRESULT WINAPI
IDirect3DDeviceImpl_2_GetDirect3D(IDirect3DDevice2
*iface
,
1681 IDirect3D2
**Direct3D2
)
1683 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
1685 TRACE("iface %p, d3d %p.\n", iface
, Direct3D2
);
1688 return DDERR_INVALIDPARAMS
;
1690 IDirect3D2_AddRef(&This
->ddraw
->IDirect3D2_iface
);
1691 *Direct3D2
= &This
->ddraw
->IDirect3D2_iface
;
1692 TRACE(" returning interface %p\n", *Direct3D2
);
1696 static HRESULT WINAPI
IDirect3DDeviceImpl_1_GetDirect3D(IDirect3DDevice
*iface
,
1697 IDirect3D
**Direct3D
)
1699 IDirect3DDeviceImpl
*This
= device_from_device1(iface
);
1701 TRACE("iface %p, d3d %p.\n", iface
, Direct3D
);
1704 return DDERR_INVALIDPARAMS
;
1706 IDirect3D_AddRef(&This
->ddraw
->IDirect3D_iface
);
1707 *Direct3D
= &This
->ddraw
->IDirect3D_iface
;
1708 TRACE(" returning interface %p\n", *Direct3D
);
1712 /*****************************************************************************
1713 * IDirect3DDevice3::SetCurrentViewport
1715 * Sets a Direct3DViewport as the current viewport.
1716 * For the thunks note that all viewport interface versions are equal
1719 * Direct3DViewport3: The viewport to set
1725 * (Is a NULL viewport valid?)
1727 *****************************************************************************/
1728 static HRESULT WINAPI
1729 IDirect3DDeviceImpl_3_SetCurrentViewport(IDirect3DDevice3
*iface
,
1730 IDirect3DViewport3
*Direct3DViewport3
)
1732 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
1733 IDirect3DViewportImpl
*vp
= (IDirect3DViewportImpl
*)Direct3DViewport3
;
1735 TRACE("iface %p, viewport %p.\n", iface
, Direct3DViewport3
);
1737 EnterCriticalSection(&ddraw_cs
);
1738 /* Do nothing if the specified viewport is the same as the current one */
1739 if (This
->current_viewport
== vp
)
1741 LeaveCriticalSection(&ddraw_cs
);
1745 /* Should check if the viewport was added or not */
1747 /* Release previous viewport and AddRef the new one */
1748 if (This
->current_viewport
)
1750 TRACE("ViewportImpl is at %p, interface is at %p\n", This
->current_viewport
,
1751 (IDirect3DViewport3
*)This
->current_viewport
);
1752 IDirect3DViewport3_Release((IDirect3DViewport3
*)This
->current_viewport
);
1754 IDirect3DViewport3_AddRef(Direct3DViewport3
);
1756 /* Set this viewport as the current viewport */
1757 This
->current_viewport
= vp
;
1759 /* Activate this viewport */
1760 This
->current_viewport
->active_device
= This
;
1761 viewport_activate(This
->current_viewport
, FALSE
);
1763 LeaveCriticalSection(&ddraw_cs
);
1767 static HRESULT WINAPI
IDirect3DDeviceImpl_2_SetCurrentViewport(IDirect3DDevice2
*iface
,
1768 IDirect3DViewport2
*Direct3DViewport2
)
1770 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
1771 IDirect3DViewportImpl
*vp
= (IDirect3DViewportImpl
*)Direct3DViewport2
;
1773 TRACE("iface %p, viewport %p.\n", iface
, Direct3DViewport2
);
1775 return IDirect3DDevice3_SetCurrentViewport((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
,
1776 (IDirect3DViewport3
*)vp
);
1779 /*****************************************************************************
1780 * IDirect3DDevice3::GetCurrentViewport
1782 * Returns the currently active viewport.
1787 * Direct3DViewport3: Address to return the interface pointer at
1791 * DDERR_INVALIDPARAMS if Direct3DViewport == NULL
1793 *****************************************************************************/
1794 static HRESULT WINAPI
1795 IDirect3DDeviceImpl_3_GetCurrentViewport(IDirect3DDevice3
*iface
,
1796 IDirect3DViewport3
**Direct3DViewport3
)
1798 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
1800 TRACE("iface %p, viewport %p.\n", iface
, Direct3DViewport3
);
1802 if(!Direct3DViewport3
)
1803 return DDERR_INVALIDPARAMS
;
1805 EnterCriticalSection(&ddraw_cs
);
1806 *Direct3DViewport3
= (IDirect3DViewport3
*)This
->current_viewport
;
1808 /* AddRef the returned viewport */
1809 if(*Direct3DViewport3
) IDirect3DViewport3_AddRef(*Direct3DViewport3
);
1811 TRACE(" returning interface %p\n", *Direct3DViewport3
);
1813 LeaveCriticalSection(&ddraw_cs
);
1817 static HRESULT WINAPI
IDirect3DDeviceImpl_2_GetCurrentViewport(IDirect3DDevice2
*iface
,
1818 IDirect3DViewport2
**Direct3DViewport2
)
1820 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
1823 TRACE("iface %p, viewport %p.\n", iface
, Direct3DViewport2
);
1825 hr
= IDirect3DDevice3_GetCurrentViewport((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
,
1826 (IDirect3DViewport3
**)Direct3DViewport2
);
1827 if(hr
!= D3D_OK
) return hr
;
1831 /*****************************************************************************
1832 * IDirect3DDevice7::SetRenderTarget
1834 * Sets the render target for the Direct3DDevice.
1835 * For the thunks note that IDirectDrawSurface7 == IDirectDrawSurface4 and
1836 * IDirectDrawSurface3 == IDirectDrawSurface
1838 * Version 2, 3 and 7
1841 * NewTarget: Pointer to an IDirectDrawSurface7 interface to set as the new
1846 * D3D_OK on success, for details see IWineD3DDevice::SetRenderTarget
1848 *****************************************************************************/
1850 IDirect3DDeviceImpl_7_SetRenderTarget(IDirect3DDevice7
*iface
,
1851 IDirectDrawSurface7
*NewTarget
,
1854 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
1855 IDirectDrawSurfaceImpl
*Target
= (IDirectDrawSurfaceImpl
*)NewTarget
;
1858 TRACE("iface %p, target %p, flags %#x.\n", iface
, NewTarget
, Flags
);
1860 EnterCriticalSection(&ddraw_cs
);
1861 /* Flags: Not used */
1863 if(This
->target
== Target
)
1865 TRACE("No-op SetRenderTarget operation, not doing anything\n");
1866 LeaveCriticalSection(&ddraw_cs
);
1870 hr
= IWineD3DDevice_SetRenderTarget(This
->wineD3DDevice
,
1872 Target
? Target
->WineD3DSurface
: NULL
,
1876 LeaveCriticalSection(&ddraw_cs
);
1879 IDirectDrawSurface7_AddRef(NewTarget
);
1880 IDirectDrawSurface7_Release((IDirectDrawSurface7
*)This
->target
);
1881 This
->target
= Target
;
1882 IDirect3DDeviceImpl_UpdateDepthStencil(This
);
1883 LeaveCriticalSection(&ddraw_cs
);
1887 static HRESULT WINAPI
1888 IDirect3DDeviceImpl_7_SetRenderTarget_FPUSetup(IDirect3DDevice7
*iface
,
1889 IDirectDrawSurface7
*NewTarget
,
1892 return IDirect3DDeviceImpl_7_SetRenderTarget(iface
, NewTarget
, Flags
);
1895 static HRESULT WINAPI
1896 IDirect3DDeviceImpl_7_SetRenderTarget_FPUPreserve(IDirect3DDevice7
*iface
,
1897 IDirectDrawSurface7
*NewTarget
,
1903 old_fpucw
= d3d_fpu_setup();
1904 hr
= IDirect3DDeviceImpl_7_SetRenderTarget(iface
, NewTarget
, Flags
);
1905 set_fpu_control_word(old_fpucw
);
1910 static HRESULT WINAPI
IDirect3DDeviceImpl_3_SetRenderTarget(IDirect3DDevice3
*iface
,
1911 IDirectDrawSurface4
*NewRenderTarget
, DWORD Flags
)
1913 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
1914 IDirectDrawSurfaceImpl
*Target
= (IDirectDrawSurfaceImpl
*)NewRenderTarget
;
1916 TRACE("iface %p, target %p, flags %#x.\n", iface
, NewRenderTarget
, Flags
);
1918 return IDirect3DDevice7_SetRenderTarget((IDirect3DDevice7
*)This
, (IDirectDrawSurface7
*)Target
, Flags
);
1921 static HRESULT WINAPI
IDirect3DDeviceImpl_2_SetRenderTarget(IDirect3DDevice2
*iface
,
1922 IDirectDrawSurface
*NewRenderTarget
, DWORD Flags
)
1924 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
1925 IDirectDrawSurfaceImpl
*Target
= (IDirectDrawSurfaceImpl
*)NewRenderTarget
;
1927 TRACE("iface %p, target %p, flags %#x.\n", iface
, NewRenderTarget
, Flags
);
1929 return IDirect3DDevice7_SetRenderTarget((IDirect3DDevice7
*)This
, (IDirectDrawSurface7
*)Target
, Flags
);
1932 /*****************************************************************************
1933 * IDirect3DDevice7::GetRenderTarget
1935 * Returns the current render target.
1936 * This is handled locally, because the WineD3D render target's parent
1939 * Version 2, 3 and 7
1942 * RenderTarget: Address to store the surface interface pointer
1946 * DDERR_INVALIDPARAMS if RenderTarget == NULL
1948 *****************************************************************************/
1949 static HRESULT WINAPI
1950 IDirect3DDeviceImpl_7_GetRenderTarget(IDirect3DDevice7
*iface
,
1951 IDirectDrawSurface7
**RenderTarget
)
1953 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
1955 TRACE("iface %p, target %p.\n", iface
, RenderTarget
);
1958 return DDERR_INVALIDPARAMS
;
1960 EnterCriticalSection(&ddraw_cs
);
1961 *RenderTarget
= (IDirectDrawSurface7
*)This
->target
;
1962 IDirectDrawSurface7_AddRef(*RenderTarget
);
1964 LeaveCriticalSection(&ddraw_cs
);
1968 static HRESULT WINAPI
IDirect3DDeviceImpl_3_GetRenderTarget(IDirect3DDevice3
*iface
,
1969 IDirectDrawSurface4
**RenderTarget
)
1971 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
1974 TRACE("iface %p, target %p.\n", iface
, RenderTarget
);
1976 hr
= IDirect3DDevice7_GetRenderTarget((IDirect3DDevice7
*)This
, (IDirectDrawSurface7
**)RenderTarget
);
1977 if(hr
!= D3D_OK
) return hr
;
1981 static HRESULT WINAPI
IDirect3DDeviceImpl_2_GetRenderTarget(IDirect3DDevice2
*iface
,
1982 IDirectDrawSurface
**RenderTarget
)
1984 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
1987 TRACE("iface %p, target %p.\n", iface
, RenderTarget
);
1989 hr
= IDirect3DDevice7_GetRenderTarget((IDirect3DDevice7
*)This
, (IDirectDrawSurface7
**)RenderTarget
);
1990 if(hr
!= D3D_OK
) return hr
;
1991 *RenderTarget
= *RenderTarget
?
1992 (IDirectDrawSurface
*)&((IDirectDrawSurfaceImpl
*)*RenderTarget
)->IDirectDrawSurface3_vtbl
: NULL
;
1996 /*****************************************************************************
1997 * IDirect3DDevice3::Begin
1999 * Begins a description block of vertices. This is similar to glBegin()
2000 * and glEnd(). After a call to IDirect3DDevice3::End, the vertices
2001 * described with IDirect3DDevice::Vertex are drawn.
2006 * PrimitiveType: The type of primitives to draw
2007 * VertexTypeDesc: A flexible vertex format description of the vertices
2008 * Flags: Some flags..
2013 *****************************************************************************/
2014 static HRESULT WINAPI
2015 IDirect3DDeviceImpl_3_Begin(IDirect3DDevice3
*iface
,
2016 D3DPRIMITIVETYPE PrimitiveType
,
2017 DWORD VertexTypeDesc
,
2020 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
2022 TRACE("iface %p, primitive_type %#x, FVF %#x, flags %#x.\n",
2023 iface
, PrimitiveType
, VertexTypeDesc
, Flags
);
2025 EnterCriticalSection(&ddraw_cs
);
2026 This
->primitive_type
= PrimitiveType
;
2027 This
->vertex_type
= VertexTypeDesc
;
2028 This
->render_flags
= Flags
;
2029 This
->vertex_size
= get_flexible_vertex_size(This
->vertex_type
);
2030 This
->nb_vertices
= 0;
2031 LeaveCriticalSection(&ddraw_cs
);
2036 static HRESULT WINAPI
IDirect3DDeviceImpl_2_Begin(IDirect3DDevice2
*iface
, D3DPRIMITIVETYPE d3dpt
,
2037 D3DVERTEXTYPE dwVertexTypeDesc
, DWORD dwFlags
)
2040 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
2042 TRACE("iface %p, primitive_type %#x, vertex_type %#x, flags %#x.\n",
2043 iface
, d3dpt
, dwVertexTypeDesc
, dwFlags
);
2045 switch(dwVertexTypeDesc
)
2047 case D3DVT_VERTEX
: FVF
= D3DFVF_VERTEX
; break;
2048 case D3DVT_LVERTEX
: FVF
= D3DFVF_LVERTEX
; break;
2049 case D3DVT_TLVERTEX
: FVF
= D3DFVF_TLVERTEX
; break;
2051 ERR("Unexpected vertex type %d\n", dwVertexTypeDesc
);
2052 return DDERR_INVALIDPARAMS
; /* Should never happen */
2055 return IDirect3DDevice3_Begin((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
, d3dpt
, FVF
, dwFlags
);
2058 /*****************************************************************************
2059 * IDirect3DDevice3::BeginIndexed
2061 * Draws primitives based on vertices in a vertex array which are specified
2067 * PrimitiveType: Primitive type to draw
2068 * VertexType: A FVF description of the vertex format
2069 * Vertices: pointer to an array containing the vertices
2070 * NumVertices: The number of vertices in the vertex array
2071 * Flags: Some flags ...
2074 * D3D_OK, because it's a stub
2076 *****************************************************************************/
2077 static HRESULT WINAPI
2078 IDirect3DDeviceImpl_3_BeginIndexed(IDirect3DDevice3
*iface
,
2079 D3DPRIMITIVETYPE PrimitiveType
,
2085 FIXME("iface %p, primitive_type %#x, FVF %#x, vertices %p, vertex_count %u, flags %#x stub!\n",
2086 iface
, PrimitiveType
, VertexType
, Vertices
, NumVertices
, Flags
);
2092 static HRESULT WINAPI
IDirect3DDeviceImpl_2_BeginIndexed(IDirect3DDevice2
*iface
,
2093 D3DPRIMITIVETYPE d3dptPrimitiveType
, D3DVERTEXTYPE d3dvtVertexType
,
2094 void *lpvVertices
, DWORD dwNumVertices
, DWORD dwFlags
)
2097 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
2099 TRACE("iface %p, primitive_type %#x, vertex_type %#x, vertices %p, vertex_count %u, flags %#x stub!\n",
2100 iface
, d3dptPrimitiveType
, d3dvtVertexType
, lpvVertices
, dwNumVertices
, dwFlags
);
2102 switch(d3dvtVertexType
)
2104 case D3DVT_VERTEX
: FVF
= D3DFVF_VERTEX
; break;
2105 case D3DVT_LVERTEX
: FVF
= D3DFVF_LVERTEX
; break;
2106 case D3DVT_TLVERTEX
: FVF
= D3DFVF_TLVERTEX
; break;
2108 ERR("Unexpected vertex type %d\n", d3dvtVertexType
);
2109 return DDERR_INVALIDPARAMS
; /* Should never happen */
2112 return IDirect3DDevice3_BeginIndexed((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
,
2113 d3dptPrimitiveType
, FVF
, lpvVertices
, dwNumVertices
, dwFlags
);
2116 /*****************************************************************************
2117 * IDirect3DDevice3::Vertex
2119 * Draws a vertex as described by IDirect3DDevice3::Begin. It places all
2120 * drawn vertices in a vertex buffer. If the buffer is too small, its
2121 * size is increased.
2126 * Vertex: Pointer to the vertex
2129 * D3D_OK, on success
2130 * DDERR_INVALIDPARAMS if Vertex is NULL
2132 *****************************************************************************/
2133 static HRESULT WINAPI
2134 IDirect3DDeviceImpl_3_Vertex(IDirect3DDevice3
*iface
,
2137 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
2139 TRACE("iface %p, vertex %p.\n", iface
, Vertex
);
2142 return DDERR_INVALIDPARAMS
;
2144 EnterCriticalSection(&ddraw_cs
);
2145 if ((This
->nb_vertices
+1)*This
->vertex_size
> This
->buffer_size
)
2148 This
->buffer_size
= This
->buffer_size
? This
->buffer_size
* 2 : This
->vertex_size
* 3;
2149 old_buffer
= This
->vertex_buffer
;
2150 This
->vertex_buffer
= HeapAlloc(GetProcessHeap(), 0, This
->buffer_size
);
2153 CopyMemory(This
->vertex_buffer
, old_buffer
, This
->nb_vertices
* This
->vertex_size
);
2154 HeapFree(GetProcessHeap(), 0, old_buffer
);
2158 CopyMemory(This
->vertex_buffer
+ This
->nb_vertices
++ * This
->vertex_size
, Vertex
, This
->vertex_size
);
2160 LeaveCriticalSection(&ddraw_cs
);
2164 static HRESULT WINAPI
IDirect3DDeviceImpl_2_Vertex(IDirect3DDevice2
*iface
, void *lpVertexType
)
2166 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
2168 TRACE("iface %p, vertex %p.\n", iface
, lpVertexType
);
2170 return IDirect3DDevice3_Vertex((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
, lpVertexType
);
2173 /*****************************************************************************
2174 * IDirect3DDevice3::Index
2176 * Specifies an index to a vertex to be drawn. The vertex array has to
2177 * be specified with BeginIndexed first.
2180 * VertexIndex: The index of the vertex to draw
2183 * D3D_OK because it's a stub
2185 *****************************************************************************/
2186 static HRESULT WINAPI
2187 IDirect3DDeviceImpl_3_Index(IDirect3DDevice3
*iface
,
2190 FIXME("iface %p, index %#x stub!\n", iface
, VertexIndex
);
2195 static HRESULT WINAPI
IDirect3DDeviceImpl_2_Index(IDirect3DDevice2
*iface
, WORD wVertexIndex
)
2197 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
2199 TRACE("iface %p, index %#x.\n", iface
, wVertexIndex
);
2201 return IDirect3DDevice3_Index((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
, wVertexIndex
);
2204 /*****************************************************************************
2205 * IDirect3DDevice3::End
2207 * Ends a draw begun with IDirect3DDevice3::Begin or
2208 * IDirect3DDevice::BeginIndexed. The vertices specified with
2209 * IDirect3DDevice::Vertex or IDirect3DDevice::Index are drawn using
2210 * the IDirect3DDevice7::DrawPrimitive method. So far only
2211 * non-indexed mode is supported
2216 * Flags: Some flags, as usual. Don't know which are defined
2219 * The return value of IDirect3DDevice7::DrawPrimitive
2221 *****************************************************************************/
2222 static HRESULT WINAPI
2223 IDirect3DDeviceImpl_3_End(IDirect3DDevice3
*iface
,
2226 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
2228 TRACE("iface %p, flags %#x.\n", iface
, Flags
);
2230 return IDirect3DDevice7_DrawPrimitive((IDirect3DDevice7
*)This
, This
->primitive_type
,
2231 This
->vertex_type
, This
->vertex_buffer
, This
->nb_vertices
, This
->render_flags
);
2234 static HRESULT WINAPI
IDirect3DDeviceImpl_2_End(IDirect3DDevice2
*iface
, DWORD dwFlags
)
2236 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
2238 TRACE("iface %p, flags %#x.\n", iface
, dwFlags
);
2240 return IDirect3DDevice3_End((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
, dwFlags
);
2243 /*****************************************************************************
2244 * IDirect3DDevice7::GetRenderState
2246 * Returns the value of a render state. The possible render states are
2247 * defined in include/d3dtypes.h
2249 * Version 2, 3 and 7
2252 * RenderStateType: Render state to return the current setting of
2253 * Value: Address to store the value at
2256 * D3D_OK on success, for details see IWineD3DDevice::GetRenderState
2257 * DDERR_INVALIDPARAMS if Value == NULL
2259 *****************************************************************************/
2261 IDirect3DDeviceImpl_7_GetRenderState(IDirect3DDevice7
*iface
,
2262 D3DRENDERSTATETYPE RenderStateType
,
2265 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
2268 TRACE("iface %p, state %#x, value %p.\n", iface
, RenderStateType
, Value
);
2271 return DDERR_INVALIDPARAMS
;
2273 EnterCriticalSection(&ddraw_cs
);
2274 switch(RenderStateType
)
2276 case D3DRENDERSTATE_TEXTUREMAG
:
2278 WINED3DTEXTUREFILTERTYPE tex_mag
;
2280 hr
= IWineD3DDevice_GetSamplerState(This
->wineD3DDevice
,
2281 0, WINED3DSAMP_MAGFILTER
,
2286 case WINED3DTEXF_POINT
:
2287 *Value
= D3DFILTER_NEAREST
;
2289 case WINED3DTEXF_LINEAR
:
2290 *Value
= D3DFILTER_LINEAR
;
2293 ERR("Unhandled texture mag %d !\n",tex_mag
);
2299 case D3DRENDERSTATE_TEXTUREMIN
:
2301 WINED3DTEXTUREFILTERTYPE tex_min
;
2302 WINED3DTEXTUREFILTERTYPE tex_mip
;
2304 hr
= IWineD3DDevice_GetSamplerState(This
->wineD3DDevice
,
2305 0, WINED3DSAMP_MINFILTER
, &tex_min
);
2308 LeaveCriticalSection(&ddraw_cs
);
2311 hr
= IWineD3DDevice_GetSamplerState(This
->wineD3DDevice
,
2312 0, WINED3DSAMP_MIPFILTER
, &tex_mip
);
2316 case WINED3DTEXF_POINT
:
2319 case WINED3DTEXF_NONE
:
2320 *Value
= D3DFILTER_NEAREST
;
2322 case WINED3DTEXF_POINT
:
2323 *Value
= D3DFILTER_MIPNEAREST
;
2325 case WINED3DTEXF_LINEAR
:
2326 *Value
= D3DFILTER_LINEARMIPNEAREST
;
2329 ERR("Unhandled mip filter %#x.\n", tex_mip
);
2330 *Value
= D3DFILTER_NEAREST
;
2334 case WINED3DTEXF_LINEAR
:
2337 case WINED3DTEXF_NONE
:
2338 *Value
= D3DFILTER_LINEAR
;
2340 case WINED3DTEXF_POINT
:
2341 *Value
= D3DFILTER_MIPLINEAR
;
2343 case WINED3DTEXF_LINEAR
:
2344 *Value
= D3DFILTER_LINEARMIPLINEAR
;
2347 ERR("Unhandled mip filter %#x.\n", tex_mip
);
2348 *Value
= D3DFILTER_LINEAR
;
2353 ERR("Unhandled texture min filter %#x.\n",tex_min
);
2354 *Value
= D3DFILTER_NEAREST
;
2360 case D3DRENDERSTATE_TEXTUREADDRESS
:
2361 case D3DRENDERSTATE_TEXTUREADDRESSU
:
2362 hr
= IWineD3DDevice_GetSamplerState(This
->wineD3DDevice
,
2363 0, WINED3DSAMP_ADDRESSU
,
2366 case D3DRENDERSTATE_TEXTUREADDRESSV
:
2367 hr
= IWineD3DDevice_GetSamplerState(This
->wineD3DDevice
,
2368 0, WINED3DSAMP_ADDRESSV
,
2372 case D3DRENDERSTATE_BORDERCOLOR
:
2373 FIXME("Unhandled render state D3DRENDERSTATE_BORDERCOLOR.\n");
2377 case D3DRENDERSTATE_TEXTUREHANDLE
:
2378 case D3DRENDERSTATE_TEXTUREMAPBLEND
:
2379 WARN("Render state %#x is invalid in d3d7.\n", RenderStateType
);
2380 hr
= DDERR_INVALIDPARAMS
;
2384 if (RenderStateType
>= D3DRENDERSTATE_STIPPLEPATTERN00
2385 && RenderStateType
<= D3DRENDERSTATE_STIPPLEPATTERN31
)
2387 FIXME("Unhandled stipple pattern render state (%#x).\n",
2392 hr
= IWineD3DDevice_GetRenderState(This
->wineD3DDevice
,
2396 LeaveCriticalSection(&ddraw_cs
);
2400 static HRESULT WINAPI
2401 IDirect3DDeviceImpl_7_GetRenderState_FPUSetup(IDirect3DDevice7
*iface
,
2402 D3DRENDERSTATETYPE RenderStateType
,
2405 return IDirect3DDeviceImpl_7_GetRenderState(iface
, RenderStateType
, Value
);
2408 static HRESULT WINAPI
2409 IDirect3DDeviceImpl_7_GetRenderState_FPUPreserve(IDirect3DDevice7
*iface
,
2410 D3DRENDERSTATETYPE RenderStateType
,
2416 old_fpucw
= d3d_fpu_setup();
2417 hr
= IDirect3DDeviceImpl_7_GetRenderState(iface
, RenderStateType
, Value
);
2418 set_fpu_control_word(old_fpucw
);
2423 static HRESULT WINAPI
2424 IDirect3DDeviceImpl_3_GetRenderState(IDirect3DDevice3
*iface
,
2425 D3DRENDERSTATETYPE dwRenderStateType
,
2426 DWORD
*lpdwRenderState
)
2428 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
2431 TRACE("iface %p, state %#x, value %p.\n", iface
, dwRenderStateType
, lpdwRenderState
);
2433 switch(dwRenderStateType
)
2435 case D3DRENDERSTATE_TEXTUREHANDLE
:
2437 /* This state is wrapped to SetTexture in SetRenderState, so
2438 * it has to be wrapped to GetTexture here. */
2439 struct wined3d_texture
*tex
= NULL
;
2440 *lpdwRenderState
= 0;
2442 EnterCriticalSection(&ddraw_cs
);
2444 hr
= IWineD3DDevice_GetTexture(This
->wineD3DDevice
, 0, &tex
);
2445 if (SUCCEEDED(hr
) && tex
)
2447 /* The parent of the texture is the IDirectDrawSurface7
2448 * interface of the ddraw surface. */
2449 IDirectDrawSurfaceImpl
*parent
= wined3d_texture_get_parent(tex
);
2450 if (parent
) *lpdwRenderState
= parent
->Handle
;
2451 wined3d_texture_decref(tex
);
2454 LeaveCriticalSection(&ddraw_cs
);
2459 case D3DRENDERSTATE_TEXTUREMAPBLEND
:
2461 /* D3DRENDERSTATE_TEXTUREMAPBLEND is mapped to texture state stages in SetRenderState; reverse
2462 the mapping to get the value. */
2463 DWORD colorop
, colorarg1
, colorarg2
;
2464 DWORD alphaop
, alphaarg1
, alphaarg2
;
2466 EnterCriticalSection(&ddraw_cs
);
2468 This
->legacyTextureBlending
= TRUE
;
2470 IWineD3DDevice_GetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_COLOROP
, &colorop
);
2471 IWineD3DDevice_GetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_COLORARG1
, &colorarg1
);
2472 IWineD3DDevice_GetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_COLORARG2
, &colorarg2
);
2473 IWineD3DDevice_GetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAOP
, &alphaop
);
2474 IWineD3DDevice_GetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAARG1
, &alphaarg1
);
2475 IWineD3DDevice_GetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAARG2
, &alphaarg2
);
2477 if (colorop
== WINED3DTOP_SELECTARG1
&& colorarg1
== WINED3DTA_TEXTURE
&&
2478 alphaop
== WINED3DTOP_SELECTARG1
&& alphaarg1
== WINED3DTA_TEXTURE
)
2480 *lpdwRenderState
= D3DTBLEND_DECAL
;
2482 else if (colorop
== WINED3DTOP_SELECTARG1
&& colorarg1
== WINED3DTA_TEXTURE
&&
2483 alphaop
== WINED3DTOP_MODULATE
&& alphaarg1
== WINED3DTA_TEXTURE
&& alphaarg2
== WINED3DTA_CURRENT
)
2485 *lpdwRenderState
= D3DTBLEND_DECALALPHA
;
2487 else if (colorop
== WINED3DTOP_MODULATE
&& colorarg1
== WINED3DTA_TEXTURE
&& colorarg2
== WINED3DTA_CURRENT
&&
2488 alphaop
== WINED3DTOP_MODULATE
&& alphaarg1
== WINED3DTA_TEXTURE
&& alphaarg2
== WINED3DTA_CURRENT
)
2490 *lpdwRenderState
= D3DTBLEND_MODULATEALPHA
;
2494 struct wined3d_texture
*tex
= NULL
;
2496 BOOL tex_alpha
= FALSE
;
2497 DDPIXELFORMAT ddfmt
;
2499 hr
= IWineD3DDevice_GetTexture(This
->wineD3DDevice
, 0, &tex
);
2501 if(hr
== WINED3D_OK
&& tex
)
2503 struct wined3d_resource
*sub_resource
;
2505 if ((sub_resource
= wined3d_texture_get_sub_resource(tex
, 0)))
2507 struct wined3d_resource_desc desc
;
2509 wined3d_resource_get_desc(sub_resource
, &desc
);
2510 ddfmt
.dwSize
= sizeof(ddfmt
);
2511 PixelFormat_WineD3DtoDD(&ddfmt
, desc
.format
);
2512 if (ddfmt
.u5
.dwRGBAlphaBitMask
) tex_alpha
= TRUE
;
2515 wined3d_texture_decref(tex
);
2518 if (!(colorop
== WINED3DTOP_MODULATE
&& colorarg1
== WINED3DTA_TEXTURE
&& colorarg2
== WINED3DTA_CURRENT
&&
2519 alphaop
== (tex_alpha
? WINED3DTOP_SELECTARG1
: WINED3DTOP_SELECTARG2
) &&
2520 alphaarg1
== WINED3DTA_TEXTURE
&& alphaarg2
== WINED3DTA_CURRENT
))
2522 ERR("Unexpected texture stage state setup, returning D3DTBLEND_MODULATE - likely erroneous\n");
2525 *lpdwRenderState
= D3DTBLEND_MODULATE
;
2528 LeaveCriticalSection(&ddraw_cs
);
2534 return IDirect3DDevice7_GetRenderState((IDirect3DDevice7
*)This
, dwRenderStateType
, lpdwRenderState
);
2538 static HRESULT WINAPI
IDirect3DDeviceImpl_2_GetRenderState(IDirect3DDevice2
*iface
,
2539 D3DRENDERSTATETYPE dwRenderStateType
, DWORD
*lpdwRenderState
)
2541 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
2543 TRACE("iface %p, state %#x, value %p.\n", iface
, dwRenderStateType
, lpdwRenderState
);
2545 return IDirect3DDevice3_GetRenderState((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
,
2546 dwRenderStateType
, lpdwRenderState
);
2549 /*****************************************************************************
2550 * IDirect3DDevice7::SetRenderState
2552 * Sets a render state. The possible render states are defined in
2553 * include/d3dtypes.h
2555 * Version 2, 3 and 7
2558 * RenderStateType: State to set
2559 * Value: Value to assign to that state
2562 * D3D_OK on success,
2563 * for details see IWineD3DDevice::SetRenderState
2565 *****************************************************************************/
2567 IDirect3DDeviceImpl_7_SetRenderState(IDirect3DDevice7
*iface
,
2568 D3DRENDERSTATETYPE RenderStateType
,
2571 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
2574 TRACE("iface %p, state %#x, value %#x.\n", iface
, RenderStateType
, Value
);
2576 EnterCriticalSection(&ddraw_cs
);
2577 /* Some render states need special care */
2578 switch(RenderStateType
)
2581 * The ddraw texture filter mapping works like this:
2582 * D3DFILTER_NEAREST Point min/mag, no mip
2583 * D3DFILTER_MIPNEAREST Point min/mag, point mip
2584 * D3DFILTER_LINEARMIPNEAREST: Point min/mag, linear mip
2586 * D3DFILTER_LINEAR Linear min/mag, no mip
2587 * D3DFILTER_MIPLINEAR Linear min/mag, point mip
2588 * D3DFILTER_LINEARMIPLINEAR Linear min/mag, linear mip
2590 * This is the opposite of the GL naming convention,
2591 * D3DFILTER_LINEARMIPNEAREST corresponds to GL_NEAREST_MIPMAP_LINEAR.
2593 case D3DRENDERSTATE_TEXTUREMAG
:
2595 WINED3DTEXTUREFILTERTYPE tex_mag
;
2599 case D3DFILTER_NEAREST
:
2600 case D3DFILTER_MIPNEAREST
:
2601 case D3DFILTER_LINEARMIPNEAREST
:
2602 tex_mag
= WINED3DTEXF_POINT
;
2604 case D3DFILTER_LINEAR
:
2605 case D3DFILTER_MIPLINEAR
:
2606 case D3DFILTER_LINEARMIPLINEAR
:
2607 tex_mag
= WINED3DTEXF_LINEAR
;
2610 tex_mag
= WINED3DTEXF_POINT
;
2611 ERR("Unhandled texture mag %d !\n",Value
);
2615 hr
= IWineD3DDevice_SetSamplerState(This
->wineD3DDevice
,
2616 0, WINED3DSAMP_MAGFILTER
,
2621 case D3DRENDERSTATE_TEXTUREMIN
:
2623 WINED3DTEXTUREFILTERTYPE tex_min
;
2624 WINED3DTEXTUREFILTERTYPE tex_mip
;
2626 switch ((D3DTEXTUREFILTER
) Value
)
2628 case D3DFILTER_NEAREST
:
2629 tex_min
= WINED3DTEXF_POINT
;
2630 tex_mip
= WINED3DTEXF_NONE
;
2632 case D3DFILTER_LINEAR
:
2633 tex_min
= WINED3DTEXF_LINEAR
;
2634 tex_mip
= WINED3DTEXF_NONE
;
2636 case D3DFILTER_MIPNEAREST
:
2637 tex_min
= WINED3DTEXF_POINT
;
2638 tex_mip
= WINED3DTEXF_POINT
;
2640 case D3DFILTER_MIPLINEAR
:
2641 tex_min
= WINED3DTEXF_LINEAR
;
2642 tex_mip
= WINED3DTEXF_POINT
;
2644 case D3DFILTER_LINEARMIPNEAREST
:
2645 tex_min
= WINED3DTEXF_POINT
;
2646 tex_mip
= WINED3DTEXF_LINEAR
;
2648 case D3DFILTER_LINEARMIPLINEAR
:
2649 tex_min
= WINED3DTEXF_LINEAR
;
2650 tex_mip
= WINED3DTEXF_LINEAR
;
2654 ERR("Unhandled texture min %d !\n",Value
);
2655 tex_min
= WINED3DTEXF_POINT
;
2656 tex_mip
= WINED3DTEXF_NONE
;
2660 IWineD3DDevice_SetSamplerState(This
->wineD3DDevice
,
2661 0, WINED3DSAMP_MIPFILTER
, tex_mip
);
2662 hr
= IWineD3DDevice_SetSamplerState(This
->wineD3DDevice
,
2663 0, WINED3DSAMP_MINFILTER
,
2668 case D3DRENDERSTATE_TEXTUREADDRESS
:
2669 IWineD3DDevice_SetSamplerState(This
->wineD3DDevice
,
2670 0, WINED3DSAMP_ADDRESSV
,
2673 case D3DRENDERSTATE_TEXTUREADDRESSU
:
2674 hr
= IWineD3DDevice_SetSamplerState(This
->wineD3DDevice
,
2675 0, WINED3DSAMP_ADDRESSU
,
2678 case D3DRENDERSTATE_TEXTUREADDRESSV
:
2679 hr
= IWineD3DDevice_SetSamplerState(This
->wineD3DDevice
,
2680 0, WINED3DSAMP_ADDRESSV
,
2684 case D3DRENDERSTATE_BORDERCOLOR
:
2685 /* This should probably just forward to the corresponding sampler
2686 * state. Needs tests. */
2687 FIXME("Unhandled render state D3DRENDERSTATE_BORDERCOLOR.\n");
2691 case D3DRENDERSTATE_TEXTUREHANDLE
:
2692 case D3DRENDERSTATE_TEXTUREMAPBLEND
:
2693 WARN("Render state %#x is invalid in d3d7.\n", RenderStateType
);
2694 hr
= DDERR_INVALIDPARAMS
;
2698 if (RenderStateType
>= D3DRENDERSTATE_STIPPLEPATTERN00
2699 && RenderStateType
<= D3DRENDERSTATE_STIPPLEPATTERN31
)
2701 FIXME("Unhandled stipple pattern render state (%#x).\n",
2707 hr
= IWineD3DDevice_SetRenderState(This
->wineD3DDevice
,
2712 LeaveCriticalSection(&ddraw_cs
);
2716 static HRESULT WINAPI
2717 IDirect3DDeviceImpl_7_SetRenderState_FPUSetup(IDirect3DDevice7
*iface
,
2718 D3DRENDERSTATETYPE RenderStateType
,
2721 return IDirect3DDeviceImpl_7_SetRenderState(iface
, RenderStateType
, Value
);
2724 static HRESULT WINAPI
2725 IDirect3DDeviceImpl_7_SetRenderState_FPUPreserve(IDirect3DDevice7
*iface
,
2726 D3DRENDERSTATETYPE RenderStateType
,
2732 old_fpucw
= d3d_fpu_setup();
2733 hr
= IDirect3DDeviceImpl_7_SetRenderState(iface
, RenderStateType
, Value
);
2734 set_fpu_control_word(old_fpucw
);
2739 static HRESULT WINAPI
2740 IDirect3DDeviceImpl_3_SetRenderState(IDirect3DDevice3
*iface
,
2741 D3DRENDERSTATETYPE RenderStateType
,
2744 /* Note about D3DRENDERSTATE_TEXTUREMAPBLEND implementation: most of values
2745 for this state can be directly mapped to texture stage colorop and alphaop, but
2746 D3DTBLEND_MODULATE is tricky: it uses alpha from texture when available and alpha
2747 from diffuse otherwise. So changing the texture must be monitored in SetTexture to modify
2748 alphaarg when needed.
2750 Aliens vs Predator 1 depends on accurate D3DTBLEND_MODULATE emulation
2752 Legacy texture blending (TEXTUREMAPBLEND) and texture stage states: directx6 docs state that
2753 TEXTUREMAPBLEND is deprecated, yet can still be used. Games must not use both or results
2754 are undefined. D3DTBLEND_MODULATE mode in particular is dependent on texture pixel format and
2755 requires fixup of stage 0 texture states when texture changes, but this fixup can interfere
2756 with games not using this deprecated state. So a flag 'legacyTextureBlending' has to be kept
2757 in device - TRUE if the app is using TEXTUREMAPBLEND.
2759 Tests show that setting TEXTUREMAPBLEND on native doesn't seem to change values returned by
2760 GetTextureStageState and vice versa. Not so on Wine, but it is 'undefined' anyway so, probably, ok,
2761 unless some broken game will be found that cares. */
2764 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
2766 TRACE("iface %p, state %#x, value %#x.\n", iface
, RenderStateType
, Value
);
2768 EnterCriticalSection(&ddraw_cs
);
2770 switch(RenderStateType
)
2772 case D3DRENDERSTATE_TEXTUREHANDLE
:
2774 IDirectDrawSurfaceImpl
*surf
;
2778 hr
= IWineD3DDevice_SetTexture(This
->wineD3DDevice
,
2784 surf
= ddraw_get_object(&This
->handle_table
, Value
- 1, DDRAW_HANDLE_SURFACE
);
2787 WARN("Invalid texture handle.\n");
2788 hr
= DDERR_INVALIDPARAMS
;
2792 hr
= IDirect3DDevice3_SetTexture(iface
, 0, (IDirect3DTexture2
*)&surf
->IDirect3DTexture2_vtbl
);
2796 case D3DRENDERSTATE_TEXTUREMAPBLEND
:
2798 This
->legacyTextureBlending
= TRUE
;
2800 switch ( (D3DTEXTUREBLEND
) Value
)
2802 case D3DTBLEND_MODULATE
:
2804 struct wined3d_texture
*tex
= NULL
;
2805 BOOL tex_alpha
= FALSE
;
2806 DDPIXELFORMAT ddfmt
;
2808 hr
= IWineD3DDevice_GetTexture(This
->wineD3DDevice
, 0, &tex
);
2810 if(hr
== WINED3D_OK
&& tex
)
2812 struct wined3d_resource
*sub_resource
;
2814 if ((sub_resource
= wined3d_texture_get_sub_resource(tex
, 0)))
2816 struct wined3d_resource_desc desc
;
2818 wined3d_resource_get_desc(sub_resource
, &desc
);
2819 ddfmt
.dwSize
= sizeof(ddfmt
);
2820 PixelFormat_WineD3DtoDD(&ddfmt
, desc
.format
);
2821 if (ddfmt
.u5
.dwRGBAlphaBitMask
) tex_alpha
= TRUE
;
2824 wined3d_texture_decref(tex
);
2828 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAOP
, WINED3DTOP_SELECTARG1
);
2830 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAOP
, WINED3DTOP_SELECTARG2
);
2831 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAARG1
, WINED3DTA_TEXTURE
);
2832 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAARG2
, WINED3DTA_CURRENT
);
2833 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_COLORARG1
, WINED3DTA_TEXTURE
);
2834 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_COLORARG2
, WINED3DTA_CURRENT
);
2835 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_COLOROP
, WINED3DTOP_MODULATE
);
2841 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_COLOROP
, WINED3DTOP_ADD
);
2842 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_COLORARG1
, WINED3DTA_TEXTURE
);
2843 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_COLORARG2
, WINED3DTA_CURRENT
);
2844 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAOP
, WINED3DTOP_SELECTARG2
);
2845 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAARG2
, WINED3DTA_CURRENT
);
2848 case D3DTBLEND_MODULATEALPHA
:
2849 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_COLORARG1
, WINED3DTA_TEXTURE
);
2850 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAARG1
, WINED3DTA_TEXTURE
);
2851 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_COLORARG2
, WINED3DTA_CURRENT
);
2852 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAARG2
, WINED3DTA_CURRENT
);
2853 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_COLOROP
, WINED3DTOP_MODULATE
);
2854 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAOP
, WINED3DTOP_MODULATE
);
2857 case D3DTBLEND_COPY
:
2858 case D3DTBLEND_DECAL
:
2859 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_COLORARG1
, WINED3DTA_TEXTURE
);
2860 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAARG1
, WINED3DTA_TEXTURE
);
2861 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_COLOROP
, WINED3DTOP_SELECTARG1
);
2862 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAOP
, WINED3DTOP_SELECTARG1
);
2865 case D3DTBLEND_DECALALPHA
:
2866 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_COLOROP
, WINED3DTOP_BLENDTEXTUREALPHA
);
2867 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_COLORARG1
, WINED3DTA_TEXTURE
);
2868 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_COLORARG2
, WINED3DTA_CURRENT
);
2869 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAOP
, WINED3DTOP_SELECTARG2
);
2870 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAARG2
, WINED3DTA_CURRENT
);
2874 ERR("Unhandled texture environment %d !\n",Value
);
2882 hr
= IDirect3DDevice7_SetRenderState((IDirect3DDevice7
*)This
, RenderStateType
, Value
);
2886 LeaveCriticalSection(&ddraw_cs
);
2891 static HRESULT WINAPI
IDirect3DDeviceImpl_2_SetRenderState(IDirect3DDevice2
*iface
,
2892 D3DRENDERSTATETYPE RenderStateType
, DWORD Value
)
2894 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
2896 TRACE("iface %p, state %#x, value %#x.\n", iface
, RenderStateType
, Value
);
2898 return IDirect3DDevice3_SetRenderState((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
, RenderStateType
, Value
);
2901 /*****************************************************************************
2902 * Direct3DDevice3::SetLightState
2904 * Sets a light state for Direct3DDevice3 and Direct3DDevice2. The
2905 * light states are forwarded to Direct3DDevice7 render states
2910 * LightStateType: The light state to change
2911 * Value: The value to assign to that light state
2915 * DDERR_INVALIDPARAMS if the parameters were incorrect
2916 * Also check IDirect3DDevice7::SetRenderState
2918 *****************************************************************************/
2919 static HRESULT WINAPI
2920 IDirect3DDeviceImpl_3_SetLightState(IDirect3DDevice3
*iface
,
2921 D3DLIGHTSTATETYPE LightStateType
,
2924 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
2927 TRACE("iface %p, state %#x, value %#x.\n", iface
, LightStateType
, Value
);
2929 if (!LightStateType
|| (LightStateType
> D3DLIGHTSTATE_COLORVERTEX
))
2931 TRACE("Unexpected Light State Type\n");
2932 return DDERR_INVALIDPARAMS
;
2935 EnterCriticalSection(&ddraw_cs
);
2936 if (LightStateType
== D3DLIGHTSTATE_MATERIAL
/* 1 */)
2938 IDirect3DMaterialImpl
*m
= ddraw_get_object(&This
->handle_table
, Value
- 1, DDRAW_HANDLE_MATERIAL
);
2941 WARN("Invalid material handle.\n");
2942 LeaveCriticalSection(&ddraw_cs
);
2943 return DDERR_INVALIDPARAMS
;
2946 TRACE(" activating material %p.\n", m
);
2947 material_activate(m
);
2949 This
->material
= Value
;
2951 else if (LightStateType
== D3DLIGHTSTATE_COLORMODEL
/* 3 */)
2956 ERR("DDCOLOR_MONO should not happen!\n");
2959 /* We are already in this mode */
2960 TRACE("Setting color model to RGB (no-op).\n");
2963 ERR("Unknown color model!\n");
2964 LeaveCriticalSection(&ddraw_cs
);
2965 return DDERR_INVALIDPARAMS
;
2970 D3DRENDERSTATETYPE rs
;
2971 switch (LightStateType
)
2973 case D3DLIGHTSTATE_AMBIENT
: /* 2 */
2974 rs
= D3DRENDERSTATE_AMBIENT
;
2976 case D3DLIGHTSTATE_FOGMODE
: /* 4 */
2977 rs
= D3DRENDERSTATE_FOGVERTEXMODE
;
2979 case D3DLIGHTSTATE_FOGSTART
: /* 5 */
2980 rs
= D3DRENDERSTATE_FOGSTART
;
2982 case D3DLIGHTSTATE_FOGEND
: /* 6 */
2983 rs
= D3DRENDERSTATE_FOGEND
;
2985 case D3DLIGHTSTATE_FOGDENSITY
: /* 7 */
2986 rs
= D3DRENDERSTATE_FOGDENSITY
;
2988 case D3DLIGHTSTATE_COLORVERTEX
: /* 8 */
2989 rs
= D3DRENDERSTATE_COLORVERTEX
;
2992 ERR("Unknown D3DLIGHTSTATETYPE %d.\n", LightStateType
);
2993 LeaveCriticalSection(&ddraw_cs
);
2994 return DDERR_INVALIDPARAMS
;
2997 hr
= IDirect3DDevice7_SetRenderState((IDirect3DDevice7
*)This
, rs
, Value
);
2998 LeaveCriticalSection(&ddraw_cs
);
3002 LeaveCriticalSection(&ddraw_cs
);
3006 static HRESULT WINAPI
IDirect3DDeviceImpl_2_SetLightState(IDirect3DDevice2
*iface
,
3007 D3DLIGHTSTATETYPE LightStateType
, DWORD Value
)
3009 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
3011 TRACE("iface %p, state %#x, value %#x.\n", iface
, LightStateType
, Value
);
3013 return IDirect3DDevice3_SetLightState((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
, LightStateType
, Value
);
3016 /*****************************************************************************
3017 * IDirect3DDevice3::GetLightState
3019 * Returns the current setting of a light state. The state is read from
3020 * the Direct3DDevice7 render state.
3025 * LightStateType: The light state to return
3026 * Value: The address to store the light state setting at
3030 * DDDERR_INVALIDPARAMS if the parameters were incorrect
3031 * Also see IDirect3DDevice7::GetRenderState
3033 *****************************************************************************/
3034 static HRESULT WINAPI
3035 IDirect3DDeviceImpl_3_GetLightState(IDirect3DDevice3
*iface
,
3036 D3DLIGHTSTATETYPE LightStateType
,
3039 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
3042 TRACE("iface %p, state %#x, value %p.\n", iface
, LightStateType
, Value
);
3044 if (!LightStateType
|| (LightStateType
> D3DLIGHTSTATE_COLORVERTEX
))
3046 TRACE("Unexpected Light State Type\n");
3047 return DDERR_INVALIDPARAMS
;
3051 return DDERR_INVALIDPARAMS
;
3053 EnterCriticalSection(&ddraw_cs
);
3054 if (LightStateType
== D3DLIGHTSTATE_MATERIAL
/* 1 */)
3056 *Value
= This
->material
;
3058 else if (LightStateType
== D3DLIGHTSTATE_COLORMODEL
/* 3 */)
3060 *Value
= D3DCOLOR_RGB
;
3064 D3DRENDERSTATETYPE rs
;
3065 switch (LightStateType
)
3067 case D3DLIGHTSTATE_AMBIENT
: /* 2 */
3068 rs
= D3DRENDERSTATE_AMBIENT
;
3070 case D3DLIGHTSTATE_FOGMODE
: /* 4 */
3071 rs
= D3DRENDERSTATE_FOGVERTEXMODE
;
3073 case D3DLIGHTSTATE_FOGSTART
: /* 5 */
3074 rs
= D3DRENDERSTATE_FOGSTART
;
3076 case D3DLIGHTSTATE_FOGEND
: /* 6 */
3077 rs
= D3DRENDERSTATE_FOGEND
;
3079 case D3DLIGHTSTATE_FOGDENSITY
: /* 7 */
3080 rs
= D3DRENDERSTATE_FOGDENSITY
;
3082 case D3DLIGHTSTATE_COLORVERTEX
: /* 8 */
3083 rs
= D3DRENDERSTATE_COLORVERTEX
;
3086 ERR("Unknown D3DLIGHTSTATETYPE %d.\n", LightStateType
);
3087 LeaveCriticalSection(&ddraw_cs
);
3088 return DDERR_INVALIDPARAMS
;
3091 hr
= IDirect3DDevice7_GetRenderState((IDirect3DDevice7
*)This
, rs
, Value
);
3092 LeaveCriticalSection(&ddraw_cs
);
3096 LeaveCriticalSection(&ddraw_cs
);
3100 static HRESULT WINAPI
IDirect3DDeviceImpl_2_GetLightState(IDirect3DDevice2
*iface
,
3101 D3DLIGHTSTATETYPE LightStateType
, DWORD
*Value
)
3103 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
3105 TRACE("iface %p, state %#x, value %p.\n", iface
, LightStateType
, Value
);
3107 return IDirect3DDevice3_GetLightState((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
, LightStateType
, Value
);
3110 /*****************************************************************************
3111 * IDirect3DDevice7::SetTransform
3113 * Assigns a D3DMATRIX to a transform type. The transform types are defined
3114 * in include/d3dtypes.h.
3115 * The D3DTRANSFORMSTATE_WORLD (=1) is translated to D3DTS_WORLDMATRIX(0)
3116 * (=255) for wined3d, because the 1 transform state was removed in d3d8
3117 * and WineD3D already understands the replacement D3DTS_WORLDMATRIX(0)
3119 * Version 2, 3 and 7
3122 * TransformStateType: transform state to set
3123 * Matrix: Matrix to assign to the state
3127 * DDERR_INVALIDPARAMS if Matrix == NULL
3128 * For details see IWineD3DDevice::SetTransform
3130 *****************************************************************************/
3132 IDirect3DDeviceImpl_7_SetTransform(IDirect3DDevice7
*iface
,
3133 D3DTRANSFORMSTATETYPE TransformStateType
,
3136 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
3137 D3DTRANSFORMSTATETYPE type
;
3140 TRACE("iface %p, state %#x, matrix %p.\n", iface
, TransformStateType
, Matrix
);
3142 switch(TransformStateType
)
3144 case D3DTRANSFORMSTATE_WORLD
: type
= WINED3DTS_WORLDMATRIX(0); break;
3145 case D3DTRANSFORMSTATE_WORLD1
: type
= WINED3DTS_WORLDMATRIX(1); break;
3146 case D3DTRANSFORMSTATE_WORLD2
: type
= WINED3DTS_WORLDMATRIX(2); break;
3147 case D3DTRANSFORMSTATE_WORLD3
: type
= WINED3DTS_WORLDMATRIX(3); break;
3148 default: type
= TransformStateType
;
3152 return DDERR_INVALIDPARAMS
;
3154 /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
3155 EnterCriticalSection(&ddraw_cs
);
3156 hr
= IWineD3DDevice_SetTransform(This
->wineD3DDevice
,
3158 (WINED3DMATRIX
*) Matrix
);
3159 LeaveCriticalSection(&ddraw_cs
);
3163 static HRESULT WINAPI
3164 IDirect3DDeviceImpl_7_SetTransform_FPUSetup(IDirect3DDevice7
*iface
,
3165 D3DTRANSFORMSTATETYPE TransformStateType
,
3168 return IDirect3DDeviceImpl_7_SetTransform(iface
, TransformStateType
, Matrix
);
3171 static HRESULT WINAPI
3172 IDirect3DDeviceImpl_7_SetTransform_FPUPreserve(IDirect3DDevice7
*iface
,
3173 D3DTRANSFORMSTATETYPE TransformStateType
,
3179 old_fpucw
= d3d_fpu_setup();
3180 hr
= IDirect3DDeviceImpl_7_SetTransform(iface
, TransformStateType
, Matrix
);
3181 set_fpu_control_word(old_fpucw
);
3186 static HRESULT WINAPI
IDirect3DDeviceImpl_3_SetTransform(IDirect3DDevice3
*iface
,
3187 D3DTRANSFORMSTATETYPE TransformStateType
, D3DMATRIX
*D3DMatrix
)
3189 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
3191 TRACE("iface %p, state %#x, matrix %p.\n", iface
, TransformStateType
, D3DMatrix
);
3193 return IDirect3DDevice7_SetTransform((IDirect3DDevice7
*)This
, TransformStateType
, D3DMatrix
);
3196 static HRESULT WINAPI
IDirect3DDeviceImpl_2_SetTransform(IDirect3DDevice2
*iface
,
3197 D3DTRANSFORMSTATETYPE TransformStateType
, D3DMATRIX
*D3DMatrix
)
3199 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
3201 TRACE("iface %p, state %#x, matrix %p.\n", iface
, TransformStateType
, D3DMatrix
);
3203 return IDirect3DDevice7_SetTransform((IDirect3DDevice7
*)This
, TransformStateType
, D3DMatrix
);
3206 /*****************************************************************************
3207 * IDirect3DDevice7::GetTransform
3209 * Returns the matrix assigned to a transform state
3210 * D3DTRANSFORMSTATE_WORLD is translated to D3DTS_WORLDMATRIX(0), see
3214 * TransformStateType: State to read the matrix from
3215 * Matrix: Address to store the matrix at
3219 * DDERR_INVALIDPARAMS if Matrix == NULL
3220 * For details, see IWineD3DDevice::GetTransform
3222 *****************************************************************************/
3224 IDirect3DDeviceImpl_7_GetTransform(IDirect3DDevice7
*iface
,
3225 D3DTRANSFORMSTATETYPE TransformStateType
,
3228 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
3229 D3DTRANSFORMSTATETYPE type
;
3232 TRACE("iface %p, state %#x, matrix %p.\n", iface
, TransformStateType
, Matrix
);
3234 switch(TransformStateType
)
3236 case D3DTRANSFORMSTATE_WORLD
: type
= WINED3DTS_WORLDMATRIX(0); break;
3237 case D3DTRANSFORMSTATE_WORLD1
: type
= WINED3DTS_WORLDMATRIX(1); break;
3238 case D3DTRANSFORMSTATE_WORLD2
: type
= WINED3DTS_WORLDMATRIX(2); break;
3239 case D3DTRANSFORMSTATE_WORLD3
: type
= WINED3DTS_WORLDMATRIX(3); break;
3240 default: type
= TransformStateType
;
3244 return DDERR_INVALIDPARAMS
;
3246 /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
3247 EnterCriticalSection(&ddraw_cs
);
3248 hr
= IWineD3DDevice_GetTransform(This
->wineD3DDevice
, type
, (WINED3DMATRIX
*) Matrix
);
3249 LeaveCriticalSection(&ddraw_cs
);
3253 static HRESULT WINAPI
3254 IDirect3DDeviceImpl_7_GetTransform_FPUSetup(IDirect3DDevice7
*iface
,
3255 D3DTRANSFORMSTATETYPE TransformStateType
,
3258 return IDirect3DDeviceImpl_7_GetTransform(iface
, TransformStateType
, Matrix
);
3261 static HRESULT WINAPI
3262 IDirect3DDeviceImpl_7_GetTransform_FPUPreserve(IDirect3DDevice7
*iface
,
3263 D3DTRANSFORMSTATETYPE TransformStateType
,
3269 old_fpucw
= d3d_fpu_setup();
3270 hr
= IDirect3DDeviceImpl_7_GetTransform(iface
, TransformStateType
, Matrix
);
3271 set_fpu_control_word(old_fpucw
);
3276 static HRESULT WINAPI
IDirect3DDeviceImpl_3_GetTransform(IDirect3DDevice3
*iface
,
3277 D3DTRANSFORMSTATETYPE TransformStateType
, D3DMATRIX
*D3DMatrix
)
3279 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
3281 TRACE("iface %p, state %#x, matrix %p.\n", iface
, TransformStateType
, D3DMatrix
);
3283 return IDirect3DDevice7_GetTransform((IDirect3DDevice7
*)This
, TransformStateType
, D3DMatrix
);
3286 static HRESULT WINAPI
IDirect3DDeviceImpl_2_GetTransform(IDirect3DDevice2
*iface
,
3287 D3DTRANSFORMSTATETYPE TransformStateType
, D3DMATRIX
*D3DMatrix
)
3289 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
3291 TRACE("iface %p, state %#x, matrix %p.\n", iface
, TransformStateType
, D3DMatrix
);
3293 return IDirect3DDevice7_GetTransform((IDirect3DDevice7
*)This
, TransformStateType
, D3DMatrix
);
3296 /*****************************************************************************
3297 * IDirect3DDevice7::MultiplyTransform
3299 * Multiplies the already-set transform matrix of a transform state
3300 * with another matrix. For the world matrix, see SetTransform
3302 * Version 2, 3 and 7
3305 * TransformStateType: Transform state to multiply
3306 * D3DMatrix Matrix to multiply with.
3310 * DDERR_INVALIDPARAMS if D3DMatrix is NULL
3311 * For details, see IWineD3DDevice::MultiplyTransform
3313 *****************************************************************************/
3315 IDirect3DDeviceImpl_7_MultiplyTransform(IDirect3DDevice7
*iface
,
3316 D3DTRANSFORMSTATETYPE TransformStateType
,
3317 D3DMATRIX
*D3DMatrix
)
3319 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
3321 D3DTRANSFORMSTATETYPE type
;
3323 TRACE("iface %p, state %#x, matrix %p.\n", iface
, TransformStateType
, D3DMatrix
);
3325 switch(TransformStateType
)
3327 case D3DTRANSFORMSTATE_WORLD
: type
= WINED3DTS_WORLDMATRIX(0); break;
3328 case D3DTRANSFORMSTATE_WORLD1
: type
= WINED3DTS_WORLDMATRIX(1); break;
3329 case D3DTRANSFORMSTATE_WORLD2
: type
= WINED3DTS_WORLDMATRIX(2); break;
3330 case D3DTRANSFORMSTATE_WORLD3
: type
= WINED3DTS_WORLDMATRIX(3); break;
3331 default: type
= TransformStateType
;
3334 /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
3335 EnterCriticalSection(&ddraw_cs
);
3336 hr
= IWineD3DDevice_MultiplyTransform(This
->wineD3DDevice
,
3338 (WINED3DMATRIX
*) D3DMatrix
);
3339 LeaveCriticalSection(&ddraw_cs
);
3343 static HRESULT WINAPI
3344 IDirect3DDeviceImpl_7_MultiplyTransform_FPUSetup(IDirect3DDevice7
*iface
,
3345 D3DTRANSFORMSTATETYPE TransformStateType
,
3346 D3DMATRIX
*D3DMatrix
)
3348 return IDirect3DDeviceImpl_7_MultiplyTransform(iface
, TransformStateType
, D3DMatrix
);
3351 static HRESULT WINAPI
3352 IDirect3DDeviceImpl_7_MultiplyTransform_FPUPreserve(IDirect3DDevice7
*iface
,
3353 D3DTRANSFORMSTATETYPE TransformStateType
,
3354 D3DMATRIX
*D3DMatrix
)
3359 old_fpucw
= d3d_fpu_setup();
3360 hr
= IDirect3DDeviceImpl_7_MultiplyTransform(iface
, TransformStateType
, D3DMatrix
);
3361 set_fpu_control_word(old_fpucw
);
3366 static HRESULT WINAPI
IDirect3DDeviceImpl_3_MultiplyTransform(IDirect3DDevice3
*iface
,
3367 D3DTRANSFORMSTATETYPE TransformStateType
, D3DMATRIX
*D3DMatrix
)
3369 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
3371 TRACE("iface %p, state %#x, matrix %p.\n", iface
, TransformStateType
, D3DMatrix
);
3373 return IDirect3DDevice7_MultiplyTransform((IDirect3DDevice7
*)This
, TransformStateType
, D3DMatrix
);
3376 static HRESULT WINAPI
IDirect3DDeviceImpl_2_MultiplyTransform(IDirect3DDevice2
*iface
,
3377 D3DTRANSFORMSTATETYPE TransformStateType
, D3DMATRIX
*D3DMatrix
)
3379 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
3381 TRACE("iface %p, state %#x, matrix %p.\n", iface
, TransformStateType
, D3DMatrix
);
3383 return IDirect3DDevice7_MultiplyTransform((IDirect3DDevice7
*)This
, TransformStateType
, D3DMatrix
);
3386 /*****************************************************************************
3387 * IDirect3DDevice7::DrawPrimitive
3389 * Draws primitives based on vertices in an application-provided pointer
3391 * Version 2, 3 and 7. The IDirect3DDevice2 thunk converts the fixed vertex type into
3392 * an FVF format for D3D7
3395 * PrimitiveType: The type of the primitives to draw
3396 * Vertex type: Flexible vertex format vertex description
3397 * Vertices: Pointer to the vertex array
3398 * VertexCount: The number of vertices to draw
3399 * Flags: As usual a few flags
3403 * DDERR_INVALIDPARAMS if Vertices is NULL
3404 * For details, see IWineD3DDevice::DrawPrimitiveUP
3406 *****************************************************************************/
3408 IDirect3DDeviceImpl_7_DrawPrimitive(IDirect3DDevice7
*iface
,
3409 D3DPRIMITIVETYPE PrimitiveType
,
3415 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
3419 TRACE("iface %p, primitive_type %#x, FVF %#x, vertices %p, vertex_count %u, flags %#x.\n",
3420 iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Flags
);
3423 return DDERR_INVALIDPARAMS
;
3425 /* Get the stride */
3426 stride
= get_flexible_vertex_size(VertexType
);
3429 EnterCriticalSection(&ddraw_cs
);
3430 hr
= IWineD3DDevice_SetVertexDeclaration(This
->wineD3DDevice
, ddraw_find_decl(This
->ddraw
, VertexType
));
3433 LeaveCriticalSection(&ddraw_cs
);
3437 /* This method translates to the user pointer draw of WineD3D */
3438 IWineD3DDevice_SetPrimitiveType(This
->wineD3DDevice
, PrimitiveType
);
3439 hr
= IWineD3DDevice_DrawPrimitiveUP(This
->wineD3DDevice
, VertexCount
, Vertices
, stride
);
3440 LeaveCriticalSection(&ddraw_cs
);
3444 static HRESULT WINAPI
3445 IDirect3DDeviceImpl_7_DrawPrimitive_FPUSetup(IDirect3DDevice7
*iface
,
3446 D3DPRIMITIVETYPE PrimitiveType
,
3452 return IDirect3DDeviceImpl_7_DrawPrimitive(iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Flags
);
3455 static HRESULT WINAPI
3456 IDirect3DDeviceImpl_7_DrawPrimitive_FPUPreserve(IDirect3DDevice7
*iface
,
3457 D3DPRIMITIVETYPE PrimitiveType
,
3466 old_fpucw
= d3d_fpu_setup();
3467 hr
= IDirect3DDeviceImpl_7_DrawPrimitive(iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Flags
);
3468 set_fpu_control_word(old_fpucw
);
3473 static HRESULT WINAPI
IDirect3DDeviceImpl_3_DrawPrimitive(IDirect3DDevice3
*iface
,
3474 D3DPRIMITIVETYPE PrimitiveType
, DWORD VertexType
, void *Vertices
, DWORD VertexCount
,
3477 TRACE("iface %p, primitive_type %#x, FVF %#x, vertices %p, vertex_count %u, flags %#x.\n",
3478 iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Flags
);
3480 return IDirect3DDevice7_DrawPrimitive((IDirect3DDevice7
*)device_from_device3(iface
),
3481 PrimitiveType
, VertexType
, Vertices
, VertexCount
, Flags
);
3484 static HRESULT WINAPI
IDirect3DDeviceImpl_2_DrawPrimitive(IDirect3DDevice2
*iface
,
3485 D3DPRIMITIVETYPE PrimitiveType
, D3DVERTEXTYPE VertexType
, void *Vertices
,
3486 DWORD VertexCount
, DWORD Flags
)
3490 TRACE("iface %p, primitive_type %#x, vertex_type %#x, vertices %p, vertex_count %u, flags %#x.\n",
3491 iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Flags
);
3495 case D3DVT_VERTEX
: FVF
= D3DFVF_VERTEX
; break;
3496 case D3DVT_LVERTEX
: FVF
= D3DFVF_LVERTEX
; break;
3497 case D3DVT_TLVERTEX
: FVF
= D3DFVF_TLVERTEX
; break;
3499 ERR("Unexpected vertex type %d\n", VertexType
);
3500 return DDERR_INVALIDPARAMS
; /* Should never happen */
3503 return IDirect3DDevice7_DrawPrimitive((IDirect3DDevice7
*)device_from_device2(iface
),
3504 PrimitiveType
, FVF
, Vertices
, VertexCount
, Flags
);
3507 /*****************************************************************************
3508 * IDirect3DDevice7::DrawIndexedPrimitive
3510 * Draws vertices from an application-provided pointer, based on the index
3511 * numbers in a WORD array.
3513 * Version 2, 3 and 7. The version 7 thunk translates the vertex type into
3514 * an FVF format for D3D7
3517 * PrimitiveType: The primitive type to draw
3518 * VertexType: The FVF vertex description
3519 * Vertices: Pointer to the vertex array
3521 * Indices: Pointer to the index array
3522 * IndexCount: Number of indices = Number of vertices to draw
3523 * Flags: As usual, some flags
3527 * DDERR_INVALIDPARAMS if Vertices or Indices is NULL
3528 * For details, see IWineD3DDevice::DrawIndexedPrimitiveUP
3530 *****************************************************************************/
3532 IDirect3DDeviceImpl_7_DrawIndexedPrimitive(IDirect3DDevice7
*iface
,
3533 D3DPRIMITIVETYPE PrimitiveType
,
3541 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
3544 TRACE("iface %p, primitive_type %#x, FVF %#x, vertices %p, vertex_count %u, indices %p, index_count %u, flags %#x.\n",
3545 iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Indices
, IndexCount
, Flags
);
3547 /* Set the D3DDevice's FVF */
3548 EnterCriticalSection(&ddraw_cs
);
3549 hr
= IWineD3DDevice_SetVertexDeclaration(This
->wineD3DDevice
, ddraw_find_decl(This
->ddraw
, VertexType
));
3552 ERR(" (%p) Setting the FVF failed, hr = %x!\n", This
, hr
);
3553 LeaveCriticalSection(&ddraw_cs
);
3557 IWineD3DDevice_SetPrimitiveType(This
->wineD3DDevice
, PrimitiveType
);
3558 hr
= IWineD3DDevice_DrawIndexedPrimitiveUP(This
->wineD3DDevice
, IndexCount
, Indices
,
3559 WINED3DFMT_R16_UINT
, Vertices
, get_flexible_vertex_size(VertexType
));
3560 LeaveCriticalSection(&ddraw_cs
);
3564 static HRESULT WINAPI
3565 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUSetup(IDirect3DDevice7
*iface
,
3566 D3DPRIMITIVETYPE PrimitiveType
,
3574 return IDirect3DDeviceImpl_7_DrawIndexedPrimitive(iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Indices
, IndexCount
, Flags
);
3577 static HRESULT WINAPI
3578 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUPreserve(IDirect3DDevice7
*iface
,
3579 D3DPRIMITIVETYPE PrimitiveType
,
3590 old_fpucw
= d3d_fpu_setup();
3591 hr
= IDirect3DDeviceImpl_7_DrawIndexedPrimitive(iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Indices
, IndexCount
, Flags
);
3592 set_fpu_control_word(old_fpucw
);
3597 static HRESULT WINAPI
IDirect3DDeviceImpl_3_DrawIndexedPrimitive(IDirect3DDevice3
*iface
,
3598 D3DPRIMITIVETYPE PrimitiveType
, DWORD VertexType
, void *Vertices
, DWORD VertexCount
,
3599 WORD
*Indices
, DWORD IndexCount
, DWORD Flags
)
3601 TRACE("iface %p, primitive_type %#x, FVF %#x, vertices %p, vertex_count %u, indices %p, index_count %u, flags %#x.\n",
3602 iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Indices
, IndexCount
, Flags
);
3604 return IDirect3DDevice7_DrawIndexedPrimitive((IDirect3DDevice7
*)device_from_device3(iface
),
3605 PrimitiveType
, VertexType
, Vertices
, VertexCount
, Indices
, IndexCount
, Flags
);
3608 static HRESULT WINAPI
IDirect3DDeviceImpl_2_DrawIndexedPrimitive(IDirect3DDevice2
*iface
,
3609 D3DPRIMITIVETYPE PrimitiveType
, D3DVERTEXTYPE VertexType
, void *Vertices
,
3610 DWORD VertexCount
, WORD
*Indices
, DWORD IndexCount
, DWORD Flags
)
3614 TRACE("iface %p, primitive_type %#x, vertex_type %#x, vertices %p, vertex_count %u, indices %p, index_count %u, flags %#x.\n",
3615 iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Indices
, IndexCount
, Flags
);
3619 case D3DVT_VERTEX
: FVF
= D3DFVF_VERTEX
; break;
3620 case D3DVT_LVERTEX
: FVF
= D3DFVF_LVERTEX
; break;
3621 case D3DVT_TLVERTEX
: FVF
= D3DFVF_TLVERTEX
; break;
3623 ERR("Unexpected vertex type %d\n", VertexType
);
3624 return DDERR_INVALIDPARAMS
; /* Should never happen */
3627 return IDirect3DDevice7_DrawIndexedPrimitive((IDirect3DDevice7
*)device_from_device2(iface
),
3628 PrimitiveType
, FVF
, Vertices
, VertexCount
, Indices
, IndexCount
, Flags
);
3631 /*****************************************************************************
3632 * IDirect3DDevice7::SetClipStatus
3634 * Sets the clip status. This defines things as clipping conditions and
3635 * the extents of the clipping region.
3637 * Version 2, 3 and 7
3643 * D3D_OK because it's a stub
3644 * (DDERR_INVALIDPARAMS if ClipStatus == NULL)
3646 *****************************************************************************/
3647 static HRESULT WINAPI
3648 IDirect3DDeviceImpl_7_SetClipStatus(IDirect3DDevice7
*iface
,
3649 D3DCLIPSTATUS
*ClipStatus
)
3651 FIXME("iface %p, clip_status %p stub!\n", iface
, ClipStatus
);
3653 /* D3DCLIPSTATUS and WINED3DCLIPSTATUS are different. I don't know how to convert them
3654 * Perhaps this needs a new data type and an additional IWineD3DDevice method
3656 /* return IWineD3DDevice_SetClipStatus(This->wineD3DDevice, ClipStatus);*/
3660 static HRESULT WINAPI
IDirect3DDeviceImpl_3_SetClipStatus(IDirect3DDevice3
*iface
,
3661 D3DCLIPSTATUS
*ClipStatus
)
3663 TRACE("iface %p, clip_status %p.\n", iface
, ClipStatus
);
3665 return IDirect3DDevice7_SetClipStatus((IDirect3DDevice7
*)device_from_device3(iface
), ClipStatus
);
3668 static HRESULT WINAPI
IDirect3DDeviceImpl_2_SetClipStatus(IDirect3DDevice2
*iface
,
3669 D3DCLIPSTATUS
*ClipStatus
)
3671 TRACE("iface %p, clip_status %p.\n", iface
, ClipStatus
);
3673 return IDirect3DDevice7_SetClipStatus((IDirect3DDevice7
*)device_from_device2(iface
), ClipStatus
);
3676 /*****************************************************************************
3677 * IDirect3DDevice7::GetClipStatus
3679 * Returns the clip status
3682 * ClipStatus: Address to write the clip status to
3685 * D3D_OK because it's a stub
3687 *****************************************************************************/
3688 static HRESULT WINAPI
3689 IDirect3DDeviceImpl_7_GetClipStatus(IDirect3DDevice7
*iface
,
3690 D3DCLIPSTATUS
*ClipStatus
)
3692 FIXME("iface %p, clip_status %p stub!\n", iface
, ClipStatus
);
3694 /* D3DCLIPSTATUS and WINED3DCLIPSTATUS are different. I don't know how to convert them */
3695 /* return IWineD3DDevice_GetClipStatus(This->wineD3DDevice, ClipStatus);*/
3699 static HRESULT WINAPI
IDirect3DDeviceImpl_3_GetClipStatus(IDirect3DDevice3
*iface
,
3700 D3DCLIPSTATUS
*ClipStatus
)
3702 TRACE("iface %p, clip_status %p.\n", iface
, ClipStatus
);
3704 return IDirect3DDevice7_GetClipStatus((IDirect3DDevice7
*)device_from_device3(iface
), ClipStatus
);
3707 static HRESULT WINAPI
IDirect3DDeviceImpl_2_GetClipStatus(IDirect3DDevice2
*iface
,
3708 D3DCLIPSTATUS
*ClipStatus
)
3710 TRACE("iface %p, clip_status %p.\n", iface
, ClipStatus
);
3712 return IDirect3DDevice7_GetClipStatus((IDirect3DDevice7
*)device_from_device2(iface
), ClipStatus
);
3715 /*****************************************************************************
3716 * IDirect3DDevice::DrawPrimitiveStrided
3718 * Draws vertices described by a D3DDRAWPRIMITIVESTRIDEDDATA structure.
3723 * PrimitiveType: The primitive type to draw
3724 * VertexType: The FVF description of the vertices to draw (for the stride??)
3725 * D3DDrawPrimStrideData: A D3DDRAWPRIMITIVESTRIDEDDATA structure describing
3726 * the vertex data locations
3727 * VertexCount: The number of vertices to draw
3731 * D3D_OK, because it's a stub
3732 * (DDERR_INVALIDPARAMS if D3DDrawPrimStrideData is NULL)
3733 * (For details, see IWineD3DDevice::DrawPrimitiveStrided)
3735 *****************************************************************************/
3737 IDirect3DDeviceImpl_7_DrawPrimitiveStrided(IDirect3DDevice7
*iface
,
3738 D3DPRIMITIVETYPE PrimitiveType
,
3740 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
,
3744 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
3745 WineDirect3DVertexStridedData WineD3DStrided
;
3749 TRACE("iface %p, primitive_type %#x, FVF %#x, strided_data %p, vertex_count %u, flags %#x.\n",
3750 iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Flags
);
3752 memset(&WineD3DStrided
, 0, sizeof(WineD3DStrided
));
3753 /* Get the strided data right. the wined3d structure is a bit bigger
3754 * Watch out: The contents of the strided data are determined by the fvf,
3755 * not by the members set in D3DDrawPrimStrideData. So it's valid
3756 * to have diffuse.lpvData set to 0xdeadbeef if the diffuse flag is
3757 * not set in the fvf.
3759 if(VertexType
& D3DFVF_POSITION_MASK
)
3761 WineD3DStrided
.position
.format
= WINED3DFMT_R32G32B32_FLOAT
;
3762 WineD3DStrided
.position
.lpData
= D3DDrawPrimStrideData
->position
.lpvData
;
3763 WineD3DStrided
.position
.dwStride
= D3DDrawPrimStrideData
->position
.dwStride
;
3764 if (VertexType
& D3DFVF_XYZRHW
)
3766 WineD3DStrided
.position
.format
= WINED3DFMT_R32G32B32A32_FLOAT
;
3767 WineD3DStrided
.position_transformed
= TRUE
;
3769 WineD3DStrided
.position_transformed
= FALSE
;
3772 if(VertexType
& D3DFVF_NORMAL
)
3774 WineD3DStrided
.normal
.format
= WINED3DFMT_R32G32B32_FLOAT
;
3775 WineD3DStrided
.normal
.lpData
= D3DDrawPrimStrideData
->normal
.lpvData
;
3776 WineD3DStrided
.normal
.dwStride
= D3DDrawPrimStrideData
->normal
.dwStride
;
3779 if(VertexType
& D3DFVF_DIFFUSE
)
3781 WineD3DStrided
.diffuse
.format
= WINED3DFMT_B8G8R8A8_UNORM
;
3782 WineD3DStrided
.diffuse
.lpData
= D3DDrawPrimStrideData
->diffuse
.lpvData
;
3783 WineD3DStrided
.diffuse
.dwStride
= D3DDrawPrimStrideData
->diffuse
.dwStride
;
3786 if(VertexType
& D3DFVF_SPECULAR
)
3788 WineD3DStrided
.specular
.format
= WINED3DFMT_B8G8R8A8_UNORM
;
3789 WineD3DStrided
.specular
.lpData
= D3DDrawPrimStrideData
->specular
.lpvData
;
3790 WineD3DStrided
.specular
.dwStride
= D3DDrawPrimStrideData
->specular
.dwStride
;
3793 for( i
= 0; i
< GET_TEXCOUNT_FROM_FVF(VertexType
); i
++)
3795 switch(GET_TEXCOORD_SIZE_FROM_FVF(VertexType
, i
))
3797 case 1: WineD3DStrided
.texCoords
[i
].format
= WINED3DFMT_R32_FLOAT
; break;
3798 case 2: WineD3DStrided
.texCoords
[i
].format
= WINED3DFMT_R32G32_FLOAT
; break;
3799 case 3: WineD3DStrided
.texCoords
[i
].format
= WINED3DFMT_R32G32B32_FLOAT
; break;
3800 case 4: WineD3DStrided
.texCoords
[i
].format
= WINED3DFMT_R32G32B32A32_FLOAT
; break;
3801 default: ERR("Unexpected texture coordinate size %d\n",
3802 GET_TEXCOORD_SIZE_FROM_FVF(VertexType
, i
));
3804 WineD3DStrided
.texCoords
[i
].lpData
= D3DDrawPrimStrideData
->textureCoords
[i
].lpvData
;
3805 WineD3DStrided
.texCoords
[i
].dwStride
= D3DDrawPrimStrideData
->textureCoords
[i
].dwStride
;
3808 /* WineD3D doesn't need the FVF here */
3809 EnterCriticalSection(&ddraw_cs
);
3810 IWineD3DDevice_SetPrimitiveType(This
->wineD3DDevice
, PrimitiveType
);
3811 hr
= IWineD3DDevice_DrawPrimitiveStrided(This
->wineD3DDevice
, VertexCount
, &WineD3DStrided
);
3812 LeaveCriticalSection(&ddraw_cs
);
3816 static HRESULT WINAPI
3817 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUSetup(IDirect3DDevice7
*iface
,
3818 D3DPRIMITIVETYPE PrimitiveType
,
3820 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
,
3824 return IDirect3DDeviceImpl_7_DrawPrimitiveStrided(iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Flags
);
3827 static HRESULT WINAPI
3828 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUPreserve(IDirect3DDevice7
*iface
,
3829 D3DPRIMITIVETYPE PrimitiveType
,
3831 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
,
3838 old_fpucw
= d3d_fpu_setup();
3839 hr
= IDirect3DDeviceImpl_7_DrawPrimitiveStrided(iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Flags
);
3840 set_fpu_control_word(old_fpucw
);
3845 static HRESULT WINAPI
IDirect3DDeviceImpl_3_DrawPrimitiveStrided(IDirect3DDevice3
*iface
,
3846 D3DPRIMITIVETYPE PrimitiveType
, DWORD VertexType
,
3847 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
, DWORD VertexCount
, DWORD Flags
)
3849 TRACE("iface %p, primitive_type %#x, FVF %#x, strided_data %p, vertex_count %u, flags %#x.\n",
3850 iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Flags
);
3852 return IDirect3DDevice7_DrawPrimitiveStrided((IDirect3DDevice7
*)device_from_device3(iface
),
3853 PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Flags
);
3856 /*****************************************************************************
3857 * IDirect3DDevice7::DrawIndexedPrimitiveStrided
3859 * Draws primitives specified by strided data locations based on indices
3867 * D3D_OK, because it's a stub
3868 * (DDERR_INVALIDPARAMS if D3DDrawPrimStrideData is NULL)
3869 * (DDERR_INVALIDPARAMS if Indices is NULL)
3870 * (For more details, see IWineD3DDevice::DrawIndexedPrimitiveStrided)
3872 *****************************************************************************/
3874 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided(IDirect3DDevice7
*iface
,
3875 D3DPRIMITIVETYPE PrimitiveType
,
3877 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
,
3883 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
3884 WineDirect3DVertexStridedData WineD3DStrided
;
3888 TRACE("iface %p, primitive_type %#x, FVF %#x, strided_data %p, vertex_count %u, indices %p, index_count %u, flags %#x.\n",
3889 iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Indices
, IndexCount
, Flags
);
3891 memset(&WineD3DStrided
, 0, sizeof(WineD3DStrided
));
3892 /* Get the strided data right. the wined3d structure is a bit bigger
3893 * Watch out: The contents of the strided data are determined by the fvf,
3894 * not by the members set in D3DDrawPrimStrideData. So it's valid
3895 * to have diffuse.lpvData set to 0xdeadbeef if the diffuse flag is
3896 * not set in the fvf.
3898 if(VertexType
& D3DFVF_POSITION_MASK
)
3900 WineD3DStrided
.position
.format
= WINED3DFMT_R32G32B32_FLOAT
;
3901 WineD3DStrided
.position
.lpData
= D3DDrawPrimStrideData
->position
.lpvData
;
3902 WineD3DStrided
.position
.dwStride
= D3DDrawPrimStrideData
->position
.dwStride
;
3903 if (VertexType
& D3DFVF_XYZRHW
)
3905 WineD3DStrided
.position
.format
= WINED3DFMT_R32G32B32A32_FLOAT
;
3906 WineD3DStrided
.position_transformed
= TRUE
;
3908 WineD3DStrided
.position_transformed
= FALSE
;
3911 if(VertexType
& D3DFVF_NORMAL
)
3913 WineD3DStrided
.normal
.format
= WINED3DFMT_R32G32B32_FLOAT
;
3914 WineD3DStrided
.normal
.lpData
= D3DDrawPrimStrideData
->normal
.lpvData
;
3915 WineD3DStrided
.normal
.dwStride
= D3DDrawPrimStrideData
->normal
.dwStride
;
3918 if(VertexType
& D3DFVF_DIFFUSE
)
3920 WineD3DStrided
.diffuse
.format
= WINED3DFMT_B8G8R8A8_UNORM
;
3921 WineD3DStrided
.diffuse
.lpData
= D3DDrawPrimStrideData
->diffuse
.lpvData
;
3922 WineD3DStrided
.diffuse
.dwStride
= D3DDrawPrimStrideData
->diffuse
.dwStride
;
3925 if(VertexType
& D3DFVF_SPECULAR
)
3927 WineD3DStrided
.specular
.format
= WINED3DFMT_B8G8R8A8_UNORM
;
3928 WineD3DStrided
.specular
.lpData
= D3DDrawPrimStrideData
->specular
.lpvData
;
3929 WineD3DStrided
.specular
.dwStride
= D3DDrawPrimStrideData
->specular
.dwStride
;
3932 for( i
= 0; i
< GET_TEXCOUNT_FROM_FVF(VertexType
); i
++)
3934 switch(GET_TEXCOORD_SIZE_FROM_FVF(VertexType
, i
))
3936 case 1: WineD3DStrided
.texCoords
[i
].format
= WINED3DFMT_R32_FLOAT
; break;
3937 case 2: WineD3DStrided
.texCoords
[i
].format
= WINED3DFMT_R32G32_FLOAT
; break;
3938 case 3: WineD3DStrided
.texCoords
[i
].format
= WINED3DFMT_R32G32B32_FLOAT
; break;
3939 case 4: WineD3DStrided
.texCoords
[i
].format
= WINED3DFMT_R32G32B32A32_FLOAT
; break;
3940 default: ERR("Unexpected texture coordinate size %d\n",
3941 GET_TEXCOORD_SIZE_FROM_FVF(VertexType
, i
));
3943 WineD3DStrided
.texCoords
[i
].lpData
= D3DDrawPrimStrideData
->textureCoords
[i
].lpvData
;
3944 WineD3DStrided
.texCoords
[i
].dwStride
= D3DDrawPrimStrideData
->textureCoords
[i
].dwStride
;
3947 /* WineD3D doesn't need the FVF here */
3948 EnterCriticalSection(&ddraw_cs
);
3949 IWineD3DDevice_SetPrimitiveType(This
->wineD3DDevice
, PrimitiveType
);
3950 hr
= IWineD3DDevice_DrawIndexedPrimitiveStrided(This
->wineD3DDevice
,
3951 IndexCount
, &WineD3DStrided
, VertexCount
, Indices
, WINED3DFMT_R16_UINT
);
3952 LeaveCriticalSection(&ddraw_cs
);
3956 static HRESULT WINAPI
3957 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUSetup(IDirect3DDevice7
*iface
,
3958 D3DPRIMITIVETYPE PrimitiveType
,
3960 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
,
3966 return IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided(iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Indices
, IndexCount
, Flags
);
3969 static HRESULT WINAPI
3970 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUPreserve(IDirect3DDevice7
*iface
,
3971 D3DPRIMITIVETYPE PrimitiveType
,
3973 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
,
3982 old_fpucw
= d3d_fpu_setup();
3983 hr
= IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided(iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Indices
, IndexCount
, Flags
);
3984 set_fpu_control_word(old_fpucw
);
3989 static HRESULT WINAPI
IDirect3DDeviceImpl_3_DrawIndexedPrimitiveStrided(IDirect3DDevice3
*iface
,
3990 D3DPRIMITIVETYPE PrimitiveType
, DWORD VertexType
,
3991 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
, DWORD VertexCount
, WORD
*Indices
,
3992 DWORD IndexCount
, DWORD Flags
)
3994 TRACE("iface %p, primitive_type %#x, FVF %#x, strided_data %p, vertex_count %u, indices %p, index_count %u, flags %#x.\n",
3995 iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Indices
, IndexCount
, Flags
);
3997 return IDirect3DDevice7_DrawIndexedPrimitiveStrided((IDirect3DDevice7
*)device_from_device3(iface
),
3998 PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Indices
, IndexCount
, Flags
);
4001 /*****************************************************************************
4002 * IDirect3DDevice7::DrawPrimitiveVB
4004 * Draws primitives from a vertex buffer to the screen.
4009 * PrimitiveType: Type of primitive to be rendered.
4010 * D3DVertexBuf: Source Vertex Buffer
4011 * StartVertex: Index of the first vertex from the buffer to be rendered
4012 * NumVertices: Number of vertices to be rendered
4013 * Flags: Can be D3DDP_WAIT to wait until rendering has finished
4017 * DDERR_INVALIDPARAMS if D3DVertexBuf is NULL
4019 *****************************************************************************/
4021 IDirect3DDeviceImpl_7_DrawPrimitiveVB(IDirect3DDevice7
*iface
,
4022 D3DPRIMITIVETYPE PrimitiveType
,
4023 IDirect3DVertexBuffer7
*D3DVertexBuf
,
4028 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
4029 IDirect3DVertexBufferImpl
*vb
= (IDirect3DVertexBufferImpl
*)D3DVertexBuf
;
4033 TRACE("iface %p, primitive_type %#x, vb %p, start_vertex %u, vertex_count %u, flags %#x.\n",
4034 iface
, PrimitiveType
, D3DVertexBuf
, StartVertex
, NumVertices
, Flags
);
4039 ERR("(%p) No Vertex buffer specified\n", This
);
4040 return DDERR_INVALIDPARAMS
;
4042 stride
= get_flexible_vertex_size(vb
->fvf
);
4044 EnterCriticalSection(&ddraw_cs
);
4045 hr
= IWineD3DDevice_SetVertexDeclaration(This
->wineD3DDevice
,
4046 vb
->wineD3DVertexDeclaration
);
4049 ERR(" (%p) Setting the FVF failed, hr = %x!\n", This
, hr
);
4050 LeaveCriticalSection(&ddraw_cs
);
4054 /* Set the vertex stream source */
4055 hr
= IWineD3DDevice_SetStreamSource(This
->wineD3DDevice
,
4056 0 /* StreamNumber */,
4057 vb
->wineD3DVertexBuffer
,
4058 0 /* StartVertex - we pass this to DrawPrimitive */,
4062 ERR("(%p) IDirect3DDevice::SetStreamSource failed with hr = %08x\n", This
, hr
);
4063 LeaveCriticalSection(&ddraw_cs
);
4067 /* Now draw the primitives */
4068 IWineD3DDevice_SetPrimitiveType(This
->wineD3DDevice
, PrimitiveType
);
4069 hr
= IWineD3DDevice_DrawPrimitive(This
->wineD3DDevice
, StartVertex
, NumVertices
);
4070 LeaveCriticalSection(&ddraw_cs
);
4074 static HRESULT WINAPI
4075 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUSetup(IDirect3DDevice7
*iface
,
4076 D3DPRIMITIVETYPE PrimitiveType
,
4077 IDirect3DVertexBuffer7
*D3DVertexBuf
,
4082 return IDirect3DDeviceImpl_7_DrawPrimitiveVB(iface
, PrimitiveType
, D3DVertexBuf
, StartVertex
, NumVertices
, Flags
);
4085 static HRESULT WINAPI
4086 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUPreserve(IDirect3DDevice7
*iface
,
4087 D3DPRIMITIVETYPE PrimitiveType
,
4088 IDirect3DVertexBuffer7
*D3DVertexBuf
,
4096 old_fpucw
= d3d_fpu_setup();
4097 hr
= IDirect3DDeviceImpl_7_DrawPrimitiveVB(iface
, PrimitiveType
, D3DVertexBuf
, StartVertex
, NumVertices
, Flags
);
4098 set_fpu_control_word(old_fpucw
);
4103 static HRESULT WINAPI
IDirect3DDeviceImpl_3_DrawPrimitiveVB(IDirect3DDevice3
*iface
,
4104 D3DPRIMITIVETYPE PrimitiveType
, IDirect3DVertexBuffer
*D3DVertexBuf
, DWORD StartVertex
,
4105 DWORD NumVertices
, DWORD Flags
)
4107 IDirect3DVertexBufferImpl
*vb
= D3DVertexBuf
? vb_from_vb1(D3DVertexBuf
) : NULL
;
4109 TRACE("iface %p, primitive_type %#x, vb %p, start_vertex %u, vertex_count %u, flags %#x.\n",
4110 iface
, PrimitiveType
, D3DVertexBuf
, StartVertex
, NumVertices
, Flags
);
4112 return IDirect3DDevice7_DrawPrimitiveVB((IDirect3DDevice7
*)device_from_device3(iface
),
4113 PrimitiveType
, (IDirect3DVertexBuffer7
*)vb
, StartVertex
, NumVertices
, Flags
);
4117 /*****************************************************************************
4118 * IDirect3DDevice7::DrawIndexedPrimitiveVB
4120 * Draws primitives from a vertex buffer to the screen
4123 * PrimitiveType: Type of primitive to be rendered.
4124 * D3DVertexBuf: Source Vertex Buffer
4125 * StartVertex: Index of the first vertex from the buffer to be rendered
4126 * NumVertices: Number of vertices to be rendered
4127 * Indices: Array of DWORDs used to index into the Vertices
4128 * IndexCount: Number of indices in Indices
4129 * Flags: Can be D3DDP_WAIT to wait until rendering has finished
4133 *****************************************************************************/
4135 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB(IDirect3DDevice7
*iface
,
4136 D3DPRIMITIVETYPE PrimitiveType
,
4137 IDirect3DVertexBuffer7
*D3DVertexBuf
,
4144 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
4145 IDirect3DVertexBufferImpl
*vb
= (IDirect3DVertexBufferImpl
*)D3DVertexBuf
;
4146 DWORD stride
= get_flexible_vertex_size(vb
->fvf
);
4147 struct wined3d_resource
*wined3d_resource
;
4148 struct wined3d_resource_desc desc
;
4149 WORD
*LockedIndices
;
4152 TRACE("iface %p, primitive_type %#x, vb %p, start_vertex %u, vertex_count %u, indices %p, index_count %u, flags %#x.\n",
4153 iface
, PrimitiveType
, D3DVertexBuf
, StartVertex
, NumVertices
, Indices
, IndexCount
, Flags
);
4156 * 1) Upload the Indices to the index buffer
4157 * 2) Set the index source
4158 * 3) Set the Vertex Buffer as the Stream source
4159 * 4) Call IWineD3DDevice::DrawIndexedPrimitive
4162 EnterCriticalSection(&ddraw_cs
);
4164 hr
= IWineD3DDevice_SetVertexDeclaration(This
->wineD3DDevice
,
4165 vb
->wineD3DVertexDeclaration
);
4168 ERR(" (%p) Setting the FVF failed, hr = %x!\n", This
, hr
);
4169 LeaveCriticalSection(&ddraw_cs
);
4173 /* check that the buffer is large enough to hold the indices,
4174 * reallocate if necessary. */
4175 wined3d_resource
= wined3d_buffer_get_resource(This
->indexbuffer
);
4176 wined3d_resource_get_desc(wined3d_resource
, &desc
);
4177 if (desc
.size
< IndexCount
* sizeof(WORD
))
4179 UINT size
= max(desc
.size
* 2, IndexCount
* sizeof(WORD
));
4180 struct wined3d_buffer
*buffer
;
4182 TRACE("Growing index buffer to %u bytes\n", size
);
4184 hr
= IWineD3DDevice_CreateIndexBuffer(This
->wineD3DDevice
, size
, WINED3DUSAGE_DYNAMIC
/* Usage */,
4185 WINED3DPOOL_DEFAULT
, NULL
, &ddraw_null_wined3d_parent_ops
, &buffer
);
4188 ERR("(%p) IWineD3DDevice::CreateIndexBuffer failed with hr = %08x\n", This
, hr
);
4189 LeaveCriticalSection(&ddraw_cs
);
4193 wined3d_buffer_decref(This
->indexbuffer
);
4194 This
->indexbuffer
= buffer
;
4197 /* Copy the index stream into the index buffer. A new IWineD3DDevice
4198 * method could be created which takes an user pointer containing the
4199 * indices or a SetData-Method for the index buffer, which overrides the
4200 * index buffer data with our pointer. */
4201 hr
= wined3d_buffer_map(This
->indexbuffer
, 0, IndexCount
* sizeof(WORD
),
4202 (BYTE
**)&LockedIndices
, 0);
4205 ERR("Failed to map buffer, hr %#x.\n", hr
);
4206 LeaveCriticalSection(&ddraw_cs
);
4209 memcpy(LockedIndices
, Indices
, IndexCount
* sizeof(WORD
));
4210 wined3d_buffer_unmap(This
->indexbuffer
);
4212 /* Set the index stream */
4213 IWineD3DDevice_SetBaseVertexIndex(This
->wineD3DDevice
, StartVertex
);
4214 hr
= IWineD3DDevice_SetIndexBuffer(This
->wineD3DDevice
, This
->indexbuffer
,
4215 WINED3DFMT_R16_UINT
);
4217 /* Set the vertex stream source */
4218 hr
= IWineD3DDevice_SetStreamSource(This
->wineD3DDevice
,
4219 0 /* StreamNumber */,
4220 vb
->wineD3DVertexBuffer
,
4221 0 /* offset, we pass this to DrawIndexedPrimitive */,
4225 ERR("(%p) IDirect3DDevice::SetStreamSource failed with hr = %08x\n", This
, hr
);
4226 LeaveCriticalSection(&ddraw_cs
);
4231 IWineD3DDevice_SetPrimitiveType(This
->wineD3DDevice
, PrimitiveType
);
4232 hr
= IWineD3DDevice_DrawIndexedPrimitive(This
->wineD3DDevice
, 0 /* StartIndex */, IndexCount
);
4234 LeaveCriticalSection(&ddraw_cs
);
4238 static HRESULT WINAPI
4239 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUSetup(IDirect3DDevice7
*iface
,
4240 D3DPRIMITIVETYPE PrimitiveType
,
4241 IDirect3DVertexBuffer7
*D3DVertexBuf
,
4248 return IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB(iface
, PrimitiveType
, D3DVertexBuf
, StartVertex
, NumVertices
, Indices
, IndexCount
, Flags
);
4251 static HRESULT WINAPI
4252 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUPreserve(IDirect3DDevice7
*iface
,
4253 D3DPRIMITIVETYPE PrimitiveType
,
4254 IDirect3DVertexBuffer7
*D3DVertexBuf
,
4264 old_fpucw
= d3d_fpu_setup();
4265 hr
= IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB(iface
, PrimitiveType
, D3DVertexBuf
, StartVertex
, NumVertices
, Indices
, IndexCount
, Flags
);
4266 set_fpu_control_word(old_fpucw
);
4271 static HRESULT WINAPI
IDirect3DDeviceImpl_3_DrawIndexedPrimitiveVB(IDirect3DDevice3
*iface
,
4272 D3DPRIMITIVETYPE PrimitiveType
, IDirect3DVertexBuffer
*D3DVertexBuf
, WORD
*Indices
,
4273 DWORD IndexCount
, DWORD Flags
)
4275 IDirect3DVertexBufferImpl
*VB
= vb_from_vb1(D3DVertexBuf
);
4277 TRACE("iface %p, primitive_type %#x, vb %p, indices %p, index_count %u, flags %#x.\n",
4278 iface
, PrimitiveType
, D3DVertexBuf
, Indices
, IndexCount
, Flags
);
4280 return IDirect3DDevice7_DrawIndexedPrimitiveVB((IDirect3DDevice7
*)device_from_device3(iface
),
4281 PrimitiveType
, (IDirect3DVertexBuffer7
*)VB
, 0, IndexCount
, Indices
, IndexCount
, Flags
);
4284 /*****************************************************************************
4285 * IDirect3DDevice7::ComputeSphereVisibility
4287 * Calculates the visibility of spheres in the current viewport. The spheres
4288 * are passed in the Centers and Radii arrays, the results are passed back
4289 * in the ReturnValues array. Return values are either completely visible,
4290 * partially visible or completely invisible.
4291 * The return value consist of a combination of D3DCLIP_* flags, or it's
4292 * 0 if the sphere is completely visible(according to the SDK, not checked)
4297 * Centers: Array containing the sphere centers
4298 * Radii: Array containing the sphere radii
4299 * NumSpheres: The number of centers and radii in the arrays
4301 * ReturnValues: Array to write the results to
4305 * (DDERR_INVALIDPARAMS if Centers, Radii or ReturnValues are NULL)
4306 * (D3DERR_INVALIDMATRIX if the combined world, view and proj matrix
4309 *****************************************************************************/
4311 static DWORD
in_plane(UINT plane
, D3DVECTOR normal
, D3DVALUE origin_plane
, D3DVECTOR center
, D3DVALUE radius
)
4313 float distance
, norm
;
4315 norm
= sqrt( normal
.u1
.x
* normal
.u1
.x
+ normal
.u2
.y
* normal
.u2
.y
+ normal
.u3
.z
* normal
.u3
.z
);
4316 distance
= ( origin_plane
+ normal
.u1
.x
* center
.u1
.x
+ normal
.u2
.y
* center
.u2
.y
+ normal
.u3
.z
* center
.u3
.z
) / norm
;
4318 if ( fabs( distance
) < radius
) return D3DSTATUS_CLIPUNIONLEFT
<< plane
;
4319 if ( distance
< -radius
) return (D3DSTATUS_CLIPUNIONLEFT
| D3DSTATUS_CLIPINTERSECTIONLEFT
) << plane
;
4323 static HRESULT WINAPI
4324 IDirect3DDeviceImpl_7_ComputeSphereVisibility(IDirect3DDevice7
*iface
,
4329 DWORD
*ReturnValues
)
4332 D3DVALUE origin_plane
[6];
4337 TRACE("iface %p, centers %p, radii %p, sphere_count %u, flags %#x, return_values %p.\n",
4338 iface
, Centers
, Radii
, NumSpheres
, Flags
, ReturnValues
);
4340 hr
= IDirect3DDeviceImpl_7_GetTransform(iface
, D3DTRANSFORMSTATE_WORLD
, &m
);
4341 if ( hr
!= DD_OK
) return DDERR_INVALIDPARAMS
;
4342 hr
= IDirect3DDeviceImpl_7_GetTransform(iface
, D3DTRANSFORMSTATE_VIEW
, &temp
);
4343 if ( hr
!= DD_OK
) return DDERR_INVALIDPARAMS
;
4344 multiply_matrix(&m
, &temp
, &m
);
4346 hr
= IDirect3DDeviceImpl_7_GetTransform(iface
, D3DTRANSFORMSTATE_PROJECTION
, &temp
);
4347 if ( hr
!= DD_OK
) return DDERR_INVALIDPARAMS
;
4348 multiply_matrix(&m
, &temp
, &m
);
4351 vec
[0].u1
.x
= m
._14
+ m
._11
;
4352 vec
[0].u2
.y
= m
._24
+ m
._21
;
4353 vec
[0].u3
.z
= m
._34
+ m
._31
;
4354 origin_plane
[0] = m
._44
+ m
._41
;
4357 vec
[1].u1
.x
= m
._14
- m
._11
;
4358 vec
[1].u2
.y
= m
._24
- m
._21
;
4359 vec
[1].u3
.z
= m
._34
- m
._31
;
4360 origin_plane
[1] = m
._44
- m
._41
;
4363 vec
[2].u1
.x
= m
._14
- m
._12
;
4364 vec
[2].u2
.y
= m
._24
- m
._22
;
4365 vec
[2].u3
.z
= m
._34
- m
._32
;
4366 origin_plane
[2] = m
._44
- m
._42
;
4369 vec
[3].u1
.x
= m
._14
+ m
._12
;
4370 vec
[3].u2
.y
= m
._24
+ m
._22
;
4371 vec
[3].u3
.z
= m
._34
+ m
._32
;
4372 origin_plane
[3] = m
._44
+ m
._42
;
4375 vec
[4].u1
.x
= m
._13
;
4376 vec
[4].u2
.y
= m
._23
;
4377 vec
[4].u3
.z
= m
._33
;
4378 origin_plane
[4] = m
._43
;
4381 vec
[5].u1
.x
= m
._14
- m
._13
;
4382 vec
[5].u2
.y
= m
._24
- m
._23
;
4383 vec
[5].u3
.z
= m
._34
- m
._33
;
4384 origin_plane
[5] = m
._44
- m
._43
;
4386 for(i
=0; i
<NumSpheres
; i
++)
4388 ReturnValues
[i
] = 0;
4389 for(j
=0; j
<6; j
++) ReturnValues
[i
] |= in_plane(j
, vec
[j
], origin_plane
[j
], Centers
[i
], Radii
[i
]);
4395 static HRESULT WINAPI
IDirect3DDeviceImpl_3_ComputeSphereVisibility(IDirect3DDevice3
*iface
,
4396 D3DVECTOR
*Centers
, D3DVALUE
*Radii
, DWORD NumSpheres
, DWORD Flags
, DWORD
*ReturnValues
)
4398 TRACE("iface %p, centers %p, radii %p, sphere_count %u, flags %#x, return_values %p.\n",
4399 iface
, Centers
, Radii
, NumSpheres
, Flags
, ReturnValues
);
4401 return IDirect3DDevice7_ComputeSphereVisibility((IDirect3DDevice7
*)device_from_device3(iface
),
4402 Centers
, Radii
, NumSpheres
, Flags
, ReturnValues
);
4405 /*****************************************************************************
4406 * IDirect3DDevice7::GetTexture
4408 * Returns the texture interface handle assigned to a texture stage.
4409 * The returned texture is AddRefed. This is taken from old ddraw,
4410 * not checked in Windows.
4415 * Stage: Texture stage to read the texture from
4416 * Texture: Address to store the interface pointer at
4420 * DDERR_INVALIDPARAMS if Texture is NULL
4421 * For details, see IWineD3DDevice::GetTexture
4423 *****************************************************************************/
4425 IDirect3DDeviceImpl_7_GetTexture(IDirect3DDevice7
*iface
,
4427 IDirectDrawSurface7
**Texture
)
4429 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
4430 struct wined3d_texture
*wined3d_texture
;
4433 TRACE("iface %p, stage %u, texture %p.\n", iface
, Stage
, Texture
);
4437 TRACE("Texture == NULL, failing with DDERR_INVALIDPARAMS\n");
4438 return DDERR_INVALIDPARAMS
;
4441 EnterCriticalSection(&ddraw_cs
);
4442 hr
= IWineD3DDevice_GetTexture(This
->wineD3DDevice
, Stage
, &wined3d_texture
);
4443 if (FAILED(hr
) || !wined3d_texture
)
4446 LeaveCriticalSection(&ddraw_cs
);
4450 *Texture
= wined3d_texture_get_parent(wined3d_texture
);
4451 IDirectDrawSurface7_AddRef(*Texture
);
4452 LeaveCriticalSection(&ddraw_cs
);
4456 static HRESULT WINAPI
4457 IDirect3DDeviceImpl_7_GetTexture_FPUSetup(IDirect3DDevice7
*iface
,
4459 IDirectDrawSurface7
**Texture
)
4461 return IDirect3DDeviceImpl_7_GetTexture(iface
, Stage
, Texture
);
4464 static HRESULT WINAPI
4465 IDirect3DDeviceImpl_7_GetTexture_FPUPreserve(IDirect3DDevice7
*iface
,
4467 IDirectDrawSurface7
**Texture
)
4472 old_fpucw
= d3d_fpu_setup();
4473 hr
= IDirect3DDeviceImpl_7_GetTexture(iface
, Stage
, Texture
);
4474 set_fpu_control_word(old_fpucw
);
4479 static HRESULT WINAPI
IDirect3DDeviceImpl_3_GetTexture(IDirect3DDevice3
*iface
, DWORD Stage
,
4480 IDirect3DTexture2
**Texture2
)
4483 IDirectDrawSurface7
*ret_val
;
4485 TRACE("iface %p, stage %u, texture %p.\n", iface
, Stage
, Texture2
);
4487 ret
= IDirect3DDevice7_GetTexture((IDirect3DDevice7
*)device_from_device3(iface
), Stage
, &ret_val
);
4489 *Texture2
= ret_val
? (IDirect3DTexture2
*)&((IDirectDrawSurfaceImpl
*)ret_val
)->IDirect3DTexture2_vtbl
: NULL
;
4491 TRACE("Returning texture %p.\n", *Texture2
);
4496 /*****************************************************************************
4497 * IDirect3DDevice7::SetTexture
4499 * Assigns a texture to a texture stage. Is the texture AddRef-ed?
4504 * Stage: The stage to assign the texture to
4505 * Texture: Interface pointer to the texture surface
4509 * For details, see IWineD3DDevice::SetTexture
4511 *****************************************************************************/
4513 IDirect3DDeviceImpl_7_SetTexture(IDirect3DDevice7
*iface
,
4515 IDirectDrawSurface7
*Texture
)
4517 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
4518 IDirectDrawSurfaceImpl
*surf
= (IDirectDrawSurfaceImpl
*)Texture
;
4521 TRACE("iface %p, stage %u, texture %p.\n", iface
, Stage
, Texture
);
4523 /* Texture may be NULL here */
4524 EnterCriticalSection(&ddraw_cs
);
4525 hr
= IWineD3DDevice_SetTexture(This
->wineD3DDevice
,
4526 Stage
, surf
? surf
->wined3d_texture
: NULL
);
4527 LeaveCriticalSection(&ddraw_cs
);
4531 static HRESULT WINAPI
4532 IDirect3DDeviceImpl_7_SetTexture_FPUSetup(IDirect3DDevice7
*iface
,
4534 IDirectDrawSurface7
*Texture
)
4536 return IDirect3DDeviceImpl_7_SetTexture(iface
, Stage
, Texture
);
4539 static HRESULT WINAPI
4540 IDirect3DDeviceImpl_7_SetTexture_FPUPreserve(IDirect3DDevice7
*iface
,
4542 IDirectDrawSurface7
*Texture
)
4547 old_fpucw
= d3d_fpu_setup();
4548 hr
= IDirect3DDeviceImpl_7_SetTexture(iface
, Stage
, Texture
);
4549 set_fpu_control_word(old_fpucw
);
4554 static HRESULT WINAPI
4555 IDirect3DDeviceImpl_3_SetTexture(IDirect3DDevice3
*iface
,
4557 IDirect3DTexture2
*Texture2
)
4559 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
4560 IDirectDrawSurfaceImpl
*tex
= Texture2
? surface_from_texture2(Texture2
) : NULL
;
4564 TRACE("iface %p, stage %u, texture %p.\n", iface
, Stage
, Texture2
);
4566 EnterCriticalSection(&ddraw_cs
);
4568 if (This
->legacyTextureBlending
)
4569 IDirect3DDevice3_GetRenderState(iface
, D3DRENDERSTATE_TEXTUREMAPBLEND
, &texmapblend
);
4571 hr
= IDirect3DDevice7_SetTexture((IDirect3DDevice7
*)This
, Stage
, (IDirectDrawSurface7
*)tex
);
4573 if (This
->legacyTextureBlending
&& texmapblend
== D3DTBLEND_MODULATE
)
4575 /* This fixup is required by the way D3DTBLEND_MODULATE maps to texture stage states.
4576 See IDirect3DDeviceImpl_3_SetRenderState for details. */
4577 struct wined3d_texture
*tex
= NULL
;
4578 BOOL tex_alpha
= FALSE
;
4579 DDPIXELFORMAT ddfmt
;
4582 result
= IWineD3DDevice_GetTexture(This
->wineD3DDevice
, 0, &tex
);
4584 if(result
== WINED3D_OK
&& tex
)
4586 struct wined3d_resource
*sub_resource
;
4588 if ((sub_resource
= wined3d_texture_get_sub_resource(tex
, 0)))
4590 struct wined3d_resource_desc desc
;
4592 wined3d_resource_get_desc(sub_resource
, &desc
);
4593 ddfmt
.dwSize
= sizeof(ddfmt
);
4594 PixelFormat_WineD3DtoDD(&ddfmt
, desc
.format
);
4595 if (ddfmt
.u5
.dwRGBAlphaBitMask
) tex_alpha
= TRUE
;
4598 wined3d_texture_decref(tex
);
4601 /* Arg 1/2 are already set to WINED3DTA_TEXTURE/WINED3DTA_CURRENT in case of D3DTBLEND_MODULATE */
4603 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAOP
, WINED3DTOP_SELECTARG1
);
4605 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAOP
, WINED3DTOP_SELECTARG2
);
4608 LeaveCriticalSection(&ddraw_cs
);
4613 static const struct tss_lookup
4620 {FALSE
, WINED3DTSS_FORCE_DWORD
}, /* 0, unused */
4621 {FALSE
, WINED3DTSS_COLOROP
}, /* 1, D3DTSS_COLOROP */
4622 {FALSE
, WINED3DTSS_COLORARG1
}, /* 2, D3DTSS_COLORARG1 */
4623 {FALSE
, WINED3DTSS_COLORARG2
}, /* 3, D3DTSS_COLORARG2 */
4624 {FALSE
, WINED3DTSS_ALPHAOP
}, /* 4, D3DTSS_ALPHAOP */
4625 {FALSE
, WINED3DTSS_ALPHAARG1
}, /* 5, D3DTSS_ALPHAARG1 */
4626 {FALSE
, WINED3DTSS_ALPHAARG2
}, /* 6, D3DTSS_ALPHAARG2 */
4627 {FALSE
, WINED3DTSS_BUMPENVMAT00
}, /* 7, D3DTSS_BUMPENVMAT00 */
4628 {FALSE
, WINED3DTSS_BUMPENVMAT01
}, /* 8, D3DTSS_BUMPENVMAT01 */
4629 {FALSE
, WINED3DTSS_BUMPENVMAT10
}, /* 9, D3DTSS_BUMPENVMAT10 */
4630 {FALSE
, WINED3DTSS_BUMPENVMAT11
}, /* 10, D3DTSS_BUMPENVMAT11 */
4631 {FALSE
, WINED3DTSS_TEXCOORDINDEX
}, /* 11, D3DTSS_TEXCOORDINDEX */
4632 {TRUE
, WINED3DSAMP_ADDRESSU
}, /* 12, D3DTSS_ADDRESS */
4633 {TRUE
, WINED3DSAMP_ADDRESSU
}, /* 13, D3DTSS_ADDRESSU */
4634 {TRUE
, WINED3DSAMP_ADDRESSV
}, /* 14, D3DTSS_ADDRESSV */
4635 {TRUE
, WINED3DSAMP_BORDERCOLOR
}, /* 15, D3DTSS_BORDERCOLOR */
4636 {TRUE
, WINED3DSAMP_MAGFILTER
}, /* 16, D3DTSS_MAGFILTER */
4637 {TRUE
, WINED3DSAMP_MINFILTER
}, /* 17, D3DTSS_MINFILTER */
4638 {TRUE
, WINED3DSAMP_MIPFILTER
}, /* 18, D3DTSS_MIPFILTER */
4639 {TRUE
, WINED3DSAMP_MIPMAPLODBIAS
}, /* 19, D3DTSS_MIPMAPLODBIAS */
4640 {TRUE
, WINED3DSAMP_MAXMIPLEVEL
}, /* 20, D3DTSS_MAXMIPLEVEL */
4641 {TRUE
, WINED3DSAMP_MAXANISOTROPY
}, /* 21, D3DTSS_MAXANISOTROPY */
4642 {FALSE
, WINED3DTSS_BUMPENVLSCALE
}, /* 22, D3DTSS_BUMPENVLSCALE */
4643 {FALSE
, WINED3DTSS_BUMPENVLOFFSET
}, /* 23, D3DTSS_BUMPENVLOFFSET */
4644 {FALSE
, WINED3DTSS_TEXTURETRANSFORMFLAGS
}, /* 24, D3DTSS_TEXTURETRANSFORMFLAGS */
4647 /*****************************************************************************
4648 * IDirect3DDevice7::GetTextureStageState
4650 * Retrieves a state from a texture stage.
4655 * Stage: The stage to retrieve the state from
4656 * TexStageStateType: The state type to retrieve
4657 * State: Address to store the state's value at
4661 * DDERR_INVALIDPARAMS if State is NULL
4662 * For details, see IWineD3DDevice::GetTextureStageState
4664 *****************************************************************************/
4666 IDirect3DDeviceImpl_7_GetTextureStageState(IDirect3DDevice7
*iface
,
4668 D3DTEXTURESTAGESTATETYPE TexStageStateType
,
4671 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
4673 const struct tss_lookup
*l
;
4675 TRACE("iface %p, stage %u, state %#x, value %p.\n",
4676 iface
, Stage
, TexStageStateType
, State
);
4679 return DDERR_INVALIDPARAMS
;
4681 if (TexStageStateType
> D3DTSS_TEXTURETRANSFORMFLAGS
)
4683 WARN("Invalid TexStageStateType %#x passed.\n", TexStageStateType
);
4687 l
= &tss_lookup
[TexStageStateType
];
4689 EnterCriticalSection(&ddraw_cs
);
4691 if (l
->sampler_state
)
4693 hr
= IWineD3DDevice_GetSamplerState(This
->wineD3DDevice
, Stage
, l
->state
, State
);
4695 switch(TexStageStateType
)
4697 /* Mipfilter is a sampler state with different values */
4698 case D3DTSS_MIPFILTER
:
4702 case WINED3DTEXF_NONE
: *State
= D3DTFP_NONE
; break;
4703 case WINED3DTEXF_POINT
: *State
= D3DTFP_POINT
; break;
4704 case WINED3DTEXF_LINEAR
: *State
= D3DTFP_LINEAR
; break;
4706 ERR("Unexpected mipfilter value %#x\n", *State
);
4707 *State
= D3DTFP_NONE
;
4713 /* Magfilter has slightly different values */
4714 case D3DTSS_MAGFILTER
:
4718 case WINED3DTEXF_POINT
: *State
= D3DTFG_POINT
; break;
4719 case WINED3DTEXF_LINEAR
: *State
= D3DTFG_LINEAR
; break;
4720 case WINED3DTEXF_ANISOTROPIC
: *State
= D3DTFG_ANISOTROPIC
; break;
4721 case WINED3DTEXF_FLATCUBIC
: *State
= D3DTFG_FLATCUBIC
; break;
4722 case WINED3DTEXF_GAUSSIANCUBIC
: *State
= D3DTFG_GAUSSIANCUBIC
; break;
4724 ERR("Unexpected wined3d mag filter value %#x\n", *State
);
4725 *State
= D3DTFG_POINT
;
4737 hr
= IWineD3DDevice_GetTextureStageState(This
->wineD3DDevice
, Stage
, l
->state
, State
);
4740 LeaveCriticalSection(&ddraw_cs
);
4744 static HRESULT WINAPI
4745 IDirect3DDeviceImpl_7_GetTextureStageState_FPUSetup(IDirect3DDevice7
*iface
,
4747 D3DTEXTURESTAGESTATETYPE TexStageStateType
,
4750 return IDirect3DDeviceImpl_7_GetTextureStageState(iface
, Stage
, TexStageStateType
, State
);
4753 static HRESULT WINAPI
4754 IDirect3DDeviceImpl_7_GetTextureStageState_FPUPreserve(IDirect3DDevice7
*iface
,
4756 D3DTEXTURESTAGESTATETYPE TexStageStateType
,
4762 old_fpucw
= d3d_fpu_setup();
4763 hr
= IDirect3DDeviceImpl_7_GetTextureStageState(iface
, Stage
, TexStageStateType
, State
);
4764 set_fpu_control_word(old_fpucw
);
4769 static HRESULT WINAPI
IDirect3DDeviceImpl_3_GetTextureStageState(IDirect3DDevice3
*iface
,
4770 DWORD Stage
, D3DTEXTURESTAGESTATETYPE TexStageStateType
, DWORD
*State
)
4772 TRACE("iface %p, stage %u, state %#x, value %p.\n",
4773 iface
, Stage
, TexStageStateType
, State
);
4775 return IDirect3DDevice7_GetTextureStageState((IDirect3DDevice7
*)device_from_device3(iface
),
4776 Stage
, TexStageStateType
, State
);
4779 /*****************************************************************************
4780 * IDirect3DDevice7::SetTextureStageState
4782 * Sets a texture stage state. Some stage types need to be handled specially,
4783 * because they do not exist in WineD3D and were moved to another place
4788 * Stage: The stage to modify
4789 * TexStageStateType: The state to change
4790 * State: The new value for the state
4794 * For details, see IWineD3DDevice::SetTextureStageState
4796 *****************************************************************************/
4798 IDirect3DDeviceImpl_7_SetTextureStageState(IDirect3DDevice7
*iface
,
4800 D3DTEXTURESTAGESTATETYPE TexStageStateType
,
4803 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
4804 const struct tss_lookup
*l
;
4807 TRACE("iface %p, stage %u, state %#x, value %#x.\n",
4808 iface
, Stage
, TexStageStateType
, State
);
4810 if (TexStageStateType
> D3DTSS_TEXTURETRANSFORMFLAGS
)
4812 WARN("Invalid TexStageStateType %#x passed.\n", TexStageStateType
);
4816 l
= &tss_lookup
[TexStageStateType
];
4818 EnterCriticalSection(&ddraw_cs
);
4820 if (l
->sampler_state
)
4822 switch(TexStageStateType
)
4824 /* Mipfilter is a sampler state with different values */
4825 case D3DTSS_MIPFILTER
:
4829 case D3DTFP_NONE
: State
= WINED3DTEXF_NONE
; break;
4830 case D3DTFP_POINT
: State
= WINED3DTEXF_POINT
; break;
4831 case 0: /* Unchecked */
4832 case D3DTFP_LINEAR
: State
= WINED3DTEXF_LINEAR
; break;
4834 ERR("Unexpected mipfilter value %d\n", State
);
4835 State
= WINED3DTEXF_NONE
;
4841 /* Magfilter has slightly different values */
4842 case D3DTSS_MAGFILTER
:
4846 case D3DTFG_POINT
: State
= WINED3DTEXF_POINT
; break;
4847 case D3DTFG_LINEAR
: State
= WINED3DTEXF_LINEAR
; break;
4848 case D3DTFG_FLATCUBIC
: State
= WINED3DTEXF_FLATCUBIC
; break;
4849 case D3DTFG_GAUSSIANCUBIC
: State
= WINED3DTEXF_GAUSSIANCUBIC
; break;
4850 case D3DTFG_ANISOTROPIC
: State
= WINED3DTEXF_ANISOTROPIC
; break;
4852 ERR("Unexpected d3d7 mag filter type %d\n", State
);
4853 State
= WINED3DTEXF_POINT
;
4859 case D3DTSS_ADDRESS
:
4860 IWineD3DDevice_SetSamplerState(This
->wineD3DDevice
, Stage
, WINED3DSAMP_ADDRESSV
, State
);
4867 hr
= IWineD3DDevice_SetSamplerState(This
->wineD3DDevice
, Stage
, l
->state
, State
);
4871 hr
= IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, Stage
, l
->state
, State
);
4874 LeaveCriticalSection(&ddraw_cs
);
4878 static HRESULT WINAPI
4879 IDirect3DDeviceImpl_7_SetTextureStageState_FPUSetup(IDirect3DDevice7
*iface
,
4881 D3DTEXTURESTAGESTATETYPE TexStageStateType
,
4884 return IDirect3DDeviceImpl_7_SetTextureStageState(iface
, Stage
, TexStageStateType
, State
);
4887 static HRESULT WINAPI
4888 IDirect3DDeviceImpl_7_SetTextureStageState_FPUPreserve(IDirect3DDevice7
*iface
,
4890 D3DTEXTURESTAGESTATETYPE TexStageStateType
,
4896 old_fpucw
= d3d_fpu_setup();
4897 hr
= IDirect3DDeviceImpl_7_SetTextureStageState(iface
, Stage
, TexStageStateType
, State
);
4898 set_fpu_control_word(old_fpucw
);
4903 static HRESULT WINAPI
IDirect3DDeviceImpl_3_SetTextureStageState(IDirect3DDevice3
*iface
,
4904 DWORD Stage
, D3DTEXTURESTAGESTATETYPE TexStageStateType
, DWORD State
)
4906 TRACE("iface %p, stage %u, state %#x, value %#x.\n",
4907 iface
, Stage
, TexStageStateType
, State
);
4909 return IDirect3DDevice7_SetTextureStageState((IDirect3DDevice7
*)device_from_device3(iface
),
4910 Stage
, TexStageStateType
, State
);
4913 /*****************************************************************************
4914 * IDirect3DDevice7::ValidateDevice
4916 * SDK: "Reports the device's ability to render the currently set
4917 * texture-blending operations in a single pass". Whatever that means
4923 * NumPasses: Address to write the number of necessary passes for the
4924 * desired effect to.
4928 * See IWineD3DDevice::ValidateDevice for more details
4930 *****************************************************************************/
4932 IDirect3DDeviceImpl_7_ValidateDevice(IDirect3DDevice7
*iface
,
4935 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
4938 TRACE("iface %p, pass_count %p.\n", iface
, NumPasses
);
4940 EnterCriticalSection(&ddraw_cs
);
4941 hr
= IWineD3DDevice_ValidateDevice(This
->wineD3DDevice
, NumPasses
);
4942 LeaveCriticalSection(&ddraw_cs
);
4946 static HRESULT WINAPI
4947 IDirect3DDeviceImpl_7_ValidateDevice_FPUSetup(IDirect3DDevice7
*iface
,
4950 return IDirect3DDeviceImpl_7_ValidateDevice(iface
, NumPasses
);
4953 static HRESULT WINAPI
4954 IDirect3DDeviceImpl_7_ValidateDevice_FPUPreserve(IDirect3DDevice7
*iface
,
4960 old_fpucw
= d3d_fpu_setup();
4961 hr
= IDirect3DDeviceImpl_7_ValidateDevice(iface
, NumPasses
);
4962 set_fpu_control_word(old_fpucw
);
4967 static HRESULT WINAPI
IDirect3DDeviceImpl_3_ValidateDevice(IDirect3DDevice3
*iface
, DWORD
*Passes
)
4969 TRACE("iface %p, pass_count %p.\n", iface
, Passes
);
4971 return IDirect3DDevice7_ValidateDevice((IDirect3DDevice7
*)device_from_device3(iface
), Passes
);
4974 /*****************************************************************************
4975 * IDirect3DDevice7::Clear
4977 * Fills the render target, the z buffer and the stencil buffer with a
4978 * clear color / value
4983 * Count: Number of rectangles in Rects must be 0 if Rects is NULL
4984 * Rects: Rectangles to clear. If NULL, the whole surface is cleared
4985 * Flags: Some flags, as usual
4986 * Color: Clear color for the render target
4987 * Z: Clear value for the Z buffer
4988 * Stencil: Clear value to store in each stencil buffer entry
4992 * For details, see IWineD3DDevice::Clear
4994 *****************************************************************************/
4996 IDirect3DDeviceImpl_7_Clear(IDirect3DDevice7
*iface
,
5004 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
5007 TRACE("iface %p, count %u, rects %p, flags %#x, color 0x%08x, z %.8e, stencil %#x.\n",
5008 iface
, Count
, Rects
, Flags
, Color
, Z
, Stencil
);
5010 EnterCriticalSection(&ddraw_cs
);
5011 hr
= IWineD3DDevice_Clear(This
->wineD3DDevice
, Count
, (RECT
*)Rects
, Flags
, Color
, Z
, Stencil
);
5012 LeaveCriticalSection(&ddraw_cs
);
5016 static HRESULT WINAPI
5017 IDirect3DDeviceImpl_7_Clear_FPUSetup(IDirect3DDevice7
*iface
,
5025 return IDirect3DDeviceImpl_7_Clear(iface
, Count
, Rects
, Flags
, Color
, Z
, Stencil
);
5028 static HRESULT WINAPI
5029 IDirect3DDeviceImpl_7_Clear_FPUPreserve(IDirect3DDevice7
*iface
,
5040 old_fpucw
= d3d_fpu_setup();
5041 hr
= IDirect3DDeviceImpl_7_Clear(iface
, Count
, Rects
, Flags
, Color
, Z
, Stencil
);
5042 set_fpu_control_word(old_fpucw
);
5047 /*****************************************************************************
5048 * IDirect3DDevice7::SetViewport
5050 * Sets the current viewport.
5052 * Version 7 only, but IDirect3DViewport uses this call for older
5056 * Data: The new viewport to set
5060 * DDERR_INVALIDPARAMS if Data is NULL
5061 * For more details, see IWineDDDevice::SetViewport
5063 *****************************************************************************/
5065 IDirect3DDeviceImpl_7_SetViewport(IDirect3DDevice7
*iface
,
5068 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
5071 TRACE("iface %p, viewport %p.\n", iface
, Data
);
5074 return DDERR_INVALIDPARAMS
;
5076 /* Note: D3DVIEWPORT7 is compatible with WINED3DVIEWPORT */
5077 EnterCriticalSection(&ddraw_cs
);
5078 hr
= IWineD3DDevice_SetViewport(This
->wineD3DDevice
,
5079 (WINED3DVIEWPORT
*) Data
);
5080 LeaveCriticalSection(&ddraw_cs
);
5084 static HRESULT WINAPI
5085 IDirect3DDeviceImpl_7_SetViewport_FPUSetup(IDirect3DDevice7
*iface
,
5088 return IDirect3DDeviceImpl_7_SetViewport(iface
, Data
);
5091 static HRESULT WINAPI
5092 IDirect3DDeviceImpl_7_SetViewport_FPUPreserve(IDirect3DDevice7
*iface
,
5098 old_fpucw
= d3d_fpu_setup();
5099 hr
= IDirect3DDeviceImpl_7_SetViewport(iface
, Data
);
5100 set_fpu_control_word(old_fpucw
);
5105 /*****************************************************************************
5106 * IDirect3DDevice::GetViewport
5108 * Returns the current viewport
5113 * Data: D3D7Viewport structure to write the viewport information to
5117 * DDERR_INVALIDPARAMS if Data is NULL
5118 * For more details, see IWineD3DDevice::GetViewport
5120 *****************************************************************************/
5122 IDirect3DDeviceImpl_7_GetViewport(IDirect3DDevice7
*iface
,
5125 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
5128 TRACE("iface %p, viewport %p.\n", iface
, Data
);
5131 return DDERR_INVALIDPARAMS
;
5133 /* Note: D3DVIEWPORT7 is compatible with WINED3DVIEWPORT */
5134 EnterCriticalSection(&ddraw_cs
);
5135 hr
= IWineD3DDevice_GetViewport(This
->wineD3DDevice
,
5136 (WINED3DVIEWPORT
*) Data
);
5138 LeaveCriticalSection(&ddraw_cs
);
5139 return hr_ddraw_from_wined3d(hr
);
5142 static HRESULT WINAPI
5143 IDirect3DDeviceImpl_7_GetViewport_FPUSetup(IDirect3DDevice7
*iface
,
5146 return IDirect3DDeviceImpl_7_GetViewport(iface
, Data
);
5149 static HRESULT WINAPI
5150 IDirect3DDeviceImpl_7_GetViewport_FPUPreserve(IDirect3DDevice7
*iface
,
5156 old_fpucw
= d3d_fpu_setup();
5157 hr
= IDirect3DDeviceImpl_7_GetViewport(iface
, Data
);
5158 set_fpu_control_word(old_fpucw
);
5163 /*****************************************************************************
5164 * IDirect3DDevice7::SetMaterial
5171 * Mat: The material to set
5175 * DDERR_INVALIDPARAMS if Mat is NULL.
5176 * For more details, see IWineD3DDevice::SetMaterial
5178 *****************************************************************************/
5180 IDirect3DDeviceImpl_7_SetMaterial(IDirect3DDevice7
*iface
,
5183 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
5186 TRACE("iface %p, material %p.\n", iface
, Mat
);
5188 if (!Mat
) return DDERR_INVALIDPARAMS
;
5189 /* Note: D3DMATERIAL7 is compatible with WINED3DMATERIAL */
5190 EnterCriticalSection(&ddraw_cs
);
5191 hr
= IWineD3DDevice_SetMaterial(This
->wineD3DDevice
,
5192 (WINED3DMATERIAL
*) Mat
);
5193 LeaveCriticalSection(&ddraw_cs
);
5194 return hr_ddraw_from_wined3d(hr
);
5197 static HRESULT WINAPI
5198 IDirect3DDeviceImpl_7_SetMaterial_FPUSetup(IDirect3DDevice7
*iface
,
5201 return IDirect3DDeviceImpl_7_SetMaterial(iface
, Mat
);
5204 static HRESULT WINAPI
5205 IDirect3DDeviceImpl_7_SetMaterial_FPUPreserve(IDirect3DDevice7
*iface
,
5211 old_fpucw
= d3d_fpu_setup();
5212 hr
= IDirect3DDeviceImpl_7_SetMaterial(iface
, Mat
);
5213 set_fpu_control_word(old_fpucw
);
5218 /*****************************************************************************
5219 * IDirect3DDevice7::GetMaterial
5221 * Returns the current material
5226 * Mat: D3DMATERIAL7 structure to write the material parameters to
5230 * DDERR_INVALIDPARAMS if Mat is NULL
5231 * For more details, see IWineD3DDevice::GetMaterial
5233 *****************************************************************************/
5235 IDirect3DDeviceImpl_7_GetMaterial(IDirect3DDevice7
*iface
,
5238 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
5241 TRACE("iface %p, material %p.\n", iface
, Mat
);
5243 EnterCriticalSection(&ddraw_cs
);
5244 /* Note: D3DMATERIAL7 is compatible with WINED3DMATERIAL */
5245 hr
= IWineD3DDevice_GetMaterial(This
->wineD3DDevice
,
5246 (WINED3DMATERIAL
*) Mat
);
5247 LeaveCriticalSection(&ddraw_cs
);
5248 return hr_ddraw_from_wined3d(hr
);
5251 static HRESULT WINAPI
5252 IDirect3DDeviceImpl_7_GetMaterial_FPUSetup(IDirect3DDevice7
*iface
,
5255 return IDirect3DDeviceImpl_7_GetMaterial(iface
, Mat
);
5258 static HRESULT WINAPI
5259 IDirect3DDeviceImpl_7_GetMaterial_FPUPreserve(IDirect3DDevice7
*iface
,
5265 old_fpucw
= d3d_fpu_setup();
5266 hr
= IDirect3DDeviceImpl_7_GetMaterial(iface
, Mat
);
5267 set_fpu_control_word(old_fpucw
);
5272 /*****************************************************************************
5273 * IDirect3DDevice7::SetLight
5275 * Assigns a light to a light index, but doesn't activate it yet.
5277 * Version 7, IDirect3DLight uses this method for older versions
5280 * LightIndex: The index of the new light
5281 * Light: A D3DLIGHT7 structure describing the light
5285 * For more details, see IWineD3DDevice::SetLight
5287 *****************************************************************************/
5289 IDirect3DDeviceImpl_7_SetLight(IDirect3DDevice7
*iface
,
5293 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
5296 TRACE("iface %p, light_idx %u, light %p.\n", iface
, LightIndex
, Light
);
5298 EnterCriticalSection(&ddraw_cs
);
5299 /* Note: D3DLIGHT7 is compatible with WINED3DLIGHT */
5300 hr
= IWineD3DDevice_SetLight(This
->wineD3DDevice
,
5302 (WINED3DLIGHT
*) Light
);
5303 LeaveCriticalSection(&ddraw_cs
);
5304 return hr_ddraw_from_wined3d(hr
);
5307 static HRESULT WINAPI
5308 IDirect3DDeviceImpl_7_SetLight_FPUSetup(IDirect3DDevice7
*iface
,
5312 return IDirect3DDeviceImpl_7_SetLight(iface
, LightIndex
, Light
);
5315 static HRESULT WINAPI
5316 IDirect3DDeviceImpl_7_SetLight_FPUPreserve(IDirect3DDevice7
*iface
,
5323 old_fpucw
= d3d_fpu_setup();
5324 hr
= IDirect3DDeviceImpl_7_SetLight(iface
, LightIndex
, Light
);
5325 set_fpu_control_word(old_fpucw
);
5330 /*****************************************************************************
5331 * IDirect3DDevice7::GetLight
5333 * Returns the light assigned to a light index
5336 * Light: Structure to write the light information to
5340 * DDERR_INVALIDPARAMS if Light is NULL
5341 * For details, see IWineD3DDevice::GetLight
5343 *****************************************************************************/
5345 IDirect3DDeviceImpl_7_GetLight(IDirect3DDevice7
*iface
,
5349 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
5352 TRACE("iface %p, light_idx %u, light %p.\n", iface
, LightIndex
, Light
);
5354 EnterCriticalSection(&ddraw_cs
);
5355 /* Note: D3DLIGHT7 is compatible with WINED3DLIGHT */
5356 rc
= IWineD3DDevice_GetLight(This
->wineD3DDevice
,
5358 (WINED3DLIGHT
*) Light
);
5360 /* Translate the result. WineD3D returns other values than D3D7 */
5361 LeaveCriticalSection(&ddraw_cs
);
5362 return hr_ddraw_from_wined3d(rc
);
5365 static HRESULT WINAPI
5366 IDirect3DDeviceImpl_7_GetLight_FPUSetup(IDirect3DDevice7
*iface
,
5370 return IDirect3DDeviceImpl_7_GetLight(iface
, LightIndex
, Light
);
5373 static HRESULT WINAPI
5374 IDirect3DDeviceImpl_7_GetLight_FPUPreserve(IDirect3DDevice7
*iface
,
5381 old_fpucw
= d3d_fpu_setup();
5382 hr
= IDirect3DDeviceImpl_7_GetLight(iface
, LightIndex
, Light
);
5383 set_fpu_control_word(old_fpucw
);
5388 /*****************************************************************************
5389 * IDirect3DDevice7::BeginStateBlock
5391 * Begins recording to a stateblock
5397 * For details see IWineD3DDevice::BeginStateBlock
5399 *****************************************************************************/
5401 IDirect3DDeviceImpl_7_BeginStateBlock(IDirect3DDevice7
*iface
)
5403 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
5406 TRACE("iface %p.\n", iface
);
5408 EnterCriticalSection(&ddraw_cs
);
5409 hr
= IWineD3DDevice_BeginStateBlock(This
->wineD3DDevice
);
5410 LeaveCriticalSection(&ddraw_cs
);
5411 return hr_ddraw_from_wined3d(hr
);
5414 static HRESULT WINAPI
5415 IDirect3DDeviceImpl_7_BeginStateBlock_FPUSetup(IDirect3DDevice7
*iface
)
5417 return IDirect3DDeviceImpl_7_BeginStateBlock(iface
);
5420 static HRESULT WINAPI
5421 IDirect3DDeviceImpl_7_BeginStateBlock_FPUPreserve(IDirect3DDevice7
*iface
)
5426 old_fpucw
= d3d_fpu_setup();
5427 hr
= IDirect3DDeviceImpl_7_BeginStateBlock(iface
);
5428 set_fpu_control_word(old_fpucw
);
5433 /*****************************************************************************
5434 * IDirect3DDevice7::EndStateBlock
5436 * Stops recording to a state block and returns the created stateblock
5442 * BlockHandle: Address to store the stateblock's handle to
5446 * DDERR_INVALIDPARAMS if BlockHandle is NULL
5447 * See IWineD3DDevice::EndStateBlock for more details
5449 *****************************************************************************/
5451 IDirect3DDeviceImpl_7_EndStateBlock(IDirect3DDevice7
*iface
,
5454 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
5455 struct wined3d_stateblock
*wined3d_sb
;
5459 TRACE("iface %p, stateblock %p.\n", iface
, BlockHandle
);
5463 WARN("BlockHandle == NULL, returning DDERR_INVALIDPARAMS\n");
5464 return DDERR_INVALIDPARAMS
;
5467 EnterCriticalSection(&ddraw_cs
);
5469 hr
= IWineD3DDevice_EndStateBlock(This
->wineD3DDevice
, &wined3d_sb
);
5472 WARN("Failed to end stateblock, hr %#x.\n", hr
);
5473 LeaveCriticalSection(&ddraw_cs
);
5475 return hr_ddraw_from_wined3d(hr
);
5478 h
= ddraw_allocate_handle(&This
->handle_table
, wined3d_sb
, DDRAW_HANDLE_STATEBLOCK
);
5479 if (h
== DDRAW_INVALID_HANDLE
)
5481 ERR("Failed to allocate a stateblock handle.\n");
5482 wined3d_stateblock_decref(wined3d_sb
);
5483 LeaveCriticalSection(&ddraw_cs
);
5485 return DDERR_OUTOFMEMORY
;
5488 LeaveCriticalSection(&ddraw_cs
);
5489 *BlockHandle
= h
+ 1;
5491 return hr_ddraw_from_wined3d(hr
);
5494 static HRESULT WINAPI
5495 IDirect3DDeviceImpl_7_EndStateBlock_FPUSetup(IDirect3DDevice7
*iface
,
5498 return IDirect3DDeviceImpl_7_EndStateBlock(iface
, BlockHandle
);
5501 static HRESULT WINAPI
5502 IDirect3DDeviceImpl_7_EndStateBlock_FPUPreserve(IDirect3DDevice7
*iface
,
5508 old_fpucw
= d3d_fpu_setup();
5509 hr
= IDirect3DDeviceImpl_7_EndStateBlock(iface
, BlockHandle
);
5510 set_fpu_control_word(old_fpucw
);
5515 /*****************************************************************************
5516 * IDirect3DDevice7::PreLoad
5518 * Allows the app to signal that a texture will be used soon, to allow
5519 * the Direct3DDevice to load it to the video card in the meantime.
5524 * Texture: The texture to preload
5528 * DDERR_INVALIDPARAMS if Texture is NULL
5529 * See IWineD3DSurface::PreLoad for details
5531 *****************************************************************************/
5533 IDirect3DDeviceImpl_7_PreLoad(IDirect3DDevice7
*iface
,
5534 IDirectDrawSurface7
*Texture
)
5536 IDirectDrawSurfaceImpl
*surf
= (IDirectDrawSurfaceImpl
*)Texture
;
5538 TRACE("iface %p, texture %p.\n", iface
, Texture
);
5541 return DDERR_INVALIDPARAMS
;
5543 EnterCriticalSection(&ddraw_cs
);
5544 IWineD3DSurface_PreLoad(surf
->WineD3DSurface
);
5545 LeaveCriticalSection(&ddraw_cs
);
5549 static HRESULT WINAPI
5550 IDirect3DDeviceImpl_7_PreLoad_FPUSetup(IDirect3DDevice7
*iface
,
5551 IDirectDrawSurface7
*Texture
)
5553 return IDirect3DDeviceImpl_7_PreLoad(iface
, Texture
);
5556 static HRESULT WINAPI
5557 IDirect3DDeviceImpl_7_PreLoad_FPUPreserve(IDirect3DDevice7
*iface
,
5558 IDirectDrawSurface7
*Texture
)
5563 old_fpucw
= d3d_fpu_setup();
5564 hr
= IDirect3DDeviceImpl_7_PreLoad(iface
, Texture
);
5565 set_fpu_control_word(old_fpucw
);
5570 /*****************************************************************************
5571 * IDirect3DDevice7::ApplyStateBlock
5573 * Activates the state stored in a state block handle.
5576 * BlockHandle: The stateblock handle to activate
5580 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is NULL
5582 *****************************************************************************/
5584 IDirect3DDeviceImpl_7_ApplyStateBlock(IDirect3DDevice7
*iface
,
5587 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
5588 struct wined3d_stateblock
*wined3d_sb
;
5591 TRACE("iface %p, stateblock %#x.\n", iface
, BlockHandle
);
5593 EnterCriticalSection(&ddraw_cs
);
5595 wined3d_sb
= ddraw_get_object(&This
->handle_table
, BlockHandle
- 1, DDRAW_HANDLE_STATEBLOCK
);
5598 WARN("Invalid stateblock handle.\n");
5599 LeaveCriticalSection(&ddraw_cs
);
5600 return D3DERR_INVALIDSTATEBLOCK
;
5603 hr
= wined3d_stateblock_apply(wined3d_sb
);
5604 LeaveCriticalSection(&ddraw_cs
);
5606 return hr_ddraw_from_wined3d(hr
);
5609 static HRESULT WINAPI
5610 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUSetup(IDirect3DDevice7
*iface
,
5613 return IDirect3DDeviceImpl_7_ApplyStateBlock(iface
, BlockHandle
);
5616 static HRESULT WINAPI
5617 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUPreserve(IDirect3DDevice7
*iface
,
5623 old_fpucw
= d3d_fpu_setup();
5624 hr
= IDirect3DDeviceImpl_7_ApplyStateBlock(iface
, BlockHandle
);
5625 set_fpu_control_word(old_fpucw
);
5630 /*****************************************************************************
5631 * IDirect3DDevice7::CaptureStateBlock
5633 * Updates a stateblock's values to the values currently set for the device
5638 * BlockHandle: Stateblock to update
5642 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is NULL
5643 * See IWineD3DDevice::CaptureStateBlock for more details
5645 *****************************************************************************/
5647 IDirect3DDeviceImpl_7_CaptureStateBlock(IDirect3DDevice7
*iface
,
5650 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
5651 struct wined3d_stateblock
*wined3d_sb
;
5654 TRACE("iface %p, stateblock %#x.\n", iface
, BlockHandle
);
5656 EnterCriticalSection(&ddraw_cs
);
5658 wined3d_sb
= ddraw_get_object(&This
->handle_table
, BlockHandle
- 1, DDRAW_HANDLE_STATEBLOCK
);
5661 WARN("Invalid stateblock handle.\n");
5662 LeaveCriticalSection(&ddraw_cs
);
5663 return D3DERR_INVALIDSTATEBLOCK
;
5666 hr
= wined3d_stateblock_capture(wined3d_sb
);
5667 LeaveCriticalSection(&ddraw_cs
);
5668 return hr_ddraw_from_wined3d(hr
);
5671 static HRESULT WINAPI
5672 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUSetup(IDirect3DDevice7
*iface
,
5675 return IDirect3DDeviceImpl_7_CaptureStateBlock(iface
, BlockHandle
);
5678 static HRESULT WINAPI
5679 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUPreserve(IDirect3DDevice7
*iface
,
5685 old_fpucw
= d3d_fpu_setup();
5686 hr
= IDirect3DDeviceImpl_7_CaptureStateBlock(iface
, BlockHandle
);
5687 set_fpu_control_word(old_fpucw
);
5692 /*****************************************************************************
5693 * IDirect3DDevice7::DeleteStateBlock
5695 * Deletes a stateblock handle. This means releasing the WineD3DStateBlock
5700 * BlockHandle: Stateblock handle to delete
5704 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is 0
5706 *****************************************************************************/
5708 IDirect3DDeviceImpl_7_DeleteStateBlock(IDirect3DDevice7
*iface
,
5711 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
5712 struct wined3d_stateblock
*wined3d_sb
;
5715 TRACE("iface %p, stateblock %#x.\n", iface
, BlockHandle
);
5717 EnterCriticalSection(&ddraw_cs
);
5719 wined3d_sb
= ddraw_free_handle(&This
->handle_table
, BlockHandle
- 1, DDRAW_HANDLE_STATEBLOCK
);
5722 WARN("Invalid stateblock handle.\n");
5723 LeaveCriticalSection(&ddraw_cs
);
5724 return D3DERR_INVALIDSTATEBLOCK
;
5727 if ((ref
= wined3d_stateblock_decref(wined3d_sb
)))
5729 ERR("Something is still holding stateblock %p (refcount %u).\n", wined3d_sb
, ref
);
5732 LeaveCriticalSection(&ddraw_cs
);
5736 static HRESULT WINAPI
5737 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUSetup(IDirect3DDevice7
*iface
,
5740 return IDirect3DDeviceImpl_7_DeleteStateBlock(iface
, BlockHandle
);
5743 static HRESULT WINAPI
5744 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUPreserve(IDirect3DDevice7
*iface
,
5750 old_fpucw
= d3d_fpu_setup();
5751 hr
= IDirect3DDeviceImpl_7_DeleteStateBlock(iface
, BlockHandle
);
5752 set_fpu_control_word(old_fpucw
);
5757 /*****************************************************************************
5758 * IDirect3DDevice7::CreateStateBlock
5760 * Creates a new state block handle.
5765 * Type: The state block type
5766 * BlockHandle: Address to write the created handle to
5770 * DDERR_INVALIDPARAMS if BlockHandle is NULL
5772 *****************************************************************************/
5774 IDirect3DDeviceImpl_7_CreateStateBlock(IDirect3DDevice7
*iface
,
5775 D3DSTATEBLOCKTYPE Type
,
5778 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
5779 struct wined3d_stateblock
*wined3d_sb
;
5783 TRACE("iface %p, type %#x, stateblock %p.\n", iface
, Type
, BlockHandle
);
5787 WARN("BlockHandle == NULL, returning DDERR_INVALIDPARAMS\n");
5788 return DDERR_INVALIDPARAMS
;
5790 if(Type
!= D3DSBT_ALL
&& Type
!= D3DSBT_PIXELSTATE
&&
5791 Type
!= D3DSBT_VERTEXSTATE
) {
5792 WARN("Unexpected stateblock type, returning DDERR_INVALIDPARAMS\n");
5793 return DDERR_INVALIDPARAMS
;
5796 EnterCriticalSection(&ddraw_cs
);
5798 /* The D3DSTATEBLOCKTYPE enum is fine here. */
5799 hr
= IWineD3DDevice_CreateStateBlock(This
->wineD3DDevice
, Type
, &wined3d_sb
);
5802 WARN("Failed to create stateblock, hr %#x.\n", hr
);
5803 LeaveCriticalSection(&ddraw_cs
);
5804 return hr_ddraw_from_wined3d(hr
);
5807 h
= ddraw_allocate_handle(&This
->handle_table
, wined3d_sb
, DDRAW_HANDLE_STATEBLOCK
);
5808 if (h
== DDRAW_INVALID_HANDLE
)
5810 ERR("Failed to allocate stateblock handle.\n");
5811 wined3d_stateblock_decref(wined3d_sb
);
5812 LeaveCriticalSection(&ddraw_cs
);
5813 return DDERR_OUTOFMEMORY
;
5816 *BlockHandle
= h
+ 1;
5817 LeaveCriticalSection(&ddraw_cs
);
5819 return hr_ddraw_from_wined3d(hr
);
5822 static HRESULT WINAPI
5823 IDirect3DDeviceImpl_7_CreateStateBlock_FPUSetup(IDirect3DDevice7
*iface
,
5824 D3DSTATEBLOCKTYPE Type
,
5827 return IDirect3DDeviceImpl_7_CreateStateBlock(iface
, Type
, BlockHandle
);
5830 static HRESULT WINAPI
5831 IDirect3DDeviceImpl_7_CreateStateBlock_FPUPreserve(IDirect3DDevice7
*iface
,
5832 D3DSTATEBLOCKTYPE Type
,
5838 old_fpucw
= d3d_fpu_setup();
5839 hr
=IDirect3DDeviceImpl_7_CreateStateBlock(iface
, Type
, BlockHandle
);
5840 set_fpu_control_word(old_fpucw
);
5845 /* Helper function for IDirect3DDeviceImpl_7_Load. */
5846 static BOOL
is_mip_level_subset(IDirectDrawSurfaceImpl
*dest
,
5847 IDirectDrawSurfaceImpl
*src
)
5849 IDirectDrawSurfaceImpl
*src_level
, *dest_level
;
5850 IDirectDrawSurface7
*temp
;
5851 DDSURFACEDESC2 ddsd
;
5852 BOOL levelFound
; /* at least one suitable sublevel in dest found */
5854 /* To satisfy "destination is mip level subset of source" criteria (regular texture counts as 1 level),
5855 * 1) there must be at least one mip level in destination that matched dimensions of some mip level in source and
5856 * 2) there must be no destination levels that don't match any levels in source. Otherwise it's INVALIDPARAMS.
5863 for (;src_level
&& dest_level
;)
5865 if (src_level
->surface_desc
.dwWidth
== dest_level
->surface_desc
.dwWidth
&&
5866 src_level
->surface_desc
.dwHeight
== dest_level
->surface_desc
.dwHeight
)
5870 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
5871 ddsd
.ddsCaps
.dwCaps2
= DDSCAPS2_MIPMAPSUBLEVEL
;
5872 IDirectDrawSurface7_GetAttachedSurface((IDirectDrawSurface7
*)dest_level
, &ddsd
.ddsCaps
, &temp
);
5874 if (dest_level
!= dest
) IDirectDrawSurface7_Release((IDirectDrawSurface7
*)dest_level
);
5876 dest_level
= (IDirectDrawSurfaceImpl
*)temp
;
5879 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
5880 ddsd
.ddsCaps
.dwCaps2
= DDSCAPS2_MIPMAPSUBLEVEL
;
5881 IDirectDrawSurface7_GetAttachedSurface((IDirectDrawSurface7
*)src_level
, &ddsd
.ddsCaps
, &temp
);
5883 if (src_level
!= src
) IDirectDrawSurface7_Release((IDirectDrawSurface7
*)src_level
);
5885 src_level
= (IDirectDrawSurfaceImpl
*)temp
;
5888 if (src_level
&& src_level
!= src
) IDirectDrawSurface7_Release((IDirectDrawSurface7
*)src_level
);
5889 if (dest_level
&& dest_level
!= dest
) IDirectDrawSurface7_Release((IDirectDrawSurface7
*)dest_level
);
5891 return !dest_level
&& levelFound
;
5894 /* Helper function for IDirect3DDeviceImpl_7_Load. */
5895 static void copy_mipmap_chain(IDirect3DDeviceImpl
*device
,
5896 IDirectDrawSurfaceImpl
*dest
,
5897 IDirectDrawSurfaceImpl
*src
,
5898 const POINT
*DestPoint
,
5899 const RECT
*SrcRect
)
5901 IDirectDrawSurfaceImpl
*src_level
, *dest_level
;
5902 IDirectDrawSurface7
*temp
;
5903 DDSURFACEDESC2 ddsd
;
5907 IDirectDrawPalette
*pal
= NULL
, *pal_src
= NULL
;
5910 BOOL palette_missing
= FALSE
;
5912 /* Copy palette, if possible. */
5913 IDirectDrawSurface7_GetPalette((IDirectDrawSurface7
*)src
, &pal_src
);
5914 IDirectDrawSurface7_GetPalette((IDirectDrawSurface7
*)dest
, &pal
);
5916 if (pal_src
!= NULL
&& pal
!= NULL
)
5918 PALETTEENTRY palent
[256];
5920 IDirectDrawPalette_GetEntries(pal_src
, 0, 0, 256, palent
);
5921 IDirectDrawPalette_SetEntries(pal
, 0, 0, 256, palent
);
5924 if (dest
->surface_desc
.u4
.ddpfPixelFormat
.dwFlags
& (DDPF_PALETTEINDEXED1
| DDPF_PALETTEINDEXED2
|
5925 DDPF_PALETTEINDEXED4
| DDPF_PALETTEINDEXED8
| DDPF_PALETTEINDEXEDTO8
) && !pal
)
5927 palette_missing
= TRUE
;
5930 if (pal
) IDirectDrawPalette_Release(pal
);
5931 if (pal_src
) IDirectDrawPalette_Release(pal_src
);
5933 /* Copy colorkeys, if present. */
5934 for (ckeyflag
= DDCKEY_DESTBLT
; ckeyflag
<= DDCKEY_SRCOVERLAY
; ckeyflag
<<= 1)
5936 hr
= IDirectDrawSurface7_GetColorKey((IDirectDrawSurface7
*)src
, ckeyflag
, &ddckey
);
5940 IDirectDrawSurface7_SetColorKey((IDirectDrawSurface7
*)dest
, ckeyflag
, &ddckey
);
5950 for (;src_level
&& dest_level
;)
5952 if (src_level
->surface_desc
.dwWidth
== dest_level
->surface_desc
.dwWidth
&&
5953 src_level
->surface_desc
.dwHeight
== dest_level
->surface_desc
.dwHeight
)
5955 /* Try UpdateSurface that may perform a more direct opengl loading. But skip this if destination is paletted texture and has no palette.
5956 * Some games like Sacrifice set palette after Load, and it is a waste of effort to try to load texture without palette and generates
5957 * warnings in wined3d. */
5958 if (!palette_missing
)
5959 hr
= IWineD3DDevice_UpdateSurface(device
->wineD3DDevice
, src_level
->WineD3DSurface
, &rect
, dest_level
->WineD3DSurface
,
5962 if (palette_missing
|| FAILED(hr
))
5964 /* UpdateSurface may fail e.g. if dest is in system memory. Fall back to BltFast that is less strict. */
5965 IWineD3DSurface_BltFast(dest_level
->WineD3DSurface
,
5967 src_level
->WineD3DSurface
, &rect
, 0);
5970 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
5971 ddsd
.ddsCaps
.dwCaps2
= DDSCAPS2_MIPMAPSUBLEVEL
;
5972 IDirectDrawSurface7_GetAttachedSurface((IDirectDrawSurface7
*)dest_level
, &ddsd
.ddsCaps
, &temp
);
5974 if (dest_level
!= dest
) IDirectDrawSurface7_Release((IDirectDrawSurface7
*)dest_level
);
5976 dest_level
= (IDirectDrawSurfaceImpl
*)temp
;
5979 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
5980 ddsd
.ddsCaps
.dwCaps2
= DDSCAPS2_MIPMAPSUBLEVEL
;
5981 IDirectDrawSurface7_GetAttachedSurface((IDirectDrawSurface7
*)src_level
, &ddsd
.ddsCaps
, &temp
);
5983 if (src_level
!= src
) IDirectDrawSurface7_Release((IDirectDrawSurface7
*)src_level
);
5985 src_level
= (IDirectDrawSurfaceImpl
*)temp
;
5992 rect
.right
= (rect
.right
+ 1) / 2;
5993 rect
.bottom
= (rect
.bottom
+ 1) / 2;
5996 if (src_level
&& src_level
!= src
) IDirectDrawSurface7_Release((IDirectDrawSurface7
*)src_level
);
5997 if (dest_level
&& dest_level
!= dest
) IDirectDrawSurface7_Release((IDirectDrawSurface7
*)dest_level
);
6000 /*****************************************************************************
6001 * IDirect3DDevice7::Load
6003 * Loads a rectangular area from the source into the destination texture.
6004 * It can also copy the source to the faces of a cubic environment map
6009 * DestTex: Destination texture
6010 * DestPoint: Point in the destination where the source image should be
6012 * SrcTex: Source texture
6013 * SrcRect: Source rectangle
6014 * Flags: Cubemap faces to load (DDSCAPS2_CUBEMAP_ALLFACES, DDSCAPS2_CUBEMAP_POSITIVEX,
6015 * DDSCAPS2_CUBEMAP_NEGATIVEX, DDSCAPS2_CUBEMAP_POSITIVEY, DDSCAPS2_CUBEMAP_NEGATIVEY,
6016 * DDSCAPS2_CUBEMAP_POSITIVEZ, DDSCAPS2_CUBEMAP_NEGATIVEZ)
6020 * DDERR_INVALIDPARAMS if DestTex or SrcTex are NULL, broken coordinates or anything unexpected.
6023 *****************************************************************************/
6026 IDirect3DDeviceImpl_7_Load(IDirect3DDevice7
*iface
,
6027 IDirectDrawSurface7
*DestTex
,
6029 IDirectDrawSurface7
*SrcTex
,
6033 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
6034 IDirectDrawSurfaceImpl
*dest
= (IDirectDrawSurfaceImpl
*)DestTex
;
6035 IDirectDrawSurfaceImpl
*src
= (IDirectDrawSurfaceImpl
*)SrcTex
;
6039 TRACE("iface %p, dst_texture %p, dst_pos %s, src_texture %p, src_rect %s, flags %#x.\n",
6040 iface
, DestTex
, wine_dbgstr_point(DestPoint
), SrcTex
, wine_dbgstr_rect(SrcRect
), Flags
);
6042 if( (!src
) || (!dest
) )
6043 return DDERR_INVALIDPARAMS
;
6045 EnterCriticalSection(&ddraw_cs
);
6047 if (SrcRect
) srcrect
= *SrcRect
;
6050 srcrect
.left
= srcrect
.top
= 0;
6051 srcrect
.right
= src
->surface_desc
.dwWidth
;
6052 srcrect
.bottom
= src
->surface_desc
.dwHeight
;
6055 if (DestPoint
) destpoint
= *DestPoint
;
6058 destpoint
.x
= destpoint
.y
= 0;
6060 /* Check bad dimensions. DestPoint is validated against src, not dest, because
6061 * destination can be a subset of mip levels, in which case actual coordinates used
6062 * for it may be divided. If any dimension of dest is larger than source, it can't be
6063 * mip level subset, so an error can be returned early.
6065 if (srcrect
.left
>= srcrect
.right
|| srcrect
.top
>= srcrect
.bottom
||
6066 srcrect
.right
> src
->surface_desc
.dwWidth
||
6067 srcrect
.bottom
> src
->surface_desc
.dwHeight
||
6068 destpoint
.x
+ srcrect
.right
- srcrect
.left
> src
->surface_desc
.dwWidth
||
6069 destpoint
.y
+ srcrect
.bottom
- srcrect
.top
> src
->surface_desc
.dwHeight
||
6070 dest
->surface_desc
.dwWidth
> src
->surface_desc
.dwWidth
||
6071 dest
->surface_desc
.dwHeight
> src
->surface_desc
.dwHeight
)
6073 LeaveCriticalSection(&ddraw_cs
);
6074 return DDERR_INVALIDPARAMS
;
6077 /* Must be top level surfaces. */
6078 if (src
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_MIPMAPSUBLEVEL
||
6079 dest
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_MIPMAPSUBLEVEL
)
6081 LeaveCriticalSection(&ddraw_cs
);
6082 return DDERR_INVALIDPARAMS
;
6085 if (src
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_CUBEMAP
)
6087 DWORD src_face_flag
, dest_face_flag
;
6088 IDirectDrawSurfaceImpl
*src_face
, *dest_face
;
6089 IDirectDrawSurface7
*temp
;
6090 DDSURFACEDESC2 ddsd
;
6093 if (!(dest
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_CUBEMAP
))
6095 LeaveCriticalSection(&ddraw_cs
);
6096 return DDERR_INVALIDPARAMS
;
6099 /* Iterate through cube faces 2 times. First time is just to check INVALIDPARAMS conditions, second
6100 * time it's actual surface loading. */
6101 for (i
= 0; i
< 2; i
++)
6106 for (;dest_face
&& src_face
;)
6108 src_face_flag
= src_face
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_CUBEMAP_ALLFACES
;
6109 dest_face_flag
= dest_face
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_CUBEMAP_ALLFACES
;
6111 if (src_face_flag
== dest_face_flag
)
6115 /* Destination mip levels must be subset of source mip levels. */
6116 if (!is_mip_level_subset(dest_face
, src_face
))
6118 LeaveCriticalSection(&ddraw_cs
);
6119 return DDERR_INVALIDPARAMS
;
6122 else if (Flags
& dest_face_flag
)
6124 copy_mipmap_chain(This
, dest_face
, src_face
, &destpoint
, &srcrect
);
6127 if (src_face_flag
< DDSCAPS2_CUBEMAP_NEGATIVEZ
)
6129 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
6130 ddsd
.ddsCaps
.dwCaps2
= DDSCAPS2_CUBEMAP
| (src_face_flag
<< 1);
6131 IDirectDrawSurface7_GetAttachedSurface((IDirectDrawSurface7
*)src
, &ddsd
.ddsCaps
, &temp
);
6133 if (src_face
!= src
) IDirectDrawSurface7_Release((IDirectDrawSurface7
*)src_face
);
6135 src_face
= (IDirectDrawSurfaceImpl
*)temp
;
6139 if (src_face
!= src
) IDirectDrawSurface7_Release((IDirectDrawSurface7
*)src_face
);
6145 if (dest_face_flag
< DDSCAPS2_CUBEMAP_NEGATIVEZ
)
6147 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
6148 ddsd
.ddsCaps
.dwCaps2
= DDSCAPS2_CUBEMAP
| (dest_face_flag
<< 1);
6149 IDirectDrawSurface7_GetAttachedSurface((IDirectDrawSurface7
*)dest
, &ddsd
.ddsCaps
, &temp
);
6151 if (dest_face
!= dest
) IDirectDrawSurface7_Release((IDirectDrawSurface7
*)dest_face
);
6153 dest_face
= (IDirectDrawSurfaceImpl
*)temp
;
6157 if (dest_face
!= dest
) IDirectDrawSurface7_Release((IDirectDrawSurface7
*)dest_face
);
6165 /* Native returns error if src faces are not subset of dest faces. */
6168 LeaveCriticalSection(&ddraw_cs
);
6169 return DDERR_INVALIDPARAMS
;
6174 LeaveCriticalSection(&ddraw_cs
);
6177 else if (dest
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_CUBEMAP
)
6179 LeaveCriticalSection(&ddraw_cs
);
6180 return DDERR_INVALIDPARAMS
;
6183 /* Handle non cube map textures. */
6185 /* Destination mip levels must be subset of source mip levels. */
6186 if (!is_mip_level_subset(dest
, src
))
6188 LeaveCriticalSection(&ddraw_cs
);
6189 return DDERR_INVALIDPARAMS
;
6192 copy_mipmap_chain(This
, dest
, src
, &destpoint
, &srcrect
);
6194 LeaveCriticalSection(&ddraw_cs
);
6198 static HRESULT WINAPI
6199 IDirect3DDeviceImpl_7_Load_FPUSetup(IDirect3DDevice7
*iface
,
6200 IDirectDrawSurface7
*DestTex
,
6202 IDirectDrawSurface7
*SrcTex
,
6206 return IDirect3DDeviceImpl_7_Load(iface
, DestTex
, DestPoint
, SrcTex
, SrcRect
, Flags
);
6209 static HRESULT WINAPI
6210 IDirect3DDeviceImpl_7_Load_FPUPreserve(IDirect3DDevice7
*iface
,
6211 IDirectDrawSurface7
*DestTex
,
6213 IDirectDrawSurface7
*SrcTex
,
6220 old_fpucw
= d3d_fpu_setup();
6221 hr
= IDirect3DDeviceImpl_7_Load(iface
, DestTex
, DestPoint
, SrcTex
, SrcRect
, Flags
);
6222 set_fpu_control_word(old_fpucw
);
6227 /*****************************************************************************
6228 * IDirect3DDevice7::LightEnable
6230 * Enables or disables a light
6232 * Version 7, IDirect3DLight uses this method too.
6235 * LightIndex: The index of the light to enable / disable
6236 * Enable: Enable or disable the light
6240 * For more details, see IWineD3DDevice::SetLightEnable
6242 *****************************************************************************/
6244 IDirect3DDeviceImpl_7_LightEnable(IDirect3DDevice7
*iface
,
6248 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
6251 TRACE("iface %p, light_idx %u, enabled %#x.\n", iface
, LightIndex
, Enable
);
6253 EnterCriticalSection(&ddraw_cs
);
6254 hr
= IWineD3DDevice_SetLightEnable(This
->wineD3DDevice
, LightIndex
, Enable
);
6255 LeaveCriticalSection(&ddraw_cs
);
6256 return hr_ddraw_from_wined3d(hr
);
6259 static HRESULT WINAPI
6260 IDirect3DDeviceImpl_7_LightEnable_FPUSetup(IDirect3DDevice7
*iface
,
6264 return IDirect3DDeviceImpl_7_LightEnable(iface
, LightIndex
, Enable
);
6267 static HRESULT WINAPI
6268 IDirect3DDeviceImpl_7_LightEnable_FPUPreserve(IDirect3DDevice7
*iface
,
6275 old_fpucw
= d3d_fpu_setup();
6276 hr
= IDirect3DDeviceImpl_7_LightEnable(iface
, LightIndex
, Enable
);
6277 set_fpu_control_word(old_fpucw
);
6282 /*****************************************************************************
6283 * IDirect3DDevice7::GetLightEnable
6285 * Retrieves if the light with the given index is enabled or not
6290 * LightIndex: Index of desired light
6291 * Enable: Pointer to a BOOL which contains the result
6295 * DDERR_INVALIDPARAMS if Enable is NULL
6296 * See IWineD3DDevice::GetLightEnable for more details
6298 *****************************************************************************/
6300 IDirect3DDeviceImpl_7_GetLightEnable(IDirect3DDevice7
*iface
,
6304 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
6307 TRACE("iface %p, light_idx %u, enabled %p.\n", iface
, LightIndex
, Enable
);
6310 return DDERR_INVALIDPARAMS
;
6312 EnterCriticalSection(&ddraw_cs
);
6313 hr
= IWineD3DDevice_GetLightEnable(This
->wineD3DDevice
, LightIndex
, Enable
);
6314 LeaveCriticalSection(&ddraw_cs
);
6315 return hr_ddraw_from_wined3d(hr
);
6318 static HRESULT WINAPI
6319 IDirect3DDeviceImpl_7_GetLightEnable_FPUSetup(IDirect3DDevice7
*iface
,
6323 return IDirect3DDeviceImpl_7_GetLightEnable(iface
, LightIndex
, Enable
);
6326 static HRESULT WINAPI
6327 IDirect3DDeviceImpl_7_GetLightEnable_FPUPreserve(IDirect3DDevice7
*iface
,
6334 old_fpucw
= d3d_fpu_setup();
6335 hr
= IDirect3DDeviceImpl_7_GetLightEnable(iface
, LightIndex
, Enable
);
6336 set_fpu_control_word(old_fpucw
);
6341 /*****************************************************************************
6342 * IDirect3DDevice7::SetClipPlane
6344 * Sets custom clipping plane
6349 * Index: The index of the clipping plane
6350 * PlaneEquation: An equation defining the clipping plane
6354 * DDERR_INVALIDPARAMS if PlaneEquation is NULL
6355 * See IWineD3DDevice::SetClipPlane for more details
6357 *****************************************************************************/
6359 IDirect3DDeviceImpl_7_SetClipPlane(IDirect3DDevice7
*iface
,
6361 D3DVALUE
* PlaneEquation
)
6363 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
6366 TRACE("iface %p, idx %u, plane %p.\n", iface
, Index
, PlaneEquation
);
6369 return DDERR_INVALIDPARAMS
;
6371 EnterCriticalSection(&ddraw_cs
);
6372 hr
= IWineD3DDevice_SetClipPlane(This
->wineD3DDevice
, Index
, PlaneEquation
);
6373 LeaveCriticalSection(&ddraw_cs
);
6377 static HRESULT WINAPI
6378 IDirect3DDeviceImpl_7_SetClipPlane_FPUSetup(IDirect3DDevice7
*iface
,
6380 D3DVALUE
* PlaneEquation
)
6382 return IDirect3DDeviceImpl_7_SetClipPlane(iface
, Index
, PlaneEquation
);
6385 static HRESULT WINAPI
6386 IDirect3DDeviceImpl_7_SetClipPlane_FPUPreserve(IDirect3DDevice7
*iface
,
6388 D3DVALUE
* PlaneEquation
)
6393 old_fpucw
= d3d_fpu_setup();
6394 hr
= IDirect3DDeviceImpl_7_SetClipPlane(iface
, Index
, PlaneEquation
);
6395 set_fpu_control_word(old_fpucw
);
6400 /*****************************************************************************
6401 * IDirect3DDevice7::GetClipPlane
6403 * Returns the clipping plane with a specific index
6406 * Index: The index of the desired plane
6407 * PlaneEquation: Address to store the plane equation to
6411 * DDERR_INVALIDPARAMS if PlaneEquation is NULL
6412 * See IWineD3DDevice::GetClipPlane for more details
6414 *****************************************************************************/
6416 IDirect3DDeviceImpl_7_GetClipPlane(IDirect3DDevice7
*iface
,
6418 D3DVALUE
* PlaneEquation
)
6420 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
6423 TRACE("iface %p, idx %u, plane %p.\n", iface
, Index
, PlaneEquation
);
6426 return DDERR_INVALIDPARAMS
;
6428 EnterCriticalSection(&ddraw_cs
);
6429 hr
= IWineD3DDevice_GetClipPlane(This
->wineD3DDevice
, Index
, PlaneEquation
);
6430 LeaveCriticalSection(&ddraw_cs
);
6434 static HRESULT WINAPI
6435 IDirect3DDeviceImpl_7_GetClipPlane_FPUSetup(IDirect3DDevice7
*iface
,
6437 D3DVALUE
* PlaneEquation
)
6439 return IDirect3DDeviceImpl_7_GetClipPlane(iface
, Index
, PlaneEquation
);
6442 static HRESULT WINAPI
6443 IDirect3DDeviceImpl_7_GetClipPlane_FPUPreserve(IDirect3DDevice7
*iface
,
6445 D3DVALUE
* PlaneEquation
)
6450 old_fpucw
= d3d_fpu_setup();
6451 hr
= IDirect3DDeviceImpl_7_GetClipPlane(iface
, Index
, PlaneEquation
);
6452 set_fpu_control_word(old_fpucw
);
6457 /*****************************************************************************
6458 * IDirect3DDevice7::GetInfo
6460 * Retrieves some information about the device. The DirectX sdk says that
6461 * this version returns S_FALSE for all retail builds of DirectX, that's what
6462 * this implementation does.
6465 * DevInfoID: Information type requested
6466 * DevInfoStruct: Pointer to a structure to store the info to
6467 * Size: Size of the structure
6470 * S_FALSE, because it's a non-debug driver
6472 *****************************************************************************/
6473 static HRESULT WINAPI
6474 IDirect3DDeviceImpl_7_GetInfo(IDirect3DDevice7
*iface
,
6476 void *DevInfoStruct
,
6479 TRACE("iface %p, info_id %#x, info %p, info_size %u.\n",
6480 iface
, DevInfoID
, DevInfoStruct
, Size
);
6482 if (TRACE_ON(ddraw
))
6484 TRACE(" info requested : ");
6487 case D3DDEVINFOID_TEXTUREMANAGER
: TRACE("D3DDEVINFOID_TEXTUREMANAGER\n"); break;
6488 case D3DDEVINFOID_D3DTEXTUREMANAGER
: TRACE("D3DDEVINFOID_D3DTEXTUREMANAGER\n"); break;
6489 case D3DDEVINFOID_TEXTURING
: TRACE("D3DDEVINFOID_TEXTURING\n"); break;
6490 default: ERR(" invalid flag !!!\n"); return DDERR_INVALIDPARAMS
;
6494 return S_FALSE
; /* According to MSDN, this is valid for a non-debug driver */
6497 /* For performance optimization, devices created in FPUSETUP and FPUPRESERVE modes
6498 * have separate vtables. Simple functions where this doesn't matter like GetDirect3D
6499 * are not duplicated.
6501 * Device created with DDSCL_FPUSETUP (d3d7 default) - device methods assume that FPU
6502 * has already been setup for optimal d3d operation.
6504 * Device created with DDSCL_FPUPRESERVE - resets and restores FPU mode when necessary in
6505 * d3d calls (FPU may be in a mode non-suitable for d3d when the app calls d3d). Required
6506 * by Sacrifice (game). */
6507 static const struct IDirect3DDevice7Vtbl d3d_device7_fpu_setup_vtbl
=
6509 /*** IUnknown Methods ***/
6510 IDirect3DDeviceImpl_7_QueryInterface
,
6511 IDirect3DDeviceImpl_7_AddRef
,
6512 IDirect3DDeviceImpl_7_Release
,
6513 /*** IDirect3DDevice7 ***/
6514 IDirect3DDeviceImpl_7_GetCaps_FPUSetup
,
6515 IDirect3DDeviceImpl_7_EnumTextureFormats_FPUSetup
,
6516 IDirect3DDeviceImpl_7_BeginScene_FPUSetup
,
6517 IDirect3DDeviceImpl_7_EndScene_FPUSetup
,
6518 IDirect3DDeviceImpl_7_GetDirect3D
,
6519 IDirect3DDeviceImpl_7_SetRenderTarget_FPUSetup
,
6520 IDirect3DDeviceImpl_7_GetRenderTarget
,
6521 IDirect3DDeviceImpl_7_Clear_FPUSetup
,
6522 IDirect3DDeviceImpl_7_SetTransform_FPUSetup
,
6523 IDirect3DDeviceImpl_7_GetTransform_FPUSetup
,
6524 IDirect3DDeviceImpl_7_SetViewport_FPUSetup
,
6525 IDirect3DDeviceImpl_7_MultiplyTransform_FPUSetup
,
6526 IDirect3DDeviceImpl_7_GetViewport_FPUSetup
,
6527 IDirect3DDeviceImpl_7_SetMaterial_FPUSetup
,
6528 IDirect3DDeviceImpl_7_GetMaterial_FPUSetup
,
6529 IDirect3DDeviceImpl_7_SetLight_FPUSetup
,
6530 IDirect3DDeviceImpl_7_GetLight_FPUSetup
,
6531 IDirect3DDeviceImpl_7_SetRenderState_FPUSetup
,
6532 IDirect3DDeviceImpl_7_GetRenderState_FPUSetup
,
6533 IDirect3DDeviceImpl_7_BeginStateBlock_FPUSetup
,
6534 IDirect3DDeviceImpl_7_EndStateBlock_FPUSetup
,
6535 IDirect3DDeviceImpl_7_PreLoad_FPUSetup
,
6536 IDirect3DDeviceImpl_7_DrawPrimitive_FPUSetup
,
6537 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUSetup
,
6538 IDirect3DDeviceImpl_7_SetClipStatus
,
6539 IDirect3DDeviceImpl_7_GetClipStatus
,
6540 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUSetup
,
6541 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUSetup
,
6542 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUSetup
,
6543 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUSetup
,
6544 IDirect3DDeviceImpl_7_ComputeSphereVisibility
,
6545 IDirect3DDeviceImpl_7_GetTexture_FPUSetup
,
6546 IDirect3DDeviceImpl_7_SetTexture_FPUSetup
,
6547 IDirect3DDeviceImpl_7_GetTextureStageState_FPUSetup
,
6548 IDirect3DDeviceImpl_7_SetTextureStageState_FPUSetup
,
6549 IDirect3DDeviceImpl_7_ValidateDevice_FPUSetup
,
6550 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUSetup
,
6551 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUSetup
,
6552 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUSetup
,
6553 IDirect3DDeviceImpl_7_CreateStateBlock_FPUSetup
,
6554 IDirect3DDeviceImpl_7_Load_FPUSetup
,
6555 IDirect3DDeviceImpl_7_LightEnable_FPUSetup
,
6556 IDirect3DDeviceImpl_7_GetLightEnable_FPUSetup
,
6557 IDirect3DDeviceImpl_7_SetClipPlane_FPUSetup
,
6558 IDirect3DDeviceImpl_7_GetClipPlane_FPUSetup
,
6559 IDirect3DDeviceImpl_7_GetInfo
6562 static const struct IDirect3DDevice7Vtbl d3d_device7_fpu_preserve_vtbl
=
6564 /*** IUnknown Methods ***/
6565 IDirect3DDeviceImpl_7_QueryInterface
,
6566 IDirect3DDeviceImpl_7_AddRef
,
6567 IDirect3DDeviceImpl_7_Release
,
6568 /*** IDirect3DDevice7 ***/
6569 IDirect3DDeviceImpl_7_GetCaps_FPUPreserve
,
6570 IDirect3DDeviceImpl_7_EnumTextureFormats_FPUPreserve
,
6571 IDirect3DDeviceImpl_7_BeginScene_FPUPreserve
,
6572 IDirect3DDeviceImpl_7_EndScene_FPUPreserve
,
6573 IDirect3DDeviceImpl_7_GetDirect3D
,
6574 IDirect3DDeviceImpl_7_SetRenderTarget_FPUPreserve
,
6575 IDirect3DDeviceImpl_7_GetRenderTarget
,
6576 IDirect3DDeviceImpl_7_Clear_FPUPreserve
,
6577 IDirect3DDeviceImpl_7_SetTransform_FPUPreserve
,
6578 IDirect3DDeviceImpl_7_GetTransform_FPUPreserve
,
6579 IDirect3DDeviceImpl_7_SetViewport_FPUPreserve
,
6580 IDirect3DDeviceImpl_7_MultiplyTransform_FPUPreserve
,
6581 IDirect3DDeviceImpl_7_GetViewport_FPUPreserve
,
6582 IDirect3DDeviceImpl_7_SetMaterial_FPUPreserve
,
6583 IDirect3DDeviceImpl_7_GetMaterial_FPUPreserve
,
6584 IDirect3DDeviceImpl_7_SetLight_FPUPreserve
,
6585 IDirect3DDeviceImpl_7_GetLight_FPUPreserve
,
6586 IDirect3DDeviceImpl_7_SetRenderState_FPUPreserve
,
6587 IDirect3DDeviceImpl_7_GetRenderState_FPUPreserve
,
6588 IDirect3DDeviceImpl_7_BeginStateBlock_FPUPreserve
,
6589 IDirect3DDeviceImpl_7_EndStateBlock_FPUPreserve
,
6590 IDirect3DDeviceImpl_7_PreLoad_FPUPreserve
,
6591 IDirect3DDeviceImpl_7_DrawPrimitive_FPUPreserve
,
6592 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUPreserve
,
6593 IDirect3DDeviceImpl_7_SetClipStatus
,
6594 IDirect3DDeviceImpl_7_GetClipStatus
,
6595 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUPreserve
,
6596 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUPreserve
,
6597 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUPreserve
,
6598 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUPreserve
,
6599 IDirect3DDeviceImpl_7_ComputeSphereVisibility
,
6600 IDirect3DDeviceImpl_7_GetTexture_FPUPreserve
,
6601 IDirect3DDeviceImpl_7_SetTexture_FPUPreserve
,
6602 IDirect3DDeviceImpl_7_GetTextureStageState_FPUPreserve
,
6603 IDirect3DDeviceImpl_7_SetTextureStageState_FPUPreserve
,
6604 IDirect3DDeviceImpl_7_ValidateDevice_FPUPreserve
,
6605 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUPreserve
,
6606 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUPreserve
,
6607 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUPreserve
,
6608 IDirect3DDeviceImpl_7_CreateStateBlock_FPUPreserve
,
6609 IDirect3DDeviceImpl_7_Load_FPUPreserve
,
6610 IDirect3DDeviceImpl_7_LightEnable_FPUPreserve
,
6611 IDirect3DDeviceImpl_7_GetLightEnable_FPUPreserve
,
6612 IDirect3DDeviceImpl_7_SetClipPlane_FPUPreserve
,
6613 IDirect3DDeviceImpl_7_GetClipPlane_FPUPreserve
,
6614 IDirect3DDeviceImpl_7_GetInfo
6617 static const struct IDirect3DDevice3Vtbl d3d_device3_vtbl
=
6619 /*** IUnknown Methods ***/
6620 IDirect3DDeviceImpl_3_QueryInterface
,
6621 IDirect3DDeviceImpl_3_AddRef
,
6622 IDirect3DDeviceImpl_3_Release
,
6623 /*** IDirect3DDevice3 ***/
6624 IDirect3DDeviceImpl_3_GetCaps
,
6625 IDirect3DDeviceImpl_3_GetStats
,
6626 IDirect3DDeviceImpl_3_AddViewport
,
6627 IDirect3DDeviceImpl_3_DeleteViewport
,
6628 IDirect3DDeviceImpl_3_NextViewport
,
6629 IDirect3DDeviceImpl_3_EnumTextureFormats
,
6630 IDirect3DDeviceImpl_3_BeginScene
,
6631 IDirect3DDeviceImpl_3_EndScene
,
6632 IDirect3DDeviceImpl_3_GetDirect3D
,
6633 IDirect3DDeviceImpl_3_SetCurrentViewport
,
6634 IDirect3DDeviceImpl_3_GetCurrentViewport
,
6635 IDirect3DDeviceImpl_3_SetRenderTarget
,
6636 IDirect3DDeviceImpl_3_GetRenderTarget
,
6637 IDirect3DDeviceImpl_3_Begin
,
6638 IDirect3DDeviceImpl_3_BeginIndexed
,
6639 IDirect3DDeviceImpl_3_Vertex
,
6640 IDirect3DDeviceImpl_3_Index
,
6641 IDirect3DDeviceImpl_3_End
,
6642 IDirect3DDeviceImpl_3_GetRenderState
,
6643 IDirect3DDeviceImpl_3_SetRenderState
,
6644 IDirect3DDeviceImpl_3_GetLightState
,
6645 IDirect3DDeviceImpl_3_SetLightState
,
6646 IDirect3DDeviceImpl_3_SetTransform
,
6647 IDirect3DDeviceImpl_3_GetTransform
,
6648 IDirect3DDeviceImpl_3_MultiplyTransform
,
6649 IDirect3DDeviceImpl_3_DrawPrimitive
,
6650 IDirect3DDeviceImpl_3_DrawIndexedPrimitive
,
6651 IDirect3DDeviceImpl_3_SetClipStatus
,
6652 IDirect3DDeviceImpl_3_GetClipStatus
,
6653 IDirect3DDeviceImpl_3_DrawPrimitiveStrided
,
6654 IDirect3DDeviceImpl_3_DrawIndexedPrimitiveStrided
,
6655 IDirect3DDeviceImpl_3_DrawPrimitiveVB
,
6656 IDirect3DDeviceImpl_3_DrawIndexedPrimitiveVB
,
6657 IDirect3DDeviceImpl_3_ComputeSphereVisibility
,
6658 IDirect3DDeviceImpl_3_GetTexture
,
6659 IDirect3DDeviceImpl_3_SetTexture
,
6660 IDirect3DDeviceImpl_3_GetTextureStageState
,
6661 IDirect3DDeviceImpl_3_SetTextureStageState
,
6662 IDirect3DDeviceImpl_3_ValidateDevice
6665 static const struct IDirect3DDevice2Vtbl d3d_device2_vtbl
=
6667 /*** IUnknown Methods ***/
6668 IDirect3DDeviceImpl_2_QueryInterface
,
6669 IDirect3DDeviceImpl_2_AddRef
,
6670 IDirect3DDeviceImpl_2_Release
,
6671 /*** IDirect3DDevice2 ***/
6672 IDirect3DDeviceImpl_2_GetCaps
,
6673 IDirect3DDeviceImpl_2_SwapTextureHandles
,
6674 IDirect3DDeviceImpl_2_GetStats
,
6675 IDirect3DDeviceImpl_2_AddViewport
,
6676 IDirect3DDeviceImpl_2_DeleteViewport
,
6677 IDirect3DDeviceImpl_2_NextViewport
,
6678 IDirect3DDeviceImpl_2_EnumTextureFormats
,
6679 IDirect3DDeviceImpl_2_BeginScene
,
6680 IDirect3DDeviceImpl_2_EndScene
,
6681 IDirect3DDeviceImpl_2_GetDirect3D
,
6682 IDirect3DDeviceImpl_2_SetCurrentViewport
,
6683 IDirect3DDeviceImpl_2_GetCurrentViewport
,
6684 IDirect3DDeviceImpl_2_SetRenderTarget
,
6685 IDirect3DDeviceImpl_2_GetRenderTarget
,
6686 IDirect3DDeviceImpl_2_Begin
,
6687 IDirect3DDeviceImpl_2_BeginIndexed
,
6688 IDirect3DDeviceImpl_2_Vertex
,
6689 IDirect3DDeviceImpl_2_Index
,
6690 IDirect3DDeviceImpl_2_End
,
6691 IDirect3DDeviceImpl_2_GetRenderState
,
6692 IDirect3DDeviceImpl_2_SetRenderState
,
6693 IDirect3DDeviceImpl_2_GetLightState
,
6694 IDirect3DDeviceImpl_2_SetLightState
,
6695 IDirect3DDeviceImpl_2_SetTransform
,
6696 IDirect3DDeviceImpl_2_GetTransform
,
6697 IDirect3DDeviceImpl_2_MultiplyTransform
,
6698 IDirect3DDeviceImpl_2_DrawPrimitive
,
6699 IDirect3DDeviceImpl_2_DrawIndexedPrimitive
,
6700 IDirect3DDeviceImpl_2_SetClipStatus
,
6701 IDirect3DDeviceImpl_2_GetClipStatus
6704 static const struct IDirect3DDeviceVtbl d3d_device1_vtbl
=
6706 /*** IUnknown Methods ***/
6707 IDirect3DDeviceImpl_1_QueryInterface
,
6708 IDirect3DDeviceImpl_1_AddRef
,
6709 IDirect3DDeviceImpl_1_Release
,
6710 /*** IDirect3DDevice1 ***/
6711 IDirect3DDeviceImpl_1_Initialize
,
6712 IDirect3DDeviceImpl_1_GetCaps
,
6713 IDirect3DDeviceImpl_1_SwapTextureHandles
,
6714 IDirect3DDeviceImpl_1_CreateExecuteBuffer
,
6715 IDirect3DDeviceImpl_1_GetStats
,
6716 IDirect3DDeviceImpl_1_Execute
,
6717 IDirect3DDeviceImpl_1_AddViewport
,
6718 IDirect3DDeviceImpl_1_DeleteViewport
,
6719 IDirect3DDeviceImpl_1_NextViewport
,
6720 IDirect3DDeviceImpl_1_Pick
,
6721 IDirect3DDeviceImpl_1_GetPickRecords
,
6722 IDirect3DDeviceImpl_1_EnumTextureFormats
,
6723 IDirect3DDeviceImpl_1_CreateMatrix
,
6724 IDirect3DDeviceImpl_1_SetMatrix
,
6725 IDirect3DDeviceImpl_1_GetMatrix
,
6726 IDirect3DDeviceImpl_1_DeleteMatrix
,
6727 IDirect3DDeviceImpl_1_BeginScene
,
6728 IDirect3DDeviceImpl_1_EndScene
,
6729 IDirect3DDeviceImpl_1_GetDirect3D
6732 /*****************************************************************************
6733 * IDirect3DDeviceImpl_UpdateDepthStencil
6735 * Checks the current render target for attached depth stencils and sets the
6736 * WineD3D depth stencil accordingly.
6739 * The depth stencil state to set if creating the device
6741 *****************************************************************************/
6743 IDirect3DDeviceImpl_UpdateDepthStencil(IDirect3DDeviceImpl
*This
)
6745 IDirectDrawSurface7
*depthStencil
= NULL
;
6746 IDirectDrawSurfaceImpl
*dsi
;
6747 static DDSCAPS2 depthcaps
= { DDSCAPS_ZBUFFER
, 0, 0, 0 };
6749 IDirectDrawSurface7_GetAttachedSurface((IDirectDrawSurface7
*)This
->target
, &depthcaps
, &depthStencil
);
6752 TRACE("Setting wined3d depth stencil to NULL\n");
6753 IWineD3DDevice_SetDepthStencilSurface(This
->wineD3DDevice
,
6755 return WINED3DZB_FALSE
;
6758 dsi
= (IDirectDrawSurfaceImpl
*)depthStencil
;
6759 TRACE("Setting wined3d depth stencil to %p (wined3d %p)\n", dsi
, dsi
->WineD3DSurface
);
6760 IWineD3DDevice_SetDepthStencilSurface(This
->wineD3DDevice
,
6761 dsi
->WineD3DSurface
);
6763 IDirectDrawSurface7_Release(depthStencil
);
6764 return WINED3DZB_TRUE
;
6767 HRESULT
d3d_device_init(IDirect3DDeviceImpl
*device
, IDirectDrawImpl
*ddraw
, IDirectDrawSurfaceImpl
*target
)
6771 if (ddraw
->cooperative_level
& DDSCL_FPUPRESERVE
)
6772 device
->lpVtbl
= &d3d_device7_fpu_preserve_vtbl
;
6774 device
->lpVtbl
= &d3d_device7_fpu_setup_vtbl
;
6776 device
->IDirect3DDevice3_vtbl
= &d3d_device3_vtbl
;
6777 device
->IDirect3DDevice2_vtbl
= &d3d_device2_vtbl
;
6778 device
->IDirect3DDevice_vtbl
= &d3d_device1_vtbl
;
6780 device
->ddraw
= ddraw
;
6781 device
->target
= target
;
6783 if (!ddraw_handle_table_init(&device
->handle_table
, 64))
6785 ERR("Failed to initialize handle table.\n");
6786 return DDERR_OUTOFMEMORY
;
6789 device
->legacyTextureBlending
= FALSE
;
6791 /* Create an index buffer, it's needed for indexed drawing */
6792 hr
= IWineD3DDevice_CreateIndexBuffer(ddraw
->wineD3DDevice
, 0x40000 /* Length. Don't know how long it should be */,
6793 WINED3DUSAGE_DYNAMIC
/* Usage */, WINED3DPOOL_DEFAULT
, NULL
,
6794 &ddraw_null_wined3d_parent_ops
, &device
->indexbuffer
);
6797 ERR("Failed to create an index buffer, hr %#x.\n", hr
);
6798 ddraw_handle_table_destroy(&device
->handle_table
);
6802 /* This is for convenience. */
6803 device
->wineD3DDevice
= ddraw
->wineD3DDevice
;
6804 IWineD3DDevice_AddRef(ddraw
->wineD3DDevice
);
6806 /* Render to the back buffer */
6807 hr
= IWineD3DDevice_SetRenderTarget(ddraw
->wineD3DDevice
, 0, target
->WineD3DSurface
, TRUE
);
6810 ERR("Failed to set render target, hr %#x.\n", hr
);
6811 wined3d_buffer_decref(device
->indexbuffer
);
6812 ddraw_handle_table_destroy(&device
->handle_table
);
6816 /* FIXME: This is broken. The target AddRef() makes some sense, because
6817 * we store a pointer during initialization, but then that's also where
6818 * the AddRef() should be. We don't store ddraw->d3d_target anywhere. */
6819 /* AddRef the render target. Also AddRef the render target from ddraw,
6820 * because if it is released before the app releases the D3D device, the
6821 * D3D capabilities of wined3d will be uninitialized, which has bad effects.
6823 * In most cases, those surfaces are the same anyway, but this will simply
6824 * add another ref which is released when the device is destroyed. */
6825 IDirectDrawSurface7_AddRef((IDirectDrawSurface7
*)target
);
6826 IDirectDrawSurface7_AddRef((IDirectDrawSurface7
*)ddraw
->d3d_target
);
6828 ddraw
->d3ddevice
= device
;
6830 IWineD3DDevice_SetRenderState(ddraw
->wineD3DDevice
, WINED3DRS_ZENABLE
,
6831 IDirect3DDeviceImpl_UpdateDepthStencil(device
));