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 Interfac\x01s */
120 else if( IsEqualGUID( &IID_IDirectDraw7
, refiid
) )
123 TRACE("(%p) Returning IDirectDraw7 interface at %p\n", This
, *obj
);
125 else if ( IsEqualGUID( &IID_IDirectDraw4
, refiid
) )
127 *obj
= &This
->ddraw
->IDirectDraw4_vtbl
;
128 TRACE("(%p) Returning IDirectDraw4 interface at %p\n", This
, *obj
);
130 else if ( IsEqualGUID( &IID_IDirectDraw2
, refiid
) )
132 *obj
= &This
->ddraw
->IDirectDraw2_vtbl
;
133 TRACE("(%p) Returning IDirectDraw2 interface at %p\n", This
, *obj
);
135 else if( IsEqualGUID( &IID_IDirectDraw
, refiid
) )
137 *obj
= &This
->ddraw
->IDirectDraw_vtbl
;
138 TRACE("(%p) Returning IDirectDraw interface at %p\n", This
, *obj
);
142 else if ( IsEqualGUID( &IID_IDirect3D
, refiid
) )
144 *obj
= &This
->ddraw
->IDirect3D_vtbl
;
145 TRACE("(%p) Returning IDirect3D interface at %p\n", This
, *obj
);
147 else if ( IsEqualGUID( &IID_IDirect3D2
, refiid
) )
149 *obj
= &This
->ddraw
->IDirect3D2_vtbl
;
150 TRACE("(%p) Returning IDirect3D2 interface at %p\n", This
, *obj
);
152 else if ( IsEqualGUID( &IID_IDirect3D3
, refiid
) )
154 *obj
= &This
->ddraw
->IDirect3D3_vtbl
;
155 TRACE("(%p) Returning IDirect3D3 interface at %p\n", This
, *obj
);
157 else if ( IsEqualGUID( &IID_IDirect3D7
, refiid
) )
159 *obj
= &This
->ddraw
->IDirect3D7_vtbl
;
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
195 Thunk_IDirect3DDeviceImpl_3_QueryInterface(IDirect3DDevice3
*iface
,
199 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), obj
);
201 return IDirect3DDevice7_QueryInterface((IDirect3DDevice7
*)device_from_device3(iface
), riid
, obj
);
204 static HRESULT WINAPI
205 Thunk_IDirect3DDeviceImpl_2_QueryInterface(IDirect3DDevice2
*iface
,
209 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), obj
);
211 return IDirect3DDevice7_QueryInterface((IDirect3DDevice7
*)device_from_device2(iface
), riid
, obj
);
214 static HRESULT WINAPI
215 Thunk_IDirect3DDeviceImpl_1_QueryInterface(IDirect3DDevice
*iface
,
219 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), obp
);
221 return IDirect3DDevice7_QueryInterface((IDirect3DDevice7
*)device_from_device1(iface
), riid
, obp
);
224 /*****************************************************************************
225 * IDirect3DDevice7::AddRef
227 * Increases the refcount....
228 * The most exciting Method, definitely
230 * Exists in Version 1, 2, 3 and 7
235 *****************************************************************************/
237 IDirect3DDeviceImpl_7_AddRef(IDirect3DDevice7
*iface
)
239 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
240 ULONG ref
= InterlockedIncrement(&This
->ref
);
242 TRACE("%p increasing refcount to %u.\n", This
, ref
);
248 Thunk_IDirect3DDeviceImpl_3_AddRef(IDirect3DDevice3
*iface
)
250 TRACE("iface %p.\n", iface
);
252 return IDirect3DDevice7_AddRef((IDirect3DDevice7
*)device_from_device3(iface
));
256 Thunk_IDirect3DDeviceImpl_2_AddRef(IDirect3DDevice2
*iface
)
258 TRACE("iface %p.\n", iface
);
260 return IDirect3DDevice7_AddRef((IDirect3DDevice7
*)device_from_device2(iface
));
264 Thunk_IDirect3DDeviceImpl_1_AddRef(IDirect3DDevice
*iface
)
266 TRACE("iface %p.\n", iface
);
268 return IDirect3DDevice7_AddRef((IDirect3DDevice7
*)device_from_device1(iface
));
271 /*****************************************************************************
272 * IDirect3DDevice7::Release
274 * Decreases the refcount of the interface
275 * When the refcount is reduced to 0, the object is destroyed.
277 * Exists in Version 1, 2, 3 and 7
282 *****************************************************************************/
284 IDirect3DDeviceImpl_7_Release(IDirect3DDevice7
*iface
)
286 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
287 ULONG ref
= InterlockedDecrement(&This
->ref
);
289 TRACE("%p decreasing refcount to %u.\n", This
, ref
);
291 /* This method doesn't destroy the WineD3DDevice, because it's still in use for
292 * 2D rendering. IDirectDrawSurface7::Release will destroy the WineD3DDevice
293 * when the render target is released
297 IParent
*IndexBufferParent
;
300 EnterCriticalSection(&ddraw_cs
);
301 /* Free the index buffer. */
302 IWineD3DDevice_SetIndexBuffer(This
->wineD3DDevice
, NULL
, WINED3DFMT_UNKNOWN
);
303 IndexBufferParent
= IWineD3DBuffer_GetParent(This
->indexbuffer
);
304 if (IParent_Release(IndexBufferParent
))
306 ERR(" (%p) Something is still holding the index buffer parent %p\n", This
, IndexBufferParent
);
309 /* There is no need to unset the vertex buffer here, IWineD3DDevice_Uninit3D will do that when
310 * destroying the primary stateblock. If a vertex buffer is destroyed while it is bound
311 * IDirect3DVertexBuffer::Release will unset it.
314 /* Set the device up to render to the front buffer since the back
315 * buffer will vanish soon. */
316 IWineD3DDevice_SetRenderTarget(This
->wineD3DDevice
, 0,
317 This
->ddraw
->d3d_target
->WineD3DSurface
, TRUE
);
319 /* Release the WineD3DDevice. This won't destroy it */
320 if(IWineD3DDevice_Release(This
->wineD3DDevice
) <= 0)
322 ERR(" (%p) The wineD3D device %p was destroyed unexpectedly. Prepare for trouble\n", This
, This
->wineD3DDevice
);
325 /* The texture handles should be unset by now, but there might be some bits
326 * missing in our reference counting(needs test). Do a sanity check. */
327 for (i
= 0; i
< This
->handle_table
.entry_count
; ++i
)
329 struct ddraw_handle_entry
*entry
= &This
->handle_table
.entries
[i
];
333 case DDRAW_HANDLE_FREE
:
336 case DDRAW_HANDLE_MATERIAL
:
338 IDirect3DMaterialImpl
*m
= entry
->object
;
339 FIXME("Material handle %#x (%p) not unset properly.\n", i
+ 1, m
);
344 case DDRAW_HANDLE_MATRIX
:
346 /* No FIXME here because this might happen because of sloppy applications. */
347 WARN("Leftover matrix handle %#x (%p), deleting.\n", i
+ 1, entry
->object
);
348 IDirect3DDevice_DeleteMatrix((IDirect3DDevice
*)&This
->IDirect3DDevice_vtbl
, i
+ 1);
352 case DDRAW_HANDLE_STATEBLOCK
:
354 /* No FIXME here because this might happen because of sloppy applications. */
355 WARN("Leftover stateblock handle %#x (%p), deleting.\n", i
+ 1, entry
->object
);
356 IDirect3DDevice7_DeleteStateBlock(iface
, i
+ 1);
360 case DDRAW_HANDLE_SURFACE
:
362 IDirectDrawSurfaceImpl
*surf
= entry
->object
;
363 FIXME("Texture handle %#x (%p) not unset properly.\n", i
+ 1, surf
);
369 FIXME("Handle %#x (%p) has unknown type %#x.\n", i
+ 1, entry
->object
, entry
->type
);
374 ddraw_handle_table_destroy(&This
->handle_table
);
376 TRACE("Releasing target %p %p\n", This
->target
, This
->ddraw
->d3d_target
);
377 /* Release the render target and the WineD3D render target
378 * (See IDirect3D7::CreateDevice for more comments on this)
380 IDirectDrawSurface7_Release((IDirectDrawSurface7
*)This
->target
);
381 IDirectDrawSurface7_Release((IDirectDrawSurface7
*)This
->ddraw
->d3d_target
);
382 TRACE("Target release done\n");
384 This
->ddraw
->d3ddevice
= NULL
;
386 /* Now free the structure */
387 HeapFree(GetProcessHeap(), 0, This
);
388 LeaveCriticalSection(&ddraw_cs
);
396 Thunk_IDirect3DDeviceImpl_3_Release(IDirect3DDevice3
*iface
)
398 TRACE("iface %p.\n", iface
);
400 return IDirect3DDevice7_Release((IDirect3DDevice7
*)device_from_device3(iface
));
404 Thunk_IDirect3DDeviceImpl_2_Release(IDirect3DDevice2
*iface
)
406 TRACE("iface %p.\n", iface
);
408 return IDirect3DDevice7_Release((IDirect3DDevice7
*)device_from_device2(iface
));
412 Thunk_IDirect3DDeviceImpl_1_Release(IDirect3DDevice
*iface
)
414 TRACE("iface %p.\n", iface
);
416 return IDirect3DDevice7_Release((IDirect3DDevice7
*)device_from_device1(iface
));
419 /*****************************************************************************
420 * IDirect3DDevice Methods
421 *****************************************************************************/
423 /*****************************************************************************
424 * IDirect3DDevice::Initialize
426 * Initializes a Direct3DDevice. This implementation is a no-op, as all
427 * initialization is done at create time.
429 * Exists in Version 1
432 * No idea what they mean, as the MSDN page is gone
436 *****************************************************************************/
437 static HRESULT WINAPI
438 IDirect3DDeviceImpl_1_Initialize(IDirect3DDevice
*iface
,
439 IDirect3D
*Direct3D
, GUID
*guid
,
442 /* It shouldn't be crucial, but print a FIXME, I'm interested if
443 * any game calls it and when. */
444 FIXME("iface %p, d3d %p, guid %s, device_desc %p nop!\n",
445 iface
, Direct3D
, debugstr_guid(guid
), Desc
);
450 /*****************************************************************************
451 * IDirect3DDevice7::GetCaps
453 * Retrieves the device's capabilities
455 * This implementation is used for Version 7 only, the older versions have
456 * their own implementation.
459 * Desc: Pointer to a D3DDEVICEDESC7 structure to fill
463 * D3DERR_* if a problem occurs. See WineD3D
465 *****************************************************************************/
467 IDirect3DDeviceImpl_7_GetCaps(IDirect3DDevice7
*iface
,
468 D3DDEVICEDESC7
*Desc
)
470 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
471 D3DDEVICEDESC OldDesc
;
473 TRACE("iface %p, device_desc %p.\n", iface
, Desc
);
475 /* Call the same function used by IDirect3D, this saves code */
476 return IDirect3DImpl_GetCaps(This
->ddraw
->wineD3D
, &OldDesc
, Desc
);
479 static HRESULT WINAPI
480 IDirect3DDeviceImpl_7_GetCaps_FPUSetup(IDirect3DDevice7
*iface
,
481 D3DDEVICEDESC7
*Desc
)
483 return IDirect3DDeviceImpl_7_GetCaps(iface
, Desc
);
486 static HRESULT WINAPI
487 IDirect3DDeviceImpl_7_GetCaps_FPUPreserve(IDirect3DDevice7
*iface
,
488 D3DDEVICEDESC7
*Desc
)
493 old_fpucw
= d3d_fpu_setup();
494 hr
= IDirect3DDeviceImpl_7_GetCaps(iface
, Desc
);
495 set_fpu_control_word(old_fpucw
);
499 /*****************************************************************************
500 * IDirect3DDevice3::GetCaps
502 * Retrieves the capabilities of the hardware device and the emulation
503 * device. For Wine, hardware and emulation are the same (it's all HW).
505 * This implementation is used for Version 1, 2, and 3. Version 7 has its own
508 * HWDesc: Structure to fill with the HW caps
509 * HelDesc: Structure to fill with the hardware emulation caps
513 * D3DERR_* if a problem occurs. See WineD3D
515 *****************************************************************************/
516 static HRESULT WINAPI
517 IDirect3DDeviceImpl_3_GetCaps(IDirect3DDevice3
*iface
,
518 D3DDEVICEDESC
*HWDesc
,
519 D3DDEVICEDESC
*HelDesc
)
521 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
522 D3DDEVICEDESC7 newDesc
;
525 TRACE("iface %p, hw_desc %p, hel_desc %p.\n", iface
, HWDesc
, HelDesc
);
527 hr
= IDirect3DImpl_GetCaps(This
->ddraw
->wineD3D
, HWDesc
, &newDesc
);
528 if(hr
!= D3D_OK
) return hr
;
534 static HRESULT WINAPI
535 Thunk_IDirect3DDeviceImpl_2_GetCaps(IDirect3DDevice2
*iface
,
536 D3DDEVICEDESC
*D3DHWDevDesc
,
537 D3DDEVICEDESC
*D3DHELDevDesc
)
539 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
540 TRACE("iface %p, hw_desc %p, hel_desc %p.\n", iface
, D3DHWDevDesc
, D3DHELDevDesc
);
541 return IDirect3DDevice3_GetCaps((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
, D3DHWDevDesc
, D3DHELDevDesc
);
544 static HRESULT WINAPI
545 Thunk_IDirect3DDeviceImpl_1_GetCaps(IDirect3DDevice
*iface
,
546 D3DDEVICEDESC
*D3DHWDevDesc
,
547 D3DDEVICEDESC
*D3DHELDevDesc
)
549 IDirect3DDeviceImpl
*This
= device_from_device1(iface
);
550 TRACE("iface %p, hw_desc %p, hel_desc %p.\n", iface
, D3DHWDevDesc
, D3DHELDevDesc
);
551 return IDirect3DDevice3_GetCaps((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
, D3DHWDevDesc
, D3DHELDevDesc
);
554 /*****************************************************************************
555 * IDirect3DDevice2::SwapTextureHandles
557 * Swaps the texture handles of 2 Texture interfaces. Version 1 and 2
560 * Tex1, Tex2: The 2 Textures to swap
565 *****************************************************************************/
566 static HRESULT WINAPI
567 IDirect3DDeviceImpl_2_SwapTextureHandles(IDirect3DDevice2
*iface
,
568 IDirect3DTexture2
*Tex1
,
569 IDirect3DTexture2
*Tex2
)
571 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
572 IDirectDrawSurfaceImpl
*surf1
= surface_from_texture2(Tex1
);
573 IDirectDrawSurfaceImpl
*surf2
= surface_from_texture2(Tex2
);
576 TRACE("iface %p, tex1 %p, tex2 %p.\n", iface
, Tex1
, Tex2
);
578 EnterCriticalSection(&ddraw_cs
);
580 h1
= surf1
->Handle
- 1;
581 h2
= surf2
->Handle
- 1;
582 This
->handle_table
.entries
[h1
].object
= surf2
;
583 This
->handle_table
.entries
[h2
].object
= surf1
;
584 surf2
->Handle
= h1
+ 1;
585 surf1
->Handle
= h2
+ 1;
587 LeaveCriticalSection(&ddraw_cs
);
592 static HRESULT WINAPI
593 Thunk_IDirect3DDeviceImpl_1_SwapTextureHandles(IDirect3DDevice
*iface
,
594 IDirect3DTexture
*D3DTex1
,
595 IDirect3DTexture
*D3DTex2
)
597 IDirect3DDeviceImpl
*This
= device_from_device1(iface
);
598 IDirectDrawSurfaceImpl
*surf1
= surface_from_texture1(D3DTex1
);
599 IDirectDrawSurfaceImpl
*surf2
= surface_from_texture1(D3DTex2
);
600 IDirect3DTexture2
*t1
= surf1
? (IDirect3DTexture2
*)&surf1
->IDirect3DTexture2_vtbl
: NULL
;
601 IDirect3DTexture2
*t2
= surf2
? (IDirect3DTexture2
*)&surf2
->IDirect3DTexture2_vtbl
: NULL
;
603 TRACE("iface %p, tex1 %p, tex2 %p.\n", iface
, D3DTex1
, D3DTex2
);
605 return IDirect3DDevice2_SwapTextureHandles((IDirect3DDevice2
*)&This
->IDirect3DDevice2_vtbl
, t1
, t2
);
608 /*****************************************************************************
609 * IDirect3DDevice3::GetStats
611 * This method seems to retrieve some stats from the device.
612 * The MSDN documentation doesn't exist any more, but the D3DSTATS
613 * structure suggests that the amount of drawn primitives and processed
614 * vertices is returned.
616 * Exists in Version 1, 2 and 3
619 * Stats: Pointer to a D3DSTATS structure to be filled
623 * DDERR_INVALIDPARAMS if Stats == NULL
625 *****************************************************************************/
626 static HRESULT WINAPI
627 IDirect3DDeviceImpl_3_GetStats(IDirect3DDevice3
*iface
,
630 FIXME("iface %p, stats %p stub!\n", iface
, Stats
);
633 return DDERR_INVALIDPARAMS
;
635 /* Fill the Stats with 0 */
636 Stats
->dwTrianglesDrawn
= 0;
637 Stats
->dwLinesDrawn
= 0;
638 Stats
->dwPointsDrawn
= 0;
639 Stats
->dwSpansDrawn
= 0;
640 Stats
->dwVerticesProcessed
= 0;
645 static HRESULT WINAPI
646 Thunk_IDirect3DDeviceImpl_2_GetStats(IDirect3DDevice2
*iface
,
649 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
651 TRACE("iface %p, stats %p.\n", iface
, Stats
);
653 return IDirect3DDevice3_GetStats((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
, Stats
);
656 static HRESULT WINAPI
657 Thunk_IDirect3DDeviceImpl_1_GetStats(IDirect3DDevice
*iface
,
660 IDirect3DDeviceImpl
*This
= device_from_device1(iface
);
662 TRACE("iface %p, stats %p.\n", iface
, Stats
);
664 return IDirect3DDevice3_GetStats((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
, Stats
);
667 /*****************************************************************************
668 * IDirect3DDevice::CreateExecuteBuffer
670 * Creates an IDirect3DExecuteBuffer, used for rendering with a
676 * Desc: Buffer description
677 * ExecuteBuffer: Address to return the Interface pointer at
678 * UnkOuter: Must be NULL. Basically for aggregation, which ddraw doesn't
682 * CLASS_E_NOAGGREGATION if UnkOuter != NULL
683 * DDERR_OUTOFMEMORY if we ran out of memory
686 *****************************************************************************/
687 static HRESULT WINAPI
688 IDirect3DDeviceImpl_1_CreateExecuteBuffer(IDirect3DDevice
*iface
,
689 D3DEXECUTEBUFFERDESC
*Desc
,
690 IDirect3DExecuteBuffer
**ExecuteBuffer
,
693 IDirect3DDeviceImpl
*This
= device_from_device1(iface
);
694 IDirect3DExecuteBufferImpl
* object
;
697 TRACE("iface %p, buffer_desc %p, buffer %p, outer_unknown %p.\n",
698 iface
, Desc
, ExecuteBuffer
, UnkOuter
);
701 return CLASS_E_NOAGGREGATION
;
703 /* Allocate the new Execute Buffer */
704 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirect3DExecuteBufferImpl
));
707 ERR("Out of memory when allocating a IDirect3DExecuteBufferImpl structure\n");
708 return DDERR_OUTOFMEMORY
;
711 hr
= d3d_execute_buffer_init(object
, This
, Desc
);
714 WARN("Failed to initialize execute buffer, hr %#x.\n", hr
);
715 HeapFree(GetProcessHeap(), 0, object
);
719 *ExecuteBuffer
= (IDirect3DExecuteBuffer
*)object
;
721 TRACE(" Returning IDirect3DExecuteBuffer at %p, implementation is at %p\n", *ExecuteBuffer
, object
);
726 /*****************************************************************************
727 * IDirect3DDevice::Execute
729 * Executes all the stuff in an execute buffer.
732 * ExecuteBuffer: The buffer to execute
733 * Viewport: The viewport used for rendering
737 * DDERR_INVALIDPARAMS if ExecuteBuffer == NULL
740 *****************************************************************************/
741 static HRESULT WINAPI
742 IDirect3DDeviceImpl_1_Execute(IDirect3DDevice
*iface
,
743 IDirect3DExecuteBuffer
*ExecuteBuffer
,
744 IDirect3DViewport
*Viewport
,
747 IDirect3DDeviceImpl
*This
= device_from_device1(iface
);
748 IDirect3DExecuteBufferImpl
*Direct3DExecuteBufferImpl
= (IDirect3DExecuteBufferImpl
*)ExecuteBuffer
;
749 IDirect3DViewportImpl
*Direct3DViewportImpl
= (IDirect3DViewportImpl
*)Viewport
;
751 TRACE("iface %p, buffer %p, viewport %p, flags %#x.\n", iface
, ExecuteBuffer
, Viewport
, Flags
);
753 if(!Direct3DExecuteBufferImpl
)
754 return DDERR_INVALIDPARAMS
;
757 EnterCriticalSection(&ddraw_cs
);
758 IDirect3DExecuteBufferImpl_Execute(Direct3DExecuteBufferImpl
, This
, Direct3DViewportImpl
);
759 LeaveCriticalSection(&ddraw_cs
);
764 /*****************************************************************************
765 * IDirect3DDevice3::AddViewport
767 * Add a Direct3DViewport to the device's viewport list. These viewports
768 * are wrapped to IDirect3DDevice7 viewports in viewport.c
770 * Exists in Version 1, 2 and 3. Note that IDirect3DViewport 1, 2 and 3
771 * are the same interfaces.
774 * Viewport: The viewport to add
777 * DDERR_INVALIDPARAMS if Viewport == NULL
780 *****************************************************************************/
781 static HRESULT WINAPI
782 IDirect3DDeviceImpl_3_AddViewport(IDirect3DDevice3
*iface
,
783 IDirect3DViewport3
*Viewport
)
785 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
786 IDirect3DViewportImpl
*vp
= (IDirect3DViewportImpl
*)Viewport
;
788 TRACE("iface %p, viewport %p.\n", iface
, Viewport
);
792 return DDERR_INVALIDPARAMS
;
794 EnterCriticalSection(&ddraw_cs
);
795 vp
->next
= This
->viewport_list
;
796 This
->viewport_list
= vp
;
797 vp
->active_device
= This
; /* Viewport must be usable for Clear() after AddViewport,
798 so set active_device here. */
799 LeaveCriticalSection(&ddraw_cs
);
804 static HRESULT WINAPI
805 Thunk_IDirect3DDeviceImpl_2_AddViewport(IDirect3DDevice2
*iface
,
806 IDirect3DViewport2
*Direct3DViewport2
)
808 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
809 IDirect3DViewportImpl
*vp
= (IDirect3DViewportImpl
*)Direct3DViewport2
;
811 TRACE("iface %p, viewport %p.\n", iface
, Direct3DViewport2
);
813 return IDirect3DDevice3_AddViewport((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
, (IDirect3DViewport3
*)vp
);
816 static HRESULT WINAPI
817 Thunk_IDirect3DDeviceImpl_1_AddViewport(IDirect3DDevice
*iface
,
818 IDirect3DViewport
*Direct3DViewport
)
820 IDirect3DDeviceImpl
*This
= device_from_device1(iface
);
821 IDirect3DViewportImpl
*vp
= (IDirect3DViewportImpl
*)Direct3DViewport
;
823 TRACE("iface %p, viewport %p.\n", iface
, Direct3DViewport
);
825 return IDirect3DDevice3_AddViewport((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
, (IDirect3DViewport3
*)vp
);
828 /*****************************************************************************
829 * IDirect3DDevice3::DeleteViewport
831 * Deletes a Direct3DViewport from the device's viewport list.
833 * Exists in Version 1, 2 and 3. Note that all Viewport interface versions
837 * Viewport: The viewport to delete
841 * DDERR_INVALIDPARAMS if the viewport wasn't found in the list
843 *****************************************************************************/
844 static HRESULT WINAPI
845 IDirect3DDeviceImpl_3_DeleteViewport(IDirect3DDevice3
*iface
,
846 IDirect3DViewport3
*Viewport
)
848 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
849 IDirect3DViewportImpl
*vp
= (IDirect3DViewportImpl
*) Viewport
;
850 IDirect3DViewportImpl
*cur_viewport
, *prev_viewport
= NULL
;
852 TRACE("iface %p, viewport %p.\n", iface
, Viewport
);
854 EnterCriticalSection(&ddraw_cs
);
855 cur_viewport
= This
->viewport_list
;
856 while (cur_viewport
!= NULL
)
858 if (cur_viewport
== vp
)
860 if (prev_viewport
== NULL
) This
->viewport_list
= cur_viewport
->next
;
861 else prev_viewport
->next
= cur_viewport
->next
;
862 /* TODO : add desactivate of the viewport and all associated lights... */
863 LeaveCriticalSection(&ddraw_cs
);
866 prev_viewport
= cur_viewport
;
867 cur_viewport
= cur_viewport
->next
;
870 LeaveCriticalSection(&ddraw_cs
);
871 return DDERR_INVALIDPARAMS
;
874 static HRESULT WINAPI
875 Thunk_IDirect3DDeviceImpl_2_DeleteViewport(IDirect3DDevice2
*iface
,
876 IDirect3DViewport2
*Direct3DViewport2
)
878 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
879 IDirect3DViewportImpl
*vp
= (IDirect3DViewportImpl
*)Direct3DViewport2
;
881 TRACE("iface %p, viewport %p.\n", iface
, Direct3DViewport2
);
883 return IDirect3DDevice3_DeleteViewport((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
, (IDirect3DViewport3
*)vp
);
886 static HRESULT WINAPI
887 Thunk_IDirect3DDeviceImpl_1_DeleteViewport(IDirect3DDevice
*iface
,
888 IDirect3DViewport
*Direct3DViewport
)
890 IDirect3DDeviceImpl
*This
= device_from_device1(iface
);
891 IDirect3DViewportImpl
*vp
= (IDirect3DViewportImpl
*)Direct3DViewport
;
893 TRACE("iface %p, viewport %p.\n", iface
, Direct3DViewport
);
895 return IDirect3DDevice3_DeleteViewport((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
, (IDirect3DViewport3
*)vp
);
898 /*****************************************************************************
899 * IDirect3DDevice3::NextViewport
901 * Returns a viewport from the viewport list, depending on the
902 * passed viewport and the flags.
904 * Exists in Version 1, 2 and 3. Note that all Viewport interface versions
908 * Viewport: Viewport to use for beginning the search
909 * Flags: D3DNEXT_NEXT, D3DNEXT_HEAD or D3DNEXT_TAIL
913 * DDERR_INVALIDPARAMS if the flags were wrong, or Viewport was NULL
915 *****************************************************************************/
916 static HRESULT WINAPI
917 IDirect3DDeviceImpl_3_NextViewport(IDirect3DDevice3
*iface
,
918 IDirect3DViewport3
*Viewport3
,
919 IDirect3DViewport3
**lplpDirect3DViewport3
,
922 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
923 IDirect3DViewportImpl
*vp
= (IDirect3DViewportImpl
*)Viewport3
;
924 IDirect3DViewportImpl
*res
= NULL
;
926 TRACE("iface %p, viewport %p, next %p, flags %#x.\n",
927 iface
, Viewport3
, lplpDirect3DViewport3
, Flags
);
931 *lplpDirect3DViewport3
= NULL
;
932 return DDERR_INVALIDPARAMS
;
936 EnterCriticalSection(&ddraw_cs
);
946 res
= This
->viewport_list
;
951 IDirect3DViewportImpl
*cur_viewport
= This
->viewport_list
;
952 if (cur_viewport
!= NULL
)
954 while (cur_viewport
->next
!= NULL
) cur_viewport
= cur_viewport
->next
;
960 *lplpDirect3DViewport3
= NULL
;
961 LeaveCriticalSection(&ddraw_cs
);
962 return DDERR_INVALIDPARAMS
;
965 *lplpDirect3DViewport3
= (IDirect3DViewport3
*)res
;
966 LeaveCriticalSection(&ddraw_cs
);
970 static HRESULT WINAPI
971 Thunk_IDirect3DDeviceImpl_2_NextViewport(IDirect3DDevice2
*iface
,
972 IDirect3DViewport2
*Viewport2
,
973 IDirect3DViewport2
**lplpDirect3DViewport2
,
976 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
977 IDirect3DViewportImpl
*vp
= (IDirect3DViewportImpl
*)Viewport2
;
978 IDirect3DViewport3
*res
;
981 TRACE("iface %p, viewport %p, next %p, flags %#x.\n",
982 iface
, Viewport2
, lplpDirect3DViewport2
, Flags
);
984 hr
= IDirect3DDevice3_NextViewport((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
,
985 (IDirect3DViewport3
*)vp
, &res
, Flags
);
986 *lplpDirect3DViewport2
= (IDirect3DViewport2
*)res
;
990 static HRESULT WINAPI
991 Thunk_IDirect3DDeviceImpl_1_NextViewport(IDirect3DDevice
*iface
,
992 IDirect3DViewport
*Viewport
,
993 IDirect3DViewport
**lplpDirect3DViewport
,
996 IDirect3DDeviceImpl
*This
= device_from_device1(iface
);
997 IDirect3DViewportImpl
*vp
= (IDirect3DViewportImpl
*)Viewport
;
998 IDirect3DViewport3
*res
;
1001 TRACE("iface %p, viewport %p, next %p, flags %#x.\n",
1002 iface
, Viewport
, lplpDirect3DViewport
, Flags
);
1004 hr
= IDirect3DDevice3_NextViewport((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
,
1005 (IDirect3DViewport3
*)vp
, &res
, Flags
);
1006 *lplpDirect3DViewport
= (IDirect3DViewport
*)res
;
1010 /*****************************************************************************
1011 * IDirect3DDevice::Pick
1013 * Executes an execute buffer without performing rendering. Instead, a
1014 * list of primitives that intersect with (x1,y1) of the passed rectangle
1015 * is created. IDirect3DDevice::GetPickRecords can be used to retrieve
1021 * ExecuteBuffer: Buffer to execute
1022 * Viewport: Viewport to use for execution
1023 * Flags: None are defined, according to the SDK
1024 * Rect: Specifies the coordinates to be picked. Only x1 and y2 are used,
1025 * x2 and y2 are ignored.
1028 * D3D_OK because it's a stub
1030 *****************************************************************************/
1031 static HRESULT WINAPI
1032 IDirect3DDeviceImpl_1_Pick(IDirect3DDevice
*iface
,
1033 IDirect3DExecuteBuffer
*ExecuteBuffer
,
1034 IDirect3DViewport
*Viewport
,
1038 FIXME("iface %p, buffer %p, viewport %p, flags %#x, rect %s stub!\n",
1039 iface
, ExecuteBuffer
, Viewport
, Flags
, wine_dbgstr_rect((RECT
*)Rect
));
1044 /*****************************************************************************
1045 * IDirect3DDevice::GetPickRecords
1047 * Retrieves the pick records generated by IDirect3DDevice::GetPickRecords
1052 * Count: Pointer to a DWORD containing the numbers of pick records to
1054 * D3DPickRec: Address to store the resulting D3DPICKRECORD array.
1057 * D3D_OK, because it's a stub
1059 *****************************************************************************/
1060 static HRESULT WINAPI
1061 IDirect3DDeviceImpl_1_GetPickRecords(IDirect3DDevice
*iface
,
1063 D3DPICKRECORD
*D3DPickRec
)
1065 FIXME("iface %p, count %p, records %p stub!\n", iface
, Count
, D3DPickRec
);
1070 /*****************************************************************************
1071 * IDirect3DDevice7::EnumTextureformats
1073 * Enumerates the supported texture formats. It has a list of all possible
1074 * formats and calls IWineD3D::CheckDeviceFormat for each format to see if
1075 * WineD3D supports it. If so, then it is passed to the app.
1077 * This is for Version 7 and 3, older versions have a different
1078 * callback function and their own implementation
1081 * Callback: Callback to call for each enumerated format
1082 * Arg: Argument to pass to the callback
1086 * DDERR_INVALIDPARAMS if Callback == NULL
1088 *****************************************************************************/
1090 IDirect3DDeviceImpl_7_EnumTextureFormats(IDirect3DDevice7
*iface
,
1091 LPD3DENUMPIXELFORMATSCALLBACK Callback
,
1094 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
1096 WINED3DDISPLAYMODE mode
;
1099 static const enum wined3d_format_id FormatList
[] =
1102 WINED3DFMT_B8G8R8A8_UNORM
,
1103 WINED3DFMT_B8G8R8X8_UNORM
,
1105 WINED3DFMT_B8G8R8_UNORM
,
1107 WINED3DFMT_B5G5R5A1_UNORM
,
1108 WINED3DFMT_B4G4R4A4_UNORM
,
1109 WINED3DFMT_B5G6R5_UNORM
,
1110 WINED3DFMT_B5G5R5X1_UNORM
,
1112 WINED3DFMT_B2G3R3_UNORM
,
1120 static const enum wined3d_format_id BumpFormatList
[] =
1122 WINED3DFMT_R8G8_SNORM
,
1123 WINED3DFMT_R5G5_SNORM_L6_UNORM
,
1124 WINED3DFMT_R8G8_SNORM_L8X8_UNORM
,
1125 WINED3DFMT_R16G16_SNORM
,
1126 WINED3DFMT_R10G11B11_SNORM
,
1127 WINED3DFMT_R10G10B10_SNORM_A2_UNORM
1130 TRACE("iface %p, callback %p, context %p.\n", iface
, Callback
, Arg
);
1133 return DDERR_INVALIDPARAMS
;
1135 EnterCriticalSection(&ddraw_cs
);
1137 memset(&mode
, 0, sizeof(mode
));
1138 hr
= IWineD3DDevice_GetDisplayMode(This
->ddraw
->wineD3DDevice
,
1142 LeaveCriticalSection(&ddraw_cs
);
1143 WARN("Cannot get the current adapter format\n");
1147 for (i
= 0; i
< sizeof(FormatList
) / sizeof(*FormatList
); ++i
)
1149 hr
= IWineD3D_CheckDeviceFormat(This
->ddraw
->wineD3D
,
1150 WINED3DADAPTER_DEFAULT
,
1154 WINED3DRTYPE_TEXTURE
,
1159 DDPIXELFORMAT pformat
;
1161 memset(&pformat
, 0, sizeof(pformat
));
1162 pformat
.dwSize
= sizeof(pformat
);
1163 PixelFormat_WineD3DtoDD(&pformat
, FormatList
[i
]);
1165 TRACE("Enumerating WineD3DFormat %d\n", FormatList
[i
]);
1166 hr
= Callback(&pformat
, Arg
);
1167 if(hr
!= DDENUMRET_OK
)
1169 TRACE("Format enumeration cancelled by application\n");
1170 LeaveCriticalSection(&ddraw_cs
);
1176 for (i
= 0; i
< sizeof(BumpFormatList
) / sizeof(*BumpFormatList
); ++i
)
1178 hr
= IWineD3D_CheckDeviceFormat(This
->ddraw
->wineD3D
,
1179 WINED3DADAPTER_DEFAULT
,
1182 WINED3DUSAGE_QUERY_LEGACYBUMPMAP
,
1183 WINED3DRTYPE_TEXTURE
,
1188 DDPIXELFORMAT pformat
;
1190 memset(&pformat
, 0, sizeof(pformat
));
1191 pformat
.dwSize
= sizeof(pformat
);
1192 PixelFormat_WineD3DtoDD(&pformat
, BumpFormatList
[i
]);
1194 TRACE("Enumerating WineD3DFormat %d\n", BumpFormatList
[i
]);
1195 hr
= Callback(&pformat
, Arg
);
1196 if(hr
!= DDENUMRET_OK
)
1198 TRACE("Format enumeration cancelled by application\n");
1199 LeaveCriticalSection(&ddraw_cs
);
1204 TRACE("End of enumeration\n");
1205 LeaveCriticalSection(&ddraw_cs
);
1209 static HRESULT WINAPI
1210 IDirect3DDeviceImpl_7_EnumTextureFormats_FPUSetup(IDirect3DDevice7
*iface
,
1211 LPD3DENUMPIXELFORMATSCALLBACK Callback
,
1214 return IDirect3DDeviceImpl_7_EnumTextureFormats(iface
, Callback
, Arg
);
1217 static HRESULT WINAPI
1218 IDirect3DDeviceImpl_7_EnumTextureFormats_FPUPreserve(IDirect3DDevice7
*iface
,
1219 LPD3DENUMPIXELFORMATSCALLBACK Callback
,
1225 old_fpucw
= d3d_fpu_setup();
1226 hr
= IDirect3DDeviceImpl_7_EnumTextureFormats(iface
, Callback
, Arg
);
1227 set_fpu_control_word(old_fpucw
);
1232 static HRESULT WINAPI
1233 Thunk_IDirect3DDeviceImpl_3_EnumTextureFormats(IDirect3DDevice3
*iface
,
1234 LPD3DENUMPIXELFORMATSCALLBACK Callback
,
1237 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
1239 TRACE("iface %p, callback %p, context %p.\n", iface
, Callback
, Arg
);
1241 return IDirect3DDevice7_EnumTextureFormats((IDirect3DDevice7
*)This
, Callback
, Arg
);
1244 /*****************************************************************************
1245 * IDirect3DDevice2::EnumTextureformats
1247 * EnumTextureFormats for Version 1 and 2, see
1248 * IDirect3DDevice7::EnumTexureFormats for a more detailed description.
1250 * This version has a different callback and does not enumerate FourCC
1253 *****************************************************************************/
1254 static HRESULT WINAPI
1255 IDirect3DDeviceImpl_2_EnumTextureFormats(IDirect3DDevice2
*iface
,
1256 LPD3DENUMTEXTUREFORMATSCALLBACK Callback
,
1259 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
1262 WINED3DDISPLAYMODE mode
;
1264 static const enum wined3d_format_id FormatList
[] =
1267 WINED3DFMT_B8G8R8A8_UNORM
,
1268 WINED3DFMT_B8G8R8X8_UNORM
,
1270 WINED3DFMT_B8G8R8_UNORM
,
1272 WINED3DFMT_B5G5R5A1_UNORM
,
1273 WINED3DFMT_B4G4R4A4_UNORM
,
1274 WINED3DFMT_B5G6R5_UNORM
,
1275 WINED3DFMT_B5G5R5X1_UNORM
,
1277 WINED3DFMT_B2G3R3_UNORM
,
1279 /* FOURCC codes - Not in this version*/
1282 TRACE("iface %p, callback %p, context %p.\n", iface
, Callback
, Arg
);
1285 return DDERR_INVALIDPARAMS
;
1287 EnterCriticalSection(&ddraw_cs
);
1289 memset(&mode
, 0, sizeof(mode
));
1290 hr
= IWineD3DDevice_GetDisplayMode(This
->ddraw
->wineD3DDevice
,
1294 LeaveCriticalSection(&ddraw_cs
);
1295 WARN("Cannot get the current adapter format\n");
1299 for (i
= 0; i
< sizeof(FormatList
) / sizeof(*FormatList
); ++i
)
1301 hr
= IWineD3D_CheckDeviceFormat(This
->ddraw
->wineD3D
,
1306 WINED3DRTYPE_TEXTURE
,
1311 DDSURFACEDESC sdesc
;
1313 memset(&sdesc
, 0, sizeof(sdesc
));
1314 sdesc
.dwSize
= sizeof(sdesc
);
1315 sdesc
.dwFlags
= DDSD_PIXELFORMAT
| DDSD_CAPS
;
1316 sdesc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
1317 sdesc
.ddpfPixelFormat
.dwSize
= sizeof(sdesc
.ddpfPixelFormat
);
1318 PixelFormat_WineD3DtoDD(&sdesc
.ddpfPixelFormat
, FormatList
[i
]);
1320 TRACE("Enumerating WineD3DFormat %d\n", FormatList
[i
]);
1321 hr
= Callback(&sdesc
, Arg
);
1322 if(hr
!= DDENUMRET_OK
)
1324 TRACE("Format enumeration cancelled by application\n");
1325 LeaveCriticalSection(&ddraw_cs
);
1330 TRACE("End of enumeration\n");
1331 LeaveCriticalSection(&ddraw_cs
);
1335 static HRESULT WINAPI
1336 Thunk_IDirect3DDeviceImpl_1_EnumTextureFormats(IDirect3DDevice
*iface
,
1337 LPD3DENUMTEXTUREFORMATSCALLBACK Callback
,
1340 IDirect3DDeviceImpl
*This
= device_from_device1(iface
);
1342 TRACE("iface %p, callback %p, context %p.\n", iface
, Callback
, Arg
);
1344 return IDirect3DDevice2_EnumTextureFormats((IDirect3DDevice2
*)&This
->IDirect3DDevice2_vtbl
, Callback
, Arg
);
1347 /*****************************************************************************
1348 * IDirect3DDevice::CreateMatrix
1350 * Creates a matrix handle. A handle is created and memory for a D3DMATRIX is
1351 * allocated for the handle.
1356 * D3DMatHandle: Address to return the handle at
1360 * DDERR_INVALIDPARAMS if D3DMatHandle = NULL
1362 *****************************************************************************/
1363 static HRESULT WINAPI
1364 IDirect3DDeviceImpl_1_CreateMatrix(IDirect3DDevice
*iface
, D3DMATRIXHANDLE
*D3DMatHandle
)
1366 IDirect3DDeviceImpl
*This
= device_from_device1(iface
);
1370 TRACE("iface %p, matrix_handle %p.\n", iface
, D3DMatHandle
);
1373 return DDERR_INVALIDPARAMS
;
1375 Matrix
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(D3DMATRIX
));
1378 ERR("Out of memory when allocating a D3DMATRIX\n");
1379 return DDERR_OUTOFMEMORY
;
1382 EnterCriticalSection(&ddraw_cs
);
1384 h
= ddraw_allocate_handle(&This
->handle_table
, Matrix
, DDRAW_HANDLE_MATRIX
);
1385 if (h
== DDRAW_INVALID_HANDLE
)
1387 ERR("Failed to allocate a matrix handle.\n");
1388 HeapFree(GetProcessHeap(), 0, Matrix
);
1389 LeaveCriticalSection(&ddraw_cs
);
1390 return DDERR_OUTOFMEMORY
;
1393 *D3DMatHandle
= h
+ 1;
1395 TRACE(" returning matrix handle %d\n", *D3DMatHandle
);
1397 LeaveCriticalSection(&ddraw_cs
);
1401 /*****************************************************************************
1402 * IDirect3DDevice::SetMatrix
1404 * Sets a matrix for a matrix handle. The matrix is copied into the memory
1405 * allocated for the handle
1410 * D3DMatHandle: Handle to set the matrix to
1411 * D3DMatrix: Matrix to set
1415 * DDERR_INVALIDPARAMS if the handle of the matrix is invalid or the matrix
1418 *****************************************************************************/
1419 static HRESULT WINAPI
1420 IDirect3DDeviceImpl_1_SetMatrix(IDirect3DDevice
*iface
,
1421 D3DMATRIXHANDLE D3DMatHandle
,
1422 D3DMATRIX
*D3DMatrix
)
1424 IDirect3DDeviceImpl
*This
= device_from_device1(iface
);
1427 TRACE("iface %p, matrix_handle %#x, matrix %p.\n", iface
, D3DMatHandle
, D3DMatrix
);
1429 if (!D3DMatrix
) return DDERR_INVALIDPARAMS
;
1431 EnterCriticalSection(&ddraw_cs
);
1433 m
= ddraw_get_object(&This
->handle_table
, D3DMatHandle
- 1, DDRAW_HANDLE_MATRIX
);
1436 WARN("Invalid matrix handle.\n");
1437 LeaveCriticalSection(&ddraw_cs
);
1438 return DDERR_INVALIDPARAMS
;
1441 if (TRACE_ON(ddraw
))
1442 dump_D3DMATRIX(D3DMatrix
);
1446 if(This
->world
== D3DMatHandle
)
1448 IWineD3DDevice_SetTransform(This
->wineD3DDevice
,
1449 WINED3DTS_WORLDMATRIX(0),
1450 (WINED3DMATRIX
*) D3DMatrix
);
1452 if(This
->view
== D3DMatHandle
)
1454 IWineD3DDevice_SetTransform(This
->wineD3DDevice
,
1456 (WINED3DMATRIX
*) D3DMatrix
);
1458 if(This
->proj
== D3DMatHandle
)
1460 IWineD3DDevice_SetTransform(This
->wineD3DDevice
,
1461 WINED3DTS_PROJECTION
,
1462 (WINED3DMATRIX
*) D3DMatrix
);
1465 LeaveCriticalSection(&ddraw_cs
);
1469 /*****************************************************************************
1470 * IDirect3DDevice::GetMatrix
1472 * Returns the content of a D3DMATRIX handle
1477 * D3DMatHandle: Matrix handle to read the content from
1478 * D3DMatrix: Address to store the content at
1482 * DDERR_INVALIDPARAMS if D3DMatHandle is invalid or D3DMatrix is NULL
1484 *****************************************************************************/
1485 static HRESULT WINAPI
1486 IDirect3DDeviceImpl_1_GetMatrix(IDirect3DDevice
*iface
,
1487 D3DMATRIXHANDLE D3DMatHandle
,
1488 D3DMATRIX
*D3DMatrix
)
1490 IDirect3DDeviceImpl
*This
= device_from_device1(iface
);
1493 TRACE("iface %p, matrix_handle %#x, matrix %p.\n", iface
, D3DMatHandle
, D3DMatrix
);
1495 if (!D3DMatrix
) return DDERR_INVALIDPARAMS
;
1497 EnterCriticalSection(&ddraw_cs
);
1499 m
= ddraw_get_object(&This
->handle_table
, D3DMatHandle
- 1, DDRAW_HANDLE_MATRIX
);
1502 WARN("Invalid matrix handle.\n");
1503 LeaveCriticalSection(&ddraw_cs
);
1504 return DDERR_INVALIDPARAMS
;
1509 LeaveCriticalSection(&ddraw_cs
);
1513 /*****************************************************************************
1514 * IDirect3DDevice::DeleteMatrix
1516 * Destroys a Matrix handle. Frees the memory and unsets the handle data
1521 * D3DMatHandle: Handle to destroy
1525 * DDERR_INVALIDPARAMS if D3DMatHandle is invalid
1527 *****************************************************************************/
1528 static HRESULT WINAPI
1529 IDirect3DDeviceImpl_1_DeleteMatrix(IDirect3DDevice
*iface
,
1530 D3DMATRIXHANDLE D3DMatHandle
)
1532 IDirect3DDeviceImpl
*This
= device_from_device1(iface
);
1535 TRACE("iface %p, matrix_handle %#x.\n", iface
, D3DMatHandle
);
1537 EnterCriticalSection(&ddraw_cs
);
1539 m
= ddraw_free_handle(&This
->handle_table
, D3DMatHandle
- 1, DDRAW_HANDLE_MATRIX
);
1542 WARN("Invalid matrix handle.\n");
1543 LeaveCriticalSection(&ddraw_cs
);
1544 return DDERR_INVALIDPARAMS
;
1547 LeaveCriticalSection(&ddraw_cs
);
1549 HeapFree(GetProcessHeap(), 0, m
);
1554 /*****************************************************************************
1555 * IDirect3DDevice7::BeginScene
1557 * This method must be called before any rendering is performed.
1558 * IDirect3DDevice::EndScene has to be called after the scene is complete
1560 * Version 1, 2, 3 and 7
1563 * D3D_OK on success, for details see IWineD3DDevice::BeginScene
1564 * D3DERR_SCENE_IN_SCENE if WineD3D returns an error(Only in case of an already
1567 *****************************************************************************/
1569 IDirect3DDeviceImpl_7_BeginScene(IDirect3DDevice7
*iface
)
1571 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
1574 TRACE("iface %p.\n", iface
);
1576 EnterCriticalSection(&ddraw_cs
);
1577 hr
= IWineD3DDevice_BeginScene(This
->wineD3DDevice
);
1578 LeaveCriticalSection(&ddraw_cs
);
1579 if(hr
== WINED3D_OK
) return D3D_OK
;
1580 else return D3DERR_SCENE_IN_SCENE
; /* TODO: Other possible causes of failure */
1583 static HRESULT WINAPI
1584 IDirect3DDeviceImpl_7_BeginScene_FPUSetup(IDirect3DDevice7
*iface
)
1586 return IDirect3DDeviceImpl_7_BeginScene(iface
);
1589 static HRESULT WINAPI
1590 IDirect3DDeviceImpl_7_BeginScene_FPUPreserve(IDirect3DDevice7
*iface
)
1595 old_fpucw
= d3d_fpu_setup();
1596 hr
= IDirect3DDeviceImpl_7_BeginScene(iface
);
1597 set_fpu_control_word(old_fpucw
);
1602 static HRESULT WINAPI
1603 Thunk_IDirect3DDeviceImpl_3_BeginScene(IDirect3DDevice3
*iface
)
1605 TRACE("iface %p.\n", iface
);
1607 return IDirect3DDevice7_BeginScene((IDirect3DDevice7
*)device_from_device3(iface
));
1610 static HRESULT WINAPI
1611 Thunk_IDirect3DDeviceImpl_2_BeginScene(IDirect3DDevice2
*iface
)
1613 TRACE("iface %p.\n", iface
);
1615 return IDirect3DDevice7_BeginScene((IDirect3DDevice7
*)device_from_device2(iface
));
1618 static HRESULT WINAPI
1619 Thunk_IDirect3DDeviceImpl_1_BeginScene(IDirect3DDevice
*iface
)
1621 TRACE("iface %p.\n", iface
);
1623 return IDirect3DDevice7_BeginScene((IDirect3DDevice7
*)device_from_device1(iface
));
1626 /*****************************************************************************
1627 * IDirect3DDevice7::EndScene
1629 * Ends a scene that has been begun with IDirect3DDevice7::BeginScene.
1630 * This method must be called after rendering is finished.
1632 * Version 1, 2, 3 and 7
1635 * D3D_OK on success, for details see IWineD3DDevice::EndScene
1636 * D3DERR_SCENE_NOT_IN_SCENE is returned if WineD3D returns an error. It does
1637 * that only if the scene was already ended.
1639 *****************************************************************************/
1641 IDirect3DDeviceImpl_7_EndScene(IDirect3DDevice7
*iface
)
1643 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
1646 TRACE("iface %p.\n", iface
);
1648 EnterCriticalSection(&ddraw_cs
);
1649 hr
= IWineD3DDevice_EndScene(This
->wineD3DDevice
);
1650 LeaveCriticalSection(&ddraw_cs
);
1651 if(hr
== WINED3D_OK
) return D3D_OK
;
1652 else return D3DERR_SCENE_NOT_IN_SCENE
;
1655 static HRESULT WINAPI DECLSPEC_HOTPATCH
1656 IDirect3DDeviceImpl_7_EndScene_FPUSetup(IDirect3DDevice7
*iface
)
1658 return IDirect3DDeviceImpl_7_EndScene(iface
);
1661 static HRESULT WINAPI DECLSPEC_HOTPATCH
1662 IDirect3DDeviceImpl_7_EndScene_FPUPreserve(IDirect3DDevice7
*iface
)
1667 old_fpucw
= d3d_fpu_setup();
1668 hr
= IDirect3DDeviceImpl_7_EndScene(iface
);
1669 set_fpu_control_word(old_fpucw
);
1674 static HRESULT WINAPI DECLSPEC_HOTPATCH
1675 Thunk_IDirect3DDeviceImpl_3_EndScene(IDirect3DDevice3
*iface
)
1677 TRACE("iface %p.\n", iface
);
1679 return IDirect3DDevice7_EndScene((IDirect3DDevice7
*)device_from_device3(iface
));
1682 static HRESULT WINAPI DECLSPEC_HOTPATCH
1683 Thunk_IDirect3DDeviceImpl_2_EndScene(IDirect3DDevice2
*iface
)
1685 TRACE("iface %p.\n", iface
);
1687 return IDirect3DDevice7_EndScene((IDirect3DDevice7
*)device_from_device2(iface
));
1690 static HRESULT WINAPI DECLSPEC_HOTPATCH
1691 Thunk_IDirect3DDeviceImpl_1_EndScene(IDirect3DDevice
*iface
)
1693 TRACE("iface %p.\n", iface
);
1695 return IDirect3DDevice7_EndScene((IDirect3DDevice7
*)device_from_device1(iface
));
1698 /*****************************************************************************
1699 * IDirect3DDevice7::GetDirect3D
1701 * Returns the IDirect3D(= interface to the DirectDraw object) used to create
1705 * Direct3D7: Address to store the interface pointer at
1709 * DDERR_INVALIDPARAMS if Direct3D7 == NULL
1711 *****************************************************************************/
1712 static HRESULT WINAPI
1713 IDirect3DDeviceImpl_7_GetDirect3D(IDirect3DDevice7
*iface
,
1714 IDirect3D7
**Direct3D7
)
1716 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
1718 TRACE("iface %p, d3d %p.\n", iface
, Direct3D7
);
1721 return DDERR_INVALIDPARAMS
;
1723 *Direct3D7
= (IDirect3D7
*)&This
->ddraw
->IDirect3D7_vtbl
;
1724 IDirect3D7_AddRef(*Direct3D7
);
1726 TRACE(" returning interface %p\n", *Direct3D7
);
1730 static HRESULT WINAPI
1731 Thunk_IDirect3DDeviceImpl_3_GetDirect3D(IDirect3DDevice3
*iface
,
1732 IDirect3D3
**Direct3D3
)
1734 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
1736 IDirect3D7
*ret_ptr
;
1738 TRACE("iface %p, d3d %p.\n", iface
, Direct3D3
);
1740 ret
= IDirect3DDevice7_GetDirect3D((IDirect3DDevice7
*)This
, &ret_ptr
);
1743 *Direct3D3
= ret_ptr
? (IDirect3D3
*)&ddraw_from_d3d7(ret_ptr
)->IDirect3D3_vtbl
: NULL
;
1744 TRACE(" returning interface %p\n", *Direct3D3
);
1748 static HRESULT WINAPI
1749 Thunk_IDirect3DDeviceImpl_2_GetDirect3D(IDirect3DDevice2
*iface
,
1750 IDirect3D2
**Direct3D2
)
1752 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
1754 IDirect3D7
*ret_ptr
;
1756 TRACE("iface %p, d3d %p.\n", iface
, Direct3D2
);
1758 ret
= IDirect3DDevice7_GetDirect3D((IDirect3DDevice7
*)This
, &ret_ptr
);
1761 *Direct3D2
= ret_ptr
? (IDirect3D2
*)&ddraw_from_d3d7(ret_ptr
)->IDirect3D2_vtbl
: NULL
;
1762 TRACE(" returning interface %p\n", *Direct3D2
);
1766 static HRESULT WINAPI
1767 Thunk_IDirect3DDeviceImpl_1_GetDirect3D(IDirect3DDevice
*iface
,
1768 IDirect3D
**Direct3D
)
1770 IDirect3DDeviceImpl
*This
= device_from_device1(iface
);
1772 IDirect3D7
*ret_ptr
;
1774 TRACE("iface %p, d3d %p.\n", iface
, Direct3D
);
1776 ret
= IDirect3DDevice7_GetDirect3D((IDirect3DDevice7
*)This
, &ret_ptr
);
1779 *Direct3D
= ret_ptr
? (IDirect3D
*)&ddraw_from_d3d7(ret_ptr
)->IDirect3D_vtbl
: NULL
;
1780 TRACE(" returning interface %p\n", *Direct3D
);
1784 /*****************************************************************************
1785 * IDirect3DDevice3::SetCurrentViewport
1787 * Sets a Direct3DViewport as the current viewport.
1788 * For the thunks note that all viewport interface versions are equal
1791 * Direct3DViewport3: The viewport to set
1797 * (Is a NULL viewport valid?)
1799 *****************************************************************************/
1800 static HRESULT WINAPI
1801 IDirect3DDeviceImpl_3_SetCurrentViewport(IDirect3DDevice3
*iface
,
1802 IDirect3DViewport3
*Direct3DViewport3
)
1804 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
1805 IDirect3DViewportImpl
*vp
= (IDirect3DViewportImpl
*)Direct3DViewport3
;
1807 TRACE("iface %p, viewport %p.\n", iface
, Direct3DViewport3
);
1809 EnterCriticalSection(&ddraw_cs
);
1810 /* Do nothing if the specified viewport is the same as the current one */
1811 if (This
->current_viewport
== vp
)
1813 LeaveCriticalSection(&ddraw_cs
);
1817 /* Should check if the viewport was added or not */
1819 /* Release previous viewport and AddRef the new one */
1820 if (This
->current_viewport
)
1822 TRACE("ViewportImpl is at %p, interface is at %p\n", This
->current_viewport
,
1823 (IDirect3DViewport3
*)This
->current_viewport
);
1824 IDirect3DViewport3_Release((IDirect3DViewport3
*)This
->current_viewport
);
1826 IDirect3DViewport3_AddRef(Direct3DViewport3
);
1828 /* Set this viewport as the current viewport */
1829 This
->current_viewport
= vp
;
1831 /* Activate this viewport */
1832 This
->current_viewport
->active_device
= This
;
1833 viewport_activate(This
->current_viewport
, FALSE
);
1835 LeaveCriticalSection(&ddraw_cs
);
1839 static HRESULT WINAPI
1840 Thunk_IDirect3DDeviceImpl_2_SetCurrentViewport(IDirect3DDevice2
*iface
,
1841 IDirect3DViewport2
*Direct3DViewport2
)
1843 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
1844 IDirect3DViewportImpl
*vp
= (IDirect3DViewportImpl
*)Direct3DViewport2
;
1846 TRACE("iface %p, viewport %p.\n", iface
, Direct3DViewport2
);
1848 return IDirect3DDevice3_SetCurrentViewport((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
,
1849 (IDirect3DViewport3
*)vp
);
1852 /*****************************************************************************
1853 * IDirect3DDevice3::GetCurrentViewport
1855 * Returns the currently active viewport.
1860 * Direct3DViewport3: Address to return the interface pointer at
1864 * DDERR_INVALIDPARAMS if Direct3DViewport == NULL
1866 *****************************************************************************/
1867 static HRESULT WINAPI
1868 IDirect3DDeviceImpl_3_GetCurrentViewport(IDirect3DDevice3
*iface
,
1869 IDirect3DViewport3
**Direct3DViewport3
)
1871 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
1873 TRACE("iface %p, viewport %p.\n", iface
, Direct3DViewport3
);
1875 if(!Direct3DViewport3
)
1876 return DDERR_INVALIDPARAMS
;
1878 EnterCriticalSection(&ddraw_cs
);
1879 *Direct3DViewport3
= (IDirect3DViewport3
*)This
->current_viewport
;
1881 /* AddRef the returned viewport */
1882 if(*Direct3DViewport3
) IDirect3DViewport3_AddRef(*Direct3DViewport3
);
1884 TRACE(" returning interface %p\n", *Direct3DViewport3
);
1886 LeaveCriticalSection(&ddraw_cs
);
1890 static HRESULT WINAPI
1891 Thunk_IDirect3DDeviceImpl_2_GetCurrentViewport(IDirect3DDevice2
*iface
,
1892 IDirect3DViewport2
**Direct3DViewport2
)
1894 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
1897 TRACE("iface %p, viewport %p.\n", iface
, Direct3DViewport2
);
1899 hr
= IDirect3DDevice3_GetCurrentViewport((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
,
1900 (IDirect3DViewport3
**)Direct3DViewport2
);
1901 if(hr
!= D3D_OK
) return hr
;
1905 /*****************************************************************************
1906 * IDirect3DDevice7::SetRenderTarget
1908 * Sets the render target for the Direct3DDevice.
1909 * For the thunks note that IDirectDrawSurface7 == IDirectDrawSurface4 and
1910 * IDirectDrawSurface3 == IDirectDrawSurface
1912 * Version 2, 3 and 7
1915 * NewTarget: Pointer to an IDirectDrawSurface7 interface to set as the new
1920 * D3D_OK on success, for details see IWineD3DDevice::SetRenderTarget
1922 *****************************************************************************/
1924 IDirect3DDeviceImpl_7_SetRenderTarget(IDirect3DDevice7
*iface
,
1925 IDirectDrawSurface7
*NewTarget
,
1928 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
1929 IDirectDrawSurfaceImpl
*Target
= (IDirectDrawSurfaceImpl
*)NewTarget
;
1932 TRACE("iface %p, target %p, flags %#x.\n", iface
, NewTarget
, Flags
);
1934 EnterCriticalSection(&ddraw_cs
);
1935 /* Flags: Not used */
1937 if(This
->target
== Target
)
1939 TRACE("No-op SetRenderTarget operation, not doing anything\n");
1940 LeaveCriticalSection(&ddraw_cs
);
1944 hr
= IWineD3DDevice_SetRenderTarget(This
->wineD3DDevice
,
1946 Target
? Target
->WineD3DSurface
: NULL
,
1950 LeaveCriticalSection(&ddraw_cs
);
1953 IDirectDrawSurface7_AddRef(NewTarget
);
1954 IDirectDrawSurface7_Release((IDirectDrawSurface7
*)This
->target
);
1955 This
->target
= Target
;
1956 IDirect3DDeviceImpl_UpdateDepthStencil(This
);
1957 LeaveCriticalSection(&ddraw_cs
);
1961 static HRESULT WINAPI
1962 IDirect3DDeviceImpl_7_SetRenderTarget_FPUSetup(IDirect3DDevice7
*iface
,
1963 IDirectDrawSurface7
*NewTarget
,
1966 return IDirect3DDeviceImpl_7_SetRenderTarget(iface
, NewTarget
, Flags
);
1969 static HRESULT WINAPI
1970 IDirect3DDeviceImpl_7_SetRenderTarget_FPUPreserve(IDirect3DDevice7
*iface
,
1971 IDirectDrawSurface7
*NewTarget
,
1977 old_fpucw
= d3d_fpu_setup();
1978 hr
= IDirect3DDeviceImpl_7_SetRenderTarget(iface
, NewTarget
, Flags
);
1979 set_fpu_control_word(old_fpucw
);
1984 static HRESULT WINAPI
1985 Thunk_IDirect3DDeviceImpl_3_SetRenderTarget(IDirect3DDevice3
*iface
,
1986 IDirectDrawSurface4
*NewRenderTarget
,
1989 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
1990 IDirectDrawSurfaceImpl
*Target
= (IDirectDrawSurfaceImpl
*)NewRenderTarget
;
1992 TRACE("iface %p, target %p, flags %#x.\n", iface
, NewRenderTarget
, Flags
);
1994 return IDirect3DDevice7_SetRenderTarget((IDirect3DDevice7
*)This
, (IDirectDrawSurface7
*)Target
, Flags
);
1997 static HRESULT WINAPI
1998 Thunk_IDirect3DDeviceImpl_2_SetRenderTarget(IDirect3DDevice2
*iface
,
1999 IDirectDrawSurface
*NewRenderTarget
,
2002 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
2003 IDirectDrawSurfaceImpl
*Target
= (IDirectDrawSurfaceImpl
*)NewRenderTarget
;
2005 TRACE("iface %p, target %p, flags %#x.\n", iface
, NewRenderTarget
, Flags
);
2007 return IDirect3DDevice7_SetRenderTarget((IDirect3DDevice7
*)This
, (IDirectDrawSurface7
*)Target
, Flags
);
2010 /*****************************************************************************
2011 * IDirect3DDevice7::GetRenderTarget
2013 * Returns the current render target.
2014 * This is handled locally, because the WineD3D render target's parent
2017 * Version 2, 3 and 7
2020 * RenderTarget: Address to store the surface interface pointer
2024 * DDERR_INVALIDPARAMS if RenderTarget == NULL
2026 *****************************************************************************/
2027 static HRESULT WINAPI
2028 IDirect3DDeviceImpl_7_GetRenderTarget(IDirect3DDevice7
*iface
,
2029 IDirectDrawSurface7
**RenderTarget
)
2031 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
2033 TRACE("iface %p, target %p.\n", iface
, RenderTarget
);
2036 return DDERR_INVALIDPARAMS
;
2038 EnterCriticalSection(&ddraw_cs
);
2039 *RenderTarget
= (IDirectDrawSurface7
*)This
->target
;
2040 IDirectDrawSurface7_AddRef(*RenderTarget
);
2042 LeaveCriticalSection(&ddraw_cs
);
2046 static HRESULT WINAPI
2047 Thunk_IDirect3DDeviceImpl_3_GetRenderTarget(IDirect3DDevice3
*iface
,
2048 IDirectDrawSurface4
**RenderTarget
)
2050 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
2053 TRACE("iface %p, target %p.\n", iface
, RenderTarget
);
2055 hr
= IDirect3DDevice7_GetRenderTarget((IDirect3DDevice7
*)This
, (IDirectDrawSurface7
**)RenderTarget
);
2056 if(hr
!= D3D_OK
) return hr
;
2060 static HRESULT WINAPI
2061 Thunk_IDirect3DDeviceImpl_2_GetRenderTarget(IDirect3DDevice2
*iface
,
2062 IDirectDrawSurface
**RenderTarget
)
2064 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
2067 TRACE("iface %p, target %p.\n", iface
, RenderTarget
);
2069 hr
= IDirect3DDevice7_GetRenderTarget((IDirect3DDevice7
*)This
, (IDirectDrawSurface7
**)RenderTarget
);
2070 if(hr
!= D3D_OK
) return hr
;
2071 *RenderTarget
= *RenderTarget
?
2072 (IDirectDrawSurface
*)&((IDirectDrawSurfaceImpl
*)*RenderTarget
)->IDirectDrawSurface3_vtbl
: NULL
;
2076 /*****************************************************************************
2077 * IDirect3DDevice3::Begin
2079 * Begins a description block of vertices. This is similar to glBegin()
2080 * and glEnd(). After a call to IDirect3DDevice3::End, the vertices
2081 * described with IDirect3DDevice::Vertex are drawn.
2086 * PrimitiveType: The type of primitives to draw
2087 * VertexTypeDesc: A flexible vertex format description of the vertices
2088 * Flags: Some flags..
2093 *****************************************************************************/
2094 static HRESULT WINAPI
2095 IDirect3DDeviceImpl_3_Begin(IDirect3DDevice3
*iface
,
2096 D3DPRIMITIVETYPE PrimitiveType
,
2097 DWORD VertexTypeDesc
,
2100 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
2102 TRACE("iface %p, primitive_type %#x, FVF %#x, flags %#x.\n",
2103 iface
, PrimitiveType
, VertexTypeDesc
, Flags
);
2105 EnterCriticalSection(&ddraw_cs
);
2106 This
->primitive_type
= PrimitiveType
;
2107 This
->vertex_type
= VertexTypeDesc
;
2108 This
->render_flags
= Flags
;
2109 This
->vertex_size
= get_flexible_vertex_size(This
->vertex_type
);
2110 This
->nb_vertices
= 0;
2111 LeaveCriticalSection(&ddraw_cs
);
2116 static HRESULT WINAPI
2117 Thunk_IDirect3DDeviceImpl_2_Begin(IDirect3DDevice2
*iface
,
2118 D3DPRIMITIVETYPE d3dpt
,
2119 D3DVERTEXTYPE dwVertexTypeDesc
,
2123 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
2125 TRACE("iface %p, primitive_type %#x, vertex_type %#x, flags %#x.\n",
2126 iface
, d3dpt
, dwVertexTypeDesc
, dwFlags
);
2128 switch(dwVertexTypeDesc
)
2130 case D3DVT_VERTEX
: FVF
= D3DFVF_VERTEX
; break;
2131 case D3DVT_LVERTEX
: FVF
= D3DFVF_LVERTEX
; break;
2132 case D3DVT_TLVERTEX
: FVF
= D3DFVF_TLVERTEX
; break;
2134 ERR("Unexpected vertex type %d\n", dwVertexTypeDesc
);
2135 return DDERR_INVALIDPARAMS
; /* Should never happen */
2138 return IDirect3DDevice3_Begin((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
, d3dpt
, FVF
, dwFlags
);
2141 /*****************************************************************************
2142 * IDirect3DDevice3::BeginIndexed
2144 * Draws primitives based on vertices in a vertex array which are specified
2150 * PrimitiveType: Primitive type to draw
2151 * VertexType: A FVF description of the vertex format
2152 * Vertices: pointer to an array containing the vertices
2153 * NumVertices: The number of vertices in the vertex array
2154 * Flags: Some flags ...
2157 * D3D_OK, because it's a stub
2159 *****************************************************************************/
2160 static HRESULT WINAPI
2161 IDirect3DDeviceImpl_3_BeginIndexed(IDirect3DDevice3
*iface
,
2162 D3DPRIMITIVETYPE PrimitiveType
,
2168 FIXME("iface %p, primitive_type %#x, FVF %#x, vertices %p, vertex_count %u, flags %#x stub!\n",
2169 iface
, PrimitiveType
, VertexType
, Vertices
, NumVertices
, Flags
);
2175 static HRESULT WINAPI
2176 Thunk_IDirect3DDeviceImpl_2_BeginIndexed(IDirect3DDevice2
*iface
,
2177 D3DPRIMITIVETYPE d3dptPrimitiveType
,
2178 D3DVERTEXTYPE d3dvtVertexType
,
2180 DWORD dwNumVertices
,
2184 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
2186 TRACE("iface %p, primitive_type %#x, vertex_type %#x, vertices %p, vertex_count %u, flags %#x stub!\n",
2187 iface
, d3dptPrimitiveType
, d3dvtVertexType
, lpvVertices
, dwNumVertices
, dwFlags
);
2189 switch(d3dvtVertexType
)
2191 case D3DVT_VERTEX
: FVF
= D3DFVF_VERTEX
; break;
2192 case D3DVT_LVERTEX
: FVF
= D3DFVF_LVERTEX
; break;
2193 case D3DVT_TLVERTEX
: FVF
= D3DFVF_TLVERTEX
; break;
2195 ERR("Unexpected vertex type %d\n", d3dvtVertexType
);
2196 return DDERR_INVALIDPARAMS
; /* Should never happen */
2199 return IDirect3DDevice3_BeginIndexed((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
,
2200 d3dptPrimitiveType
, FVF
, lpvVertices
, dwNumVertices
, dwFlags
);
2203 /*****************************************************************************
2204 * IDirect3DDevice3::Vertex
2206 * Draws a vertex as described by IDirect3DDevice3::Begin. It places all
2207 * drawn vertices in a vertex buffer. If the buffer is too small, its
2208 * size is increased.
2213 * Vertex: Pointer to the vertex
2216 * D3D_OK, on success
2217 * DDERR_INVALIDPARAMS if Vertex is NULL
2219 *****************************************************************************/
2220 static HRESULT WINAPI
2221 IDirect3DDeviceImpl_3_Vertex(IDirect3DDevice3
*iface
,
2224 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
2226 TRACE("iface %p, vertex %p.\n", iface
, Vertex
);
2229 return DDERR_INVALIDPARAMS
;
2231 EnterCriticalSection(&ddraw_cs
);
2232 if ((This
->nb_vertices
+1)*This
->vertex_size
> This
->buffer_size
)
2235 This
->buffer_size
= This
->buffer_size
? This
->buffer_size
* 2 : This
->vertex_size
* 3;
2236 old_buffer
= This
->vertex_buffer
;
2237 This
->vertex_buffer
= HeapAlloc(GetProcessHeap(), 0, This
->buffer_size
);
2240 CopyMemory(This
->vertex_buffer
, old_buffer
, This
->nb_vertices
* This
->vertex_size
);
2241 HeapFree(GetProcessHeap(), 0, old_buffer
);
2245 CopyMemory(This
->vertex_buffer
+ This
->nb_vertices
++ * This
->vertex_size
, Vertex
, This
->vertex_size
);
2247 LeaveCriticalSection(&ddraw_cs
);
2251 static HRESULT WINAPI
2252 Thunk_IDirect3DDeviceImpl_2_Vertex(IDirect3DDevice2
*iface
,
2255 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
2257 TRACE("iface %p, vertex %p.\n", iface
, lpVertexType
);
2259 return IDirect3DDevice3_Vertex((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
, lpVertexType
);
2262 /*****************************************************************************
2263 * IDirect3DDevice3::Index
2265 * Specifies an index to a vertex to be drawn. The vertex array has to
2266 * be specified with BeginIndexed first.
2269 * VertexIndex: The index of the vertex to draw
2272 * D3D_OK because it's a stub
2274 *****************************************************************************/
2275 static HRESULT WINAPI
2276 IDirect3DDeviceImpl_3_Index(IDirect3DDevice3
*iface
,
2279 FIXME("iface %p, index %#x stub!\n", iface
, VertexIndex
);
2284 static HRESULT WINAPI
2285 Thunk_IDirect3DDeviceImpl_2_Index(IDirect3DDevice2
*iface
,
2288 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
2290 TRACE("iface %p, index %#x.\n", iface
, wVertexIndex
);
2292 return IDirect3DDevice3_Index((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
, wVertexIndex
);
2295 /*****************************************************************************
2296 * IDirect3DDevice3::End
2298 * Ends a draw begun with IDirect3DDevice3::Begin or
2299 * IDirect3DDevice::BeginIndexed. The vertices specified with
2300 * IDirect3DDevice::Vertex or IDirect3DDevice::Index are drawn using
2301 * the IDirect3DDevice7::DrawPrimitive method. So far only
2302 * non-indexed mode is supported
2307 * Flags: Some flags, as usual. Don't know which are defined
2310 * The return value of IDirect3DDevice7::DrawPrimitive
2312 *****************************************************************************/
2313 static HRESULT WINAPI
2314 IDirect3DDeviceImpl_3_End(IDirect3DDevice3
*iface
,
2317 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
2319 TRACE("iface %p, flags %#x.\n", iface
, Flags
);
2321 return IDirect3DDevice7_DrawPrimitive((IDirect3DDevice7
*)This
, This
->primitive_type
,
2322 This
->vertex_type
, This
->vertex_buffer
, This
->nb_vertices
, This
->render_flags
);
2325 static HRESULT WINAPI
2326 Thunk_IDirect3DDeviceImpl_2_End(IDirect3DDevice2
*iface
,
2329 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
2331 TRACE("iface %p, flags %#x.\n", iface
, dwFlags
);
2333 return IDirect3DDevice3_End((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
, dwFlags
);
2336 /*****************************************************************************
2337 * IDirect3DDevice7::GetRenderState
2339 * Returns the value of a render state. The possible render states are
2340 * defined in include/d3dtypes.h
2342 * Version 2, 3 and 7
2345 * RenderStateType: Render state to return the current setting of
2346 * Value: Address to store the value at
2349 * D3D_OK on success, for details see IWineD3DDevice::GetRenderState
2350 * DDERR_INVALIDPARAMS if Value == NULL
2352 *****************************************************************************/
2354 IDirect3DDeviceImpl_7_GetRenderState(IDirect3DDevice7
*iface
,
2355 D3DRENDERSTATETYPE RenderStateType
,
2358 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
2361 TRACE("iface %p, state %#x, value %p.\n", iface
, RenderStateType
, Value
);
2364 return DDERR_INVALIDPARAMS
;
2366 EnterCriticalSection(&ddraw_cs
);
2367 switch(RenderStateType
)
2369 case D3DRENDERSTATE_TEXTUREMAG
:
2371 WINED3DTEXTUREFILTERTYPE tex_mag
;
2373 hr
= IWineD3DDevice_GetSamplerState(This
->wineD3DDevice
,
2374 0, WINED3DSAMP_MAGFILTER
,
2379 case WINED3DTEXF_POINT
:
2380 *Value
= D3DFILTER_NEAREST
;
2382 case WINED3DTEXF_LINEAR
:
2383 *Value
= D3DFILTER_LINEAR
;
2386 ERR("Unhandled texture mag %d !\n",tex_mag
);
2392 case D3DRENDERSTATE_TEXTUREMIN
:
2394 WINED3DTEXTUREFILTERTYPE tex_min
;
2395 WINED3DTEXTUREFILTERTYPE tex_mip
;
2397 hr
= IWineD3DDevice_GetSamplerState(This
->wineD3DDevice
,
2398 0, WINED3DSAMP_MINFILTER
, &tex_min
);
2401 LeaveCriticalSection(&ddraw_cs
);
2404 hr
= IWineD3DDevice_GetSamplerState(This
->wineD3DDevice
,
2405 0, WINED3DSAMP_MIPFILTER
, &tex_mip
);
2409 case WINED3DTEXF_POINT
:
2412 case WINED3DTEXF_NONE
:
2413 *Value
= D3DFILTER_NEAREST
;
2415 case WINED3DTEXF_POINT
:
2416 *Value
= D3DFILTER_MIPNEAREST
;
2418 case WINED3DTEXF_LINEAR
:
2419 *Value
= D3DFILTER_LINEARMIPNEAREST
;
2422 ERR("Unhandled mip filter %#x.\n", tex_mip
);
2423 *Value
= D3DFILTER_NEAREST
;
2427 case WINED3DTEXF_LINEAR
:
2430 case WINED3DTEXF_NONE
:
2431 *Value
= D3DFILTER_LINEAR
;
2433 case WINED3DTEXF_POINT
:
2434 *Value
= D3DFILTER_MIPLINEAR
;
2436 case WINED3DTEXF_LINEAR
:
2437 *Value
= D3DFILTER_LINEARMIPLINEAR
;
2440 ERR("Unhandled mip filter %#x.\n", tex_mip
);
2441 *Value
= D3DFILTER_LINEAR
;
2446 ERR("Unhandled texture min filter %#x.\n",tex_min
);
2447 *Value
= D3DFILTER_NEAREST
;
2453 case D3DRENDERSTATE_TEXTUREADDRESS
:
2454 case D3DRENDERSTATE_TEXTUREADDRESSU
:
2455 hr
= IWineD3DDevice_GetSamplerState(This
->wineD3DDevice
,
2456 0, WINED3DSAMP_ADDRESSU
,
2459 case D3DRENDERSTATE_TEXTUREADDRESSV
:
2460 hr
= IWineD3DDevice_GetSamplerState(This
->wineD3DDevice
,
2461 0, WINED3DSAMP_ADDRESSV
,
2465 case D3DRENDERSTATE_BORDERCOLOR
:
2466 FIXME("Unhandled render state D3DRENDERSTATE_BORDERCOLOR.\n");
2470 case D3DRENDERSTATE_TEXTUREHANDLE
:
2471 case D3DRENDERSTATE_TEXTUREMAPBLEND
:
2472 WARN("Render state %#x is invalid in d3d7.\n", RenderStateType
);
2473 hr
= DDERR_INVALIDPARAMS
;
2477 if (RenderStateType
>= D3DRENDERSTATE_STIPPLEPATTERN00
2478 && RenderStateType
<= D3DRENDERSTATE_STIPPLEPATTERN31
)
2480 FIXME("Unhandled stipple pattern render state (%#x).\n",
2485 hr
= IWineD3DDevice_GetRenderState(This
->wineD3DDevice
,
2489 LeaveCriticalSection(&ddraw_cs
);
2493 static HRESULT WINAPI
2494 IDirect3DDeviceImpl_7_GetRenderState_FPUSetup(IDirect3DDevice7
*iface
,
2495 D3DRENDERSTATETYPE RenderStateType
,
2498 return IDirect3DDeviceImpl_7_GetRenderState(iface
, RenderStateType
, Value
);
2501 static HRESULT WINAPI
2502 IDirect3DDeviceImpl_7_GetRenderState_FPUPreserve(IDirect3DDevice7
*iface
,
2503 D3DRENDERSTATETYPE RenderStateType
,
2509 old_fpucw
= d3d_fpu_setup();
2510 hr
= IDirect3DDeviceImpl_7_GetRenderState(iface
, RenderStateType
, Value
);
2511 set_fpu_control_word(old_fpucw
);
2516 static HRESULT WINAPI
2517 IDirect3DDeviceImpl_3_GetRenderState(IDirect3DDevice3
*iface
,
2518 D3DRENDERSTATETYPE dwRenderStateType
,
2519 DWORD
*lpdwRenderState
)
2521 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
2524 TRACE("iface %p, state %#x, value %p.\n", iface
, dwRenderStateType
, lpdwRenderState
);
2526 switch(dwRenderStateType
)
2528 case D3DRENDERSTATE_TEXTUREHANDLE
:
2530 /* This state is wrapped to SetTexture in SetRenderState, so
2531 * it has to be wrapped to GetTexture here
2533 IWineD3DBaseTexture
*tex
= NULL
;
2534 *lpdwRenderState
= 0;
2536 EnterCriticalSection(&ddraw_cs
);
2538 hr
= IWineD3DDevice_GetTexture(This
->wineD3DDevice
, 0, &tex
);
2539 if (SUCCEEDED(hr
) && tex
)
2541 /* The parent of the texture is the IDirectDrawSurface7
2542 * interface of the ddraw surface. */
2543 IDirectDrawSurfaceImpl
*parent
= IWineD3DBaseTexture_GetParent(tex
);
2544 if (parent
) *lpdwRenderState
= parent
->Handle
;
2545 IWineD3DBaseTexture_Release(tex
);
2548 LeaveCriticalSection(&ddraw_cs
);
2553 case D3DRENDERSTATE_TEXTUREMAPBLEND
:
2555 /* D3DRENDERSTATE_TEXTUREMAPBLEND is mapped to texture state stages in SetRenderState; reverse
2556 the mapping to get the value. */
2557 DWORD colorop
, colorarg1
, colorarg2
;
2558 DWORD alphaop
, alphaarg1
, alphaarg2
;
2560 EnterCriticalSection(&ddraw_cs
);
2562 This
->legacyTextureBlending
= TRUE
;
2564 IWineD3DDevice_GetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_COLOROP
, &colorop
);
2565 IWineD3DDevice_GetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_COLORARG1
, &colorarg1
);
2566 IWineD3DDevice_GetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_COLORARG2
, &colorarg2
);
2567 IWineD3DDevice_GetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAOP
, &alphaop
);
2568 IWineD3DDevice_GetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAARG1
, &alphaarg1
);
2569 IWineD3DDevice_GetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAARG2
, &alphaarg2
);
2571 if (colorop
== WINED3DTOP_SELECTARG1
&& colorarg1
== WINED3DTA_TEXTURE
&&
2572 alphaop
== WINED3DTOP_SELECTARG1
&& alphaarg1
== WINED3DTA_TEXTURE
)
2574 *lpdwRenderState
= D3DTBLEND_DECAL
;
2576 else if (colorop
== WINED3DTOP_SELECTARG1
&& colorarg1
== WINED3DTA_TEXTURE
&&
2577 alphaop
== WINED3DTOP_MODULATE
&& alphaarg1
== WINED3DTA_TEXTURE
&& alphaarg2
== WINED3DTA_CURRENT
)
2579 *lpdwRenderState
= D3DTBLEND_DECALALPHA
;
2581 else if (colorop
== WINED3DTOP_MODULATE
&& colorarg1
== WINED3DTA_TEXTURE
&& colorarg2
== WINED3DTA_CURRENT
&&
2582 alphaop
== WINED3DTOP_MODULATE
&& alphaarg1
== WINED3DTA_TEXTURE
&& alphaarg2
== WINED3DTA_CURRENT
)
2584 *lpdwRenderState
= D3DTBLEND_MODULATEALPHA
;
2589 BOOL tex_alpha
= FALSE
;
2590 IWineD3DBaseTexture
*tex
= NULL
;
2591 WINED3DSURFACE_DESC desc
;
2592 DDPIXELFORMAT ddfmt
;
2594 hr
= IWineD3DDevice_GetTexture(This
->wineD3DDevice
,
2598 if(hr
== WINED3D_OK
&& tex
)
2600 hr
= IWineD3DTexture_GetLevelDesc((IWineD3DTexture
*) tex
, 0, &desc
);
2603 ddfmt
.dwSize
= sizeof(ddfmt
);
2604 PixelFormat_WineD3DtoDD(&ddfmt
, desc
.format
);
2605 if (ddfmt
.u5
.dwRGBAlphaBitMask
) tex_alpha
= TRUE
;
2608 IWineD3DBaseTexture_Release(tex
);
2611 if (!(colorop
== WINED3DTOP_MODULATE
&& colorarg1
== WINED3DTA_TEXTURE
&& colorarg2
== WINED3DTA_CURRENT
&&
2612 alphaop
== (tex_alpha
? WINED3DTOP_SELECTARG1
: WINED3DTOP_SELECTARG2
) &&
2613 alphaarg1
== WINED3DTA_TEXTURE
&& alphaarg2
== WINED3DTA_CURRENT
))
2615 ERR("Unexpected texture stage state setup, returning D3DTBLEND_MODULATE - likely erroneous\n");
2618 *lpdwRenderState
= D3DTBLEND_MODULATE
;
2621 LeaveCriticalSection(&ddraw_cs
);
2627 return IDirect3DDevice7_GetRenderState((IDirect3DDevice7
*)This
, dwRenderStateType
, lpdwRenderState
);
2631 static HRESULT WINAPI
2632 Thunk_IDirect3DDeviceImpl_2_GetRenderState(IDirect3DDevice2
*iface
,
2633 D3DRENDERSTATETYPE dwRenderStateType
,
2634 DWORD
*lpdwRenderState
)
2636 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
2638 TRACE("iface %p, state %#x, value %p.\n", iface
, dwRenderStateType
, lpdwRenderState
);
2640 return IDirect3DDevice3_GetRenderState((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
,
2641 dwRenderStateType
, lpdwRenderState
);
2644 /*****************************************************************************
2645 * IDirect3DDevice7::SetRenderState
2647 * Sets a render state. The possible render states are defined in
2648 * include/d3dtypes.h
2650 * Version 2, 3 and 7
2653 * RenderStateType: State to set
2654 * Value: Value to assign to that state
2657 * D3D_OK on success,
2658 * for details see IWineD3DDevice::SetRenderState
2660 *****************************************************************************/
2662 IDirect3DDeviceImpl_7_SetRenderState(IDirect3DDevice7
*iface
,
2663 D3DRENDERSTATETYPE RenderStateType
,
2666 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
2669 TRACE("iface %p, state %#x, value %#x.\n", iface
, RenderStateType
, Value
);
2671 EnterCriticalSection(&ddraw_cs
);
2672 /* Some render states need special care */
2673 switch(RenderStateType
)
2676 * The ddraw texture filter mapping works like this:
2677 * D3DFILTER_NEAREST Point min/mag, no mip
2678 * D3DFILTER_MIPNEAREST Point min/mag, point mip
2679 * D3DFILTER_LINEARMIPNEAREST: Point min/mag, linear mip
2681 * D3DFILTER_LINEAR Linear min/mag, no mip
2682 * D3DFILTER_MIPLINEAR Linear min/mag, point mip
2683 * D3DFILTER_LINEARMIPLINEAR Linear min/mag, linear mip
2685 * This is the opposite of the GL naming convention,
2686 * D3DFILTER_LINEARMIPNEAREST corresponds to GL_NEAREST_MIPMAP_LINEAR.
2688 case D3DRENDERSTATE_TEXTUREMAG
:
2690 WINED3DTEXTUREFILTERTYPE tex_mag
;
2694 case D3DFILTER_NEAREST
:
2695 case D3DFILTER_MIPNEAREST
:
2696 case D3DFILTER_LINEARMIPNEAREST
:
2697 tex_mag
= WINED3DTEXF_POINT
;
2699 case D3DFILTER_LINEAR
:
2700 case D3DFILTER_MIPLINEAR
:
2701 case D3DFILTER_LINEARMIPLINEAR
:
2702 tex_mag
= WINED3DTEXF_LINEAR
;
2705 tex_mag
= WINED3DTEXF_POINT
;
2706 ERR("Unhandled texture mag %d !\n",Value
);
2710 hr
= IWineD3DDevice_SetSamplerState(This
->wineD3DDevice
,
2711 0, WINED3DSAMP_MAGFILTER
,
2716 case D3DRENDERSTATE_TEXTUREMIN
:
2718 WINED3DTEXTUREFILTERTYPE tex_min
;
2719 WINED3DTEXTUREFILTERTYPE tex_mip
;
2721 switch ((D3DTEXTUREFILTER
) Value
)
2723 case D3DFILTER_NEAREST
:
2724 tex_min
= WINED3DTEXF_POINT
;
2725 tex_mip
= WINED3DTEXF_NONE
;
2727 case D3DFILTER_LINEAR
:
2728 tex_min
= WINED3DTEXF_LINEAR
;
2729 tex_mip
= WINED3DTEXF_NONE
;
2731 case D3DFILTER_MIPNEAREST
:
2732 tex_min
= WINED3DTEXF_POINT
;
2733 tex_mip
= WINED3DTEXF_POINT
;
2735 case D3DFILTER_MIPLINEAR
:
2736 tex_min
= WINED3DTEXF_LINEAR
;
2737 tex_mip
= WINED3DTEXF_POINT
;
2739 case D3DFILTER_LINEARMIPNEAREST
:
2740 tex_min
= WINED3DTEXF_POINT
;
2741 tex_mip
= WINED3DTEXF_LINEAR
;
2743 case D3DFILTER_LINEARMIPLINEAR
:
2744 tex_min
= WINED3DTEXF_LINEAR
;
2745 tex_mip
= WINED3DTEXF_LINEAR
;
2749 ERR("Unhandled texture min %d !\n",Value
);
2750 tex_min
= WINED3DTEXF_POINT
;
2751 tex_mip
= WINED3DTEXF_NONE
;
2755 IWineD3DDevice_SetSamplerState(This
->wineD3DDevice
,
2756 0, WINED3DSAMP_MIPFILTER
, tex_mip
);
2757 hr
= IWineD3DDevice_SetSamplerState(This
->wineD3DDevice
,
2758 0, WINED3DSAMP_MINFILTER
,
2763 case D3DRENDERSTATE_TEXTUREADDRESS
:
2764 IWineD3DDevice_SetSamplerState(This
->wineD3DDevice
,
2765 0, WINED3DSAMP_ADDRESSV
,
2768 case D3DRENDERSTATE_TEXTUREADDRESSU
:
2769 hr
= IWineD3DDevice_SetSamplerState(This
->wineD3DDevice
,
2770 0, WINED3DSAMP_ADDRESSU
,
2773 case D3DRENDERSTATE_TEXTUREADDRESSV
:
2774 hr
= IWineD3DDevice_SetSamplerState(This
->wineD3DDevice
,
2775 0, WINED3DSAMP_ADDRESSV
,
2779 case D3DRENDERSTATE_BORDERCOLOR
:
2780 /* This should probably just forward to the corresponding sampler
2781 * state. Needs tests. */
2782 FIXME("Unhandled render state D3DRENDERSTATE_BORDERCOLOR.\n");
2786 case D3DRENDERSTATE_TEXTUREHANDLE
:
2787 case D3DRENDERSTATE_TEXTUREMAPBLEND
:
2788 WARN("Render state %#x is invalid in d3d7.\n", RenderStateType
);
2789 hr
= DDERR_INVALIDPARAMS
;
2793 if (RenderStateType
>= D3DRENDERSTATE_STIPPLEPATTERN00
2794 && RenderStateType
<= D3DRENDERSTATE_STIPPLEPATTERN31
)
2796 FIXME("Unhandled stipple pattern render state (%#x).\n",
2802 hr
= IWineD3DDevice_SetRenderState(This
->wineD3DDevice
,
2807 LeaveCriticalSection(&ddraw_cs
);
2811 static HRESULT WINAPI
2812 IDirect3DDeviceImpl_7_SetRenderState_FPUSetup(IDirect3DDevice7
*iface
,
2813 D3DRENDERSTATETYPE RenderStateType
,
2816 return IDirect3DDeviceImpl_7_SetRenderState(iface
, RenderStateType
, Value
);
2819 static HRESULT WINAPI
2820 IDirect3DDeviceImpl_7_SetRenderState_FPUPreserve(IDirect3DDevice7
*iface
,
2821 D3DRENDERSTATETYPE RenderStateType
,
2827 old_fpucw
= d3d_fpu_setup();
2828 hr
= IDirect3DDeviceImpl_7_SetRenderState(iface
, RenderStateType
, Value
);
2829 set_fpu_control_word(old_fpucw
);
2834 static HRESULT WINAPI
2835 IDirect3DDeviceImpl_3_SetRenderState(IDirect3DDevice3
*iface
,
2836 D3DRENDERSTATETYPE RenderStateType
,
2839 /* Note about D3DRENDERSTATE_TEXTUREMAPBLEND implementation: most of values
2840 for this state can be directly mapped to texture stage colorop and alphaop, but
2841 D3DTBLEND_MODULATE is tricky: it uses alpha from texture when available and alpha
2842 from diffuse otherwise. So changing the texture must be monitored in SetTexture to modify
2843 alphaarg when needed.
2845 Aliens vs Predator 1 depends on accurate D3DTBLEND_MODULATE emulation
2847 Legacy texture blending (TEXTUREMAPBLEND) and texture stage states: directx6 docs state that
2848 TEXTUREMAPBLEND is deprecated, yet can still be used. Games must not use both or results
2849 are undefined. D3DTBLEND_MODULATE mode in particular is dependent on texture pixel format and
2850 requires fixup of stage 0 texture states when texture changes, but this fixup can interfere
2851 with games not using this deprecated state. So a flag 'legacyTextureBlending' has to be kept
2852 in device - TRUE if the app is using TEXTUREMAPBLEND.
2854 Tests show that setting TEXTUREMAPBLEND on native doesn't seem to change values returned by
2855 GetTextureStageState and vice versa. Not so on Wine, but it is 'undefined' anyway so, probably, ok,
2856 unless some broken game will be found that cares. */
2859 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
2861 TRACE("iface %p, state %#x, value %#x.\n", iface
, RenderStateType
, Value
);
2863 EnterCriticalSection(&ddraw_cs
);
2865 switch(RenderStateType
)
2867 case D3DRENDERSTATE_TEXTUREHANDLE
:
2869 IDirectDrawSurfaceImpl
*surf
;
2873 hr
= IWineD3DDevice_SetTexture(This
->wineD3DDevice
,
2879 surf
= ddraw_get_object(&This
->handle_table
, Value
- 1, DDRAW_HANDLE_SURFACE
);
2882 WARN("Invalid texture handle.\n");
2883 hr
= DDERR_INVALIDPARAMS
;
2887 hr
= IDirect3DDevice3_SetTexture(iface
, 0, (IDirect3DTexture2
*)&surf
->IDirect3DTexture2_vtbl
);
2891 case D3DRENDERSTATE_TEXTUREMAPBLEND
:
2893 This
->legacyTextureBlending
= TRUE
;
2895 switch ( (D3DTEXTUREBLEND
) Value
)
2897 case D3DTBLEND_MODULATE
:
2899 BOOL tex_alpha
= FALSE
;
2900 IWineD3DBaseTexture
*tex
= NULL
;
2901 WINED3DSURFACE_DESC desc
;
2902 DDPIXELFORMAT ddfmt
;
2904 hr
= IWineD3DDevice_GetTexture(This
->wineD3DDevice
,
2908 if(hr
== WINED3D_OK
&& tex
)
2910 memset(&desc
, 0, sizeof(desc
));
2911 hr
= IWineD3DTexture_GetLevelDesc((IWineD3DTexture
*) tex
, 0, &desc
);
2914 ddfmt
.dwSize
= sizeof(ddfmt
);
2915 PixelFormat_WineD3DtoDD(&ddfmt
, desc
.format
);
2916 if (ddfmt
.u5
.dwRGBAlphaBitMask
) tex_alpha
= TRUE
;
2919 IWineD3DBaseTexture_Release(tex
);
2923 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAOP
, WINED3DTOP_SELECTARG1
);
2925 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAOP
, WINED3DTOP_SELECTARG2
);
2926 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAARG1
, WINED3DTA_TEXTURE
);
2927 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAARG2
, WINED3DTA_CURRENT
);
2928 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_COLORARG1
, WINED3DTA_TEXTURE
);
2929 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_COLORARG2
, WINED3DTA_CURRENT
);
2930 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_COLOROP
, WINED3DTOP_MODULATE
);
2936 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_COLOROP
, WINED3DTOP_ADD
);
2937 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_COLORARG1
, WINED3DTA_TEXTURE
);
2938 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_COLORARG2
, WINED3DTA_CURRENT
);
2939 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAOP
, WINED3DTOP_SELECTARG2
);
2940 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAARG2
, WINED3DTA_CURRENT
);
2943 case D3DTBLEND_MODULATEALPHA
:
2944 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_COLORARG1
, WINED3DTA_TEXTURE
);
2945 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAARG1
, WINED3DTA_TEXTURE
);
2946 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_COLORARG2
, WINED3DTA_CURRENT
);
2947 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAARG2
, WINED3DTA_CURRENT
);
2948 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_COLOROP
, WINED3DTOP_MODULATE
);
2949 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAOP
, WINED3DTOP_MODULATE
);
2952 case D3DTBLEND_COPY
:
2953 case D3DTBLEND_DECAL
:
2954 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_COLORARG1
, WINED3DTA_TEXTURE
);
2955 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAARG1
, WINED3DTA_TEXTURE
);
2956 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_COLOROP
, WINED3DTOP_SELECTARG1
);
2957 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAOP
, WINED3DTOP_SELECTARG1
);
2960 case D3DTBLEND_DECALALPHA
:
2961 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_COLOROP
, WINED3DTOP_BLENDTEXTUREALPHA
);
2962 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_COLORARG1
, WINED3DTA_TEXTURE
);
2963 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_COLORARG2
, WINED3DTA_CURRENT
);
2964 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAOP
, WINED3DTOP_SELECTARG2
);
2965 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAARG2
, WINED3DTA_CURRENT
);
2969 ERR("Unhandled texture environment %d !\n",Value
);
2977 hr
= IDirect3DDevice7_SetRenderState((IDirect3DDevice7
*)This
, RenderStateType
, Value
);
2981 LeaveCriticalSection(&ddraw_cs
);
2986 static HRESULT WINAPI
2987 Thunk_IDirect3DDeviceImpl_2_SetRenderState(IDirect3DDevice2
*iface
,
2988 D3DRENDERSTATETYPE RenderStateType
,
2991 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
2993 TRACE("iface %p, state %#x, value %#x.\n", iface
, RenderStateType
, Value
);
2995 return IDirect3DDevice3_SetRenderState((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
, RenderStateType
, Value
);
2998 /*****************************************************************************
2999 * Direct3DDevice3::SetLightState
3001 * Sets a light state for Direct3DDevice3 and Direct3DDevice2. The
3002 * light states are forwarded to Direct3DDevice7 render states
3007 * LightStateType: The light state to change
3008 * Value: The value to assign to that light state
3012 * DDERR_INVALIDPARAMS if the parameters were incorrect
3013 * Also check IDirect3DDevice7::SetRenderState
3015 *****************************************************************************/
3016 static HRESULT WINAPI
3017 IDirect3DDeviceImpl_3_SetLightState(IDirect3DDevice3
*iface
,
3018 D3DLIGHTSTATETYPE LightStateType
,
3021 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
3024 TRACE("iface %p, state %#x, value %#x.\n", iface
, LightStateType
, Value
);
3026 if (!LightStateType
|| (LightStateType
> D3DLIGHTSTATE_COLORVERTEX
))
3028 TRACE("Unexpected Light State Type\n");
3029 return DDERR_INVALIDPARAMS
;
3032 EnterCriticalSection(&ddraw_cs
);
3033 if (LightStateType
== D3DLIGHTSTATE_MATERIAL
/* 1 */)
3035 IDirect3DMaterialImpl
*m
= ddraw_get_object(&This
->handle_table
, Value
- 1, DDRAW_HANDLE_MATERIAL
);
3038 WARN("Invalid material handle.\n");
3039 LeaveCriticalSection(&ddraw_cs
);
3040 return DDERR_INVALIDPARAMS
;
3043 TRACE(" activating material %p.\n", m
);
3044 material_activate(m
);
3046 This
->material
= Value
;
3048 else if (LightStateType
== D3DLIGHTSTATE_COLORMODEL
/* 3 */)
3053 ERR("DDCOLOR_MONO should not happen!\n");
3056 /* We are already in this mode */
3057 TRACE("Setting color model to RGB (no-op).\n");
3060 ERR("Unknown color model!\n");
3061 LeaveCriticalSection(&ddraw_cs
);
3062 return DDERR_INVALIDPARAMS
;
3067 D3DRENDERSTATETYPE rs
;
3068 switch (LightStateType
)
3070 case D3DLIGHTSTATE_AMBIENT
: /* 2 */
3071 rs
= D3DRENDERSTATE_AMBIENT
;
3073 case D3DLIGHTSTATE_FOGMODE
: /* 4 */
3074 rs
= D3DRENDERSTATE_FOGVERTEXMODE
;
3076 case D3DLIGHTSTATE_FOGSTART
: /* 5 */
3077 rs
= D3DRENDERSTATE_FOGSTART
;
3079 case D3DLIGHTSTATE_FOGEND
: /* 6 */
3080 rs
= D3DRENDERSTATE_FOGEND
;
3082 case D3DLIGHTSTATE_FOGDENSITY
: /* 7 */
3083 rs
= D3DRENDERSTATE_FOGDENSITY
;
3085 case D3DLIGHTSTATE_COLORVERTEX
: /* 8 */
3086 rs
= D3DRENDERSTATE_COLORVERTEX
;
3089 ERR("Unknown D3DLIGHTSTATETYPE %d.\n", LightStateType
);
3090 LeaveCriticalSection(&ddraw_cs
);
3091 return DDERR_INVALIDPARAMS
;
3094 hr
= IDirect3DDevice7_SetRenderState((IDirect3DDevice7
*)This
, rs
, Value
);
3095 LeaveCriticalSection(&ddraw_cs
);
3099 LeaveCriticalSection(&ddraw_cs
);
3103 static HRESULT WINAPI
3104 Thunk_IDirect3DDeviceImpl_2_SetLightState(IDirect3DDevice2
*iface
,
3105 D3DLIGHTSTATETYPE LightStateType
,
3108 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
3110 TRACE("iface %p, state %#x, value %#x.\n", iface
, LightStateType
, Value
);
3112 return IDirect3DDevice3_SetLightState((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
, LightStateType
, Value
);
3115 /*****************************************************************************
3116 * IDirect3DDevice3::GetLightState
3118 * Returns the current setting of a light state. The state is read from
3119 * the Direct3DDevice7 render state.
3124 * LightStateType: The light state to return
3125 * Value: The address to store the light state setting at
3129 * DDDERR_INVALIDPARAMS if the parameters were incorrect
3130 * Also see IDirect3DDevice7::GetRenderState
3132 *****************************************************************************/
3133 static HRESULT WINAPI
3134 IDirect3DDeviceImpl_3_GetLightState(IDirect3DDevice3
*iface
,
3135 D3DLIGHTSTATETYPE LightStateType
,
3138 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
3141 TRACE("iface %p, state %#x, value %p.\n", iface
, LightStateType
, Value
);
3143 if (!LightStateType
|| (LightStateType
> D3DLIGHTSTATE_COLORVERTEX
))
3145 TRACE("Unexpected Light State Type\n");
3146 return DDERR_INVALIDPARAMS
;
3150 return DDERR_INVALIDPARAMS
;
3152 EnterCriticalSection(&ddraw_cs
);
3153 if (LightStateType
== D3DLIGHTSTATE_MATERIAL
/* 1 */)
3155 *Value
= This
->material
;
3157 else if (LightStateType
== D3DLIGHTSTATE_COLORMODEL
/* 3 */)
3159 *Value
= D3DCOLOR_RGB
;
3163 D3DRENDERSTATETYPE rs
;
3164 switch (LightStateType
)
3166 case D3DLIGHTSTATE_AMBIENT
: /* 2 */
3167 rs
= D3DRENDERSTATE_AMBIENT
;
3169 case D3DLIGHTSTATE_FOGMODE
: /* 4 */
3170 rs
= D3DRENDERSTATE_FOGVERTEXMODE
;
3172 case D3DLIGHTSTATE_FOGSTART
: /* 5 */
3173 rs
= D3DRENDERSTATE_FOGSTART
;
3175 case D3DLIGHTSTATE_FOGEND
: /* 6 */
3176 rs
= D3DRENDERSTATE_FOGEND
;
3178 case D3DLIGHTSTATE_FOGDENSITY
: /* 7 */
3179 rs
= D3DRENDERSTATE_FOGDENSITY
;
3181 case D3DLIGHTSTATE_COLORVERTEX
: /* 8 */
3182 rs
= D3DRENDERSTATE_COLORVERTEX
;
3185 ERR("Unknown D3DLIGHTSTATETYPE %d.\n", LightStateType
);
3186 LeaveCriticalSection(&ddraw_cs
);
3187 return DDERR_INVALIDPARAMS
;
3190 hr
= IDirect3DDevice7_GetRenderState((IDirect3DDevice7
*)This
, rs
, Value
);
3191 LeaveCriticalSection(&ddraw_cs
);
3195 LeaveCriticalSection(&ddraw_cs
);
3199 static HRESULT WINAPI
3200 Thunk_IDirect3DDeviceImpl_2_GetLightState(IDirect3DDevice2
*iface
,
3201 D3DLIGHTSTATETYPE LightStateType
,
3204 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
3206 TRACE("iface %p, state %#x, value %p.\n", iface
, LightStateType
, Value
);
3208 return IDirect3DDevice3_GetLightState((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
, LightStateType
, Value
);
3211 /*****************************************************************************
3212 * IDirect3DDevice7::SetTransform
3214 * Assigns a D3DMATRIX to a transform type. The transform types are defined
3215 * in include/d3dtypes.h.
3216 * The D3DTRANSFORMSTATE_WORLD (=1) is translated to D3DTS_WORLDMATRIX(0)
3217 * (=255) for wined3d, because the 1 transform state was removed in d3d8
3218 * and WineD3D already understands the replacement D3DTS_WORLDMATRIX(0)
3220 * Version 2, 3 and 7
3223 * TransformStateType: transform state to set
3224 * Matrix: Matrix to assign to the state
3228 * DDERR_INVALIDPARAMS if Matrix == NULL
3229 * For details see IWineD3DDevice::SetTransform
3231 *****************************************************************************/
3233 IDirect3DDeviceImpl_7_SetTransform(IDirect3DDevice7
*iface
,
3234 D3DTRANSFORMSTATETYPE TransformStateType
,
3237 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
3238 D3DTRANSFORMSTATETYPE type
;
3241 TRACE("iface %p, state %#x, matrix %p.\n", iface
, TransformStateType
, Matrix
);
3243 switch(TransformStateType
)
3245 case D3DTRANSFORMSTATE_WORLD
: type
= WINED3DTS_WORLDMATRIX(0); break;
3246 case D3DTRANSFORMSTATE_WORLD1
: type
= WINED3DTS_WORLDMATRIX(1); break;
3247 case D3DTRANSFORMSTATE_WORLD2
: type
= WINED3DTS_WORLDMATRIX(2); break;
3248 case D3DTRANSFORMSTATE_WORLD3
: type
= WINED3DTS_WORLDMATRIX(3); break;
3249 default: type
= TransformStateType
;
3253 return DDERR_INVALIDPARAMS
;
3255 /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
3256 EnterCriticalSection(&ddraw_cs
);
3257 hr
= IWineD3DDevice_SetTransform(This
->wineD3DDevice
,
3259 (WINED3DMATRIX
*) Matrix
);
3260 LeaveCriticalSection(&ddraw_cs
);
3264 static HRESULT WINAPI
3265 IDirect3DDeviceImpl_7_SetTransform_FPUSetup(IDirect3DDevice7
*iface
,
3266 D3DTRANSFORMSTATETYPE TransformStateType
,
3269 return IDirect3DDeviceImpl_7_SetTransform(iface
, TransformStateType
, Matrix
);
3272 static HRESULT WINAPI
3273 IDirect3DDeviceImpl_7_SetTransform_FPUPreserve(IDirect3DDevice7
*iface
,
3274 D3DTRANSFORMSTATETYPE TransformStateType
,
3280 old_fpucw
= d3d_fpu_setup();
3281 hr
= IDirect3DDeviceImpl_7_SetTransform(iface
, TransformStateType
, Matrix
);
3282 set_fpu_control_word(old_fpucw
);
3287 static HRESULT WINAPI
3288 Thunk_IDirect3DDeviceImpl_3_SetTransform(IDirect3DDevice3
*iface
,
3289 D3DTRANSFORMSTATETYPE TransformStateType
,
3290 D3DMATRIX
*D3DMatrix
)
3292 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
3294 TRACE("iface %p, state %#x, matrix %p.\n", iface
, TransformStateType
, D3DMatrix
);
3296 return IDirect3DDevice7_SetTransform((IDirect3DDevice7
*)This
, TransformStateType
, D3DMatrix
);
3299 static HRESULT WINAPI
3300 Thunk_IDirect3DDeviceImpl_2_SetTransform(IDirect3DDevice2
*iface
,
3301 D3DTRANSFORMSTATETYPE TransformStateType
,
3302 D3DMATRIX
*D3DMatrix
)
3304 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
3306 TRACE("iface %p, state %#x, matrix %p.\n", iface
, TransformStateType
, D3DMatrix
);
3308 return IDirect3DDevice7_SetTransform((IDirect3DDevice7
*)This
, TransformStateType
, D3DMatrix
);
3311 /*****************************************************************************
3312 * IDirect3DDevice7::GetTransform
3314 * Returns the matrix assigned to a transform state
3315 * D3DTRANSFORMSTATE_WORLD is translated to D3DTS_WORLDMATRIX(0), see
3319 * TransformStateType: State to read the matrix from
3320 * Matrix: Address to store the matrix at
3324 * DDERR_INVALIDPARAMS if Matrix == NULL
3325 * For details, see IWineD3DDevice::GetTransform
3327 *****************************************************************************/
3329 IDirect3DDeviceImpl_7_GetTransform(IDirect3DDevice7
*iface
,
3330 D3DTRANSFORMSTATETYPE TransformStateType
,
3333 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
3334 D3DTRANSFORMSTATETYPE type
;
3337 TRACE("iface %p, state %#x, matrix %p.\n", iface
, TransformStateType
, Matrix
);
3339 switch(TransformStateType
)
3341 case D3DTRANSFORMSTATE_WORLD
: type
= WINED3DTS_WORLDMATRIX(0); break;
3342 case D3DTRANSFORMSTATE_WORLD1
: type
= WINED3DTS_WORLDMATRIX(1); break;
3343 case D3DTRANSFORMSTATE_WORLD2
: type
= WINED3DTS_WORLDMATRIX(2); break;
3344 case D3DTRANSFORMSTATE_WORLD3
: type
= WINED3DTS_WORLDMATRIX(3); break;
3345 default: type
= TransformStateType
;
3349 return DDERR_INVALIDPARAMS
;
3351 /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
3352 EnterCriticalSection(&ddraw_cs
);
3353 hr
= IWineD3DDevice_GetTransform(This
->wineD3DDevice
, type
, (WINED3DMATRIX
*) Matrix
);
3354 LeaveCriticalSection(&ddraw_cs
);
3358 static HRESULT WINAPI
3359 IDirect3DDeviceImpl_7_GetTransform_FPUSetup(IDirect3DDevice7
*iface
,
3360 D3DTRANSFORMSTATETYPE TransformStateType
,
3363 return IDirect3DDeviceImpl_7_GetTransform(iface
, TransformStateType
, Matrix
);
3366 static HRESULT WINAPI
3367 IDirect3DDeviceImpl_7_GetTransform_FPUPreserve(IDirect3DDevice7
*iface
,
3368 D3DTRANSFORMSTATETYPE TransformStateType
,
3374 old_fpucw
= d3d_fpu_setup();
3375 hr
= IDirect3DDeviceImpl_7_GetTransform(iface
, TransformStateType
, Matrix
);
3376 set_fpu_control_word(old_fpucw
);
3381 static HRESULT WINAPI
3382 Thunk_IDirect3DDeviceImpl_3_GetTransform(IDirect3DDevice3
*iface
,
3383 D3DTRANSFORMSTATETYPE TransformStateType
,
3384 D3DMATRIX
*D3DMatrix
)
3386 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
3388 TRACE("iface %p, state %#x, matrix %p.\n", iface
, TransformStateType
, D3DMatrix
);
3390 return IDirect3DDevice7_GetTransform((IDirect3DDevice7
*)This
, TransformStateType
, D3DMatrix
);
3393 static HRESULT WINAPI
3394 Thunk_IDirect3DDeviceImpl_2_GetTransform(IDirect3DDevice2
*iface
,
3395 D3DTRANSFORMSTATETYPE TransformStateType
,
3396 D3DMATRIX
*D3DMatrix
)
3398 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
3400 TRACE("iface %p, state %#x, matrix %p.\n", iface
, TransformStateType
, D3DMatrix
);
3402 return IDirect3DDevice7_GetTransform((IDirect3DDevice7
*)This
, TransformStateType
, D3DMatrix
);
3405 /*****************************************************************************
3406 * IDirect3DDevice7::MultiplyTransform
3408 * Multiplies the already-set transform matrix of a transform state
3409 * with another matrix. For the world matrix, see SetTransform
3411 * Version 2, 3 and 7
3414 * TransformStateType: Transform state to multiply
3415 * D3DMatrix Matrix to multiply with.
3419 * DDERR_INVALIDPARAMS if D3DMatrix is NULL
3420 * For details, see IWineD3DDevice::MultiplyTransform
3422 *****************************************************************************/
3424 IDirect3DDeviceImpl_7_MultiplyTransform(IDirect3DDevice7
*iface
,
3425 D3DTRANSFORMSTATETYPE TransformStateType
,
3426 D3DMATRIX
*D3DMatrix
)
3428 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
3430 D3DTRANSFORMSTATETYPE type
;
3432 TRACE("iface %p, state %#x, matrix %p.\n", iface
, TransformStateType
, D3DMatrix
);
3434 switch(TransformStateType
)
3436 case D3DTRANSFORMSTATE_WORLD
: type
= WINED3DTS_WORLDMATRIX(0); break;
3437 case D3DTRANSFORMSTATE_WORLD1
: type
= WINED3DTS_WORLDMATRIX(1); break;
3438 case D3DTRANSFORMSTATE_WORLD2
: type
= WINED3DTS_WORLDMATRIX(2); break;
3439 case D3DTRANSFORMSTATE_WORLD3
: type
= WINED3DTS_WORLDMATRIX(3); break;
3440 default: type
= TransformStateType
;
3443 /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
3444 EnterCriticalSection(&ddraw_cs
);
3445 hr
= IWineD3DDevice_MultiplyTransform(This
->wineD3DDevice
,
3447 (WINED3DMATRIX
*) D3DMatrix
);
3448 LeaveCriticalSection(&ddraw_cs
);
3452 static HRESULT WINAPI
3453 IDirect3DDeviceImpl_7_MultiplyTransform_FPUSetup(IDirect3DDevice7
*iface
,
3454 D3DTRANSFORMSTATETYPE TransformStateType
,
3455 D3DMATRIX
*D3DMatrix
)
3457 return IDirect3DDeviceImpl_7_MultiplyTransform(iface
, TransformStateType
, D3DMatrix
);
3460 static HRESULT WINAPI
3461 IDirect3DDeviceImpl_7_MultiplyTransform_FPUPreserve(IDirect3DDevice7
*iface
,
3462 D3DTRANSFORMSTATETYPE TransformStateType
,
3463 D3DMATRIX
*D3DMatrix
)
3468 old_fpucw
= d3d_fpu_setup();
3469 hr
= IDirect3DDeviceImpl_7_MultiplyTransform(iface
, TransformStateType
, D3DMatrix
);
3470 set_fpu_control_word(old_fpucw
);
3475 static HRESULT WINAPI
3476 Thunk_IDirect3DDeviceImpl_3_MultiplyTransform(IDirect3DDevice3
*iface
,
3477 D3DTRANSFORMSTATETYPE TransformStateType
,
3478 D3DMATRIX
*D3DMatrix
)
3480 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
3482 TRACE("iface %p, state %#x, matrix %p.\n", iface
, TransformStateType
, D3DMatrix
);
3484 return IDirect3DDevice7_MultiplyTransform((IDirect3DDevice7
*)This
, TransformStateType
, D3DMatrix
);
3487 static HRESULT WINAPI
3488 Thunk_IDirect3DDeviceImpl_2_MultiplyTransform(IDirect3DDevice2
*iface
,
3489 D3DTRANSFORMSTATETYPE TransformStateType
,
3490 D3DMATRIX
*D3DMatrix
)
3492 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
3494 TRACE("iface %p, state %#x, matrix %p.\n", iface
, TransformStateType
, D3DMatrix
);
3496 return IDirect3DDevice7_MultiplyTransform((IDirect3DDevice7
*)This
, TransformStateType
, D3DMatrix
);
3499 /*****************************************************************************
3500 * IDirect3DDevice7::DrawPrimitive
3502 * Draws primitives based on vertices in an application-provided pointer
3504 * Version 2, 3 and 7. The IDirect3DDevice2 thunk converts the fixed vertex type into
3505 * an FVF format for D3D7
3508 * PrimitiveType: The type of the primitives to draw
3509 * Vertex type: Flexible vertex format vertex description
3510 * Vertices: Pointer to the vertex array
3511 * VertexCount: The number of vertices to draw
3512 * Flags: As usual a few flags
3516 * DDERR_INVALIDPARAMS if Vertices is NULL
3517 * For details, see IWineD3DDevice::DrawPrimitiveUP
3519 *****************************************************************************/
3521 IDirect3DDeviceImpl_7_DrawPrimitive(IDirect3DDevice7
*iface
,
3522 D3DPRIMITIVETYPE PrimitiveType
,
3528 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
3532 TRACE("iface %p, primitive_type %#x, FVF %#x, vertices %p, vertex_count %u, flags %#x.\n",
3533 iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Flags
);
3536 return DDERR_INVALIDPARAMS
;
3538 /* Get the stride */
3539 stride
= get_flexible_vertex_size(VertexType
);
3542 EnterCriticalSection(&ddraw_cs
);
3543 hr
= IWineD3DDevice_SetVertexDeclaration(This
->wineD3DDevice
, ddraw_find_decl(This
->ddraw
, VertexType
));
3546 LeaveCriticalSection(&ddraw_cs
);
3550 /* This method translates to the user pointer draw of WineD3D */
3551 IWineD3DDevice_SetPrimitiveType(This
->wineD3DDevice
, PrimitiveType
);
3552 hr
= IWineD3DDevice_DrawPrimitiveUP(This
->wineD3DDevice
, VertexCount
, Vertices
, stride
);
3553 LeaveCriticalSection(&ddraw_cs
);
3557 static HRESULT WINAPI
3558 IDirect3DDeviceImpl_7_DrawPrimitive_FPUSetup(IDirect3DDevice7
*iface
,
3559 D3DPRIMITIVETYPE PrimitiveType
,
3565 return IDirect3DDeviceImpl_7_DrawPrimitive(iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Flags
);
3568 static HRESULT WINAPI
3569 IDirect3DDeviceImpl_7_DrawPrimitive_FPUPreserve(IDirect3DDevice7
*iface
,
3570 D3DPRIMITIVETYPE PrimitiveType
,
3579 old_fpucw
= d3d_fpu_setup();
3580 hr
= IDirect3DDeviceImpl_7_DrawPrimitive(iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Flags
);
3581 set_fpu_control_word(old_fpucw
);
3586 static HRESULT WINAPI
3587 Thunk_IDirect3DDeviceImpl_3_DrawPrimitive(IDirect3DDevice3
*iface
,
3588 D3DPRIMITIVETYPE PrimitiveType
,
3594 TRACE("iface %p, primitive_type %#x, FVF %#x, vertices %p, vertex_count %u, flags %#x.\n",
3595 iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Flags
);
3597 return IDirect3DDevice7_DrawPrimitive((IDirect3DDevice7
*)device_from_device3(iface
),
3598 PrimitiveType
, VertexType
, Vertices
, VertexCount
, Flags
);
3601 static HRESULT WINAPI
3602 Thunk_IDirect3DDeviceImpl_2_DrawPrimitive(IDirect3DDevice2
*iface
,
3603 D3DPRIMITIVETYPE PrimitiveType
,
3604 D3DVERTEXTYPE VertexType
,
3611 TRACE("iface %p, primitive_type %#x, vertex_type %#x, vertices %p, vertex_count %u, flags %#x.\n",
3612 iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Flags
);
3616 case D3DVT_VERTEX
: FVF
= D3DFVF_VERTEX
; break;
3617 case D3DVT_LVERTEX
: FVF
= D3DFVF_LVERTEX
; break;
3618 case D3DVT_TLVERTEX
: FVF
= D3DFVF_TLVERTEX
; break;
3620 ERR("Unexpected vertex type %d\n", VertexType
);
3621 return DDERR_INVALIDPARAMS
; /* Should never happen */
3624 return IDirect3DDevice7_DrawPrimitive((IDirect3DDevice7
*)device_from_device2(iface
),
3625 PrimitiveType
, FVF
, Vertices
, VertexCount
, Flags
);
3628 /*****************************************************************************
3629 * IDirect3DDevice7::DrawIndexedPrimitive
3631 * Draws vertices from an application-provided pointer, based on the index
3632 * numbers in a WORD array.
3634 * Version 2, 3 and 7. The version 7 thunk translates the vertex type into
3635 * an FVF format for D3D7
3638 * PrimitiveType: The primitive type to draw
3639 * VertexType: The FVF vertex description
3640 * Vertices: Pointer to the vertex array
3642 * Indices: Pointer to the index array
3643 * IndexCount: Number of indices = Number of vertices to draw
3644 * Flags: As usual, some flags
3648 * DDERR_INVALIDPARAMS if Vertices or Indices is NULL
3649 * For details, see IWineD3DDevice::DrawIndexedPrimitiveUP
3651 *****************************************************************************/
3653 IDirect3DDeviceImpl_7_DrawIndexedPrimitive(IDirect3DDevice7
*iface
,
3654 D3DPRIMITIVETYPE PrimitiveType
,
3662 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
3665 TRACE("iface %p, primitive_type %#x, FVF %#x, vertices %p, vertex_count %u, indices %p, index_count %u, flags %#x.\n",
3666 iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Indices
, IndexCount
, Flags
);
3668 /* Set the D3DDevice's FVF */
3669 EnterCriticalSection(&ddraw_cs
);
3670 hr
= IWineD3DDevice_SetVertexDeclaration(This
->wineD3DDevice
, ddraw_find_decl(This
->ddraw
, VertexType
));
3673 ERR(" (%p) Setting the FVF failed, hr = %x!\n", This
, hr
);
3674 LeaveCriticalSection(&ddraw_cs
);
3678 IWineD3DDevice_SetPrimitiveType(This
->wineD3DDevice
, PrimitiveType
);
3679 hr
= IWineD3DDevice_DrawIndexedPrimitiveUP(This
->wineD3DDevice
, IndexCount
, Indices
,
3680 WINED3DFMT_R16_UINT
, Vertices
, get_flexible_vertex_size(VertexType
));
3681 LeaveCriticalSection(&ddraw_cs
);
3685 static HRESULT WINAPI
3686 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUSetup(IDirect3DDevice7
*iface
,
3687 D3DPRIMITIVETYPE PrimitiveType
,
3695 return IDirect3DDeviceImpl_7_DrawIndexedPrimitive(iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Indices
, IndexCount
, Flags
);
3698 static HRESULT WINAPI
3699 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUPreserve(IDirect3DDevice7
*iface
,
3700 D3DPRIMITIVETYPE PrimitiveType
,
3711 old_fpucw
= d3d_fpu_setup();
3712 hr
= IDirect3DDeviceImpl_7_DrawIndexedPrimitive(iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Indices
, IndexCount
, Flags
);
3713 set_fpu_control_word(old_fpucw
);
3718 static HRESULT WINAPI
3719 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitive(IDirect3DDevice3
*iface
,
3720 D3DPRIMITIVETYPE PrimitiveType
,
3728 TRACE("iface %p, primitive_type %#x, FVF %#x, vertices %p, vertex_count %u, indices %p, index_count %u, flags %#x.\n",
3729 iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Indices
, IndexCount
, Flags
);
3731 return IDirect3DDevice7_DrawIndexedPrimitive((IDirect3DDevice7
*)device_from_device3(iface
),
3732 PrimitiveType
, VertexType
, Vertices
, VertexCount
, Indices
, IndexCount
, Flags
);
3735 static HRESULT WINAPI
3736 Thunk_IDirect3DDeviceImpl_2_DrawIndexedPrimitive(IDirect3DDevice2
*iface
,
3737 D3DPRIMITIVETYPE PrimitiveType
,
3738 D3DVERTEXTYPE VertexType
,
3747 TRACE("iface %p, primitive_type %#x, vertex_type %#x, vertices %p, vertex_count %u, indices %p, index_count %u, flags %#x.\n",
3748 iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Indices
, IndexCount
, Flags
);
3752 case D3DVT_VERTEX
: FVF
= D3DFVF_VERTEX
; break;
3753 case D3DVT_LVERTEX
: FVF
= D3DFVF_LVERTEX
; break;
3754 case D3DVT_TLVERTEX
: FVF
= D3DFVF_TLVERTEX
; break;
3756 ERR("Unexpected vertex type %d\n", VertexType
);
3757 return DDERR_INVALIDPARAMS
; /* Should never happen */
3760 return IDirect3DDevice7_DrawIndexedPrimitive((IDirect3DDevice7
*)device_from_device2(iface
),
3761 PrimitiveType
, FVF
, Vertices
, VertexCount
, Indices
, IndexCount
, Flags
);
3764 /*****************************************************************************
3765 * IDirect3DDevice7::SetClipStatus
3767 * Sets the clip status. This defines things as clipping conditions and
3768 * the extents of the clipping region.
3770 * Version 2, 3 and 7
3776 * D3D_OK because it's a stub
3777 * (DDERR_INVALIDPARAMS if ClipStatus == NULL)
3779 *****************************************************************************/
3780 static HRESULT WINAPI
3781 IDirect3DDeviceImpl_7_SetClipStatus(IDirect3DDevice7
*iface
,
3782 D3DCLIPSTATUS
*ClipStatus
)
3784 FIXME("iface %p, clip_status %p stub!\n", iface
, ClipStatus
);
3786 /* D3DCLIPSTATUS and WINED3DCLIPSTATUS are different. I don't know how to convert them
3787 * Perhaps this needs a new data type and an additional IWineD3DDevice method
3789 /* return IWineD3DDevice_SetClipStatus(This->wineD3DDevice, ClipStatus);*/
3793 static HRESULT WINAPI
3794 Thunk_IDirect3DDeviceImpl_3_SetClipStatus(IDirect3DDevice3
*iface
,
3795 D3DCLIPSTATUS
*ClipStatus
)
3797 TRACE("iface %p, clip_status %p.\n", iface
, ClipStatus
);
3799 return IDirect3DDevice7_SetClipStatus((IDirect3DDevice7
*)device_from_device3(iface
), ClipStatus
);
3802 static HRESULT WINAPI
3803 Thunk_IDirect3DDeviceImpl_2_SetClipStatus(IDirect3DDevice2
*iface
,
3804 D3DCLIPSTATUS
*ClipStatus
)
3806 TRACE("iface %p, clip_status %p.\n", iface
, ClipStatus
);
3808 return IDirect3DDevice7_SetClipStatus((IDirect3DDevice7
*)device_from_device2(iface
), ClipStatus
);
3811 /*****************************************************************************
3812 * IDirect3DDevice7::GetClipStatus
3814 * Returns the clip status
3817 * ClipStatus: Address to write the clip status to
3820 * D3D_OK because it's a stub
3822 *****************************************************************************/
3823 static HRESULT WINAPI
3824 IDirect3DDeviceImpl_7_GetClipStatus(IDirect3DDevice7
*iface
,
3825 D3DCLIPSTATUS
*ClipStatus
)
3827 FIXME("iface %p, clip_status %p stub!\n", iface
, ClipStatus
);
3829 /* D3DCLIPSTATUS and WINED3DCLIPSTATUS are different. I don't know how to convert them */
3830 /* return IWineD3DDevice_GetClipStatus(This->wineD3DDevice, ClipStatus);*/
3834 static HRESULT WINAPI
3835 Thunk_IDirect3DDeviceImpl_3_GetClipStatus(IDirect3DDevice3
*iface
,
3836 D3DCLIPSTATUS
*ClipStatus
)
3838 TRACE("iface %p, clip_status %p.\n", iface
, ClipStatus
);
3840 return IDirect3DDevice7_GetClipStatus((IDirect3DDevice7
*)device_from_device3(iface
), ClipStatus
);
3843 static HRESULT WINAPI
3844 Thunk_IDirect3DDeviceImpl_2_GetClipStatus(IDirect3DDevice2
*iface
,
3845 D3DCLIPSTATUS
*ClipStatus
)
3847 TRACE("iface %p, clip_status %p.\n", iface
, ClipStatus
);
3849 return IDirect3DDevice7_GetClipStatus((IDirect3DDevice7
*)device_from_device2(iface
), ClipStatus
);
3852 /*****************************************************************************
3853 * IDirect3DDevice::DrawPrimitiveStrided
3855 * Draws vertices described by a D3DDRAWPRIMITIVESTRIDEDDATA structure.
3860 * PrimitiveType: The primitive type to draw
3861 * VertexType: The FVF description of the vertices to draw (for the stride??)
3862 * D3DDrawPrimStrideData: A D3DDRAWPRIMITIVESTRIDEDDATA structure describing
3863 * the vertex data locations
3864 * VertexCount: The number of vertices to draw
3868 * D3D_OK, because it's a stub
3869 * (DDERR_INVALIDPARAMS if D3DDrawPrimStrideData is NULL)
3870 * (For details, see IWineD3DDevice::DrawPrimitiveStrided)
3872 *****************************************************************************/
3874 IDirect3DDeviceImpl_7_DrawPrimitiveStrided(IDirect3DDevice7
*iface
,
3875 D3DPRIMITIVETYPE PrimitiveType
,
3877 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
,
3881 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
3882 WineDirect3DVertexStridedData WineD3DStrided
;
3886 TRACE("iface %p, primitive_type %#x, FVF %#x, strided_data %p, vertex_count %u, flags %#x.\n",
3887 iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Flags
);
3889 memset(&WineD3DStrided
, 0, sizeof(WineD3DStrided
));
3890 /* Get the strided data right. the wined3d structure is a bit bigger
3891 * Watch out: The contents of the strided data are determined by the fvf,
3892 * not by the members set in D3DDrawPrimStrideData. So it's valid
3893 * to have diffuse.lpvData set to 0xdeadbeef if the diffuse flag is
3894 * not set in the fvf.
3896 if(VertexType
& D3DFVF_POSITION_MASK
)
3898 WineD3DStrided
.position
.format
= WINED3DFMT_R32G32B32_FLOAT
;
3899 WineD3DStrided
.position
.lpData
= D3DDrawPrimStrideData
->position
.lpvData
;
3900 WineD3DStrided
.position
.dwStride
= D3DDrawPrimStrideData
->position
.dwStride
;
3901 if (VertexType
& D3DFVF_XYZRHW
)
3903 WineD3DStrided
.position
.format
= WINED3DFMT_R32G32B32A32_FLOAT
;
3904 WineD3DStrided
.position_transformed
= TRUE
;
3906 WineD3DStrided
.position_transformed
= FALSE
;
3909 if(VertexType
& D3DFVF_NORMAL
)
3911 WineD3DStrided
.normal
.format
= WINED3DFMT_R32G32B32_FLOAT
;
3912 WineD3DStrided
.normal
.lpData
= D3DDrawPrimStrideData
->normal
.lpvData
;
3913 WineD3DStrided
.normal
.dwStride
= D3DDrawPrimStrideData
->normal
.dwStride
;
3916 if(VertexType
& D3DFVF_DIFFUSE
)
3918 WineD3DStrided
.diffuse
.format
= WINED3DFMT_B8G8R8A8_UNORM
;
3919 WineD3DStrided
.diffuse
.lpData
= D3DDrawPrimStrideData
->diffuse
.lpvData
;
3920 WineD3DStrided
.diffuse
.dwStride
= D3DDrawPrimStrideData
->diffuse
.dwStride
;
3923 if(VertexType
& D3DFVF_SPECULAR
)
3925 WineD3DStrided
.specular
.format
= WINED3DFMT_B8G8R8A8_UNORM
;
3926 WineD3DStrided
.specular
.lpData
= D3DDrawPrimStrideData
->specular
.lpvData
;
3927 WineD3DStrided
.specular
.dwStride
= D3DDrawPrimStrideData
->specular
.dwStride
;
3930 for( i
= 0; i
< GET_TEXCOUNT_FROM_FVF(VertexType
); i
++)
3932 switch(GET_TEXCOORD_SIZE_FROM_FVF(VertexType
, i
))
3934 case 1: WineD3DStrided
.texCoords
[i
].format
= WINED3DFMT_R32_FLOAT
; break;
3935 case 2: WineD3DStrided
.texCoords
[i
].format
= WINED3DFMT_R32G32_FLOAT
; break;
3936 case 3: WineD3DStrided
.texCoords
[i
].format
= WINED3DFMT_R32G32B32_FLOAT
; break;
3937 case 4: WineD3DStrided
.texCoords
[i
].format
= WINED3DFMT_R32G32B32A32_FLOAT
; break;
3938 default: ERR("Unexpected texture coordinate size %d\n",
3939 GET_TEXCOORD_SIZE_FROM_FVF(VertexType
, i
));
3941 WineD3DStrided
.texCoords
[i
].lpData
= D3DDrawPrimStrideData
->textureCoords
[i
].lpvData
;
3942 WineD3DStrided
.texCoords
[i
].dwStride
= D3DDrawPrimStrideData
->textureCoords
[i
].dwStride
;
3945 /* WineD3D doesn't need the FVF here */
3946 EnterCriticalSection(&ddraw_cs
);
3947 IWineD3DDevice_SetPrimitiveType(This
->wineD3DDevice
, PrimitiveType
);
3948 hr
= IWineD3DDevice_DrawPrimitiveStrided(This
->wineD3DDevice
, VertexCount
, &WineD3DStrided
);
3949 LeaveCriticalSection(&ddraw_cs
);
3953 static HRESULT WINAPI
3954 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUSetup(IDirect3DDevice7
*iface
,
3955 D3DPRIMITIVETYPE PrimitiveType
,
3957 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
,
3961 return IDirect3DDeviceImpl_7_DrawPrimitiveStrided(iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Flags
);
3964 static HRESULT WINAPI
3965 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUPreserve(IDirect3DDevice7
*iface
,
3966 D3DPRIMITIVETYPE PrimitiveType
,
3968 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
,
3975 old_fpucw
= d3d_fpu_setup();
3976 hr
= IDirect3DDeviceImpl_7_DrawPrimitiveStrided(iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Flags
);
3977 set_fpu_control_word(old_fpucw
);
3982 static HRESULT WINAPI
3983 Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveStrided(IDirect3DDevice3
*iface
,
3984 D3DPRIMITIVETYPE PrimitiveType
,
3986 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
,
3990 TRACE("iface %p, primitive_type %#x, FVF %#x, strided_data %p, vertex_count %u, flags %#x.\n",
3991 iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Flags
);
3993 return IDirect3DDevice7_DrawPrimitiveStrided((IDirect3DDevice7
*)device_from_device3(iface
),
3994 PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Flags
);
3997 /*****************************************************************************
3998 * IDirect3DDevice7::DrawIndexedPrimitiveStrided
4000 * Draws primitives specified by strided data locations based on indices
4008 * D3D_OK, because it's a stub
4009 * (DDERR_INVALIDPARAMS if D3DDrawPrimStrideData is NULL)
4010 * (DDERR_INVALIDPARAMS if Indices is NULL)
4011 * (For more details, see IWineD3DDevice::DrawIndexedPrimitiveStrided)
4013 *****************************************************************************/
4015 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided(IDirect3DDevice7
*iface
,
4016 D3DPRIMITIVETYPE PrimitiveType
,
4018 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
,
4024 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
4025 WineDirect3DVertexStridedData WineD3DStrided
;
4029 TRACE("iface %p, primitive_type %#x, FVF %#x, strided_data %p, vertex_count %u, indices %p, index_count %u, flags %#x.\n",
4030 iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Indices
, IndexCount
, Flags
);
4032 memset(&WineD3DStrided
, 0, sizeof(WineD3DStrided
));
4033 /* Get the strided data right. the wined3d structure is a bit bigger
4034 * Watch out: The contents of the strided data are determined by the fvf,
4035 * not by the members set in D3DDrawPrimStrideData. So it's valid
4036 * to have diffuse.lpvData set to 0xdeadbeef if the diffuse flag is
4037 * not set in the fvf.
4039 if(VertexType
& D3DFVF_POSITION_MASK
)
4041 WineD3DStrided
.position
.format
= WINED3DFMT_R32G32B32_FLOAT
;
4042 WineD3DStrided
.position
.lpData
= D3DDrawPrimStrideData
->position
.lpvData
;
4043 WineD3DStrided
.position
.dwStride
= D3DDrawPrimStrideData
->position
.dwStride
;
4044 if (VertexType
& D3DFVF_XYZRHW
)
4046 WineD3DStrided
.position
.format
= WINED3DFMT_R32G32B32A32_FLOAT
;
4047 WineD3DStrided
.position_transformed
= TRUE
;
4049 WineD3DStrided
.position_transformed
= FALSE
;
4052 if(VertexType
& D3DFVF_NORMAL
)
4054 WineD3DStrided
.normal
.format
= WINED3DFMT_R32G32B32_FLOAT
;
4055 WineD3DStrided
.normal
.lpData
= D3DDrawPrimStrideData
->normal
.lpvData
;
4056 WineD3DStrided
.normal
.dwStride
= D3DDrawPrimStrideData
->normal
.dwStride
;
4059 if(VertexType
& D3DFVF_DIFFUSE
)
4061 WineD3DStrided
.diffuse
.format
= WINED3DFMT_B8G8R8A8_UNORM
;
4062 WineD3DStrided
.diffuse
.lpData
= D3DDrawPrimStrideData
->diffuse
.lpvData
;
4063 WineD3DStrided
.diffuse
.dwStride
= D3DDrawPrimStrideData
->diffuse
.dwStride
;
4066 if(VertexType
& D3DFVF_SPECULAR
)
4068 WineD3DStrided
.specular
.format
= WINED3DFMT_B8G8R8A8_UNORM
;
4069 WineD3DStrided
.specular
.lpData
= D3DDrawPrimStrideData
->specular
.lpvData
;
4070 WineD3DStrided
.specular
.dwStride
= D3DDrawPrimStrideData
->specular
.dwStride
;
4073 for( i
= 0; i
< GET_TEXCOUNT_FROM_FVF(VertexType
); i
++)
4075 switch(GET_TEXCOORD_SIZE_FROM_FVF(VertexType
, i
))
4077 case 1: WineD3DStrided
.texCoords
[i
].format
= WINED3DFMT_R32_FLOAT
; break;
4078 case 2: WineD3DStrided
.texCoords
[i
].format
= WINED3DFMT_R32G32_FLOAT
; break;
4079 case 3: WineD3DStrided
.texCoords
[i
].format
= WINED3DFMT_R32G32B32_FLOAT
; break;
4080 case 4: WineD3DStrided
.texCoords
[i
].format
= WINED3DFMT_R32G32B32A32_FLOAT
; break;
4081 default: ERR("Unexpected texture coordinate size %d\n",
4082 GET_TEXCOORD_SIZE_FROM_FVF(VertexType
, i
));
4084 WineD3DStrided
.texCoords
[i
].lpData
= D3DDrawPrimStrideData
->textureCoords
[i
].lpvData
;
4085 WineD3DStrided
.texCoords
[i
].dwStride
= D3DDrawPrimStrideData
->textureCoords
[i
].dwStride
;
4088 /* WineD3D doesn't need the FVF here */
4089 EnterCriticalSection(&ddraw_cs
);
4090 IWineD3DDevice_SetPrimitiveType(This
->wineD3DDevice
, PrimitiveType
);
4091 hr
= IWineD3DDevice_DrawIndexedPrimitiveStrided(This
->wineD3DDevice
,
4092 IndexCount
, &WineD3DStrided
, VertexCount
, Indices
, WINED3DFMT_R16_UINT
);
4093 LeaveCriticalSection(&ddraw_cs
);
4097 static HRESULT WINAPI
4098 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUSetup(IDirect3DDevice7
*iface
,
4099 D3DPRIMITIVETYPE PrimitiveType
,
4101 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
,
4107 return IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided(iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Indices
, IndexCount
, Flags
);
4110 static HRESULT WINAPI
4111 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUPreserve(IDirect3DDevice7
*iface
,
4112 D3DPRIMITIVETYPE PrimitiveType
,
4114 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
,
4123 old_fpucw
= d3d_fpu_setup();
4124 hr
= IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided(iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Indices
, IndexCount
, Flags
);
4125 set_fpu_control_word(old_fpucw
);
4130 static HRESULT WINAPI
4131 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveStrided(IDirect3DDevice3
*iface
,
4132 D3DPRIMITIVETYPE PrimitiveType
,
4134 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
,
4140 TRACE("iface %p, primitive_type %#x, FVF %#x, strided_data %p, vertex_count %u, indices %p, index_count %u, flags %#x.\n",
4141 iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Indices
, IndexCount
, Flags
);
4143 return IDirect3DDevice7_DrawIndexedPrimitiveStrided((IDirect3DDevice7
*)device_from_device3(iface
),
4144 PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Indices
, IndexCount
, Flags
);
4147 /*****************************************************************************
4148 * IDirect3DDevice7::DrawPrimitiveVB
4150 * Draws primitives from a vertex buffer to the screen.
4155 * PrimitiveType: Type of primitive to be rendered.
4156 * D3DVertexBuf: Source Vertex Buffer
4157 * StartVertex: Index of the first vertex from the buffer to be rendered
4158 * NumVertices: Number of vertices to be rendered
4159 * Flags: Can be D3DDP_WAIT to wait until rendering has finished
4163 * DDERR_INVALIDPARAMS if D3DVertexBuf is NULL
4165 *****************************************************************************/
4167 IDirect3DDeviceImpl_7_DrawPrimitiveVB(IDirect3DDevice7
*iface
,
4168 D3DPRIMITIVETYPE PrimitiveType
,
4169 IDirect3DVertexBuffer7
*D3DVertexBuf
,
4174 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
4175 IDirect3DVertexBufferImpl
*vb
= (IDirect3DVertexBufferImpl
*)D3DVertexBuf
;
4179 TRACE("iface %p, primitive_type %#x, vb %p, start_vertex %u, vertex_count %u, flags %#x.\n",
4180 iface
, PrimitiveType
, D3DVertexBuf
, StartVertex
, NumVertices
, Flags
);
4185 ERR("(%p) No Vertex buffer specified\n", This
);
4186 return DDERR_INVALIDPARAMS
;
4188 stride
= get_flexible_vertex_size(vb
->fvf
);
4190 EnterCriticalSection(&ddraw_cs
);
4191 hr
= IWineD3DDevice_SetVertexDeclaration(This
->wineD3DDevice
,
4192 vb
->wineD3DVertexDeclaration
);
4195 ERR(" (%p) Setting the FVF failed, hr = %x!\n", This
, hr
);
4196 LeaveCriticalSection(&ddraw_cs
);
4200 /* Set the vertex stream source */
4201 hr
= IWineD3DDevice_SetStreamSource(This
->wineD3DDevice
,
4202 0 /* StreamNumber */,
4203 vb
->wineD3DVertexBuffer
,
4204 0 /* StartVertex - we pass this to DrawPrimitive */,
4208 ERR("(%p) IDirect3DDevice::SetStreamSource failed with hr = %08x\n", This
, hr
);
4209 LeaveCriticalSection(&ddraw_cs
);
4213 /* Now draw the primitives */
4214 IWineD3DDevice_SetPrimitiveType(This
->wineD3DDevice
, PrimitiveType
);
4215 hr
= IWineD3DDevice_DrawPrimitive(This
->wineD3DDevice
, StartVertex
, NumVertices
);
4216 LeaveCriticalSection(&ddraw_cs
);
4220 static HRESULT WINAPI
4221 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUSetup(IDirect3DDevice7
*iface
,
4222 D3DPRIMITIVETYPE PrimitiveType
,
4223 IDirect3DVertexBuffer7
*D3DVertexBuf
,
4228 return IDirect3DDeviceImpl_7_DrawPrimitiveVB(iface
, PrimitiveType
, D3DVertexBuf
, StartVertex
, NumVertices
, Flags
);
4231 static HRESULT WINAPI
4232 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUPreserve(IDirect3DDevice7
*iface
,
4233 D3DPRIMITIVETYPE PrimitiveType
,
4234 IDirect3DVertexBuffer7
*D3DVertexBuf
,
4242 old_fpucw
= d3d_fpu_setup();
4243 hr
= IDirect3DDeviceImpl_7_DrawPrimitiveVB(iface
, PrimitiveType
, D3DVertexBuf
, StartVertex
, NumVertices
, Flags
);
4244 set_fpu_control_word(old_fpucw
);
4249 static HRESULT WINAPI
4250 Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveVB(IDirect3DDevice3
*iface
,
4251 D3DPRIMITIVETYPE PrimitiveType
,
4252 IDirect3DVertexBuffer
*D3DVertexBuf
,
4257 IDirect3DVertexBufferImpl
*vb
= D3DVertexBuf
? vb_from_vb1(D3DVertexBuf
) : NULL
;
4259 TRACE("iface %p, primitive_type %#x, vb %p, start_vertex %u, vertex_count %u, flags %#x.\n",
4260 iface
, PrimitiveType
, D3DVertexBuf
, StartVertex
, NumVertices
, Flags
);
4262 return IDirect3DDevice7_DrawPrimitiveVB((IDirect3DDevice7
*)device_from_device3(iface
),
4263 PrimitiveType
, (IDirect3DVertexBuffer7
*)vb
, StartVertex
, NumVertices
, Flags
);
4267 /*****************************************************************************
4268 * IDirect3DDevice7::DrawIndexedPrimitiveVB
4270 * Draws primitives from a vertex buffer to the screen
4273 * PrimitiveType: Type of primitive to be rendered.
4274 * D3DVertexBuf: Source Vertex Buffer
4275 * StartVertex: Index of the first vertex from the buffer to be rendered
4276 * NumVertices: Number of vertices to be rendered
4277 * Indices: Array of DWORDs used to index into the Vertices
4278 * IndexCount: Number of indices in Indices
4279 * Flags: Can be D3DDP_WAIT to wait until rendering has finished
4283 *****************************************************************************/
4285 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB(IDirect3DDevice7
*iface
,
4286 D3DPRIMITIVETYPE PrimitiveType
,
4287 IDirect3DVertexBuffer7
*D3DVertexBuf
,
4294 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
4295 IDirect3DVertexBufferImpl
*vb
= (IDirect3DVertexBufferImpl
*)D3DVertexBuf
;
4296 DWORD stride
= get_flexible_vertex_size(vb
->fvf
);
4297 WORD
*LockedIndices
;
4299 WINED3DBUFFER_DESC desc
;
4301 TRACE("iface %p, primitive_type %#x, vb %p, start_vertex %u, vertex_count %u, indices %p, index_count %u, flags %#x.\n",
4302 iface
, PrimitiveType
, D3DVertexBuf
, StartVertex
, NumVertices
, Indices
, IndexCount
, Flags
);
4305 * 1) Upload the Indices to the index buffer
4306 * 2) Set the index source
4307 * 3) Set the Vertex Buffer as the Stream source
4308 * 4) Call IWineD3DDevice::DrawIndexedPrimitive
4311 EnterCriticalSection(&ddraw_cs
);
4313 hr
= IWineD3DDevice_SetVertexDeclaration(This
->wineD3DDevice
,
4314 vb
->wineD3DVertexDeclaration
);
4317 ERR(" (%p) Setting the FVF failed, hr = %x!\n", This
, hr
);
4318 LeaveCriticalSection(&ddraw_cs
);
4322 /* check that the buffer is large enough to hold the indices,
4323 * reallocate if necessary. */
4324 IWineD3DBuffer_GetDesc(This
->indexbuffer
, &desc
);
4325 if (desc
.Size
< IndexCount
* sizeof(WORD
))
4327 UINT size
= max(desc
.Size
* 2, IndexCount
* sizeof(WORD
));
4328 IWineD3DBuffer
*buffer
;
4329 IParentImpl
*parent
;
4331 TRACE("Growing index buffer to %u bytes\n", size
);
4333 parent
= IWineD3DBuffer_GetParent(This
->indexbuffer
);
4334 hr
= IWineD3DDevice_CreateIndexBuffer(This
->wineD3DDevice
, size
, WINED3DUSAGE_DYNAMIC
/* Usage */,
4335 WINED3DPOOL_DEFAULT
, parent
, &ddraw_null_wined3d_parent_ops
, &buffer
);
4338 ERR("(%p) IWineD3DDevice::CreateIndexBuffer failed with hr = %08x\n", This
, hr
);
4339 LeaveCriticalSection(&ddraw_cs
);
4343 IWineD3DBuffer_Release(This
->indexbuffer
);
4344 This
->indexbuffer
= buffer
;
4346 parent
->child
= (IUnknown
*)buffer
;
4349 /* copy the index stream into the index buffer.
4350 * A new IWineD3DDevice method could be created
4351 * which takes an user pointer containing the indices
4352 * or a SetData-Method for the index buffer, which
4353 * overrides the index buffer data with our pointer.
4355 hr
= IWineD3DBuffer_Map(This
->indexbuffer
,
4356 0 /* OffSetToLock */,
4357 IndexCount
* sizeof(WORD
),
4358 (BYTE
**) &LockedIndices
,
4362 ERR("(%p) IWineD3DBuffer::Map failed with hr = %08x\n", This
, hr
);
4363 LeaveCriticalSection(&ddraw_cs
);
4366 memcpy(LockedIndices
, Indices
, IndexCount
* sizeof(WORD
));
4367 IWineD3DBuffer_Unmap(This
->indexbuffer
);
4369 /* Set the index stream */
4370 IWineD3DDevice_SetBaseVertexIndex(This
->wineD3DDevice
, StartVertex
);
4371 hr
= IWineD3DDevice_SetIndexBuffer(This
->wineD3DDevice
, This
->indexbuffer
,
4372 WINED3DFMT_R16_UINT
);
4374 /* Set the vertex stream source */
4375 hr
= IWineD3DDevice_SetStreamSource(This
->wineD3DDevice
,
4376 0 /* StreamNumber */,
4377 vb
->wineD3DVertexBuffer
,
4378 0 /* offset, we pass this to DrawIndexedPrimitive */,
4382 ERR("(%p) IDirect3DDevice::SetStreamSource failed with hr = %08x\n", This
, hr
);
4383 LeaveCriticalSection(&ddraw_cs
);
4388 IWineD3DDevice_SetPrimitiveType(This
->wineD3DDevice
, PrimitiveType
);
4389 hr
= IWineD3DDevice_DrawIndexedPrimitive(This
->wineD3DDevice
, 0 /* StartIndex */, IndexCount
);
4391 LeaveCriticalSection(&ddraw_cs
);
4395 static HRESULT WINAPI
4396 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUSetup(IDirect3DDevice7
*iface
,
4397 D3DPRIMITIVETYPE PrimitiveType
,
4398 IDirect3DVertexBuffer7
*D3DVertexBuf
,
4405 return IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB(iface
, PrimitiveType
, D3DVertexBuf
, StartVertex
, NumVertices
, Indices
, IndexCount
, Flags
);
4408 static HRESULT WINAPI
4409 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUPreserve(IDirect3DDevice7
*iface
,
4410 D3DPRIMITIVETYPE PrimitiveType
,
4411 IDirect3DVertexBuffer7
*D3DVertexBuf
,
4421 old_fpucw
= d3d_fpu_setup();
4422 hr
= IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB(iface
, PrimitiveType
, D3DVertexBuf
, StartVertex
, NumVertices
, Indices
, IndexCount
, Flags
);
4423 set_fpu_control_word(old_fpucw
);
4428 static HRESULT WINAPI
4429 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveVB(IDirect3DDevice3
*iface
,
4430 D3DPRIMITIVETYPE PrimitiveType
,
4431 IDirect3DVertexBuffer
*D3DVertexBuf
,
4436 IDirect3DVertexBufferImpl
*VB
= vb_from_vb1(D3DVertexBuf
);
4438 TRACE("iface %p, primitive_type %#x, vb %p, indices %p, index_count %u, flags %#x.\n",
4439 iface
, PrimitiveType
, D3DVertexBuf
, Indices
, IndexCount
, Flags
);
4441 return IDirect3DDevice7_DrawIndexedPrimitiveVB((IDirect3DDevice7
*)device_from_device3(iface
),
4442 PrimitiveType
, (IDirect3DVertexBuffer7
*)VB
, 0, IndexCount
, Indices
, IndexCount
, Flags
);
4445 /*****************************************************************************
4446 * IDirect3DDevice7::ComputeSphereVisibility
4448 * Calculates the visibility of spheres in the current viewport. The spheres
4449 * are passed in the Centers and Radii arrays, the results are passed back
4450 * in the ReturnValues array. Return values are either completely visible,
4451 * partially visible or completely invisible.
4452 * The return value consist of a combination of D3DCLIP_* flags, or it's
4453 * 0 if the sphere is completely visible(according to the SDK, not checked)
4458 * Centers: Array containing the sphere centers
4459 * Radii: Array containing the sphere radii
4460 * NumSpheres: The number of centers and radii in the arrays
4462 * ReturnValues: Array to write the results to
4466 * (DDERR_INVALIDPARAMS if Centers, Radii or ReturnValues are NULL)
4467 * (D3DERR_INVALIDMATRIX if the combined world, view and proj matrix
4470 *****************************************************************************/
4472 static DWORD
in_plane(UINT plane
, D3DVECTOR normal
, D3DVALUE origin_plane
, D3DVECTOR center
, D3DVALUE radius
)
4474 float distance
, norm
;
4476 norm
= sqrt( normal
.u1
.x
* normal
.u1
.x
+ normal
.u2
.y
* normal
.u2
.y
+ normal
.u3
.z
* normal
.u3
.z
);
4477 distance
= ( origin_plane
+ normal
.u1
.x
* center
.u1
.x
+ normal
.u2
.y
* center
.u2
.y
+ normal
.u3
.z
* center
.u3
.z
) / norm
;
4479 if ( fabs( distance
) < radius
) return D3DSTATUS_CLIPUNIONLEFT
<< plane
;
4480 if ( distance
< -radius
) return (D3DSTATUS_CLIPUNIONLEFT
| D3DSTATUS_CLIPINTERSECTIONLEFT
) << plane
;
4484 static HRESULT WINAPI
4485 IDirect3DDeviceImpl_7_ComputeSphereVisibility(IDirect3DDevice7
*iface
,
4490 DWORD
*ReturnValues
)
4493 D3DVALUE origin_plane
[6];
4498 TRACE("iface %p, centers %p, radii %p, sphere_count %u, flags %#x, return_values %p.\n",
4499 iface
, Centers
, Radii
, NumSpheres
, Flags
, ReturnValues
);
4501 hr
= IDirect3DDeviceImpl_7_GetTransform(iface
, D3DTRANSFORMSTATE_WORLD
, &m
);
4502 if ( hr
!= DD_OK
) return DDERR_INVALIDPARAMS
;
4503 hr
= IDirect3DDeviceImpl_7_GetTransform(iface
, D3DTRANSFORMSTATE_VIEW
, &temp
);
4504 if ( hr
!= DD_OK
) return DDERR_INVALIDPARAMS
;
4505 multiply_matrix(&m
, &temp
, &m
);
4507 hr
= IDirect3DDeviceImpl_7_GetTransform(iface
, D3DTRANSFORMSTATE_PROJECTION
, &temp
);
4508 if ( hr
!= DD_OK
) return DDERR_INVALIDPARAMS
;
4509 multiply_matrix(&m
, &temp
, &m
);
4512 vec
[0].u1
.x
= m
._14
+ m
._11
;
4513 vec
[0].u2
.y
= m
._24
+ m
._21
;
4514 vec
[0].u3
.z
= m
._34
+ m
._31
;
4515 origin_plane
[0] = m
._44
+ m
._41
;
4518 vec
[1].u1
.x
= m
._14
- m
._11
;
4519 vec
[1].u2
.y
= m
._24
- m
._21
;
4520 vec
[1].u3
.z
= m
._34
- m
._31
;
4521 origin_plane
[1] = m
._44
- m
._41
;
4524 vec
[2].u1
.x
= m
._14
- m
._12
;
4525 vec
[2].u2
.y
= m
._24
- m
._22
;
4526 vec
[2].u3
.z
= m
._34
- m
._32
;
4527 origin_plane
[2] = m
._44
- m
._42
;
4530 vec
[3].u1
.x
= m
._14
+ m
._12
;
4531 vec
[3].u2
.y
= m
._24
+ m
._22
;
4532 vec
[3].u3
.z
= m
._34
+ m
._32
;
4533 origin_plane
[3] = m
._44
+ m
._42
;
4536 vec
[4].u1
.x
= m
._13
;
4537 vec
[4].u2
.y
= m
._23
;
4538 vec
[4].u3
.z
= m
._33
;
4539 origin_plane
[4] = m
._43
;
4542 vec
[5].u1
.x
= m
._14
- m
._13
;
4543 vec
[5].u2
.y
= m
._24
- m
._23
;
4544 vec
[5].u3
.z
= m
._34
- m
._33
;
4545 origin_plane
[5] = m
._44
- m
._43
;
4547 for(i
=0; i
<NumSpheres
; i
++)
4549 ReturnValues
[i
] = 0;
4550 for(j
=0; j
<6; j
++) ReturnValues
[i
] |= in_plane(j
, vec
[j
], origin_plane
[j
], Centers
[i
], Radii
[i
]);
4556 static HRESULT WINAPI
4557 Thunk_IDirect3DDeviceImpl_3_ComputeSphereVisibility(IDirect3DDevice3
*iface
,
4562 DWORD
*ReturnValues
)
4564 TRACE("iface %p, centers %p, radii %p, sphere_count %u, flags %#x, return_values %p.\n",
4565 iface
, Centers
, Radii
, NumSpheres
, Flags
, ReturnValues
);
4567 return IDirect3DDevice7_ComputeSphereVisibility((IDirect3DDevice7
*)device_from_device3(iface
),
4568 Centers
, Radii
, NumSpheres
, Flags
, ReturnValues
);
4571 /*****************************************************************************
4572 * IDirect3DDevice7::GetTexture
4574 * Returns the texture interface handle assigned to a texture stage.
4575 * The returned texture is AddRefed. This is taken from old ddraw,
4576 * not checked in Windows.
4581 * Stage: Texture stage to read the texture from
4582 * Texture: Address to store the interface pointer at
4586 * DDERR_INVALIDPARAMS if Texture is NULL
4587 * For details, see IWineD3DDevice::GetTexture
4589 *****************************************************************************/
4591 IDirect3DDeviceImpl_7_GetTexture(IDirect3DDevice7
*iface
,
4593 IDirectDrawSurface7
**Texture
)
4595 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
4596 IWineD3DBaseTexture
*Surf
;
4599 TRACE("iface %p, stage %u, texture %p.\n", iface
, Stage
, Texture
);
4603 TRACE("Texture == NULL, failing with DDERR_INVALIDPARAMS\n");
4604 return DDERR_INVALIDPARAMS
;
4607 EnterCriticalSection(&ddraw_cs
);
4608 hr
= IWineD3DDevice_GetTexture(This
->wineD3DDevice
, Stage
, &Surf
);
4609 if( (hr
!= D3D_OK
) || (!Surf
) )
4612 LeaveCriticalSection(&ddraw_cs
);
4616 *Texture
= IWineD3DBaseTexture_GetParent(Surf
);
4617 IDirectDrawSurface7_AddRef(*Texture
);
4618 LeaveCriticalSection(&ddraw_cs
);
4622 static HRESULT WINAPI
4623 IDirect3DDeviceImpl_7_GetTexture_FPUSetup(IDirect3DDevice7
*iface
,
4625 IDirectDrawSurface7
**Texture
)
4627 return IDirect3DDeviceImpl_7_GetTexture(iface
, Stage
, Texture
);
4630 static HRESULT WINAPI
4631 IDirect3DDeviceImpl_7_GetTexture_FPUPreserve(IDirect3DDevice7
*iface
,
4633 IDirectDrawSurface7
**Texture
)
4638 old_fpucw
= d3d_fpu_setup();
4639 hr
= IDirect3DDeviceImpl_7_GetTexture(iface
, Stage
, Texture
);
4640 set_fpu_control_word(old_fpucw
);
4645 static HRESULT WINAPI
4646 Thunk_IDirect3DDeviceImpl_3_GetTexture(IDirect3DDevice3
*iface
,
4648 IDirect3DTexture2
**Texture2
)
4651 IDirectDrawSurface7
*ret_val
;
4653 TRACE("iface %p, stage %u, texture %p.\n", iface
, Stage
, Texture2
);
4655 ret
= IDirect3DDevice7_GetTexture((IDirect3DDevice7
*)device_from_device3(iface
), Stage
, &ret_val
);
4657 *Texture2
= ret_val
? (IDirect3DTexture2
*)&((IDirectDrawSurfaceImpl
*)ret_val
)->IDirect3DTexture2_vtbl
: NULL
;
4659 TRACE("Returning texture %p.\n", *Texture2
);
4664 /*****************************************************************************
4665 * IDirect3DDevice7::SetTexture
4667 * Assigns a texture to a texture stage. Is the texture AddRef-ed?
4672 * Stage: The stage to assign the texture to
4673 * Texture: Interface pointer to the texture surface
4677 * For details, see IWineD3DDevice::SetTexture
4679 *****************************************************************************/
4681 IDirect3DDeviceImpl_7_SetTexture(IDirect3DDevice7
*iface
,
4683 IDirectDrawSurface7
*Texture
)
4685 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
4686 IDirectDrawSurfaceImpl
*surf
= (IDirectDrawSurfaceImpl
*)Texture
;
4689 TRACE("iface %p, stage %u, texture %p.\n", iface
, Stage
, Texture
);
4691 /* Texture may be NULL here */
4692 EnterCriticalSection(&ddraw_cs
);
4693 hr
= IWineD3DDevice_SetTexture(This
->wineD3DDevice
,
4695 surf
? surf
->wineD3DTexture
: NULL
);
4696 LeaveCriticalSection(&ddraw_cs
);
4700 static HRESULT WINAPI
4701 IDirect3DDeviceImpl_7_SetTexture_FPUSetup(IDirect3DDevice7
*iface
,
4703 IDirectDrawSurface7
*Texture
)
4705 return IDirect3DDeviceImpl_7_SetTexture(iface
, Stage
, Texture
);
4708 static HRESULT WINAPI
4709 IDirect3DDeviceImpl_7_SetTexture_FPUPreserve(IDirect3DDevice7
*iface
,
4711 IDirectDrawSurface7
*Texture
)
4716 old_fpucw
= d3d_fpu_setup();
4717 hr
= IDirect3DDeviceImpl_7_SetTexture(iface
, Stage
, Texture
);
4718 set_fpu_control_word(old_fpucw
);
4723 static HRESULT WINAPI
4724 IDirect3DDeviceImpl_3_SetTexture(IDirect3DDevice3
*iface
,
4726 IDirect3DTexture2
*Texture2
)
4728 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
4729 IDirectDrawSurfaceImpl
*tex
= Texture2
? surface_from_texture2(Texture2
) : NULL
;
4733 TRACE("iface %p, stage %u, texture %p.\n", iface
, Stage
, Texture2
);
4735 EnterCriticalSection(&ddraw_cs
);
4737 if (This
->legacyTextureBlending
)
4738 IDirect3DDevice3_GetRenderState(iface
, D3DRENDERSTATE_TEXTUREMAPBLEND
, &texmapblend
);
4740 hr
= IDirect3DDevice7_SetTexture((IDirect3DDevice7
*)This
, Stage
, (IDirectDrawSurface7
*)tex
);
4742 if (This
->legacyTextureBlending
&& texmapblend
== D3DTBLEND_MODULATE
)
4744 /* This fixup is required by the way D3DTBLEND_MODULATE maps to texture stage states.
4745 See IDirect3DDeviceImpl_3_SetRenderState for details. */
4746 BOOL tex_alpha
= FALSE
;
4747 IWineD3DBaseTexture
*tex
= NULL
;
4748 WINED3DSURFACE_DESC desc
;
4749 DDPIXELFORMAT ddfmt
;
4752 result
= IWineD3DDevice_GetTexture(This
->wineD3DDevice
,
4756 if(result
== WINED3D_OK
&& tex
)
4758 memset(&desc
, 0, sizeof(desc
));
4759 result
= IWineD3DTexture_GetLevelDesc((IWineD3DTexture
*) tex
, 0, &desc
);
4760 if (SUCCEEDED(result
))
4762 ddfmt
.dwSize
= sizeof(ddfmt
);
4763 PixelFormat_WineD3DtoDD(&ddfmt
, desc
.format
);
4764 if (ddfmt
.u5
.dwRGBAlphaBitMask
) tex_alpha
= TRUE
;
4767 IWineD3DBaseTexture_Release(tex
);
4770 /* Arg 1/2 are already set to WINED3DTA_TEXTURE/WINED3DTA_CURRENT in case of D3DTBLEND_MODULATE */
4772 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAOP
, WINED3DTOP_SELECTARG1
);
4774 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAOP
, WINED3DTOP_SELECTARG2
);
4777 LeaveCriticalSection(&ddraw_cs
);
4782 static const struct tss_lookup
4789 {FALSE
, WINED3DTSS_FORCE_DWORD
}, /* 0, unused */
4790 {FALSE
, WINED3DTSS_COLOROP
}, /* 1, D3DTSS_COLOROP */
4791 {FALSE
, WINED3DTSS_COLORARG1
}, /* 2, D3DTSS_COLORARG1 */
4792 {FALSE
, WINED3DTSS_COLORARG2
}, /* 3, D3DTSS_COLORARG2 */
4793 {FALSE
, WINED3DTSS_ALPHAOP
}, /* 4, D3DTSS_ALPHAOP */
4794 {FALSE
, WINED3DTSS_ALPHAARG1
}, /* 5, D3DTSS_ALPHAARG1 */
4795 {FALSE
, WINED3DTSS_ALPHAARG2
}, /* 6, D3DTSS_ALPHAARG2 */
4796 {FALSE
, WINED3DTSS_BUMPENVMAT00
}, /* 7, D3DTSS_BUMPENVMAT00 */
4797 {FALSE
, WINED3DTSS_BUMPENVMAT01
}, /* 8, D3DTSS_BUMPENVMAT01 */
4798 {FALSE
, WINED3DTSS_BUMPENVMAT10
}, /* 9, D3DTSS_BUMPENVMAT10 */
4799 {FALSE
, WINED3DTSS_BUMPENVMAT11
}, /* 10, D3DTSS_BUMPENVMAT11 */
4800 {FALSE
, WINED3DTSS_TEXCOORDINDEX
}, /* 11, D3DTSS_TEXCOORDINDEX */
4801 {TRUE
, WINED3DSAMP_ADDRESSU
}, /* 12, D3DTSS_ADDRESS */
4802 {TRUE
, WINED3DSAMP_ADDRESSU
}, /* 13, D3DTSS_ADDRESSU */
4803 {TRUE
, WINED3DSAMP_ADDRESSV
}, /* 14, D3DTSS_ADDRESSV */
4804 {TRUE
, WINED3DSAMP_BORDERCOLOR
}, /* 15, D3DTSS_BORDERCOLOR */
4805 {TRUE
, WINED3DSAMP_MAGFILTER
}, /* 16, D3DTSS_MAGFILTER */
4806 {TRUE
, WINED3DSAMP_MINFILTER
}, /* 17, D3DTSS_MINFILTER */
4807 {TRUE
, WINED3DSAMP_MIPFILTER
}, /* 18, D3DTSS_MIPFILTER */
4808 {TRUE
, WINED3DSAMP_MIPMAPLODBIAS
}, /* 19, D3DTSS_MIPMAPLODBIAS */
4809 {TRUE
, WINED3DSAMP_MAXMIPLEVEL
}, /* 20, D3DTSS_MAXMIPLEVEL */
4810 {TRUE
, WINED3DSAMP_MAXANISOTROPY
}, /* 21, D3DTSS_MAXANISOTROPY */
4811 {FALSE
, WINED3DTSS_BUMPENVLSCALE
}, /* 22, D3DTSS_BUMPENVLSCALE */
4812 {FALSE
, WINED3DTSS_BUMPENVLOFFSET
}, /* 23, D3DTSS_BUMPENVLOFFSET */
4813 {FALSE
, WINED3DTSS_TEXTURETRANSFORMFLAGS
}, /* 24, D3DTSS_TEXTURETRANSFORMFLAGS */
4816 /*****************************************************************************
4817 * IDirect3DDevice7::GetTextureStageState
4819 * Retrieves a state from a texture stage.
4824 * Stage: The stage to retrieve the state from
4825 * TexStageStateType: The state type to retrieve
4826 * State: Address to store the state's value at
4830 * DDERR_INVALIDPARAMS if State is NULL
4831 * For details, see IWineD3DDevice::GetTextureStageState
4833 *****************************************************************************/
4835 IDirect3DDeviceImpl_7_GetTextureStageState(IDirect3DDevice7
*iface
,
4837 D3DTEXTURESTAGESTATETYPE TexStageStateType
,
4840 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
4842 const struct tss_lookup
*l
;
4844 TRACE("iface %p, stage %u, state %#x, value %p.\n",
4845 iface
, Stage
, TexStageStateType
, State
);
4848 return DDERR_INVALIDPARAMS
;
4850 if (TexStageStateType
> D3DTSS_TEXTURETRANSFORMFLAGS
)
4852 WARN("Invalid TexStageStateType %#x passed.\n", TexStageStateType
);
4856 l
= &tss_lookup
[TexStageStateType
];
4858 EnterCriticalSection(&ddraw_cs
);
4860 if (l
->sampler_state
)
4862 hr
= IWineD3DDevice_GetSamplerState(This
->wineD3DDevice
, Stage
, l
->state
, State
);
4864 switch(TexStageStateType
)
4866 /* Mipfilter is a sampler state with different values */
4867 case D3DTSS_MIPFILTER
:
4871 case WINED3DTEXF_NONE
: *State
= D3DTFP_NONE
; break;
4872 case WINED3DTEXF_POINT
: *State
= D3DTFP_POINT
; break;
4873 case WINED3DTEXF_LINEAR
: *State
= D3DTFP_LINEAR
; break;
4875 ERR("Unexpected mipfilter value %#x\n", *State
);
4876 *State
= D3DTFP_NONE
;
4882 /* Magfilter has slightly different values */
4883 case D3DTSS_MAGFILTER
:
4887 case WINED3DTEXF_POINT
: *State
= D3DTFG_POINT
; break;
4888 case WINED3DTEXF_LINEAR
: *State
= D3DTFG_LINEAR
; break;
4889 case WINED3DTEXF_ANISOTROPIC
: *State
= D3DTFG_ANISOTROPIC
; break;
4890 case WINED3DTEXF_FLATCUBIC
: *State
= D3DTFG_FLATCUBIC
; break;
4891 case WINED3DTEXF_GAUSSIANCUBIC
: *State
= D3DTFG_GAUSSIANCUBIC
; break;
4893 ERR("Unexpected wined3d mag filter value %#x\n", *State
);
4894 *State
= D3DTFG_POINT
;
4906 hr
= IWineD3DDevice_GetTextureStageState(This
->wineD3DDevice
, Stage
, l
->state
, State
);
4909 LeaveCriticalSection(&ddraw_cs
);
4913 static HRESULT WINAPI
4914 IDirect3DDeviceImpl_7_GetTextureStageState_FPUSetup(IDirect3DDevice7
*iface
,
4916 D3DTEXTURESTAGESTATETYPE TexStageStateType
,
4919 return IDirect3DDeviceImpl_7_GetTextureStageState(iface
, Stage
, TexStageStateType
, State
);
4922 static HRESULT WINAPI
4923 IDirect3DDeviceImpl_7_GetTextureStageState_FPUPreserve(IDirect3DDevice7
*iface
,
4925 D3DTEXTURESTAGESTATETYPE TexStageStateType
,
4931 old_fpucw
= d3d_fpu_setup();
4932 hr
= IDirect3DDeviceImpl_7_GetTextureStageState(iface
, Stage
, TexStageStateType
, State
);
4933 set_fpu_control_word(old_fpucw
);
4938 static HRESULT WINAPI
4939 Thunk_IDirect3DDeviceImpl_3_GetTextureStageState(IDirect3DDevice3
*iface
,
4941 D3DTEXTURESTAGESTATETYPE TexStageStateType
,
4944 TRACE("iface %p, stage %u, state %#x, value %p.\n",
4945 iface
, Stage
, TexStageStateType
, State
);
4947 return IDirect3DDevice7_GetTextureStageState((IDirect3DDevice7
*)device_from_device3(iface
),
4948 Stage
, TexStageStateType
, State
);
4951 /*****************************************************************************
4952 * IDirect3DDevice7::SetTextureStageState
4954 * Sets a texture stage state. Some stage types need to be handled specially,
4955 * because they do not exist in WineD3D and were moved to another place
4960 * Stage: The stage to modify
4961 * TexStageStateType: The state to change
4962 * State: The new value for the state
4966 * For details, see IWineD3DDevice::SetTextureStageState
4968 *****************************************************************************/
4970 IDirect3DDeviceImpl_7_SetTextureStageState(IDirect3DDevice7
*iface
,
4972 D3DTEXTURESTAGESTATETYPE TexStageStateType
,
4975 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
4976 const struct tss_lookup
*l
;
4979 TRACE("iface %p, stage %u, state %#x, value %#x.\n",
4980 iface
, Stage
, TexStageStateType
, State
);
4982 if (TexStageStateType
> D3DTSS_TEXTURETRANSFORMFLAGS
)
4984 WARN("Invalid TexStageStateType %#x passed.\n", TexStageStateType
);
4988 l
= &tss_lookup
[TexStageStateType
];
4990 EnterCriticalSection(&ddraw_cs
);
4992 if (l
->sampler_state
)
4994 switch(TexStageStateType
)
4996 /* Mipfilter is a sampler state with different values */
4997 case D3DTSS_MIPFILTER
:
5001 case D3DTFP_NONE
: State
= WINED3DTEXF_NONE
; break;
5002 case D3DTFP_POINT
: State
= WINED3DTEXF_POINT
; break;
5003 case 0: /* Unchecked */
5004 case D3DTFP_LINEAR
: State
= WINED3DTEXF_LINEAR
; break;
5006 ERR("Unexpected mipfilter value %d\n", State
);
5007 State
= WINED3DTEXF_NONE
;
5013 /* Magfilter has slightly different values */
5014 case D3DTSS_MAGFILTER
:
5018 case D3DTFG_POINT
: State
= WINED3DTEXF_POINT
; break;
5019 case D3DTFG_LINEAR
: State
= WINED3DTEXF_LINEAR
; break;
5020 case D3DTFG_FLATCUBIC
: State
= WINED3DTEXF_FLATCUBIC
; break;
5021 case D3DTFG_GAUSSIANCUBIC
: State
= WINED3DTEXF_GAUSSIANCUBIC
; break;
5022 case D3DTFG_ANISOTROPIC
: State
= WINED3DTEXF_ANISOTROPIC
; break;
5024 ERR("Unexpected d3d7 mag filter type %d\n", State
);
5025 State
= WINED3DTEXF_POINT
;
5031 case D3DTSS_ADDRESS
:
5032 IWineD3DDevice_SetSamplerState(This
->wineD3DDevice
, Stage
, WINED3DSAMP_ADDRESSV
, State
);
5039 hr
= IWineD3DDevice_SetSamplerState(This
->wineD3DDevice
, Stage
, l
->state
, State
);
5043 hr
= IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, Stage
, l
->state
, State
);
5046 LeaveCriticalSection(&ddraw_cs
);
5050 static HRESULT WINAPI
5051 IDirect3DDeviceImpl_7_SetTextureStageState_FPUSetup(IDirect3DDevice7
*iface
,
5053 D3DTEXTURESTAGESTATETYPE TexStageStateType
,
5056 return IDirect3DDeviceImpl_7_SetTextureStageState(iface
, Stage
, TexStageStateType
, State
);
5059 static HRESULT WINAPI
5060 IDirect3DDeviceImpl_7_SetTextureStageState_FPUPreserve(IDirect3DDevice7
*iface
,
5062 D3DTEXTURESTAGESTATETYPE TexStageStateType
,
5068 old_fpucw
= d3d_fpu_setup();
5069 hr
= IDirect3DDeviceImpl_7_SetTextureStageState(iface
, Stage
, TexStageStateType
, State
);
5070 set_fpu_control_word(old_fpucw
);
5075 static HRESULT WINAPI
5076 Thunk_IDirect3DDeviceImpl_3_SetTextureStageState(IDirect3DDevice3
*iface
,
5078 D3DTEXTURESTAGESTATETYPE TexStageStateType
,
5081 TRACE("iface %p, stage %u, state %#x, value %#x.\n",
5082 iface
, Stage
, TexStageStateType
, State
);
5084 return IDirect3DDevice7_SetTextureStageState((IDirect3DDevice7
*)device_from_device3(iface
),
5085 Stage
, TexStageStateType
, State
);
5088 /*****************************************************************************
5089 * IDirect3DDevice7::ValidateDevice
5091 * SDK: "Reports the device's ability to render the currently set
5092 * texture-blending operations in a single pass". Whatever that means
5098 * NumPasses: Address to write the number of necessary passes for the
5099 * desired effect to.
5103 * See IWineD3DDevice::ValidateDevice for more details
5105 *****************************************************************************/
5107 IDirect3DDeviceImpl_7_ValidateDevice(IDirect3DDevice7
*iface
,
5110 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
5113 TRACE("iface %p, pass_count %p.\n", iface
, NumPasses
);
5115 EnterCriticalSection(&ddraw_cs
);
5116 hr
= IWineD3DDevice_ValidateDevice(This
->wineD3DDevice
, NumPasses
);
5117 LeaveCriticalSection(&ddraw_cs
);
5121 static HRESULT WINAPI
5122 IDirect3DDeviceImpl_7_ValidateDevice_FPUSetup(IDirect3DDevice7
*iface
,
5125 return IDirect3DDeviceImpl_7_ValidateDevice(iface
, NumPasses
);
5128 static HRESULT WINAPI
5129 IDirect3DDeviceImpl_7_ValidateDevice_FPUPreserve(IDirect3DDevice7
*iface
,
5135 old_fpucw
= d3d_fpu_setup();
5136 hr
= IDirect3DDeviceImpl_7_ValidateDevice(iface
, NumPasses
);
5137 set_fpu_control_word(old_fpucw
);
5142 static HRESULT WINAPI
5143 Thunk_IDirect3DDeviceImpl_3_ValidateDevice(IDirect3DDevice3
*iface
,
5146 TRACE("iface %p, pass_count %p.\n", iface
, Passes
);
5148 return IDirect3DDevice7_ValidateDevice((IDirect3DDevice7
*)device_from_device3(iface
), Passes
);
5151 /*****************************************************************************
5152 * IDirect3DDevice7::Clear
5154 * Fills the render target, the z buffer and the stencil buffer with a
5155 * clear color / value
5160 * Count: Number of rectangles in Rects must be 0 if Rects is NULL
5161 * Rects: Rectangles to clear. If NULL, the whole surface is cleared
5162 * Flags: Some flags, as usual
5163 * Color: Clear color for the render target
5164 * Z: Clear value for the Z buffer
5165 * Stencil: Clear value to store in each stencil buffer entry
5169 * For details, see IWineD3DDevice::Clear
5171 *****************************************************************************/
5173 IDirect3DDeviceImpl_7_Clear(IDirect3DDevice7
*iface
,
5181 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
5184 TRACE("iface %p, count %u, rects %p, flags %#x, color 0x%08x, z %.8e, stencil %#x.\n",
5185 iface
, Count
, Rects
, Flags
, Color
, Z
, Stencil
);
5187 EnterCriticalSection(&ddraw_cs
);
5188 hr
= IWineD3DDevice_Clear(This
->wineD3DDevice
, Count
, (RECT
*)Rects
, Flags
, Color
, Z
, Stencil
);
5189 LeaveCriticalSection(&ddraw_cs
);
5193 static HRESULT WINAPI
5194 IDirect3DDeviceImpl_7_Clear_FPUSetup(IDirect3DDevice7
*iface
,
5202 return IDirect3DDeviceImpl_7_Clear(iface
, Count
, Rects
, Flags
, Color
, Z
, Stencil
);
5205 static HRESULT WINAPI
5206 IDirect3DDeviceImpl_7_Clear_FPUPreserve(IDirect3DDevice7
*iface
,
5217 old_fpucw
= d3d_fpu_setup();
5218 hr
= IDirect3DDeviceImpl_7_Clear(iface
, Count
, Rects
, Flags
, Color
, Z
, Stencil
);
5219 set_fpu_control_word(old_fpucw
);
5224 /*****************************************************************************
5225 * IDirect3DDevice7::SetViewport
5227 * Sets the current viewport.
5229 * Version 7 only, but IDirect3DViewport uses this call for older
5233 * Data: The new viewport to set
5237 * DDERR_INVALIDPARAMS if Data is NULL
5238 * For more details, see IWineDDDevice::SetViewport
5240 *****************************************************************************/
5242 IDirect3DDeviceImpl_7_SetViewport(IDirect3DDevice7
*iface
,
5245 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
5248 TRACE("iface %p, viewport %p.\n", iface
, Data
);
5251 return DDERR_INVALIDPARAMS
;
5253 /* Note: D3DVIEWPORT7 is compatible with WINED3DVIEWPORT */
5254 EnterCriticalSection(&ddraw_cs
);
5255 hr
= IWineD3DDevice_SetViewport(This
->wineD3DDevice
,
5256 (WINED3DVIEWPORT
*) Data
);
5257 LeaveCriticalSection(&ddraw_cs
);
5261 static HRESULT WINAPI
5262 IDirect3DDeviceImpl_7_SetViewport_FPUSetup(IDirect3DDevice7
*iface
,
5265 return IDirect3DDeviceImpl_7_SetViewport(iface
, Data
);
5268 static HRESULT WINAPI
5269 IDirect3DDeviceImpl_7_SetViewport_FPUPreserve(IDirect3DDevice7
*iface
,
5275 old_fpucw
= d3d_fpu_setup();
5276 hr
= IDirect3DDeviceImpl_7_SetViewport(iface
, Data
);
5277 set_fpu_control_word(old_fpucw
);
5282 /*****************************************************************************
5283 * IDirect3DDevice::GetViewport
5285 * Returns the current viewport
5290 * Data: D3D7Viewport structure to write the viewport information to
5294 * DDERR_INVALIDPARAMS if Data is NULL
5295 * For more details, see IWineD3DDevice::GetViewport
5297 *****************************************************************************/
5299 IDirect3DDeviceImpl_7_GetViewport(IDirect3DDevice7
*iface
,
5302 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
5305 TRACE("iface %p, viewport %p.\n", iface
, Data
);
5308 return DDERR_INVALIDPARAMS
;
5310 /* Note: D3DVIEWPORT7 is compatible with WINED3DVIEWPORT */
5311 EnterCriticalSection(&ddraw_cs
);
5312 hr
= IWineD3DDevice_GetViewport(This
->wineD3DDevice
,
5313 (WINED3DVIEWPORT
*) Data
);
5315 LeaveCriticalSection(&ddraw_cs
);
5316 return hr_ddraw_from_wined3d(hr
);
5319 static HRESULT WINAPI
5320 IDirect3DDeviceImpl_7_GetViewport_FPUSetup(IDirect3DDevice7
*iface
,
5323 return IDirect3DDeviceImpl_7_GetViewport(iface
, Data
);
5326 static HRESULT WINAPI
5327 IDirect3DDeviceImpl_7_GetViewport_FPUPreserve(IDirect3DDevice7
*iface
,
5333 old_fpucw
= d3d_fpu_setup();
5334 hr
= IDirect3DDeviceImpl_7_GetViewport(iface
, Data
);
5335 set_fpu_control_word(old_fpucw
);
5340 /*****************************************************************************
5341 * IDirect3DDevice7::SetMaterial
5348 * Mat: The material to set
5352 * DDERR_INVALIDPARAMS if Mat is NULL.
5353 * For more details, see IWineD3DDevice::SetMaterial
5355 *****************************************************************************/
5357 IDirect3DDeviceImpl_7_SetMaterial(IDirect3DDevice7
*iface
,
5360 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
5363 TRACE("iface %p, material %p.\n", iface
, Mat
);
5365 if (!Mat
) return DDERR_INVALIDPARAMS
;
5366 /* Note: D3DMATERIAL7 is compatible with WINED3DMATERIAL */
5367 EnterCriticalSection(&ddraw_cs
);
5368 hr
= IWineD3DDevice_SetMaterial(This
->wineD3DDevice
,
5369 (WINED3DMATERIAL
*) Mat
);
5370 LeaveCriticalSection(&ddraw_cs
);
5371 return hr_ddraw_from_wined3d(hr
);
5374 static HRESULT WINAPI
5375 IDirect3DDeviceImpl_7_SetMaterial_FPUSetup(IDirect3DDevice7
*iface
,
5378 return IDirect3DDeviceImpl_7_SetMaterial(iface
, Mat
);
5381 static HRESULT WINAPI
5382 IDirect3DDeviceImpl_7_SetMaterial_FPUPreserve(IDirect3DDevice7
*iface
,
5388 old_fpucw
= d3d_fpu_setup();
5389 hr
= IDirect3DDeviceImpl_7_SetMaterial(iface
, Mat
);
5390 set_fpu_control_word(old_fpucw
);
5395 /*****************************************************************************
5396 * IDirect3DDevice7::GetMaterial
5398 * Returns the current material
5403 * Mat: D3DMATERIAL7 structure to write the material parameters to
5407 * DDERR_INVALIDPARAMS if Mat is NULL
5408 * For more details, see IWineD3DDevice::GetMaterial
5410 *****************************************************************************/
5412 IDirect3DDeviceImpl_7_GetMaterial(IDirect3DDevice7
*iface
,
5415 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
5418 TRACE("iface %p, material %p.\n", iface
, Mat
);
5420 EnterCriticalSection(&ddraw_cs
);
5421 /* Note: D3DMATERIAL7 is compatible with WINED3DMATERIAL */
5422 hr
= IWineD3DDevice_GetMaterial(This
->wineD3DDevice
,
5423 (WINED3DMATERIAL
*) Mat
);
5424 LeaveCriticalSection(&ddraw_cs
);
5425 return hr_ddraw_from_wined3d(hr
);
5428 static HRESULT WINAPI
5429 IDirect3DDeviceImpl_7_GetMaterial_FPUSetup(IDirect3DDevice7
*iface
,
5432 return IDirect3DDeviceImpl_7_GetMaterial(iface
, Mat
);
5435 static HRESULT WINAPI
5436 IDirect3DDeviceImpl_7_GetMaterial_FPUPreserve(IDirect3DDevice7
*iface
,
5442 old_fpucw
= d3d_fpu_setup();
5443 hr
= IDirect3DDeviceImpl_7_GetMaterial(iface
, Mat
);
5444 set_fpu_control_word(old_fpucw
);
5449 /*****************************************************************************
5450 * IDirect3DDevice7::SetLight
5452 * Assigns a light to a light index, but doesn't activate it yet.
5454 * Version 7, IDirect3DLight uses this method for older versions
5457 * LightIndex: The index of the new light
5458 * Light: A D3DLIGHT7 structure describing the light
5462 * For more details, see IWineD3DDevice::SetLight
5464 *****************************************************************************/
5466 IDirect3DDeviceImpl_7_SetLight(IDirect3DDevice7
*iface
,
5470 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
5473 TRACE("iface %p, light_idx %u, light %p.\n", iface
, LightIndex
, Light
);
5475 EnterCriticalSection(&ddraw_cs
);
5476 /* Note: D3DLIGHT7 is compatible with WINED3DLIGHT */
5477 hr
= IWineD3DDevice_SetLight(This
->wineD3DDevice
,
5479 (WINED3DLIGHT
*) Light
);
5480 LeaveCriticalSection(&ddraw_cs
);
5481 return hr_ddraw_from_wined3d(hr
);
5484 static HRESULT WINAPI
5485 IDirect3DDeviceImpl_7_SetLight_FPUSetup(IDirect3DDevice7
*iface
,
5489 return IDirect3DDeviceImpl_7_SetLight(iface
, LightIndex
, Light
);
5492 static HRESULT WINAPI
5493 IDirect3DDeviceImpl_7_SetLight_FPUPreserve(IDirect3DDevice7
*iface
,
5500 old_fpucw
= d3d_fpu_setup();
5501 hr
= IDirect3DDeviceImpl_7_SetLight(iface
, LightIndex
, Light
);
5502 set_fpu_control_word(old_fpucw
);
5507 /*****************************************************************************
5508 * IDirect3DDevice7::GetLight
5510 * Returns the light assigned to a light index
5513 * Light: Structure to write the light information to
5517 * DDERR_INVALIDPARAMS if Light is NULL
5518 * For details, see IWineD3DDevice::GetLight
5520 *****************************************************************************/
5522 IDirect3DDeviceImpl_7_GetLight(IDirect3DDevice7
*iface
,
5526 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
5529 TRACE("iface %p, light_idx %u, light %p.\n", iface
, LightIndex
, Light
);
5531 EnterCriticalSection(&ddraw_cs
);
5532 /* Note: D3DLIGHT7 is compatible with WINED3DLIGHT */
5533 rc
= IWineD3DDevice_GetLight(This
->wineD3DDevice
,
5535 (WINED3DLIGHT
*) Light
);
5537 /* Translate the result. WineD3D returns other values than D3D7 */
5538 LeaveCriticalSection(&ddraw_cs
);
5539 return hr_ddraw_from_wined3d(rc
);
5542 static HRESULT WINAPI
5543 IDirect3DDeviceImpl_7_GetLight_FPUSetup(IDirect3DDevice7
*iface
,
5547 return IDirect3DDeviceImpl_7_GetLight(iface
, LightIndex
, Light
);
5550 static HRESULT WINAPI
5551 IDirect3DDeviceImpl_7_GetLight_FPUPreserve(IDirect3DDevice7
*iface
,
5558 old_fpucw
= d3d_fpu_setup();
5559 hr
= IDirect3DDeviceImpl_7_GetLight(iface
, LightIndex
, Light
);
5560 set_fpu_control_word(old_fpucw
);
5565 /*****************************************************************************
5566 * IDirect3DDevice7::BeginStateBlock
5568 * Begins recording to a stateblock
5574 * For details see IWineD3DDevice::BeginStateBlock
5576 *****************************************************************************/
5578 IDirect3DDeviceImpl_7_BeginStateBlock(IDirect3DDevice7
*iface
)
5580 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
5583 TRACE("iface %p.\n", iface
);
5585 EnterCriticalSection(&ddraw_cs
);
5586 hr
= IWineD3DDevice_BeginStateBlock(This
->wineD3DDevice
);
5587 LeaveCriticalSection(&ddraw_cs
);
5588 return hr_ddraw_from_wined3d(hr
);
5591 static HRESULT WINAPI
5592 IDirect3DDeviceImpl_7_BeginStateBlock_FPUSetup(IDirect3DDevice7
*iface
)
5594 return IDirect3DDeviceImpl_7_BeginStateBlock(iface
);
5597 static HRESULT WINAPI
5598 IDirect3DDeviceImpl_7_BeginStateBlock_FPUPreserve(IDirect3DDevice7
*iface
)
5603 old_fpucw
= d3d_fpu_setup();
5604 hr
= IDirect3DDeviceImpl_7_BeginStateBlock(iface
);
5605 set_fpu_control_word(old_fpucw
);
5610 /*****************************************************************************
5611 * IDirect3DDevice7::EndStateBlock
5613 * Stops recording to a state block and returns the created stateblock
5619 * BlockHandle: Address to store the stateblock's handle to
5623 * DDERR_INVALIDPARAMS if BlockHandle is NULL
5624 * See IWineD3DDevice::EndStateBlock for more details
5626 *****************************************************************************/
5628 IDirect3DDeviceImpl_7_EndStateBlock(IDirect3DDevice7
*iface
,
5631 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
5632 IWineD3DStateBlock
*wined3d_sb
;
5636 TRACE("iface %p, stateblock %p.\n", iface
, BlockHandle
);
5640 WARN("BlockHandle == NULL, returning DDERR_INVALIDPARAMS\n");
5641 return DDERR_INVALIDPARAMS
;
5644 EnterCriticalSection(&ddraw_cs
);
5646 hr
= IWineD3DDevice_EndStateBlock(This
->wineD3DDevice
, &wined3d_sb
);
5649 WARN("Failed to end stateblock, hr %#x.\n", hr
);
5650 LeaveCriticalSection(&ddraw_cs
);
5652 return hr_ddraw_from_wined3d(hr
);
5655 h
= ddraw_allocate_handle(&This
->handle_table
, wined3d_sb
, DDRAW_HANDLE_STATEBLOCK
);
5656 if (h
== DDRAW_INVALID_HANDLE
)
5658 ERR("Failed to allocate a stateblock handle.\n");
5659 IWineD3DStateBlock_Release(wined3d_sb
);
5660 LeaveCriticalSection(&ddraw_cs
);
5662 return DDERR_OUTOFMEMORY
;
5665 LeaveCriticalSection(&ddraw_cs
);
5666 *BlockHandle
= h
+ 1;
5668 return hr_ddraw_from_wined3d(hr
);
5671 static HRESULT WINAPI
5672 IDirect3DDeviceImpl_7_EndStateBlock_FPUSetup(IDirect3DDevice7
*iface
,
5675 return IDirect3DDeviceImpl_7_EndStateBlock(iface
, BlockHandle
);
5678 static HRESULT WINAPI
5679 IDirect3DDeviceImpl_7_EndStateBlock_FPUPreserve(IDirect3DDevice7
*iface
,
5685 old_fpucw
= d3d_fpu_setup();
5686 hr
= IDirect3DDeviceImpl_7_EndStateBlock(iface
, BlockHandle
);
5687 set_fpu_control_word(old_fpucw
);
5692 /*****************************************************************************
5693 * IDirect3DDevice7::PreLoad
5695 * Allows the app to signal that a texture will be used soon, to allow
5696 * the Direct3DDevice to load it to the video card in the meantime.
5701 * Texture: The texture to preload
5705 * DDERR_INVALIDPARAMS if Texture is NULL
5706 * See IWineD3DSurface::PreLoad for details
5708 *****************************************************************************/
5710 IDirect3DDeviceImpl_7_PreLoad(IDirect3DDevice7
*iface
,
5711 IDirectDrawSurface7
*Texture
)
5713 IDirectDrawSurfaceImpl
*surf
= (IDirectDrawSurfaceImpl
*)Texture
;
5715 TRACE("iface %p, texture %p.\n", iface
, Texture
);
5718 return DDERR_INVALIDPARAMS
;
5720 EnterCriticalSection(&ddraw_cs
);
5721 IWineD3DSurface_PreLoad(surf
->WineD3DSurface
);
5722 LeaveCriticalSection(&ddraw_cs
);
5726 static HRESULT WINAPI
5727 IDirect3DDeviceImpl_7_PreLoad_FPUSetup(IDirect3DDevice7
*iface
,
5728 IDirectDrawSurface7
*Texture
)
5730 return IDirect3DDeviceImpl_7_PreLoad(iface
, Texture
);
5733 static HRESULT WINAPI
5734 IDirect3DDeviceImpl_7_PreLoad_FPUPreserve(IDirect3DDevice7
*iface
,
5735 IDirectDrawSurface7
*Texture
)
5740 old_fpucw
= d3d_fpu_setup();
5741 hr
= IDirect3DDeviceImpl_7_PreLoad(iface
, Texture
);
5742 set_fpu_control_word(old_fpucw
);
5747 /*****************************************************************************
5748 * IDirect3DDevice7::ApplyStateBlock
5750 * Activates the state stored in a state block handle.
5753 * BlockHandle: The stateblock handle to activate
5757 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is NULL
5759 *****************************************************************************/
5761 IDirect3DDeviceImpl_7_ApplyStateBlock(IDirect3DDevice7
*iface
,
5764 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
5765 IWineD3DStateBlock
*wined3d_sb
;
5768 TRACE("iface %p, stateblock %#x.\n", iface
, BlockHandle
);
5770 EnterCriticalSection(&ddraw_cs
);
5772 wined3d_sb
= ddraw_get_object(&This
->handle_table
, BlockHandle
- 1, DDRAW_HANDLE_STATEBLOCK
);
5775 WARN("Invalid stateblock handle.\n");
5776 LeaveCriticalSection(&ddraw_cs
);
5777 return D3DERR_INVALIDSTATEBLOCK
;
5780 hr
= IWineD3DStateBlock_Apply(wined3d_sb
);
5781 LeaveCriticalSection(&ddraw_cs
);
5783 return hr_ddraw_from_wined3d(hr
);
5786 static HRESULT WINAPI
5787 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUSetup(IDirect3DDevice7
*iface
,
5790 return IDirect3DDeviceImpl_7_ApplyStateBlock(iface
, BlockHandle
);
5793 static HRESULT WINAPI
5794 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUPreserve(IDirect3DDevice7
*iface
,
5800 old_fpucw
= d3d_fpu_setup();
5801 hr
= IDirect3DDeviceImpl_7_ApplyStateBlock(iface
, BlockHandle
);
5802 set_fpu_control_word(old_fpucw
);
5807 /*****************************************************************************
5808 * IDirect3DDevice7::CaptureStateBlock
5810 * Updates a stateblock's values to the values currently set for the device
5815 * BlockHandle: Stateblock to update
5819 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is NULL
5820 * See IWineD3DDevice::CaptureStateBlock for more details
5822 *****************************************************************************/
5824 IDirect3DDeviceImpl_7_CaptureStateBlock(IDirect3DDevice7
*iface
,
5827 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
5828 IWineD3DStateBlock
*wined3d_sb
;
5831 TRACE("iface %p, stateblock %#x.\n", iface
, BlockHandle
);
5833 EnterCriticalSection(&ddraw_cs
);
5835 wined3d_sb
= ddraw_get_object(&This
->handle_table
, BlockHandle
- 1, DDRAW_HANDLE_STATEBLOCK
);
5838 WARN("Invalid stateblock handle.\n");
5839 LeaveCriticalSection(&ddraw_cs
);
5840 return D3DERR_INVALIDSTATEBLOCK
;
5843 hr
= IWineD3DStateBlock_Capture(wined3d_sb
);
5844 LeaveCriticalSection(&ddraw_cs
);
5845 return hr_ddraw_from_wined3d(hr
);
5848 static HRESULT WINAPI
5849 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUSetup(IDirect3DDevice7
*iface
,
5852 return IDirect3DDeviceImpl_7_CaptureStateBlock(iface
, BlockHandle
);
5855 static HRESULT WINAPI
5856 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUPreserve(IDirect3DDevice7
*iface
,
5862 old_fpucw
= d3d_fpu_setup();
5863 hr
= IDirect3DDeviceImpl_7_CaptureStateBlock(iface
, BlockHandle
);
5864 set_fpu_control_word(old_fpucw
);
5869 /*****************************************************************************
5870 * IDirect3DDevice7::DeleteStateBlock
5872 * Deletes a stateblock handle. This means releasing the WineD3DStateBlock
5877 * BlockHandle: Stateblock handle to delete
5881 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is 0
5883 *****************************************************************************/
5885 IDirect3DDeviceImpl_7_DeleteStateBlock(IDirect3DDevice7
*iface
,
5888 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
5889 IWineD3DStateBlock
*wined3d_sb
;
5892 TRACE("iface %p, stateblock %#x.\n", iface
, BlockHandle
);
5894 EnterCriticalSection(&ddraw_cs
);
5896 wined3d_sb
= ddraw_free_handle(&This
->handle_table
, BlockHandle
- 1, DDRAW_HANDLE_STATEBLOCK
);
5899 WARN("Invalid stateblock handle.\n");
5900 LeaveCriticalSection(&ddraw_cs
);
5901 return D3DERR_INVALIDSTATEBLOCK
;
5904 if ((ref
= IWineD3DStateBlock_Release(wined3d_sb
)))
5906 ERR("Something is still holding stateblock %p (refcount %u).\n", wined3d_sb
, ref
);
5909 LeaveCriticalSection(&ddraw_cs
);
5913 static HRESULT WINAPI
5914 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUSetup(IDirect3DDevice7
*iface
,
5917 return IDirect3DDeviceImpl_7_DeleteStateBlock(iface
, BlockHandle
);
5920 static HRESULT WINAPI
5921 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUPreserve(IDirect3DDevice7
*iface
,
5927 old_fpucw
= d3d_fpu_setup();
5928 hr
= IDirect3DDeviceImpl_7_DeleteStateBlock(iface
, BlockHandle
);
5929 set_fpu_control_word(old_fpucw
);
5934 /*****************************************************************************
5935 * IDirect3DDevice7::CreateStateBlock
5937 * Creates a new state block handle.
5942 * Type: The state block type
5943 * BlockHandle: Address to write the created handle to
5947 * DDERR_INVALIDPARAMS if BlockHandle is NULL
5949 *****************************************************************************/
5951 IDirect3DDeviceImpl_7_CreateStateBlock(IDirect3DDevice7
*iface
,
5952 D3DSTATEBLOCKTYPE Type
,
5955 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
5956 IWineD3DStateBlock
*wined3d_sb
;
5960 TRACE("iface %p, type %#x, stateblock %p.\n", iface
, Type
, BlockHandle
);
5964 WARN("BlockHandle == NULL, returning DDERR_INVALIDPARAMS\n");
5965 return DDERR_INVALIDPARAMS
;
5967 if(Type
!= D3DSBT_ALL
&& Type
!= D3DSBT_PIXELSTATE
&&
5968 Type
!= D3DSBT_VERTEXSTATE
) {
5969 WARN("Unexpected stateblock type, returning DDERR_INVALIDPARAMS\n");
5970 return DDERR_INVALIDPARAMS
;
5973 EnterCriticalSection(&ddraw_cs
);
5975 /* The D3DSTATEBLOCKTYPE enum is fine here. */
5976 hr
= IWineD3DDevice_CreateStateBlock(This
->wineD3DDevice
, Type
, &wined3d_sb
);
5979 WARN("Failed to create stateblock, hr %#x.\n", hr
);
5980 LeaveCriticalSection(&ddraw_cs
);
5981 return hr_ddraw_from_wined3d(hr
);
5984 h
= ddraw_allocate_handle(&This
->handle_table
, wined3d_sb
, DDRAW_HANDLE_STATEBLOCK
);
5985 if (h
== DDRAW_INVALID_HANDLE
)
5987 ERR("Failed to allocate stateblock handle.\n");
5988 IWineD3DStateBlock_Release(wined3d_sb
);
5989 LeaveCriticalSection(&ddraw_cs
);
5990 return DDERR_OUTOFMEMORY
;
5993 *BlockHandle
= h
+ 1;
5994 LeaveCriticalSection(&ddraw_cs
);
5996 return hr_ddraw_from_wined3d(hr
);
5999 static HRESULT WINAPI
6000 IDirect3DDeviceImpl_7_CreateStateBlock_FPUSetup(IDirect3DDevice7
*iface
,
6001 D3DSTATEBLOCKTYPE Type
,
6004 return IDirect3DDeviceImpl_7_CreateStateBlock(iface
, Type
, BlockHandle
);
6007 static HRESULT WINAPI
6008 IDirect3DDeviceImpl_7_CreateStateBlock_FPUPreserve(IDirect3DDevice7
*iface
,
6009 D3DSTATEBLOCKTYPE Type
,
6015 old_fpucw
= d3d_fpu_setup();
6016 hr
=IDirect3DDeviceImpl_7_CreateStateBlock(iface
, Type
, BlockHandle
);
6017 set_fpu_control_word(old_fpucw
);
6022 /* Helper function for IDirect3DDeviceImpl_7_Load. */
6023 static BOOL
is_mip_level_subset(IDirectDrawSurfaceImpl
*dest
,
6024 IDirectDrawSurfaceImpl
*src
)
6026 IDirectDrawSurfaceImpl
*src_level
, *dest_level
;
6027 IDirectDrawSurface7
*temp
;
6028 DDSURFACEDESC2 ddsd
;
6029 BOOL levelFound
; /* at least one suitable sublevel in dest found */
6031 /* To satisfy "destination is mip level subset of source" criteria (regular texture counts as 1 level),
6032 * 1) there must be at least one mip level in destination that matched dimensions of some mip level in source and
6033 * 2) there must be no destination levels that don't match any levels in source. Otherwise it's INVALIDPARAMS.
6040 for (;src_level
&& dest_level
;)
6042 if (src_level
->surface_desc
.dwWidth
== dest_level
->surface_desc
.dwWidth
&&
6043 src_level
->surface_desc
.dwHeight
== dest_level
->surface_desc
.dwHeight
)
6047 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
6048 ddsd
.ddsCaps
.dwCaps2
= DDSCAPS2_MIPMAPSUBLEVEL
;
6049 IDirectDrawSurface7_GetAttachedSurface((IDirectDrawSurface7
*)dest_level
, &ddsd
.ddsCaps
, &temp
);
6051 if (dest_level
!= dest
) IDirectDrawSurface7_Release((IDirectDrawSurface7
*)dest_level
);
6053 dest_level
= (IDirectDrawSurfaceImpl
*)temp
;
6056 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
6057 ddsd
.ddsCaps
.dwCaps2
= DDSCAPS2_MIPMAPSUBLEVEL
;
6058 IDirectDrawSurface7_GetAttachedSurface((IDirectDrawSurface7
*)src_level
, &ddsd
.ddsCaps
, &temp
);
6060 if (src_level
!= src
) IDirectDrawSurface7_Release((IDirectDrawSurface7
*)src_level
);
6062 src_level
= (IDirectDrawSurfaceImpl
*)temp
;
6065 if (src_level
&& src_level
!= src
) IDirectDrawSurface7_Release((IDirectDrawSurface7
*)src_level
);
6066 if (dest_level
&& dest_level
!= dest
) IDirectDrawSurface7_Release((IDirectDrawSurface7
*)dest_level
);
6068 return !dest_level
&& levelFound
;
6071 /* Helper function for IDirect3DDeviceImpl_7_Load. */
6072 static void copy_mipmap_chain(IDirect3DDeviceImpl
*device
,
6073 IDirectDrawSurfaceImpl
*dest
,
6074 IDirectDrawSurfaceImpl
*src
,
6075 const POINT
*DestPoint
,
6076 const RECT
*SrcRect
)
6078 IDirectDrawSurfaceImpl
*src_level
, *dest_level
;
6079 IDirectDrawSurface7
*temp
;
6080 DDSURFACEDESC2 ddsd
;
6084 IDirectDrawPalette
*pal
= NULL
, *pal_src
= NULL
;
6087 BOOL palette_missing
= FALSE
;
6089 /* Copy palette, if possible. */
6090 IDirectDrawSurface7_GetPalette((IDirectDrawSurface7
*)src
, &pal_src
);
6091 IDirectDrawSurface7_GetPalette((IDirectDrawSurface7
*)dest
, &pal
);
6093 if (pal_src
!= NULL
&& pal
!= NULL
)
6095 PALETTEENTRY palent
[256];
6097 IDirectDrawPalette_GetEntries(pal_src
, 0, 0, 256, palent
);
6098 IDirectDrawPalette_SetEntries(pal
, 0, 0, 256, palent
);
6101 if (dest
->surface_desc
.u4
.ddpfPixelFormat
.dwFlags
& (DDPF_PALETTEINDEXED1
| DDPF_PALETTEINDEXED2
|
6102 DDPF_PALETTEINDEXED4
| DDPF_PALETTEINDEXED8
| DDPF_PALETTEINDEXEDTO8
) && !pal
)
6104 palette_missing
= TRUE
;
6107 if (pal
) IDirectDrawPalette_Release(pal
);
6108 if (pal_src
) IDirectDrawPalette_Release(pal_src
);
6110 /* Copy colorkeys, if present. */
6111 for (ckeyflag
= DDCKEY_DESTBLT
; ckeyflag
<= DDCKEY_SRCOVERLAY
; ckeyflag
<<= 1)
6113 hr
= IDirectDrawSurface7_GetColorKey((IDirectDrawSurface7
*)src
, ckeyflag
, &ddckey
);
6117 IDirectDrawSurface7_SetColorKey((IDirectDrawSurface7
*)dest
, ckeyflag
, &ddckey
);
6127 for (;src_level
&& dest_level
;)
6129 if (src_level
->surface_desc
.dwWidth
== dest_level
->surface_desc
.dwWidth
&&
6130 src_level
->surface_desc
.dwHeight
== dest_level
->surface_desc
.dwHeight
)
6132 /* Try UpdateSurface that may perform a more direct opengl loading. But skip this if destination is paletted texture and has no palette.
6133 * Some games like Sacrifice set palette after Load, and it is a waste of effort to try to load texture without palette and generates
6134 * warnings in wined3d. */
6135 if (!palette_missing
)
6136 hr
= IWineD3DDevice_UpdateSurface(device
->wineD3DDevice
, src_level
->WineD3DSurface
, &rect
, dest_level
->WineD3DSurface
,
6139 if (palette_missing
|| FAILED(hr
))
6141 /* UpdateSurface may fail e.g. if dest is in system memory. Fall back to BltFast that is less strict. */
6142 IWineD3DSurface_BltFast(dest_level
->WineD3DSurface
,
6144 src_level
->WineD3DSurface
, &rect
, 0);
6147 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
6148 ddsd
.ddsCaps
.dwCaps2
= DDSCAPS2_MIPMAPSUBLEVEL
;
6149 IDirectDrawSurface7_GetAttachedSurface((IDirectDrawSurface7
*)dest_level
, &ddsd
.ddsCaps
, &temp
);
6151 if (dest_level
!= dest
) IDirectDrawSurface7_Release((IDirectDrawSurface7
*)dest_level
);
6153 dest_level
= (IDirectDrawSurfaceImpl
*)temp
;
6156 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
6157 ddsd
.ddsCaps
.dwCaps2
= DDSCAPS2_MIPMAPSUBLEVEL
;
6158 IDirectDrawSurface7_GetAttachedSurface((IDirectDrawSurface7
*)src_level
, &ddsd
.ddsCaps
, &temp
);
6160 if (src_level
!= src
) IDirectDrawSurface7_Release((IDirectDrawSurface7
*)src_level
);
6162 src_level
= (IDirectDrawSurfaceImpl
*)temp
;
6169 rect
.right
= (rect
.right
+ 1) / 2;
6170 rect
.bottom
= (rect
.bottom
+ 1) / 2;
6173 if (src_level
&& src_level
!= src
) IDirectDrawSurface7_Release((IDirectDrawSurface7
*)src_level
);
6174 if (dest_level
&& dest_level
!= dest
) IDirectDrawSurface7_Release((IDirectDrawSurface7
*)dest_level
);
6177 /*****************************************************************************
6178 * IDirect3DDevice7::Load
6180 * Loads a rectangular area from the source into the destination texture.
6181 * It can also copy the source to the faces of a cubic environment map
6186 * DestTex: Destination texture
6187 * DestPoint: Point in the destination where the source image should be
6189 * SrcTex: Source texture
6190 * SrcRect: Source rectangle
6191 * Flags: Cubemap faces to load (DDSCAPS2_CUBEMAP_ALLFACES, DDSCAPS2_CUBEMAP_POSITIVEX,
6192 * DDSCAPS2_CUBEMAP_NEGATIVEX, DDSCAPS2_CUBEMAP_POSITIVEY, DDSCAPS2_CUBEMAP_NEGATIVEY,
6193 * DDSCAPS2_CUBEMAP_POSITIVEZ, DDSCAPS2_CUBEMAP_NEGATIVEZ)
6197 * DDERR_INVALIDPARAMS if DestTex or SrcTex are NULL, broken coordinates or anything unexpected.
6200 *****************************************************************************/
6203 IDirect3DDeviceImpl_7_Load(IDirect3DDevice7
*iface
,
6204 IDirectDrawSurface7
*DestTex
,
6206 IDirectDrawSurface7
*SrcTex
,
6210 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
6211 IDirectDrawSurfaceImpl
*dest
= (IDirectDrawSurfaceImpl
*)DestTex
;
6212 IDirectDrawSurfaceImpl
*src
= (IDirectDrawSurfaceImpl
*)SrcTex
;
6216 TRACE("iface %p, dst_texture %p, dst_pos %s, src_texture %p, src_rect %s, flags %#x.\n",
6217 iface
, DestTex
, wine_dbgstr_point(DestPoint
), SrcTex
, wine_dbgstr_rect(SrcRect
), Flags
);
6219 if( (!src
) || (!dest
) )
6220 return DDERR_INVALIDPARAMS
;
6222 EnterCriticalSection(&ddraw_cs
);
6224 if (SrcRect
) srcrect
= *SrcRect
;
6227 srcrect
.left
= srcrect
.top
= 0;
6228 srcrect
.right
= src
->surface_desc
.dwWidth
;
6229 srcrect
.bottom
= src
->surface_desc
.dwHeight
;
6232 if (DestPoint
) destpoint
= *DestPoint
;
6235 destpoint
.x
= destpoint
.y
= 0;
6237 /* Check bad dimensions. DestPoint is validated against src, not dest, because
6238 * destination can be a subset of mip levels, in which case actual coordinates used
6239 * for it may be divided. If any dimension of dest is larger than source, it can't be
6240 * mip level subset, so an error can be returned early.
6242 if (srcrect
.left
>= srcrect
.right
|| srcrect
.top
>= srcrect
.bottom
||
6243 srcrect
.right
> src
->surface_desc
.dwWidth
||
6244 srcrect
.bottom
> src
->surface_desc
.dwHeight
||
6245 destpoint
.x
+ srcrect
.right
- srcrect
.left
> src
->surface_desc
.dwWidth
||
6246 destpoint
.y
+ srcrect
.bottom
- srcrect
.top
> src
->surface_desc
.dwHeight
||
6247 dest
->surface_desc
.dwWidth
> src
->surface_desc
.dwWidth
||
6248 dest
->surface_desc
.dwHeight
> src
->surface_desc
.dwHeight
)
6250 LeaveCriticalSection(&ddraw_cs
);
6251 return DDERR_INVALIDPARAMS
;
6254 /* Must be top level surfaces. */
6255 if (src
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_MIPMAPSUBLEVEL
||
6256 dest
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_MIPMAPSUBLEVEL
)
6258 LeaveCriticalSection(&ddraw_cs
);
6259 return DDERR_INVALIDPARAMS
;
6262 if (src
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_CUBEMAP
)
6264 DWORD src_face_flag
, dest_face_flag
;
6265 IDirectDrawSurfaceImpl
*src_face
, *dest_face
;
6266 IDirectDrawSurface7
*temp
;
6267 DDSURFACEDESC2 ddsd
;
6270 if (!(dest
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_CUBEMAP
))
6272 LeaveCriticalSection(&ddraw_cs
);
6273 return DDERR_INVALIDPARAMS
;
6276 /* Iterate through cube faces 2 times. First time is just to check INVALIDPARAMS conditions, second
6277 * time it's actual surface loading. */
6278 for (i
= 0; i
< 2; i
++)
6283 for (;dest_face
&& src_face
;)
6285 src_face_flag
= src_face
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_CUBEMAP_ALLFACES
;
6286 dest_face_flag
= dest_face
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_CUBEMAP_ALLFACES
;
6288 if (src_face_flag
== dest_face_flag
)
6292 /* Destination mip levels must be subset of source mip levels. */
6293 if (!is_mip_level_subset(dest_face
, src_face
))
6295 LeaveCriticalSection(&ddraw_cs
);
6296 return DDERR_INVALIDPARAMS
;
6299 else if (Flags
& dest_face_flag
)
6301 copy_mipmap_chain(This
, dest_face
, src_face
, &destpoint
, &srcrect
);
6304 if (src_face_flag
< DDSCAPS2_CUBEMAP_NEGATIVEZ
)
6306 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
6307 ddsd
.ddsCaps
.dwCaps2
= DDSCAPS2_CUBEMAP
| (src_face_flag
<< 1);
6308 IDirectDrawSurface7_GetAttachedSurface((IDirectDrawSurface7
*)src
, &ddsd
.ddsCaps
, &temp
);
6310 if (src_face
!= src
) IDirectDrawSurface7_Release((IDirectDrawSurface7
*)src_face
);
6312 src_face
= (IDirectDrawSurfaceImpl
*)temp
;
6316 if (src_face
!= src
) IDirectDrawSurface7_Release((IDirectDrawSurface7
*)src_face
);
6322 if (dest_face_flag
< DDSCAPS2_CUBEMAP_NEGATIVEZ
)
6324 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
6325 ddsd
.ddsCaps
.dwCaps2
= DDSCAPS2_CUBEMAP
| (dest_face_flag
<< 1);
6326 IDirectDrawSurface7_GetAttachedSurface((IDirectDrawSurface7
*)dest
, &ddsd
.ddsCaps
, &temp
);
6328 if (dest_face
!= dest
) IDirectDrawSurface7_Release((IDirectDrawSurface7
*)dest_face
);
6330 dest_face
= (IDirectDrawSurfaceImpl
*)temp
;
6334 if (dest_face
!= dest
) IDirectDrawSurface7_Release((IDirectDrawSurface7
*)dest_face
);
6342 /* Native returns error if src faces are not subset of dest faces. */
6345 LeaveCriticalSection(&ddraw_cs
);
6346 return DDERR_INVALIDPARAMS
;
6351 LeaveCriticalSection(&ddraw_cs
);
6354 else if (dest
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_CUBEMAP
)
6356 LeaveCriticalSection(&ddraw_cs
);
6357 return DDERR_INVALIDPARAMS
;
6360 /* Handle non cube map textures. */
6362 /* Destination mip levels must be subset of source mip levels. */
6363 if (!is_mip_level_subset(dest
, src
))
6365 LeaveCriticalSection(&ddraw_cs
);
6366 return DDERR_INVALIDPARAMS
;
6369 copy_mipmap_chain(This
, dest
, src
, &destpoint
, &srcrect
);
6371 LeaveCriticalSection(&ddraw_cs
);
6375 static HRESULT WINAPI
6376 IDirect3DDeviceImpl_7_Load_FPUSetup(IDirect3DDevice7
*iface
,
6377 IDirectDrawSurface7
*DestTex
,
6379 IDirectDrawSurface7
*SrcTex
,
6383 return IDirect3DDeviceImpl_7_Load(iface
, DestTex
, DestPoint
, SrcTex
, SrcRect
, Flags
);
6386 static HRESULT WINAPI
6387 IDirect3DDeviceImpl_7_Load_FPUPreserve(IDirect3DDevice7
*iface
,
6388 IDirectDrawSurface7
*DestTex
,
6390 IDirectDrawSurface7
*SrcTex
,
6397 old_fpucw
= d3d_fpu_setup();
6398 hr
= IDirect3DDeviceImpl_7_Load(iface
, DestTex
, DestPoint
, SrcTex
, SrcRect
, Flags
);
6399 set_fpu_control_word(old_fpucw
);
6404 /*****************************************************************************
6405 * IDirect3DDevice7::LightEnable
6407 * Enables or disables a light
6409 * Version 7, IDirect3DLight uses this method too.
6412 * LightIndex: The index of the light to enable / disable
6413 * Enable: Enable or disable the light
6417 * For more details, see IWineD3DDevice::SetLightEnable
6419 *****************************************************************************/
6421 IDirect3DDeviceImpl_7_LightEnable(IDirect3DDevice7
*iface
,
6425 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
6428 TRACE("iface %p, light_idx %u, enabled %#x.\n", iface
, LightIndex
, Enable
);
6430 EnterCriticalSection(&ddraw_cs
);
6431 hr
= IWineD3DDevice_SetLightEnable(This
->wineD3DDevice
, LightIndex
, Enable
);
6432 LeaveCriticalSection(&ddraw_cs
);
6433 return hr_ddraw_from_wined3d(hr
);
6436 static HRESULT WINAPI
6437 IDirect3DDeviceImpl_7_LightEnable_FPUSetup(IDirect3DDevice7
*iface
,
6441 return IDirect3DDeviceImpl_7_LightEnable(iface
, LightIndex
, Enable
);
6444 static HRESULT WINAPI
6445 IDirect3DDeviceImpl_7_LightEnable_FPUPreserve(IDirect3DDevice7
*iface
,
6452 old_fpucw
= d3d_fpu_setup();
6453 hr
= IDirect3DDeviceImpl_7_LightEnable(iface
, LightIndex
, Enable
);
6454 set_fpu_control_word(old_fpucw
);
6459 /*****************************************************************************
6460 * IDirect3DDevice7::GetLightEnable
6462 * Retrieves if the light with the given index is enabled or not
6467 * LightIndex: Index of desired light
6468 * Enable: Pointer to a BOOL which contains the result
6472 * DDERR_INVALIDPARAMS if Enable is NULL
6473 * See IWineD3DDevice::GetLightEnable for more details
6475 *****************************************************************************/
6477 IDirect3DDeviceImpl_7_GetLightEnable(IDirect3DDevice7
*iface
,
6481 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
6484 TRACE("iface %p, light_idx %u, enabled %p.\n", iface
, LightIndex
, Enable
);
6487 return DDERR_INVALIDPARAMS
;
6489 EnterCriticalSection(&ddraw_cs
);
6490 hr
= IWineD3DDevice_GetLightEnable(This
->wineD3DDevice
, LightIndex
, Enable
);
6491 LeaveCriticalSection(&ddraw_cs
);
6492 return hr_ddraw_from_wined3d(hr
);
6495 static HRESULT WINAPI
6496 IDirect3DDeviceImpl_7_GetLightEnable_FPUSetup(IDirect3DDevice7
*iface
,
6500 return IDirect3DDeviceImpl_7_GetLightEnable(iface
, LightIndex
, Enable
);
6503 static HRESULT WINAPI
6504 IDirect3DDeviceImpl_7_GetLightEnable_FPUPreserve(IDirect3DDevice7
*iface
,
6511 old_fpucw
= d3d_fpu_setup();
6512 hr
= IDirect3DDeviceImpl_7_GetLightEnable(iface
, LightIndex
, Enable
);
6513 set_fpu_control_word(old_fpucw
);
6518 /*****************************************************************************
6519 * IDirect3DDevice7::SetClipPlane
6521 * Sets custom clipping plane
6526 * Index: The index of the clipping plane
6527 * PlaneEquation: An equation defining the clipping plane
6531 * DDERR_INVALIDPARAMS if PlaneEquation is NULL
6532 * See IWineD3DDevice::SetClipPlane for more details
6534 *****************************************************************************/
6536 IDirect3DDeviceImpl_7_SetClipPlane(IDirect3DDevice7
*iface
,
6538 D3DVALUE
* PlaneEquation
)
6540 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
6543 TRACE("iface %p, idx %u, plane %p.\n", iface
, Index
, PlaneEquation
);
6546 return DDERR_INVALIDPARAMS
;
6548 EnterCriticalSection(&ddraw_cs
);
6549 hr
= IWineD3DDevice_SetClipPlane(This
->wineD3DDevice
, Index
, PlaneEquation
);
6550 LeaveCriticalSection(&ddraw_cs
);
6554 static HRESULT WINAPI
6555 IDirect3DDeviceImpl_7_SetClipPlane_FPUSetup(IDirect3DDevice7
*iface
,
6557 D3DVALUE
* PlaneEquation
)
6559 return IDirect3DDeviceImpl_7_SetClipPlane(iface
, Index
, PlaneEquation
);
6562 static HRESULT WINAPI
6563 IDirect3DDeviceImpl_7_SetClipPlane_FPUPreserve(IDirect3DDevice7
*iface
,
6565 D3DVALUE
* PlaneEquation
)
6570 old_fpucw
= d3d_fpu_setup();
6571 hr
= IDirect3DDeviceImpl_7_SetClipPlane(iface
, Index
, PlaneEquation
);
6572 set_fpu_control_word(old_fpucw
);
6577 /*****************************************************************************
6578 * IDirect3DDevice7::GetClipPlane
6580 * Returns the clipping plane with a specific index
6583 * Index: The index of the desired plane
6584 * PlaneEquation: Address to store the plane equation to
6588 * DDERR_INVALIDPARAMS if PlaneEquation is NULL
6589 * See IWineD3DDevice::GetClipPlane for more details
6591 *****************************************************************************/
6593 IDirect3DDeviceImpl_7_GetClipPlane(IDirect3DDevice7
*iface
,
6595 D3DVALUE
* PlaneEquation
)
6597 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
6600 TRACE("iface %p, idx %u, plane %p.\n", iface
, Index
, PlaneEquation
);
6603 return DDERR_INVALIDPARAMS
;
6605 EnterCriticalSection(&ddraw_cs
);
6606 hr
= IWineD3DDevice_GetClipPlane(This
->wineD3DDevice
, Index
, PlaneEquation
);
6607 LeaveCriticalSection(&ddraw_cs
);
6611 static HRESULT WINAPI
6612 IDirect3DDeviceImpl_7_GetClipPlane_FPUSetup(IDirect3DDevice7
*iface
,
6614 D3DVALUE
* PlaneEquation
)
6616 return IDirect3DDeviceImpl_7_GetClipPlane(iface
, Index
, PlaneEquation
);
6619 static HRESULT WINAPI
6620 IDirect3DDeviceImpl_7_GetClipPlane_FPUPreserve(IDirect3DDevice7
*iface
,
6622 D3DVALUE
* PlaneEquation
)
6627 old_fpucw
= d3d_fpu_setup();
6628 hr
= IDirect3DDeviceImpl_7_GetClipPlane(iface
, Index
, PlaneEquation
);
6629 set_fpu_control_word(old_fpucw
);
6634 /*****************************************************************************
6635 * IDirect3DDevice7::GetInfo
6637 * Retrieves some information about the device. The DirectX sdk says that
6638 * this version returns S_FALSE for all retail builds of DirectX, that's what
6639 * this implementation does.
6642 * DevInfoID: Information type requested
6643 * DevInfoStruct: Pointer to a structure to store the info to
6644 * Size: Size of the structure
6647 * S_FALSE, because it's a non-debug driver
6649 *****************************************************************************/
6650 static HRESULT WINAPI
6651 IDirect3DDeviceImpl_7_GetInfo(IDirect3DDevice7
*iface
,
6653 void *DevInfoStruct
,
6656 TRACE("iface %p, info_id %#x, info %p, info_size %u.\n",
6657 iface
, DevInfoID
, DevInfoStruct
, Size
);
6659 if (TRACE_ON(ddraw
))
6661 TRACE(" info requested : ");
6664 case D3DDEVINFOID_TEXTUREMANAGER
: TRACE("D3DDEVINFOID_TEXTUREMANAGER\n"); break;
6665 case D3DDEVINFOID_D3DTEXTUREMANAGER
: TRACE("D3DDEVINFOID_D3DTEXTUREMANAGER\n"); break;
6666 case D3DDEVINFOID_TEXTURING
: TRACE("D3DDEVINFOID_TEXTURING\n"); break;
6667 default: ERR(" invalid flag !!!\n"); return DDERR_INVALIDPARAMS
;
6671 return S_FALSE
; /* According to MSDN, this is valid for a non-debug driver */
6674 /* For performance optimization, devices created in FPUSETUP and FPUPRESERVE modes
6675 * have separate vtables. Simple functions where this doesn't matter like GetDirect3D
6676 * are not duplicated.
6678 * Device created with DDSCL_FPUSETUP (d3d7 default) - device methods assume that FPU
6679 * has already been setup for optimal d3d operation.
6681 * Device created with DDSCL_FPUPRESERVE - resets and restores FPU mode when necessary in
6682 * d3d calls (FPU may be in a mode non-suitable for d3d when the app calls d3d). Required
6683 * by Sacrifice (game). */
6684 static const struct IDirect3DDevice7Vtbl d3d_device7_fpu_setup_vtbl
=
6686 /*** IUnknown Methods ***/
6687 IDirect3DDeviceImpl_7_QueryInterface
,
6688 IDirect3DDeviceImpl_7_AddRef
,
6689 IDirect3DDeviceImpl_7_Release
,
6690 /*** IDirect3DDevice7 ***/
6691 IDirect3DDeviceImpl_7_GetCaps_FPUSetup
,
6692 IDirect3DDeviceImpl_7_EnumTextureFormats_FPUSetup
,
6693 IDirect3DDeviceImpl_7_BeginScene_FPUSetup
,
6694 IDirect3DDeviceImpl_7_EndScene_FPUSetup
,
6695 IDirect3DDeviceImpl_7_GetDirect3D
,
6696 IDirect3DDeviceImpl_7_SetRenderTarget_FPUSetup
,
6697 IDirect3DDeviceImpl_7_GetRenderTarget
,
6698 IDirect3DDeviceImpl_7_Clear_FPUSetup
,
6699 IDirect3DDeviceImpl_7_SetTransform_FPUSetup
,
6700 IDirect3DDeviceImpl_7_GetTransform_FPUSetup
,
6701 IDirect3DDeviceImpl_7_SetViewport_FPUSetup
,
6702 IDirect3DDeviceImpl_7_MultiplyTransform_FPUSetup
,
6703 IDirect3DDeviceImpl_7_GetViewport_FPUSetup
,
6704 IDirect3DDeviceImpl_7_SetMaterial_FPUSetup
,
6705 IDirect3DDeviceImpl_7_GetMaterial_FPUSetup
,
6706 IDirect3DDeviceImpl_7_SetLight_FPUSetup
,
6707 IDirect3DDeviceImpl_7_GetLight_FPUSetup
,
6708 IDirect3DDeviceImpl_7_SetRenderState_FPUSetup
,
6709 IDirect3DDeviceImpl_7_GetRenderState_FPUSetup
,
6710 IDirect3DDeviceImpl_7_BeginStateBlock_FPUSetup
,
6711 IDirect3DDeviceImpl_7_EndStateBlock_FPUSetup
,
6712 IDirect3DDeviceImpl_7_PreLoad_FPUSetup
,
6713 IDirect3DDeviceImpl_7_DrawPrimitive_FPUSetup
,
6714 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUSetup
,
6715 IDirect3DDeviceImpl_7_SetClipStatus
,
6716 IDirect3DDeviceImpl_7_GetClipStatus
,
6717 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUSetup
,
6718 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUSetup
,
6719 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUSetup
,
6720 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUSetup
,
6721 IDirect3DDeviceImpl_7_ComputeSphereVisibility
,
6722 IDirect3DDeviceImpl_7_GetTexture_FPUSetup
,
6723 IDirect3DDeviceImpl_7_SetTexture_FPUSetup
,
6724 IDirect3DDeviceImpl_7_GetTextureStageState_FPUSetup
,
6725 IDirect3DDeviceImpl_7_SetTextureStageState_FPUSetup
,
6726 IDirect3DDeviceImpl_7_ValidateDevice_FPUSetup
,
6727 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUSetup
,
6728 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUSetup
,
6729 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUSetup
,
6730 IDirect3DDeviceImpl_7_CreateStateBlock_FPUSetup
,
6731 IDirect3DDeviceImpl_7_Load_FPUSetup
,
6732 IDirect3DDeviceImpl_7_LightEnable_FPUSetup
,
6733 IDirect3DDeviceImpl_7_GetLightEnable_FPUSetup
,
6734 IDirect3DDeviceImpl_7_SetClipPlane_FPUSetup
,
6735 IDirect3DDeviceImpl_7_GetClipPlane_FPUSetup
,
6736 IDirect3DDeviceImpl_7_GetInfo
6739 static const struct IDirect3DDevice7Vtbl d3d_device7_fpu_preserve_vtbl
=
6741 /*** IUnknown Methods ***/
6742 IDirect3DDeviceImpl_7_QueryInterface
,
6743 IDirect3DDeviceImpl_7_AddRef
,
6744 IDirect3DDeviceImpl_7_Release
,
6745 /*** IDirect3DDevice7 ***/
6746 IDirect3DDeviceImpl_7_GetCaps_FPUPreserve
,
6747 IDirect3DDeviceImpl_7_EnumTextureFormats_FPUPreserve
,
6748 IDirect3DDeviceImpl_7_BeginScene_FPUPreserve
,
6749 IDirect3DDeviceImpl_7_EndScene_FPUPreserve
,
6750 IDirect3DDeviceImpl_7_GetDirect3D
,
6751 IDirect3DDeviceImpl_7_SetRenderTarget_FPUPreserve
,
6752 IDirect3DDeviceImpl_7_GetRenderTarget
,
6753 IDirect3DDeviceImpl_7_Clear_FPUPreserve
,
6754 IDirect3DDeviceImpl_7_SetTransform_FPUPreserve
,
6755 IDirect3DDeviceImpl_7_GetTransform_FPUPreserve
,
6756 IDirect3DDeviceImpl_7_SetViewport_FPUPreserve
,
6757 IDirect3DDeviceImpl_7_MultiplyTransform_FPUPreserve
,
6758 IDirect3DDeviceImpl_7_GetViewport_FPUPreserve
,
6759 IDirect3DDeviceImpl_7_SetMaterial_FPUPreserve
,
6760 IDirect3DDeviceImpl_7_GetMaterial_FPUPreserve
,
6761 IDirect3DDeviceImpl_7_SetLight_FPUPreserve
,
6762 IDirect3DDeviceImpl_7_GetLight_FPUPreserve
,
6763 IDirect3DDeviceImpl_7_SetRenderState_FPUPreserve
,
6764 IDirect3DDeviceImpl_7_GetRenderState_FPUPreserve
,
6765 IDirect3DDeviceImpl_7_BeginStateBlock_FPUPreserve
,
6766 IDirect3DDeviceImpl_7_EndStateBlock_FPUPreserve
,
6767 IDirect3DDeviceImpl_7_PreLoad_FPUPreserve
,
6768 IDirect3DDeviceImpl_7_DrawPrimitive_FPUPreserve
,
6769 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUPreserve
,
6770 IDirect3DDeviceImpl_7_SetClipStatus
,
6771 IDirect3DDeviceImpl_7_GetClipStatus
,
6772 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUPreserve
,
6773 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUPreserve
,
6774 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUPreserve
,
6775 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUPreserve
,
6776 IDirect3DDeviceImpl_7_ComputeSphereVisibility
,
6777 IDirect3DDeviceImpl_7_GetTexture_FPUPreserve
,
6778 IDirect3DDeviceImpl_7_SetTexture_FPUPreserve
,
6779 IDirect3DDeviceImpl_7_GetTextureStageState_FPUPreserve
,
6780 IDirect3DDeviceImpl_7_SetTextureStageState_FPUPreserve
,
6781 IDirect3DDeviceImpl_7_ValidateDevice_FPUPreserve
,
6782 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUPreserve
,
6783 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUPreserve
,
6784 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUPreserve
,
6785 IDirect3DDeviceImpl_7_CreateStateBlock_FPUPreserve
,
6786 IDirect3DDeviceImpl_7_Load_FPUPreserve
,
6787 IDirect3DDeviceImpl_7_LightEnable_FPUPreserve
,
6788 IDirect3DDeviceImpl_7_GetLightEnable_FPUPreserve
,
6789 IDirect3DDeviceImpl_7_SetClipPlane_FPUPreserve
,
6790 IDirect3DDeviceImpl_7_GetClipPlane_FPUPreserve
,
6791 IDirect3DDeviceImpl_7_GetInfo
6794 static const struct IDirect3DDevice3Vtbl d3d_device3_vtbl
=
6796 /*** IUnknown Methods ***/
6797 Thunk_IDirect3DDeviceImpl_3_QueryInterface
,
6798 Thunk_IDirect3DDeviceImpl_3_AddRef
,
6799 Thunk_IDirect3DDeviceImpl_3_Release
,
6800 /*** IDirect3DDevice3 ***/
6801 IDirect3DDeviceImpl_3_GetCaps
,
6802 IDirect3DDeviceImpl_3_GetStats
,
6803 IDirect3DDeviceImpl_3_AddViewport
,
6804 IDirect3DDeviceImpl_3_DeleteViewport
,
6805 IDirect3DDeviceImpl_3_NextViewport
,
6806 Thunk_IDirect3DDeviceImpl_3_EnumTextureFormats
,
6807 Thunk_IDirect3DDeviceImpl_3_BeginScene
,
6808 Thunk_IDirect3DDeviceImpl_3_EndScene
,
6809 Thunk_IDirect3DDeviceImpl_3_GetDirect3D
,
6810 IDirect3DDeviceImpl_3_SetCurrentViewport
,
6811 IDirect3DDeviceImpl_3_GetCurrentViewport
,
6812 Thunk_IDirect3DDeviceImpl_3_SetRenderTarget
,
6813 Thunk_IDirect3DDeviceImpl_3_GetRenderTarget
,
6814 IDirect3DDeviceImpl_3_Begin
,
6815 IDirect3DDeviceImpl_3_BeginIndexed
,
6816 IDirect3DDeviceImpl_3_Vertex
,
6817 IDirect3DDeviceImpl_3_Index
,
6818 IDirect3DDeviceImpl_3_End
,
6819 IDirect3DDeviceImpl_3_GetRenderState
,
6820 IDirect3DDeviceImpl_3_SetRenderState
,
6821 IDirect3DDeviceImpl_3_GetLightState
,
6822 IDirect3DDeviceImpl_3_SetLightState
,
6823 Thunk_IDirect3DDeviceImpl_3_SetTransform
,
6824 Thunk_IDirect3DDeviceImpl_3_GetTransform
,
6825 Thunk_IDirect3DDeviceImpl_3_MultiplyTransform
,
6826 Thunk_IDirect3DDeviceImpl_3_DrawPrimitive
,
6827 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitive
,
6828 Thunk_IDirect3DDeviceImpl_3_SetClipStatus
,
6829 Thunk_IDirect3DDeviceImpl_3_GetClipStatus
,
6830 Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveStrided
,
6831 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveStrided
,
6832 Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveVB
,
6833 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveVB
,
6834 Thunk_IDirect3DDeviceImpl_3_ComputeSphereVisibility
,
6835 Thunk_IDirect3DDeviceImpl_3_GetTexture
,
6836 IDirect3DDeviceImpl_3_SetTexture
,
6837 Thunk_IDirect3DDeviceImpl_3_GetTextureStageState
,
6838 Thunk_IDirect3DDeviceImpl_3_SetTextureStageState
,
6839 Thunk_IDirect3DDeviceImpl_3_ValidateDevice
6842 static const struct IDirect3DDevice2Vtbl d3d_device2_vtbl
=
6844 /*** IUnknown Methods ***/
6845 Thunk_IDirect3DDeviceImpl_2_QueryInterface
,
6846 Thunk_IDirect3DDeviceImpl_2_AddRef
,
6847 Thunk_IDirect3DDeviceImpl_2_Release
,
6848 /*** IDirect3DDevice2 ***/
6849 Thunk_IDirect3DDeviceImpl_2_GetCaps
,
6850 IDirect3DDeviceImpl_2_SwapTextureHandles
,
6851 Thunk_IDirect3DDeviceImpl_2_GetStats
,
6852 Thunk_IDirect3DDeviceImpl_2_AddViewport
,
6853 Thunk_IDirect3DDeviceImpl_2_DeleteViewport
,
6854 Thunk_IDirect3DDeviceImpl_2_NextViewport
,
6855 IDirect3DDeviceImpl_2_EnumTextureFormats
,
6856 Thunk_IDirect3DDeviceImpl_2_BeginScene
,
6857 Thunk_IDirect3DDeviceImpl_2_EndScene
,
6858 Thunk_IDirect3DDeviceImpl_2_GetDirect3D
,
6859 Thunk_IDirect3DDeviceImpl_2_SetCurrentViewport
,
6860 Thunk_IDirect3DDeviceImpl_2_GetCurrentViewport
,
6861 Thunk_IDirect3DDeviceImpl_2_SetRenderTarget
,
6862 Thunk_IDirect3DDeviceImpl_2_GetRenderTarget
,
6863 Thunk_IDirect3DDeviceImpl_2_Begin
,
6864 Thunk_IDirect3DDeviceImpl_2_BeginIndexed
,
6865 Thunk_IDirect3DDeviceImpl_2_Vertex
,
6866 Thunk_IDirect3DDeviceImpl_2_Index
,
6867 Thunk_IDirect3DDeviceImpl_2_End
,
6868 Thunk_IDirect3DDeviceImpl_2_GetRenderState
,
6869 Thunk_IDirect3DDeviceImpl_2_SetRenderState
,
6870 Thunk_IDirect3DDeviceImpl_2_GetLightState
,
6871 Thunk_IDirect3DDeviceImpl_2_SetLightState
,
6872 Thunk_IDirect3DDeviceImpl_2_SetTransform
,
6873 Thunk_IDirect3DDeviceImpl_2_GetTransform
,
6874 Thunk_IDirect3DDeviceImpl_2_MultiplyTransform
,
6875 Thunk_IDirect3DDeviceImpl_2_DrawPrimitive
,
6876 Thunk_IDirect3DDeviceImpl_2_DrawIndexedPrimitive
,
6877 Thunk_IDirect3DDeviceImpl_2_SetClipStatus
,
6878 Thunk_IDirect3DDeviceImpl_2_GetClipStatus
6881 static const struct IDirect3DDeviceVtbl d3d_device1_vtbl
=
6883 /*** IUnknown Methods ***/
6884 Thunk_IDirect3DDeviceImpl_1_QueryInterface
,
6885 Thunk_IDirect3DDeviceImpl_1_AddRef
,
6886 Thunk_IDirect3DDeviceImpl_1_Release
,
6887 /*** IDirect3DDevice1 ***/
6888 IDirect3DDeviceImpl_1_Initialize
,
6889 Thunk_IDirect3DDeviceImpl_1_GetCaps
,
6890 Thunk_IDirect3DDeviceImpl_1_SwapTextureHandles
,
6891 IDirect3DDeviceImpl_1_CreateExecuteBuffer
,
6892 Thunk_IDirect3DDeviceImpl_1_GetStats
,
6893 IDirect3DDeviceImpl_1_Execute
,
6894 Thunk_IDirect3DDeviceImpl_1_AddViewport
,
6895 Thunk_IDirect3DDeviceImpl_1_DeleteViewport
,
6896 Thunk_IDirect3DDeviceImpl_1_NextViewport
,
6897 IDirect3DDeviceImpl_1_Pick
,
6898 IDirect3DDeviceImpl_1_GetPickRecords
,
6899 Thunk_IDirect3DDeviceImpl_1_EnumTextureFormats
,
6900 IDirect3DDeviceImpl_1_CreateMatrix
,
6901 IDirect3DDeviceImpl_1_SetMatrix
,
6902 IDirect3DDeviceImpl_1_GetMatrix
,
6903 IDirect3DDeviceImpl_1_DeleteMatrix
,
6904 Thunk_IDirect3DDeviceImpl_1_BeginScene
,
6905 Thunk_IDirect3DDeviceImpl_1_EndScene
,
6906 Thunk_IDirect3DDeviceImpl_1_GetDirect3D
6909 /*****************************************************************************
6910 * IDirect3DDeviceImpl_UpdateDepthStencil
6912 * Checks the current render target for attached depth stencils and sets the
6913 * WineD3D depth stencil accordingly.
6916 * The depth stencil state to set if creating the device
6918 *****************************************************************************/
6920 IDirect3DDeviceImpl_UpdateDepthStencil(IDirect3DDeviceImpl
*This
)
6922 IDirectDrawSurface7
*depthStencil
= NULL
;
6923 IDirectDrawSurfaceImpl
*dsi
;
6924 static DDSCAPS2 depthcaps
= { DDSCAPS_ZBUFFER
, 0, 0, 0 };
6926 IDirectDrawSurface7_GetAttachedSurface((IDirectDrawSurface7
*)This
->target
, &depthcaps
, &depthStencil
);
6929 TRACE("Setting wined3d depth stencil to NULL\n");
6930 IWineD3DDevice_SetDepthStencilSurface(This
->wineD3DDevice
,
6932 return WINED3DZB_FALSE
;
6935 dsi
= (IDirectDrawSurfaceImpl
*)depthStencil
;
6936 TRACE("Setting wined3d depth stencil to %p (wined3d %p)\n", dsi
, dsi
->WineD3DSurface
);
6937 IWineD3DDevice_SetDepthStencilSurface(This
->wineD3DDevice
,
6938 dsi
->WineD3DSurface
);
6940 IDirectDrawSurface7_Release(depthStencil
);
6941 return WINED3DZB_TRUE
;
6944 HRESULT
d3d_device_init(IDirect3DDeviceImpl
*device
, IDirectDrawImpl
*ddraw
, IDirectDrawSurfaceImpl
*target
)
6946 IParentImpl
*index_buffer_parent
;
6949 if (ddraw
->cooperative_level
& DDSCL_FPUPRESERVE
)
6950 device
->lpVtbl
= &d3d_device7_fpu_preserve_vtbl
;
6952 device
->lpVtbl
= &d3d_device7_fpu_setup_vtbl
;
6954 device
->IDirect3DDevice3_vtbl
= &d3d_device3_vtbl
;
6955 device
->IDirect3DDevice2_vtbl
= &d3d_device2_vtbl
;
6956 device
->IDirect3DDevice_vtbl
= &d3d_device1_vtbl
;
6958 device
->ddraw
= ddraw
;
6959 device
->target
= target
;
6961 if (!ddraw_handle_table_init(&device
->handle_table
, 64))
6963 ERR("Failed to initialize handle table.\n");
6964 return DDERR_OUTOFMEMORY
;
6967 device
->legacyTextureBlending
= FALSE
;
6969 /* Create an index buffer, it's needed for indexed drawing */
6970 index_buffer_parent
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*index_buffer_parent
));
6971 if (!index_buffer_parent
)
6973 ERR("Failed to allocate index buffer parent memory.\n");
6974 ddraw_handle_table_destroy(&device
->handle_table
);
6975 return DDERR_OUTOFMEMORY
;
6978 ddraw_parent_init(index_buffer_parent
);
6980 hr
= IWineD3DDevice_CreateIndexBuffer(ddraw
->wineD3DDevice
, 0x40000 /* Length. Don't know how long it should be */,
6981 WINED3DUSAGE_DYNAMIC
/* Usage */, WINED3DPOOL_DEFAULT
, index_buffer_parent
,
6982 &ddraw_null_wined3d_parent_ops
, &device
->indexbuffer
);
6985 ERR("Failed to create an index buffer, hr %#x.\n", hr
);
6986 HeapFree(GetProcessHeap(), 0, index_buffer_parent
);
6987 ddraw_handle_table_destroy(&device
->handle_table
);
6990 index_buffer_parent
->child
= (IUnknown
*)device
->indexbuffer
;
6992 /* This is for convenience. */
6993 device
->wineD3DDevice
= ddraw
->wineD3DDevice
;
6994 IWineD3DDevice_AddRef(ddraw
->wineD3DDevice
);
6996 /* Render to the back buffer */
6997 hr
= IWineD3DDevice_SetRenderTarget(ddraw
->wineD3DDevice
, 0, target
->WineD3DSurface
, TRUE
);
7000 ERR("Failed to set render target, hr %#x.\n", hr
);
7001 IParent_Release((IParent
*)index_buffer_parent
);
7002 ddraw_handle_table_destroy(&device
->handle_table
);
7006 /* FIXME: This is broken. The target AddRef() makes some sense, because
7007 * we store a pointer during initialization, but then that's also where
7008 * the AddRef() should be. We don't store ddraw->d3d_target anywhere. */
7009 /* AddRef the render target. Also AddRef the render target from ddraw,
7010 * because if it is released before the app releases the D3D device, the
7011 * D3D capabilities of wined3d will be uninitialized, which has bad effects.
7013 * In most cases, those surfaces are the same anyway, but this will simply
7014 * add another ref which is released when the device is destroyed. */
7015 IDirectDrawSurface7_AddRef((IDirectDrawSurface7
*)target
);
7016 IDirectDrawSurface7_AddRef((IDirectDrawSurface7
*)ddraw
->d3d_target
);
7018 ddraw
->d3ddevice
= device
;
7020 IWineD3DDevice_SetRenderState(ddraw
->wineD3DDevice
, WINED3DRS_ZENABLE
,
7021 IDirect3DDeviceImpl_UpdateDepthStencil(device
));