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
) )
122 *obj
= &This
->ddraw
->IDirectDraw7_iface
;
123 TRACE("(%p) Returning IDirectDraw7 interface at %p\n", This
, *obj
);
125 else if ( IsEqualGUID( &IID_IDirectDraw4
, refiid
) )
127 *obj
= &This
->ddraw
->IDirectDraw4_iface
;
128 TRACE("(%p) Returning IDirectDraw4 interface at %p\n", This
, *obj
);
130 else if ( IsEqualGUID( &IID_IDirectDraw2
, refiid
) )
132 *obj
= &This
->ddraw
->IDirectDraw2_iface
;
133 TRACE("(%p) Returning IDirectDraw2 interface at %p\n", This
, *obj
);
135 else if( IsEqualGUID( &IID_IDirectDraw
, refiid
) )
137 *obj
= &This
->ddraw
->IDirectDraw_iface
;
138 TRACE("(%p) Returning IDirectDraw interface at %p\n", This
, *obj
);
142 else if ( IsEqualGUID( &IID_IDirect3D
, refiid
) )
144 *obj
= &This
->ddraw
->IDirect3D_iface
;
145 TRACE("(%p) Returning IDirect3D interface at %p\n", This
, *obj
);
147 else if ( IsEqualGUID( &IID_IDirect3D2
, refiid
) )
149 *obj
= &This
->ddraw
->IDirect3D2_iface
;
150 TRACE("(%p) Returning IDirect3D2 interface at %p\n", This
, *obj
);
152 else if ( IsEqualGUID( &IID_IDirect3D3
, refiid
) )
154 *obj
= &This
->ddraw
->IDirect3D3_iface
;
155 TRACE("(%p) Returning IDirect3D3 interface at %p\n", This
, *obj
);
157 else if ( IsEqualGUID( &IID_IDirect3D7
, refiid
) )
159 *obj
= &This
->ddraw
->IDirect3D7_iface
;
160 TRACE("(%p) Returning IDirect3D7 interface at %p\n", This
, *obj
);
164 else if ( IsEqualGUID( &IID_IDirect3DDevice
, refiid
) )
166 *obj
= &This
->IDirect3DDevice_vtbl
;
167 TRACE("(%p) Returning IDirect3DDevice interface at %p\n", This
, *obj
);
169 else if ( IsEqualGUID( &IID_IDirect3DDevice2
, refiid
) ) {
170 *obj
= &This
->IDirect3DDevice2_vtbl
;
171 TRACE("(%p) Returning IDirect3DDevice2 interface at %p\n", This
, *obj
);
173 else if ( IsEqualGUID( &IID_IDirect3DDevice3
, refiid
) ) {
174 *obj
= &This
->IDirect3DDevice3_vtbl
;
175 TRACE("(%p) Returning IDirect3DDevice3 interface at %p\n", This
, *obj
);
177 else if ( IsEqualGUID( &IID_IDirect3DDevice7
, refiid
) ) {
179 TRACE("(%p) Returning IDirect3DDevice7 interface at %p\n", This
, *obj
);
182 /* Unknown interface */
185 ERR("(%p)->(%s, %p): No interface found\n", This
, debugstr_guid(refiid
), obj
);
186 return E_NOINTERFACE
;
189 /* AddRef the returned interface */
190 IUnknown_AddRef( (IUnknown
*) *obj
);
194 static HRESULT WINAPI
IDirect3DDeviceImpl_3_QueryInterface(IDirect3DDevice3
*iface
, REFIID riid
,
197 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), obj
);
199 return IDirect3DDevice7_QueryInterface((IDirect3DDevice7
*)device_from_device3(iface
), riid
, obj
);
202 static HRESULT WINAPI
IDirect3DDeviceImpl_2_QueryInterface(IDirect3DDevice2
*iface
, REFIID riid
,
205 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), obj
);
207 return IDirect3DDevice7_QueryInterface((IDirect3DDevice7
*)device_from_device2(iface
), riid
, obj
);
210 static HRESULT WINAPI
IDirect3DDeviceImpl_1_QueryInterface(IDirect3DDevice
*iface
, REFIID riid
,
213 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), obp
);
215 return IDirect3DDevice7_QueryInterface((IDirect3DDevice7
*)device_from_device1(iface
), riid
, obp
);
218 /*****************************************************************************
219 * IDirect3DDevice7::AddRef
221 * Increases the refcount....
222 * The most exciting Method, definitely
224 * Exists in Version 1, 2, 3 and 7
229 *****************************************************************************/
231 IDirect3DDeviceImpl_7_AddRef(IDirect3DDevice7
*iface
)
233 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
234 ULONG ref
= InterlockedIncrement(&This
->ref
);
236 TRACE("%p increasing refcount to %u.\n", This
, ref
);
241 static ULONG WINAPI
IDirect3DDeviceImpl_3_AddRef(IDirect3DDevice3
*iface
)
243 TRACE("iface %p.\n", iface
);
245 return IDirect3DDevice7_AddRef((IDirect3DDevice7
*)device_from_device3(iface
));
248 static ULONG WINAPI
IDirect3DDeviceImpl_2_AddRef(IDirect3DDevice2
*iface
)
250 TRACE("iface %p.\n", iface
);
252 return IDirect3DDevice7_AddRef((IDirect3DDevice7
*)device_from_device2(iface
));
255 static ULONG WINAPI
IDirect3DDeviceImpl_1_AddRef(IDirect3DDevice
*iface
)
257 TRACE("iface %p.\n", iface
);
259 return IDirect3DDevice7_AddRef((IDirect3DDevice7
*)device_from_device1(iface
));
262 /*****************************************************************************
263 * IDirect3DDevice7::Release
265 * Decreases the refcount of the interface
266 * When the refcount is reduced to 0, the object is destroyed.
268 * Exists in Version 1, 2, 3 and 7
273 *****************************************************************************/
275 IDirect3DDeviceImpl_7_Release(IDirect3DDevice7
*iface
)
277 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
278 ULONG ref
= InterlockedDecrement(&This
->ref
);
280 TRACE("%p decreasing refcount to %u.\n", This
, ref
);
282 /* This method doesn't destroy the WineD3DDevice, because it's still in use for
283 * 2D rendering. IDirectDrawSurface7::Release will destroy the WineD3DDevice
284 * when the render target is released
288 IParent
*IndexBufferParent
;
291 EnterCriticalSection(&ddraw_cs
);
292 /* Free the index buffer. */
293 IWineD3DDevice_SetIndexBuffer(This
->wineD3DDevice
, NULL
, WINED3DFMT_UNKNOWN
);
294 IndexBufferParent
= IWineD3DBuffer_GetParent(This
->indexbuffer
);
295 if (IParent_Release(IndexBufferParent
))
297 ERR(" (%p) Something is still holding the index buffer parent %p\n", This
, IndexBufferParent
);
300 /* There is no need to unset the vertex buffer here, IWineD3DDevice_Uninit3D will do that when
301 * destroying the primary stateblock. If a vertex buffer is destroyed while it is bound
302 * IDirect3DVertexBuffer::Release will unset it.
305 /* Set the device up to render to the front buffer since the back
306 * buffer will vanish soon. */
307 IWineD3DDevice_SetRenderTarget(This
->wineD3DDevice
, 0,
308 This
->ddraw
->d3d_target
->WineD3DSurface
, TRUE
);
310 /* Release the WineD3DDevice. This won't destroy it */
311 if(IWineD3DDevice_Release(This
->wineD3DDevice
) <= 0)
313 ERR(" (%p) The wineD3D device %p was destroyed unexpectedly. Prepare for trouble\n", This
, This
->wineD3DDevice
);
316 /* The texture handles should be unset by now, but there might be some bits
317 * missing in our reference counting(needs test). Do a sanity check. */
318 for (i
= 0; i
< This
->handle_table
.entry_count
; ++i
)
320 struct ddraw_handle_entry
*entry
= &This
->handle_table
.entries
[i
];
324 case DDRAW_HANDLE_FREE
:
327 case DDRAW_HANDLE_MATERIAL
:
329 IDirect3DMaterialImpl
*m
= entry
->object
;
330 FIXME("Material handle %#x (%p) not unset properly.\n", i
+ 1, m
);
335 case DDRAW_HANDLE_MATRIX
:
337 /* No FIXME here because this might happen because of sloppy applications. */
338 WARN("Leftover matrix handle %#x (%p), deleting.\n", i
+ 1, entry
->object
);
339 IDirect3DDevice_DeleteMatrix((IDirect3DDevice
*)&This
->IDirect3DDevice_vtbl
, i
+ 1);
343 case DDRAW_HANDLE_STATEBLOCK
:
345 /* No FIXME here because this might happen because of sloppy applications. */
346 WARN("Leftover stateblock handle %#x (%p), deleting.\n", i
+ 1, entry
->object
);
347 IDirect3DDevice7_DeleteStateBlock(iface
, i
+ 1);
351 case DDRAW_HANDLE_SURFACE
:
353 IDirectDrawSurfaceImpl
*surf
= entry
->object
;
354 FIXME("Texture handle %#x (%p) not unset properly.\n", i
+ 1, surf
);
360 FIXME("Handle %#x (%p) has unknown type %#x.\n", i
+ 1, entry
->object
, entry
->type
);
365 ddraw_handle_table_destroy(&This
->handle_table
);
367 TRACE("Releasing target %p %p\n", This
->target
, This
->ddraw
->d3d_target
);
368 /* Release the render target and the WineD3D render target
369 * (See IDirect3D7::CreateDevice for more comments on this)
371 IDirectDrawSurface7_Release((IDirectDrawSurface7
*)This
->target
);
372 IDirectDrawSurface7_Release((IDirectDrawSurface7
*)This
->ddraw
->d3d_target
);
373 TRACE("Target release done\n");
375 This
->ddraw
->d3ddevice
= NULL
;
377 /* Now free the structure */
378 HeapFree(GetProcessHeap(), 0, This
);
379 LeaveCriticalSection(&ddraw_cs
);
386 static ULONG WINAPI
IDirect3DDeviceImpl_3_Release(IDirect3DDevice3
*iface
)
388 TRACE("iface %p.\n", iface
);
390 return IDirect3DDevice7_Release((IDirect3DDevice7
*)device_from_device3(iface
));
393 static ULONG WINAPI
IDirect3DDeviceImpl_2_Release(IDirect3DDevice2
*iface
)
395 TRACE("iface %p.\n", iface
);
397 return IDirect3DDevice7_Release((IDirect3DDevice7
*)device_from_device2(iface
));
400 static ULONG WINAPI
IDirect3DDeviceImpl_1_Release(IDirect3DDevice
*iface
)
402 TRACE("iface %p.\n", iface
);
404 return IDirect3DDevice7_Release((IDirect3DDevice7
*)device_from_device1(iface
));
407 /*****************************************************************************
408 * IDirect3DDevice Methods
409 *****************************************************************************/
411 /*****************************************************************************
412 * IDirect3DDevice::Initialize
414 * Initializes a Direct3DDevice. This implementation is a no-op, as all
415 * initialization is done at create time.
417 * Exists in Version 1
420 * No idea what they mean, as the MSDN page is gone
424 *****************************************************************************/
425 static HRESULT WINAPI
426 IDirect3DDeviceImpl_1_Initialize(IDirect3DDevice
*iface
,
427 IDirect3D
*Direct3D
, GUID
*guid
,
430 /* It shouldn't be crucial, but print a FIXME, I'm interested if
431 * any game calls it and when. */
432 FIXME("iface %p, d3d %p, guid %s, device_desc %p nop!\n",
433 iface
, Direct3D
, debugstr_guid(guid
), Desc
);
438 /*****************************************************************************
439 * IDirect3DDevice7::GetCaps
441 * Retrieves the device's capabilities
443 * This implementation is used for Version 7 only, the older versions have
444 * their own implementation.
447 * Desc: Pointer to a D3DDEVICEDESC7 structure to fill
451 * D3DERR_* if a problem occurs. See WineD3D
453 *****************************************************************************/
455 IDirect3DDeviceImpl_7_GetCaps(IDirect3DDevice7
*iface
,
456 D3DDEVICEDESC7
*Desc
)
458 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
459 D3DDEVICEDESC OldDesc
;
461 TRACE("iface %p, device_desc %p.\n", iface
, Desc
);
463 /* Call the same function used by IDirect3D, this saves code */
464 return IDirect3DImpl_GetCaps(This
->ddraw
->wineD3D
, &OldDesc
, Desc
);
467 static HRESULT WINAPI
468 IDirect3DDeviceImpl_7_GetCaps_FPUSetup(IDirect3DDevice7
*iface
,
469 D3DDEVICEDESC7
*Desc
)
471 return IDirect3DDeviceImpl_7_GetCaps(iface
, Desc
);
474 static HRESULT WINAPI
475 IDirect3DDeviceImpl_7_GetCaps_FPUPreserve(IDirect3DDevice7
*iface
,
476 D3DDEVICEDESC7
*Desc
)
481 old_fpucw
= d3d_fpu_setup();
482 hr
= IDirect3DDeviceImpl_7_GetCaps(iface
, Desc
);
483 set_fpu_control_word(old_fpucw
);
487 /*****************************************************************************
488 * IDirect3DDevice3::GetCaps
490 * Retrieves the capabilities of the hardware device and the emulation
491 * device. For Wine, hardware and emulation are the same (it's all HW).
493 * This implementation is used for Version 1, 2, and 3. Version 7 has its own
496 * HWDesc: Structure to fill with the HW caps
497 * HelDesc: Structure to fill with the hardware emulation caps
501 * D3DERR_* if a problem occurs. See WineD3D
503 *****************************************************************************/
504 static HRESULT WINAPI
505 IDirect3DDeviceImpl_3_GetCaps(IDirect3DDevice3
*iface
,
506 D3DDEVICEDESC
*HWDesc
,
507 D3DDEVICEDESC
*HelDesc
)
509 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
510 D3DDEVICEDESC7 newDesc
;
513 TRACE("iface %p, hw_desc %p, hel_desc %p.\n", iface
, HWDesc
, HelDesc
);
515 hr
= IDirect3DImpl_GetCaps(This
->ddraw
->wineD3D
, HWDesc
, &newDesc
);
516 if(hr
!= D3D_OK
) return hr
;
522 static HRESULT WINAPI
IDirect3DDeviceImpl_2_GetCaps(IDirect3DDevice2
*iface
,
523 D3DDEVICEDESC
*D3DHWDevDesc
, D3DDEVICEDESC
*D3DHELDevDesc
)
525 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
526 TRACE("iface %p, hw_desc %p, hel_desc %p.\n", iface
, D3DHWDevDesc
, D3DHELDevDesc
);
527 return IDirect3DDevice3_GetCaps((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
, D3DHWDevDesc
, D3DHELDevDesc
);
530 static HRESULT WINAPI
IDirect3DDeviceImpl_1_GetCaps(IDirect3DDevice
*iface
,
531 D3DDEVICEDESC
*D3DHWDevDesc
, D3DDEVICEDESC
*D3DHELDevDesc
)
533 IDirect3DDeviceImpl
*This
= device_from_device1(iface
);
534 TRACE("iface %p, hw_desc %p, hel_desc %p.\n", iface
, D3DHWDevDesc
, D3DHELDevDesc
);
535 return IDirect3DDevice3_GetCaps((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
, D3DHWDevDesc
, D3DHELDevDesc
);
538 /*****************************************************************************
539 * IDirect3DDevice2::SwapTextureHandles
541 * Swaps the texture handles of 2 Texture interfaces. Version 1 and 2
544 * Tex1, Tex2: The 2 Textures to swap
549 *****************************************************************************/
550 static HRESULT WINAPI
551 IDirect3DDeviceImpl_2_SwapTextureHandles(IDirect3DDevice2
*iface
,
552 IDirect3DTexture2
*Tex1
,
553 IDirect3DTexture2
*Tex2
)
555 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
556 IDirectDrawSurfaceImpl
*surf1
= surface_from_texture2(Tex1
);
557 IDirectDrawSurfaceImpl
*surf2
= surface_from_texture2(Tex2
);
560 TRACE("iface %p, tex1 %p, tex2 %p.\n", iface
, Tex1
, Tex2
);
562 EnterCriticalSection(&ddraw_cs
);
564 h1
= surf1
->Handle
- 1;
565 h2
= surf2
->Handle
- 1;
566 This
->handle_table
.entries
[h1
].object
= surf2
;
567 This
->handle_table
.entries
[h2
].object
= surf1
;
568 surf2
->Handle
= h1
+ 1;
569 surf1
->Handle
= h2
+ 1;
571 LeaveCriticalSection(&ddraw_cs
);
576 static HRESULT WINAPI
IDirect3DDeviceImpl_1_SwapTextureHandles(IDirect3DDevice
*iface
,
577 IDirect3DTexture
*D3DTex1
, IDirect3DTexture
*D3DTex2
)
579 IDirect3DDeviceImpl
*This
= device_from_device1(iface
);
580 IDirectDrawSurfaceImpl
*surf1
= surface_from_texture1(D3DTex1
);
581 IDirectDrawSurfaceImpl
*surf2
= surface_from_texture1(D3DTex2
);
582 IDirect3DTexture2
*t1
= surf1
? (IDirect3DTexture2
*)&surf1
->IDirect3DTexture2_vtbl
: NULL
;
583 IDirect3DTexture2
*t2
= surf2
? (IDirect3DTexture2
*)&surf2
->IDirect3DTexture2_vtbl
: NULL
;
585 TRACE("iface %p, tex1 %p, tex2 %p.\n", iface
, D3DTex1
, D3DTex2
);
587 return IDirect3DDevice2_SwapTextureHandles((IDirect3DDevice2
*)&This
->IDirect3DDevice2_vtbl
, t1
, t2
);
590 /*****************************************************************************
591 * IDirect3DDevice3::GetStats
593 * This method seems to retrieve some stats from the device.
594 * The MSDN documentation doesn't exist any more, but the D3DSTATS
595 * structure suggests that the amount of drawn primitives and processed
596 * vertices is returned.
598 * Exists in Version 1, 2 and 3
601 * Stats: Pointer to a D3DSTATS structure to be filled
605 * DDERR_INVALIDPARAMS if Stats == NULL
607 *****************************************************************************/
608 static HRESULT WINAPI
609 IDirect3DDeviceImpl_3_GetStats(IDirect3DDevice3
*iface
,
612 FIXME("iface %p, stats %p stub!\n", iface
, Stats
);
615 return DDERR_INVALIDPARAMS
;
617 /* Fill the Stats with 0 */
618 Stats
->dwTrianglesDrawn
= 0;
619 Stats
->dwLinesDrawn
= 0;
620 Stats
->dwPointsDrawn
= 0;
621 Stats
->dwSpansDrawn
= 0;
622 Stats
->dwVerticesProcessed
= 0;
627 static HRESULT WINAPI
IDirect3DDeviceImpl_2_GetStats(IDirect3DDevice2
*iface
, D3DSTATS
*Stats
)
629 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
631 TRACE("iface %p, stats %p.\n", iface
, Stats
);
633 return IDirect3DDevice3_GetStats((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
, Stats
);
636 static HRESULT WINAPI
IDirect3DDeviceImpl_1_GetStats(IDirect3DDevice
*iface
, D3DSTATS
*Stats
)
638 IDirect3DDeviceImpl
*This
= device_from_device1(iface
);
640 TRACE("iface %p, stats %p.\n", iface
, Stats
);
642 return IDirect3DDevice3_GetStats((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
, Stats
);
645 /*****************************************************************************
646 * IDirect3DDevice::CreateExecuteBuffer
648 * Creates an IDirect3DExecuteBuffer, used for rendering with a
654 * Desc: Buffer description
655 * ExecuteBuffer: Address to return the Interface pointer at
656 * UnkOuter: Must be NULL. Basically for aggregation, which ddraw doesn't
660 * CLASS_E_NOAGGREGATION if UnkOuter != NULL
661 * DDERR_OUTOFMEMORY if we ran out of memory
664 *****************************************************************************/
665 static HRESULT WINAPI
666 IDirect3DDeviceImpl_1_CreateExecuteBuffer(IDirect3DDevice
*iface
,
667 D3DEXECUTEBUFFERDESC
*Desc
,
668 IDirect3DExecuteBuffer
**ExecuteBuffer
,
671 IDirect3DDeviceImpl
*This
= device_from_device1(iface
);
672 IDirect3DExecuteBufferImpl
* object
;
675 TRACE("iface %p, buffer_desc %p, buffer %p, outer_unknown %p.\n",
676 iface
, Desc
, ExecuteBuffer
, UnkOuter
);
679 return CLASS_E_NOAGGREGATION
;
681 /* Allocate the new Execute Buffer */
682 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirect3DExecuteBufferImpl
));
685 ERR("Out of memory when allocating a IDirect3DExecuteBufferImpl structure\n");
686 return DDERR_OUTOFMEMORY
;
689 hr
= d3d_execute_buffer_init(object
, This
, Desc
);
692 WARN("Failed to initialize execute buffer, hr %#x.\n", hr
);
693 HeapFree(GetProcessHeap(), 0, object
);
697 *ExecuteBuffer
= (IDirect3DExecuteBuffer
*)object
;
699 TRACE(" Returning IDirect3DExecuteBuffer at %p, implementation is at %p\n", *ExecuteBuffer
, object
);
704 /*****************************************************************************
705 * IDirect3DDevice::Execute
707 * Executes all the stuff in an execute buffer.
710 * ExecuteBuffer: The buffer to execute
711 * Viewport: The viewport used for rendering
715 * DDERR_INVALIDPARAMS if ExecuteBuffer == NULL
718 *****************************************************************************/
719 static HRESULT WINAPI
720 IDirect3DDeviceImpl_1_Execute(IDirect3DDevice
*iface
,
721 IDirect3DExecuteBuffer
*ExecuteBuffer
,
722 IDirect3DViewport
*Viewport
,
725 IDirect3DDeviceImpl
*This
= device_from_device1(iface
);
726 IDirect3DExecuteBufferImpl
*Direct3DExecuteBufferImpl
= (IDirect3DExecuteBufferImpl
*)ExecuteBuffer
;
727 IDirect3DViewportImpl
*Direct3DViewportImpl
= (IDirect3DViewportImpl
*)Viewport
;
729 TRACE("iface %p, buffer %p, viewport %p, flags %#x.\n", iface
, ExecuteBuffer
, Viewport
, Flags
);
731 if(!Direct3DExecuteBufferImpl
)
732 return DDERR_INVALIDPARAMS
;
735 EnterCriticalSection(&ddraw_cs
);
736 IDirect3DExecuteBufferImpl_Execute(Direct3DExecuteBufferImpl
, This
, Direct3DViewportImpl
);
737 LeaveCriticalSection(&ddraw_cs
);
742 /*****************************************************************************
743 * IDirect3DDevice3::AddViewport
745 * Add a Direct3DViewport to the device's viewport list. These viewports
746 * are wrapped to IDirect3DDevice7 viewports in viewport.c
748 * Exists in Version 1, 2 and 3. Note that IDirect3DViewport 1, 2 and 3
749 * are the same interfaces.
752 * Viewport: The viewport to add
755 * DDERR_INVALIDPARAMS if Viewport == NULL
758 *****************************************************************************/
759 static HRESULT WINAPI
760 IDirect3DDeviceImpl_3_AddViewport(IDirect3DDevice3
*iface
,
761 IDirect3DViewport3
*Viewport
)
763 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
764 IDirect3DViewportImpl
*vp
= (IDirect3DViewportImpl
*)Viewport
;
766 TRACE("iface %p, viewport %p.\n", iface
, Viewport
);
770 return DDERR_INVALIDPARAMS
;
772 EnterCriticalSection(&ddraw_cs
);
773 vp
->next
= This
->viewport_list
;
774 This
->viewport_list
= vp
;
775 vp
->active_device
= This
; /* Viewport must be usable for Clear() after AddViewport,
776 so set active_device here. */
777 LeaveCriticalSection(&ddraw_cs
);
782 static HRESULT WINAPI
IDirect3DDeviceImpl_2_AddViewport(IDirect3DDevice2
*iface
,
783 IDirect3DViewport2
*Direct3DViewport2
)
785 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
786 IDirect3DViewportImpl
*vp
= (IDirect3DViewportImpl
*)Direct3DViewport2
;
788 TRACE("iface %p, viewport %p.\n", iface
, Direct3DViewport2
);
790 return IDirect3DDevice3_AddViewport((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
, (IDirect3DViewport3
*)vp
);
793 static HRESULT WINAPI
IDirect3DDeviceImpl_1_AddViewport(IDirect3DDevice
*iface
,
794 IDirect3DViewport
*Direct3DViewport
)
796 IDirect3DDeviceImpl
*This
= device_from_device1(iface
);
797 IDirect3DViewportImpl
*vp
= (IDirect3DViewportImpl
*)Direct3DViewport
;
799 TRACE("iface %p, viewport %p.\n", iface
, Direct3DViewport
);
801 return IDirect3DDevice3_AddViewport((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
, (IDirect3DViewport3
*)vp
);
804 /*****************************************************************************
805 * IDirect3DDevice3::DeleteViewport
807 * Deletes a Direct3DViewport from the device's viewport list.
809 * Exists in Version 1, 2 and 3. Note that all Viewport interface versions
813 * Viewport: The viewport to delete
817 * DDERR_INVALIDPARAMS if the viewport wasn't found in the list
819 *****************************************************************************/
820 static HRESULT WINAPI
821 IDirect3DDeviceImpl_3_DeleteViewport(IDirect3DDevice3
*iface
,
822 IDirect3DViewport3
*Viewport
)
824 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
825 IDirect3DViewportImpl
*vp
= (IDirect3DViewportImpl
*) Viewport
;
826 IDirect3DViewportImpl
*cur_viewport
, *prev_viewport
= NULL
;
828 TRACE("iface %p, viewport %p.\n", iface
, Viewport
);
830 EnterCriticalSection(&ddraw_cs
);
831 cur_viewport
= This
->viewport_list
;
832 while (cur_viewport
!= NULL
)
834 if (cur_viewport
== vp
)
836 if (prev_viewport
== NULL
) This
->viewport_list
= cur_viewport
->next
;
837 else prev_viewport
->next
= cur_viewport
->next
;
838 /* TODO : add desactivate of the viewport and all associated lights... */
839 LeaveCriticalSection(&ddraw_cs
);
842 prev_viewport
= cur_viewport
;
843 cur_viewport
= cur_viewport
->next
;
846 LeaveCriticalSection(&ddraw_cs
);
847 return DDERR_INVALIDPARAMS
;
850 static HRESULT WINAPI
IDirect3DDeviceImpl_2_DeleteViewport(IDirect3DDevice2
*iface
,
851 IDirect3DViewport2
*Direct3DViewport2
)
853 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
854 IDirect3DViewportImpl
*vp
= (IDirect3DViewportImpl
*)Direct3DViewport2
;
856 TRACE("iface %p, viewport %p.\n", iface
, Direct3DViewport2
);
858 return IDirect3DDevice3_DeleteViewport((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
, (IDirect3DViewport3
*)vp
);
861 static HRESULT WINAPI
IDirect3DDeviceImpl_1_DeleteViewport(IDirect3DDevice
*iface
,
862 IDirect3DViewport
*Direct3DViewport
)
864 IDirect3DDeviceImpl
*This
= device_from_device1(iface
);
865 IDirect3DViewportImpl
*vp
= (IDirect3DViewportImpl
*)Direct3DViewport
;
867 TRACE("iface %p, viewport %p.\n", iface
, Direct3DViewport
);
869 return IDirect3DDevice3_DeleteViewport((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
, (IDirect3DViewport3
*)vp
);
872 /*****************************************************************************
873 * IDirect3DDevice3::NextViewport
875 * Returns a viewport from the viewport list, depending on the
876 * passed viewport and the flags.
878 * Exists in Version 1, 2 and 3. Note that all Viewport interface versions
882 * Viewport: Viewport to use for beginning the search
883 * Flags: D3DNEXT_NEXT, D3DNEXT_HEAD or D3DNEXT_TAIL
887 * DDERR_INVALIDPARAMS if the flags were wrong, or Viewport was NULL
889 *****************************************************************************/
890 static HRESULT WINAPI
891 IDirect3DDeviceImpl_3_NextViewport(IDirect3DDevice3
*iface
,
892 IDirect3DViewport3
*Viewport3
,
893 IDirect3DViewport3
**lplpDirect3DViewport3
,
896 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
897 IDirect3DViewportImpl
*vp
= (IDirect3DViewportImpl
*)Viewport3
;
898 IDirect3DViewportImpl
*res
= NULL
;
900 TRACE("iface %p, viewport %p, next %p, flags %#x.\n",
901 iface
, Viewport3
, lplpDirect3DViewport3
, Flags
);
905 *lplpDirect3DViewport3
= NULL
;
906 return DDERR_INVALIDPARAMS
;
910 EnterCriticalSection(&ddraw_cs
);
920 res
= This
->viewport_list
;
925 IDirect3DViewportImpl
*cur_viewport
= This
->viewport_list
;
926 if (cur_viewport
!= NULL
)
928 while (cur_viewport
->next
!= NULL
) cur_viewport
= cur_viewport
->next
;
934 *lplpDirect3DViewport3
= NULL
;
935 LeaveCriticalSection(&ddraw_cs
);
936 return DDERR_INVALIDPARAMS
;
939 *lplpDirect3DViewport3
= (IDirect3DViewport3
*)res
;
940 LeaveCriticalSection(&ddraw_cs
);
944 static HRESULT WINAPI
IDirect3DDeviceImpl_2_NextViewport(IDirect3DDevice2
*iface
,
945 IDirect3DViewport2
*Viewport2
, IDirect3DViewport2
**lplpDirect3DViewport2
, DWORD Flags
)
947 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
948 IDirect3DViewportImpl
*vp
= (IDirect3DViewportImpl
*)Viewport2
;
949 IDirect3DViewport3
*res
;
952 TRACE("iface %p, viewport %p, next %p, flags %#x.\n",
953 iface
, Viewport2
, lplpDirect3DViewport2
, Flags
);
955 hr
= IDirect3DDevice3_NextViewport((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
,
956 (IDirect3DViewport3
*)vp
, &res
, Flags
);
957 *lplpDirect3DViewport2
= (IDirect3DViewport2
*)res
;
961 static HRESULT WINAPI
IDirect3DDeviceImpl_1_NextViewport(IDirect3DDevice
*iface
,
962 IDirect3DViewport
*Viewport
, IDirect3DViewport
**lplpDirect3DViewport
, DWORD Flags
)
964 IDirect3DDeviceImpl
*This
= device_from_device1(iface
);
965 IDirect3DViewportImpl
*vp
= (IDirect3DViewportImpl
*)Viewport
;
966 IDirect3DViewport3
*res
;
969 TRACE("iface %p, viewport %p, next %p, flags %#x.\n",
970 iface
, Viewport
, lplpDirect3DViewport
, Flags
);
972 hr
= IDirect3DDevice3_NextViewport((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
,
973 (IDirect3DViewport3
*)vp
, &res
, Flags
);
974 *lplpDirect3DViewport
= (IDirect3DViewport
*)res
;
978 /*****************************************************************************
979 * IDirect3DDevice::Pick
981 * Executes an execute buffer without performing rendering. Instead, a
982 * list of primitives that intersect with (x1,y1) of the passed rectangle
983 * is created. IDirect3DDevice::GetPickRecords can be used to retrieve
989 * ExecuteBuffer: Buffer to execute
990 * Viewport: Viewport to use for execution
991 * Flags: None are defined, according to the SDK
992 * Rect: Specifies the coordinates to be picked. Only x1 and y2 are used,
993 * x2 and y2 are ignored.
996 * D3D_OK because it's a stub
998 *****************************************************************************/
999 static HRESULT WINAPI
1000 IDirect3DDeviceImpl_1_Pick(IDirect3DDevice
*iface
,
1001 IDirect3DExecuteBuffer
*ExecuteBuffer
,
1002 IDirect3DViewport
*Viewport
,
1006 FIXME("iface %p, buffer %p, viewport %p, flags %#x, rect %s stub!\n",
1007 iface
, ExecuteBuffer
, Viewport
, Flags
, wine_dbgstr_rect((RECT
*)Rect
));
1012 /*****************************************************************************
1013 * IDirect3DDevice::GetPickRecords
1015 * Retrieves the pick records generated by IDirect3DDevice::GetPickRecords
1020 * Count: Pointer to a DWORD containing the numbers of pick records to
1022 * D3DPickRec: Address to store the resulting D3DPICKRECORD array.
1025 * D3D_OK, because it's a stub
1027 *****************************************************************************/
1028 static HRESULT WINAPI
1029 IDirect3DDeviceImpl_1_GetPickRecords(IDirect3DDevice
*iface
,
1031 D3DPICKRECORD
*D3DPickRec
)
1033 FIXME("iface %p, count %p, records %p stub!\n", iface
, Count
, D3DPickRec
);
1038 /*****************************************************************************
1039 * IDirect3DDevice7::EnumTextureformats
1041 * Enumerates the supported texture formats. It has a list of all possible
1042 * formats and calls IWineD3D::CheckDeviceFormat for each format to see if
1043 * WineD3D supports it. If so, then it is passed to the app.
1045 * This is for Version 7 and 3, older versions have a different
1046 * callback function and their own implementation
1049 * Callback: Callback to call for each enumerated format
1050 * Arg: Argument to pass to the callback
1054 * DDERR_INVALIDPARAMS if Callback == NULL
1056 *****************************************************************************/
1058 IDirect3DDeviceImpl_7_EnumTextureFormats(IDirect3DDevice7
*iface
,
1059 LPD3DENUMPIXELFORMATSCALLBACK Callback
,
1062 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
1064 WINED3DDISPLAYMODE mode
;
1067 static const enum wined3d_format_id FormatList
[] =
1070 WINED3DFMT_B8G8R8A8_UNORM
,
1071 WINED3DFMT_B8G8R8X8_UNORM
,
1073 WINED3DFMT_B8G8R8_UNORM
,
1075 WINED3DFMT_B5G5R5A1_UNORM
,
1076 WINED3DFMT_B4G4R4A4_UNORM
,
1077 WINED3DFMT_B5G6R5_UNORM
,
1078 WINED3DFMT_B5G5R5X1_UNORM
,
1080 WINED3DFMT_B2G3R3_UNORM
,
1088 static const enum wined3d_format_id BumpFormatList
[] =
1090 WINED3DFMT_R8G8_SNORM
,
1091 WINED3DFMT_R5G5_SNORM_L6_UNORM
,
1092 WINED3DFMT_R8G8_SNORM_L8X8_UNORM
,
1093 WINED3DFMT_R16G16_SNORM
,
1094 WINED3DFMT_R10G11B11_SNORM
,
1095 WINED3DFMT_R10G10B10_SNORM_A2_UNORM
1098 TRACE("iface %p, callback %p, context %p.\n", iface
, Callback
, Arg
);
1101 return DDERR_INVALIDPARAMS
;
1103 EnterCriticalSection(&ddraw_cs
);
1105 memset(&mode
, 0, sizeof(mode
));
1106 hr
= IWineD3DDevice_GetDisplayMode(This
->ddraw
->wineD3DDevice
,
1110 LeaveCriticalSection(&ddraw_cs
);
1111 WARN("Cannot get the current adapter format\n");
1115 for (i
= 0; i
< sizeof(FormatList
) / sizeof(*FormatList
); ++i
)
1117 hr
= wined3d_check_device_format(This
->ddraw
->wineD3D
, WINED3DADAPTER_DEFAULT
, WINED3DDEVTYPE_HAL
,
1118 mode
.Format
, 0, WINED3DRTYPE_TEXTURE
, FormatList
[i
], SURFACE_OPENGL
);
1121 DDPIXELFORMAT pformat
;
1123 memset(&pformat
, 0, sizeof(pformat
));
1124 pformat
.dwSize
= sizeof(pformat
);
1125 PixelFormat_WineD3DtoDD(&pformat
, FormatList
[i
]);
1127 TRACE("Enumerating WineD3DFormat %d\n", FormatList
[i
]);
1128 hr
= Callback(&pformat
, Arg
);
1129 if(hr
!= DDENUMRET_OK
)
1131 TRACE("Format enumeration cancelled by application\n");
1132 LeaveCriticalSection(&ddraw_cs
);
1138 for (i
= 0; i
< sizeof(BumpFormatList
) / sizeof(*BumpFormatList
); ++i
)
1140 hr
= wined3d_check_device_format(This
->ddraw
->wineD3D
, WINED3DADAPTER_DEFAULT
,
1141 WINED3DDEVTYPE_HAL
, mode
.Format
, WINED3DUSAGE_QUERY_LEGACYBUMPMAP
,
1142 WINED3DRTYPE_TEXTURE
, BumpFormatList
[i
], SURFACE_OPENGL
);
1145 DDPIXELFORMAT pformat
;
1147 memset(&pformat
, 0, sizeof(pformat
));
1148 pformat
.dwSize
= sizeof(pformat
);
1149 PixelFormat_WineD3DtoDD(&pformat
, BumpFormatList
[i
]);
1151 TRACE("Enumerating WineD3DFormat %d\n", BumpFormatList
[i
]);
1152 hr
= Callback(&pformat
, Arg
);
1153 if(hr
!= DDENUMRET_OK
)
1155 TRACE("Format enumeration cancelled by application\n");
1156 LeaveCriticalSection(&ddraw_cs
);
1161 TRACE("End of enumeration\n");
1162 LeaveCriticalSection(&ddraw_cs
);
1166 static HRESULT WINAPI
1167 IDirect3DDeviceImpl_7_EnumTextureFormats_FPUSetup(IDirect3DDevice7
*iface
,
1168 LPD3DENUMPIXELFORMATSCALLBACK Callback
,
1171 return IDirect3DDeviceImpl_7_EnumTextureFormats(iface
, Callback
, Arg
);
1174 static HRESULT WINAPI
1175 IDirect3DDeviceImpl_7_EnumTextureFormats_FPUPreserve(IDirect3DDevice7
*iface
,
1176 LPD3DENUMPIXELFORMATSCALLBACK Callback
,
1182 old_fpucw
= d3d_fpu_setup();
1183 hr
= IDirect3DDeviceImpl_7_EnumTextureFormats(iface
, Callback
, Arg
);
1184 set_fpu_control_word(old_fpucw
);
1189 static HRESULT WINAPI
IDirect3DDeviceImpl_3_EnumTextureFormats(IDirect3DDevice3
*iface
,
1190 LPD3DENUMPIXELFORMATSCALLBACK Callback
, void *Arg
)
1192 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
1194 TRACE("iface %p, callback %p, context %p.\n", iface
, Callback
, Arg
);
1196 return IDirect3DDevice7_EnumTextureFormats((IDirect3DDevice7
*)This
, Callback
, Arg
);
1199 /*****************************************************************************
1200 * IDirect3DDevice2::EnumTextureformats
1202 * EnumTextureFormats for Version 1 and 2, see
1203 * IDirect3DDevice7::EnumTexureFormats for a more detailed description.
1205 * This version has a different callback and does not enumerate FourCC
1208 *****************************************************************************/
1209 static HRESULT WINAPI
1210 IDirect3DDeviceImpl_2_EnumTextureFormats(IDirect3DDevice2
*iface
,
1211 LPD3DENUMTEXTUREFORMATSCALLBACK Callback
,
1214 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
1217 WINED3DDISPLAYMODE mode
;
1219 static const enum wined3d_format_id FormatList
[] =
1222 WINED3DFMT_B8G8R8A8_UNORM
,
1223 WINED3DFMT_B8G8R8X8_UNORM
,
1225 WINED3DFMT_B8G8R8_UNORM
,
1227 WINED3DFMT_B5G5R5A1_UNORM
,
1228 WINED3DFMT_B4G4R4A4_UNORM
,
1229 WINED3DFMT_B5G6R5_UNORM
,
1230 WINED3DFMT_B5G5R5X1_UNORM
,
1232 WINED3DFMT_B2G3R3_UNORM
,
1234 /* FOURCC codes - Not in this version*/
1237 TRACE("iface %p, callback %p, context %p.\n", iface
, Callback
, Arg
);
1240 return DDERR_INVALIDPARAMS
;
1242 EnterCriticalSection(&ddraw_cs
);
1244 memset(&mode
, 0, sizeof(mode
));
1245 hr
= IWineD3DDevice_GetDisplayMode(This
->ddraw
->wineD3DDevice
,
1249 LeaveCriticalSection(&ddraw_cs
);
1250 WARN("Cannot get the current adapter format\n");
1254 for (i
= 0; i
< sizeof(FormatList
) / sizeof(*FormatList
); ++i
)
1256 hr
= wined3d_check_device_format(This
->ddraw
->wineD3D
, 0, WINED3DDEVTYPE_HAL
,
1257 mode
.Format
, 0, WINED3DRTYPE_TEXTURE
, FormatList
[i
], SURFACE_OPENGL
);
1260 DDSURFACEDESC sdesc
;
1262 memset(&sdesc
, 0, sizeof(sdesc
));
1263 sdesc
.dwSize
= sizeof(sdesc
);
1264 sdesc
.dwFlags
= DDSD_PIXELFORMAT
| DDSD_CAPS
;
1265 sdesc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
1266 sdesc
.ddpfPixelFormat
.dwSize
= sizeof(sdesc
.ddpfPixelFormat
);
1267 PixelFormat_WineD3DtoDD(&sdesc
.ddpfPixelFormat
, FormatList
[i
]);
1269 TRACE("Enumerating WineD3DFormat %d\n", FormatList
[i
]);
1270 hr
= Callback(&sdesc
, Arg
);
1271 if(hr
!= DDENUMRET_OK
)
1273 TRACE("Format enumeration cancelled by application\n");
1274 LeaveCriticalSection(&ddraw_cs
);
1279 TRACE("End of enumeration\n");
1280 LeaveCriticalSection(&ddraw_cs
);
1284 static HRESULT WINAPI
IDirect3DDeviceImpl_1_EnumTextureFormats(IDirect3DDevice
*iface
,
1285 LPD3DENUMTEXTUREFORMATSCALLBACK Callback
, void *Arg
)
1287 IDirect3DDeviceImpl
*This
= device_from_device1(iface
);
1289 TRACE("iface %p, callback %p, context %p.\n", iface
, Callback
, Arg
);
1291 return IDirect3DDevice2_EnumTextureFormats((IDirect3DDevice2
*)&This
->IDirect3DDevice2_vtbl
, Callback
, Arg
);
1294 /*****************************************************************************
1295 * IDirect3DDevice::CreateMatrix
1297 * Creates a matrix handle. A handle is created and memory for a D3DMATRIX is
1298 * allocated for the handle.
1303 * D3DMatHandle: Address to return the handle at
1307 * DDERR_INVALIDPARAMS if D3DMatHandle = NULL
1309 *****************************************************************************/
1310 static HRESULT WINAPI
1311 IDirect3DDeviceImpl_1_CreateMatrix(IDirect3DDevice
*iface
, D3DMATRIXHANDLE
*D3DMatHandle
)
1313 IDirect3DDeviceImpl
*This
= device_from_device1(iface
);
1317 TRACE("iface %p, matrix_handle %p.\n", iface
, D3DMatHandle
);
1320 return DDERR_INVALIDPARAMS
;
1322 Matrix
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(D3DMATRIX
));
1325 ERR("Out of memory when allocating a D3DMATRIX\n");
1326 return DDERR_OUTOFMEMORY
;
1329 EnterCriticalSection(&ddraw_cs
);
1331 h
= ddraw_allocate_handle(&This
->handle_table
, Matrix
, DDRAW_HANDLE_MATRIX
);
1332 if (h
== DDRAW_INVALID_HANDLE
)
1334 ERR("Failed to allocate a matrix handle.\n");
1335 HeapFree(GetProcessHeap(), 0, Matrix
);
1336 LeaveCriticalSection(&ddraw_cs
);
1337 return DDERR_OUTOFMEMORY
;
1340 *D3DMatHandle
= h
+ 1;
1342 TRACE(" returning matrix handle %d\n", *D3DMatHandle
);
1344 LeaveCriticalSection(&ddraw_cs
);
1348 /*****************************************************************************
1349 * IDirect3DDevice::SetMatrix
1351 * Sets a matrix for a matrix handle. The matrix is copied into the memory
1352 * allocated for the handle
1357 * D3DMatHandle: Handle to set the matrix to
1358 * D3DMatrix: Matrix to set
1362 * DDERR_INVALIDPARAMS if the handle of the matrix is invalid or the matrix
1365 *****************************************************************************/
1366 static HRESULT WINAPI
1367 IDirect3DDeviceImpl_1_SetMatrix(IDirect3DDevice
*iface
,
1368 D3DMATRIXHANDLE D3DMatHandle
,
1369 D3DMATRIX
*D3DMatrix
)
1371 IDirect3DDeviceImpl
*This
= device_from_device1(iface
);
1374 TRACE("iface %p, matrix_handle %#x, matrix %p.\n", iface
, D3DMatHandle
, D3DMatrix
);
1376 if (!D3DMatrix
) return DDERR_INVALIDPARAMS
;
1378 EnterCriticalSection(&ddraw_cs
);
1380 m
= ddraw_get_object(&This
->handle_table
, D3DMatHandle
- 1, DDRAW_HANDLE_MATRIX
);
1383 WARN("Invalid matrix handle.\n");
1384 LeaveCriticalSection(&ddraw_cs
);
1385 return DDERR_INVALIDPARAMS
;
1388 if (TRACE_ON(ddraw
))
1389 dump_D3DMATRIX(D3DMatrix
);
1393 if(This
->world
== D3DMatHandle
)
1395 IWineD3DDevice_SetTransform(This
->wineD3DDevice
,
1396 WINED3DTS_WORLDMATRIX(0),
1397 (WINED3DMATRIX
*) D3DMatrix
);
1399 if(This
->view
== D3DMatHandle
)
1401 IWineD3DDevice_SetTransform(This
->wineD3DDevice
,
1403 (WINED3DMATRIX
*) D3DMatrix
);
1405 if(This
->proj
== D3DMatHandle
)
1407 IWineD3DDevice_SetTransform(This
->wineD3DDevice
,
1408 WINED3DTS_PROJECTION
,
1409 (WINED3DMATRIX
*) D3DMatrix
);
1412 LeaveCriticalSection(&ddraw_cs
);
1416 /*****************************************************************************
1417 * IDirect3DDevice::GetMatrix
1419 * Returns the content of a D3DMATRIX handle
1424 * D3DMatHandle: Matrix handle to read the content from
1425 * D3DMatrix: Address to store the content at
1429 * DDERR_INVALIDPARAMS if D3DMatHandle is invalid or D3DMatrix is NULL
1431 *****************************************************************************/
1432 static HRESULT WINAPI
1433 IDirect3DDeviceImpl_1_GetMatrix(IDirect3DDevice
*iface
,
1434 D3DMATRIXHANDLE D3DMatHandle
,
1435 D3DMATRIX
*D3DMatrix
)
1437 IDirect3DDeviceImpl
*This
= device_from_device1(iface
);
1440 TRACE("iface %p, matrix_handle %#x, matrix %p.\n", iface
, D3DMatHandle
, D3DMatrix
);
1442 if (!D3DMatrix
) return DDERR_INVALIDPARAMS
;
1444 EnterCriticalSection(&ddraw_cs
);
1446 m
= ddraw_get_object(&This
->handle_table
, D3DMatHandle
- 1, DDRAW_HANDLE_MATRIX
);
1449 WARN("Invalid matrix handle.\n");
1450 LeaveCriticalSection(&ddraw_cs
);
1451 return DDERR_INVALIDPARAMS
;
1456 LeaveCriticalSection(&ddraw_cs
);
1460 /*****************************************************************************
1461 * IDirect3DDevice::DeleteMatrix
1463 * Destroys a Matrix handle. Frees the memory and unsets the handle data
1468 * D3DMatHandle: Handle to destroy
1472 * DDERR_INVALIDPARAMS if D3DMatHandle is invalid
1474 *****************************************************************************/
1475 static HRESULT WINAPI
1476 IDirect3DDeviceImpl_1_DeleteMatrix(IDirect3DDevice
*iface
,
1477 D3DMATRIXHANDLE D3DMatHandle
)
1479 IDirect3DDeviceImpl
*This
= device_from_device1(iface
);
1482 TRACE("iface %p, matrix_handle %#x.\n", iface
, D3DMatHandle
);
1484 EnterCriticalSection(&ddraw_cs
);
1486 m
= ddraw_free_handle(&This
->handle_table
, D3DMatHandle
- 1, DDRAW_HANDLE_MATRIX
);
1489 WARN("Invalid matrix handle.\n");
1490 LeaveCriticalSection(&ddraw_cs
);
1491 return DDERR_INVALIDPARAMS
;
1494 LeaveCriticalSection(&ddraw_cs
);
1496 HeapFree(GetProcessHeap(), 0, m
);
1501 /*****************************************************************************
1502 * IDirect3DDevice7::BeginScene
1504 * This method must be called before any rendering is performed.
1505 * IDirect3DDevice::EndScene has to be called after the scene is complete
1507 * Version 1, 2, 3 and 7
1510 * D3D_OK on success, for details see IWineD3DDevice::BeginScene
1511 * D3DERR_SCENE_IN_SCENE if WineD3D returns an error(Only in case of an already
1514 *****************************************************************************/
1516 IDirect3DDeviceImpl_7_BeginScene(IDirect3DDevice7
*iface
)
1518 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
1521 TRACE("iface %p.\n", iface
);
1523 EnterCriticalSection(&ddraw_cs
);
1524 hr
= IWineD3DDevice_BeginScene(This
->wineD3DDevice
);
1525 LeaveCriticalSection(&ddraw_cs
);
1526 if(hr
== WINED3D_OK
) return D3D_OK
;
1527 else return D3DERR_SCENE_IN_SCENE
; /* TODO: Other possible causes of failure */
1530 static HRESULT WINAPI
1531 IDirect3DDeviceImpl_7_BeginScene_FPUSetup(IDirect3DDevice7
*iface
)
1533 return IDirect3DDeviceImpl_7_BeginScene(iface
);
1536 static HRESULT WINAPI
1537 IDirect3DDeviceImpl_7_BeginScene_FPUPreserve(IDirect3DDevice7
*iface
)
1542 old_fpucw
= d3d_fpu_setup();
1543 hr
= IDirect3DDeviceImpl_7_BeginScene(iface
);
1544 set_fpu_control_word(old_fpucw
);
1549 static HRESULT WINAPI
IDirect3DDeviceImpl_3_BeginScene(IDirect3DDevice3
*iface
)
1551 TRACE("iface %p.\n", iface
);
1553 return IDirect3DDevice7_BeginScene((IDirect3DDevice7
*)device_from_device3(iface
));
1556 static HRESULT WINAPI
IDirect3DDeviceImpl_2_BeginScene(IDirect3DDevice2
*iface
)
1558 TRACE("iface %p.\n", iface
);
1560 return IDirect3DDevice7_BeginScene((IDirect3DDevice7
*)device_from_device2(iface
));
1563 static HRESULT WINAPI
IDirect3DDeviceImpl_1_BeginScene(IDirect3DDevice
*iface
)
1565 TRACE("iface %p.\n", iface
);
1567 return IDirect3DDevice7_BeginScene((IDirect3DDevice7
*)device_from_device1(iface
));
1570 /*****************************************************************************
1571 * IDirect3DDevice7::EndScene
1573 * Ends a scene that has been begun with IDirect3DDevice7::BeginScene.
1574 * This method must be called after rendering is finished.
1576 * Version 1, 2, 3 and 7
1579 * D3D_OK on success, for details see IWineD3DDevice::EndScene
1580 * D3DERR_SCENE_NOT_IN_SCENE is returned if WineD3D returns an error. It does
1581 * that only if the scene was already ended.
1583 *****************************************************************************/
1585 IDirect3DDeviceImpl_7_EndScene(IDirect3DDevice7
*iface
)
1587 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
1590 TRACE("iface %p.\n", iface
);
1592 EnterCriticalSection(&ddraw_cs
);
1593 hr
= IWineD3DDevice_EndScene(This
->wineD3DDevice
);
1594 LeaveCriticalSection(&ddraw_cs
);
1595 if(hr
== WINED3D_OK
) return D3D_OK
;
1596 else return D3DERR_SCENE_NOT_IN_SCENE
;
1599 static HRESULT WINAPI DECLSPEC_HOTPATCH
1600 IDirect3DDeviceImpl_7_EndScene_FPUSetup(IDirect3DDevice7
*iface
)
1602 return IDirect3DDeviceImpl_7_EndScene(iface
);
1605 static HRESULT WINAPI DECLSPEC_HOTPATCH
1606 IDirect3DDeviceImpl_7_EndScene_FPUPreserve(IDirect3DDevice7
*iface
)
1611 old_fpucw
= d3d_fpu_setup();
1612 hr
= IDirect3DDeviceImpl_7_EndScene(iface
);
1613 set_fpu_control_word(old_fpucw
);
1618 static HRESULT WINAPI DECLSPEC_HOTPATCH
IDirect3DDeviceImpl_3_EndScene(IDirect3DDevice3
*iface
)
1620 TRACE("iface %p.\n", iface
);
1622 return IDirect3DDevice7_EndScene((IDirect3DDevice7
*)device_from_device3(iface
));
1625 static HRESULT WINAPI DECLSPEC_HOTPATCH
IDirect3DDeviceImpl_2_EndScene(IDirect3DDevice2
*iface
)
1627 TRACE("iface %p.\n", iface
);
1629 return IDirect3DDevice7_EndScene((IDirect3DDevice7
*)device_from_device2(iface
));
1632 static HRESULT WINAPI DECLSPEC_HOTPATCH
IDirect3DDeviceImpl_1_EndScene(IDirect3DDevice
*iface
)
1634 TRACE("iface %p.\n", iface
);
1636 return IDirect3DDevice7_EndScene((IDirect3DDevice7
*)device_from_device1(iface
));
1639 /*****************************************************************************
1640 * IDirect3DDevice7::GetDirect3D
1642 * Returns the IDirect3D(= interface to the DirectDraw object) used to create
1646 * Direct3D7: Address to store the interface pointer at
1650 * DDERR_INVALIDPARAMS if Direct3D7 == NULL
1652 *****************************************************************************/
1653 static HRESULT WINAPI
1654 IDirect3DDeviceImpl_7_GetDirect3D(IDirect3DDevice7
*iface
,
1655 IDirect3D7
**Direct3D7
)
1657 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
1659 TRACE("iface %p, d3d %p.\n", iface
, Direct3D7
);
1662 return DDERR_INVALIDPARAMS
;
1664 *Direct3D7
= &This
->ddraw
->IDirect3D7_iface
;
1665 IDirect3D7_AddRef(*Direct3D7
);
1667 TRACE(" returning interface %p\n", *Direct3D7
);
1671 static HRESULT WINAPI
IDirect3DDeviceImpl_3_GetDirect3D(IDirect3DDevice3
*iface
,
1672 IDirect3D3
**Direct3D3
)
1674 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
1676 TRACE("iface %p, d3d %p.\n", iface
, Direct3D3
);
1679 return DDERR_INVALIDPARAMS
;
1681 IDirect3D3_AddRef(&This
->ddraw
->IDirect3D3_iface
);
1682 *Direct3D3
= &This
->ddraw
->IDirect3D3_iface
;
1683 TRACE(" returning interface %p\n", *Direct3D3
);
1687 static HRESULT WINAPI
IDirect3DDeviceImpl_2_GetDirect3D(IDirect3DDevice2
*iface
,
1688 IDirect3D2
**Direct3D2
)
1690 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
1692 TRACE("iface %p, d3d %p.\n", iface
, Direct3D2
);
1695 return DDERR_INVALIDPARAMS
;
1697 IDirect3D2_AddRef(&This
->ddraw
->IDirect3D2_iface
);
1698 *Direct3D2
= &This
->ddraw
->IDirect3D2_iface
;
1699 TRACE(" returning interface %p\n", *Direct3D2
);
1703 static HRESULT WINAPI
IDirect3DDeviceImpl_1_GetDirect3D(IDirect3DDevice
*iface
,
1704 IDirect3D
**Direct3D
)
1706 IDirect3DDeviceImpl
*This
= device_from_device1(iface
);
1708 TRACE("iface %p, d3d %p.\n", iface
, Direct3D
);
1711 return DDERR_INVALIDPARAMS
;
1713 IDirect3D_AddRef(&This
->ddraw
->IDirect3D_iface
);
1714 *Direct3D
= &This
->ddraw
->IDirect3D_iface
;
1715 TRACE(" returning interface %p\n", *Direct3D
);
1719 /*****************************************************************************
1720 * IDirect3DDevice3::SetCurrentViewport
1722 * Sets a Direct3DViewport as the current viewport.
1723 * For the thunks note that all viewport interface versions are equal
1726 * Direct3DViewport3: The viewport to set
1732 * (Is a NULL viewport valid?)
1734 *****************************************************************************/
1735 static HRESULT WINAPI
1736 IDirect3DDeviceImpl_3_SetCurrentViewport(IDirect3DDevice3
*iface
,
1737 IDirect3DViewport3
*Direct3DViewport3
)
1739 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
1740 IDirect3DViewportImpl
*vp
= (IDirect3DViewportImpl
*)Direct3DViewport3
;
1742 TRACE("iface %p, viewport %p.\n", iface
, Direct3DViewport3
);
1744 EnterCriticalSection(&ddraw_cs
);
1745 /* Do nothing if the specified viewport is the same as the current one */
1746 if (This
->current_viewport
== vp
)
1748 LeaveCriticalSection(&ddraw_cs
);
1752 /* Should check if the viewport was added or not */
1754 /* Release previous viewport and AddRef the new one */
1755 if (This
->current_viewport
)
1757 TRACE("ViewportImpl is at %p, interface is at %p\n", This
->current_viewport
,
1758 (IDirect3DViewport3
*)This
->current_viewport
);
1759 IDirect3DViewport3_Release((IDirect3DViewport3
*)This
->current_viewport
);
1761 IDirect3DViewport3_AddRef(Direct3DViewport3
);
1763 /* Set this viewport as the current viewport */
1764 This
->current_viewport
= vp
;
1766 /* Activate this viewport */
1767 This
->current_viewport
->active_device
= This
;
1768 viewport_activate(This
->current_viewport
, FALSE
);
1770 LeaveCriticalSection(&ddraw_cs
);
1774 static HRESULT WINAPI
IDirect3DDeviceImpl_2_SetCurrentViewport(IDirect3DDevice2
*iface
,
1775 IDirect3DViewport2
*Direct3DViewport2
)
1777 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
1778 IDirect3DViewportImpl
*vp
= (IDirect3DViewportImpl
*)Direct3DViewport2
;
1780 TRACE("iface %p, viewport %p.\n", iface
, Direct3DViewport2
);
1782 return IDirect3DDevice3_SetCurrentViewport((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
,
1783 (IDirect3DViewport3
*)vp
);
1786 /*****************************************************************************
1787 * IDirect3DDevice3::GetCurrentViewport
1789 * Returns the currently active viewport.
1794 * Direct3DViewport3: Address to return the interface pointer at
1798 * DDERR_INVALIDPARAMS if Direct3DViewport == NULL
1800 *****************************************************************************/
1801 static HRESULT WINAPI
1802 IDirect3DDeviceImpl_3_GetCurrentViewport(IDirect3DDevice3
*iface
,
1803 IDirect3DViewport3
**Direct3DViewport3
)
1805 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
1807 TRACE("iface %p, viewport %p.\n", iface
, Direct3DViewport3
);
1809 if(!Direct3DViewport3
)
1810 return DDERR_INVALIDPARAMS
;
1812 EnterCriticalSection(&ddraw_cs
);
1813 *Direct3DViewport3
= (IDirect3DViewport3
*)This
->current_viewport
;
1815 /* AddRef the returned viewport */
1816 if(*Direct3DViewport3
) IDirect3DViewport3_AddRef(*Direct3DViewport3
);
1818 TRACE(" returning interface %p\n", *Direct3DViewport3
);
1820 LeaveCriticalSection(&ddraw_cs
);
1824 static HRESULT WINAPI
IDirect3DDeviceImpl_2_GetCurrentViewport(IDirect3DDevice2
*iface
,
1825 IDirect3DViewport2
**Direct3DViewport2
)
1827 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
1830 TRACE("iface %p, viewport %p.\n", iface
, Direct3DViewport2
);
1832 hr
= IDirect3DDevice3_GetCurrentViewport((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
,
1833 (IDirect3DViewport3
**)Direct3DViewport2
);
1834 if(hr
!= D3D_OK
) return hr
;
1838 /*****************************************************************************
1839 * IDirect3DDevice7::SetRenderTarget
1841 * Sets the render target for the Direct3DDevice.
1842 * For the thunks note that IDirectDrawSurface7 == IDirectDrawSurface4 and
1843 * IDirectDrawSurface3 == IDirectDrawSurface
1845 * Version 2, 3 and 7
1848 * NewTarget: Pointer to an IDirectDrawSurface7 interface to set as the new
1853 * D3D_OK on success, for details see IWineD3DDevice::SetRenderTarget
1855 *****************************************************************************/
1857 IDirect3DDeviceImpl_7_SetRenderTarget(IDirect3DDevice7
*iface
,
1858 IDirectDrawSurface7
*NewTarget
,
1861 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
1862 IDirectDrawSurfaceImpl
*Target
= (IDirectDrawSurfaceImpl
*)NewTarget
;
1865 TRACE("iface %p, target %p, flags %#x.\n", iface
, NewTarget
, Flags
);
1867 EnterCriticalSection(&ddraw_cs
);
1868 /* Flags: Not used */
1870 if(This
->target
== Target
)
1872 TRACE("No-op SetRenderTarget operation, not doing anything\n");
1873 LeaveCriticalSection(&ddraw_cs
);
1877 hr
= IWineD3DDevice_SetRenderTarget(This
->wineD3DDevice
,
1879 Target
? Target
->WineD3DSurface
: NULL
,
1883 LeaveCriticalSection(&ddraw_cs
);
1886 IDirectDrawSurface7_AddRef(NewTarget
);
1887 IDirectDrawSurface7_Release((IDirectDrawSurface7
*)This
->target
);
1888 This
->target
= Target
;
1889 IDirect3DDeviceImpl_UpdateDepthStencil(This
);
1890 LeaveCriticalSection(&ddraw_cs
);
1894 static HRESULT WINAPI
1895 IDirect3DDeviceImpl_7_SetRenderTarget_FPUSetup(IDirect3DDevice7
*iface
,
1896 IDirectDrawSurface7
*NewTarget
,
1899 return IDirect3DDeviceImpl_7_SetRenderTarget(iface
, NewTarget
, Flags
);
1902 static HRESULT WINAPI
1903 IDirect3DDeviceImpl_7_SetRenderTarget_FPUPreserve(IDirect3DDevice7
*iface
,
1904 IDirectDrawSurface7
*NewTarget
,
1910 old_fpucw
= d3d_fpu_setup();
1911 hr
= IDirect3DDeviceImpl_7_SetRenderTarget(iface
, NewTarget
, Flags
);
1912 set_fpu_control_word(old_fpucw
);
1917 static HRESULT WINAPI
IDirect3DDeviceImpl_3_SetRenderTarget(IDirect3DDevice3
*iface
,
1918 IDirectDrawSurface4
*NewRenderTarget
, DWORD Flags
)
1920 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
1921 IDirectDrawSurfaceImpl
*Target
= (IDirectDrawSurfaceImpl
*)NewRenderTarget
;
1923 TRACE("iface %p, target %p, flags %#x.\n", iface
, NewRenderTarget
, Flags
);
1925 return IDirect3DDevice7_SetRenderTarget((IDirect3DDevice7
*)This
, (IDirectDrawSurface7
*)Target
, Flags
);
1928 static HRESULT WINAPI
IDirect3DDeviceImpl_2_SetRenderTarget(IDirect3DDevice2
*iface
,
1929 IDirectDrawSurface
*NewRenderTarget
, DWORD Flags
)
1931 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
1932 IDirectDrawSurfaceImpl
*Target
= (IDirectDrawSurfaceImpl
*)NewRenderTarget
;
1934 TRACE("iface %p, target %p, flags %#x.\n", iface
, NewRenderTarget
, Flags
);
1936 return IDirect3DDevice7_SetRenderTarget((IDirect3DDevice7
*)This
, (IDirectDrawSurface7
*)Target
, Flags
);
1939 /*****************************************************************************
1940 * IDirect3DDevice7::GetRenderTarget
1942 * Returns the current render target.
1943 * This is handled locally, because the WineD3D render target's parent
1946 * Version 2, 3 and 7
1949 * RenderTarget: Address to store the surface interface pointer
1953 * DDERR_INVALIDPARAMS if RenderTarget == NULL
1955 *****************************************************************************/
1956 static HRESULT WINAPI
1957 IDirect3DDeviceImpl_7_GetRenderTarget(IDirect3DDevice7
*iface
,
1958 IDirectDrawSurface7
**RenderTarget
)
1960 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
1962 TRACE("iface %p, target %p.\n", iface
, RenderTarget
);
1965 return DDERR_INVALIDPARAMS
;
1967 EnterCriticalSection(&ddraw_cs
);
1968 *RenderTarget
= (IDirectDrawSurface7
*)This
->target
;
1969 IDirectDrawSurface7_AddRef(*RenderTarget
);
1971 LeaveCriticalSection(&ddraw_cs
);
1975 static HRESULT WINAPI
IDirect3DDeviceImpl_3_GetRenderTarget(IDirect3DDevice3
*iface
,
1976 IDirectDrawSurface4
**RenderTarget
)
1978 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
1981 TRACE("iface %p, target %p.\n", iface
, RenderTarget
);
1983 hr
= IDirect3DDevice7_GetRenderTarget((IDirect3DDevice7
*)This
, (IDirectDrawSurface7
**)RenderTarget
);
1984 if(hr
!= D3D_OK
) return hr
;
1988 static HRESULT WINAPI
IDirect3DDeviceImpl_2_GetRenderTarget(IDirect3DDevice2
*iface
,
1989 IDirectDrawSurface
**RenderTarget
)
1991 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
1994 TRACE("iface %p, target %p.\n", iface
, RenderTarget
);
1996 hr
= IDirect3DDevice7_GetRenderTarget((IDirect3DDevice7
*)This
, (IDirectDrawSurface7
**)RenderTarget
);
1997 if(hr
!= D3D_OK
) return hr
;
1998 *RenderTarget
= *RenderTarget
?
1999 (IDirectDrawSurface
*)&((IDirectDrawSurfaceImpl
*)*RenderTarget
)->IDirectDrawSurface3_vtbl
: NULL
;
2003 /*****************************************************************************
2004 * IDirect3DDevice3::Begin
2006 * Begins a description block of vertices. This is similar to glBegin()
2007 * and glEnd(). After a call to IDirect3DDevice3::End, the vertices
2008 * described with IDirect3DDevice::Vertex are drawn.
2013 * PrimitiveType: The type of primitives to draw
2014 * VertexTypeDesc: A flexible vertex format description of the vertices
2015 * Flags: Some flags..
2020 *****************************************************************************/
2021 static HRESULT WINAPI
2022 IDirect3DDeviceImpl_3_Begin(IDirect3DDevice3
*iface
,
2023 D3DPRIMITIVETYPE PrimitiveType
,
2024 DWORD VertexTypeDesc
,
2027 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
2029 TRACE("iface %p, primitive_type %#x, FVF %#x, flags %#x.\n",
2030 iface
, PrimitiveType
, VertexTypeDesc
, Flags
);
2032 EnterCriticalSection(&ddraw_cs
);
2033 This
->primitive_type
= PrimitiveType
;
2034 This
->vertex_type
= VertexTypeDesc
;
2035 This
->render_flags
= Flags
;
2036 This
->vertex_size
= get_flexible_vertex_size(This
->vertex_type
);
2037 This
->nb_vertices
= 0;
2038 LeaveCriticalSection(&ddraw_cs
);
2043 static HRESULT WINAPI
IDirect3DDeviceImpl_2_Begin(IDirect3DDevice2
*iface
, D3DPRIMITIVETYPE d3dpt
,
2044 D3DVERTEXTYPE dwVertexTypeDesc
, DWORD dwFlags
)
2047 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
2049 TRACE("iface %p, primitive_type %#x, vertex_type %#x, flags %#x.\n",
2050 iface
, d3dpt
, dwVertexTypeDesc
, dwFlags
);
2052 switch(dwVertexTypeDesc
)
2054 case D3DVT_VERTEX
: FVF
= D3DFVF_VERTEX
; break;
2055 case D3DVT_LVERTEX
: FVF
= D3DFVF_LVERTEX
; break;
2056 case D3DVT_TLVERTEX
: FVF
= D3DFVF_TLVERTEX
; break;
2058 ERR("Unexpected vertex type %d\n", dwVertexTypeDesc
);
2059 return DDERR_INVALIDPARAMS
; /* Should never happen */
2062 return IDirect3DDevice3_Begin((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
, d3dpt
, FVF
, dwFlags
);
2065 /*****************************************************************************
2066 * IDirect3DDevice3::BeginIndexed
2068 * Draws primitives based on vertices in a vertex array which are specified
2074 * PrimitiveType: Primitive type to draw
2075 * VertexType: A FVF description of the vertex format
2076 * Vertices: pointer to an array containing the vertices
2077 * NumVertices: The number of vertices in the vertex array
2078 * Flags: Some flags ...
2081 * D3D_OK, because it's a stub
2083 *****************************************************************************/
2084 static HRESULT WINAPI
2085 IDirect3DDeviceImpl_3_BeginIndexed(IDirect3DDevice3
*iface
,
2086 D3DPRIMITIVETYPE PrimitiveType
,
2092 FIXME("iface %p, primitive_type %#x, FVF %#x, vertices %p, vertex_count %u, flags %#x stub!\n",
2093 iface
, PrimitiveType
, VertexType
, Vertices
, NumVertices
, Flags
);
2099 static HRESULT WINAPI
IDirect3DDeviceImpl_2_BeginIndexed(IDirect3DDevice2
*iface
,
2100 D3DPRIMITIVETYPE d3dptPrimitiveType
, D3DVERTEXTYPE d3dvtVertexType
,
2101 void *lpvVertices
, DWORD dwNumVertices
, DWORD dwFlags
)
2104 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
2106 TRACE("iface %p, primitive_type %#x, vertex_type %#x, vertices %p, vertex_count %u, flags %#x stub!\n",
2107 iface
, d3dptPrimitiveType
, d3dvtVertexType
, lpvVertices
, dwNumVertices
, dwFlags
);
2109 switch(d3dvtVertexType
)
2111 case D3DVT_VERTEX
: FVF
= D3DFVF_VERTEX
; break;
2112 case D3DVT_LVERTEX
: FVF
= D3DFVF_LVERTEX
; break;
2113 case D3DVT_TLVERTEX
: FVF
= D3DFVF_TLVERTEX
; break;
2115 ERR("Unexpected vertex type %d\n", d3dvtVertexType
);
2116 return DDERR_INVALIDPARAMS
; /* Should never happen */
2119 return IDirect3DDevice3_BeginIndexed((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
,
2120 d3dptPrimitiveType
, FVF
, lpvVertices
, dwNumVertices
, dwFlags
);
2123 /*****************************************************************************
2124 * IDirect3DDevice3::Vertex
2126 * Draws a vertex as described by IDirect3DDevice3::Begin. It places all
2127 * drawn vertices in a vertex buffer. If the buffer is too small, its
2128 * size is increased.
2133 * Vertex: Pointer to the vertex
2136 * D3D_OK, on success
2137 * DDERR_INVALIDPARAMS if Vertex is NULL
2139 *****************************************************************************/
2140 static HRESULT WINAPI
2141 IDirect3DDeviceImpl_3_Vertex(IDirect3DDevice3
*iface
,
2144 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
2146 TRACE("iface %p, vertex %p.\n", iface
, Vertex
);
2149 return DDERR_INVALIDPARAMS
;
2151 EnterCriticalSection(&ddraw_cs
);
2152 if ((This
->nb_vertices
+1)*This
->vertex_size
> This
->buffer_size
)
2155 This
->buffer_size
= This
->buffer_size
? This
->buffer_size
* 2 : This
->vertex_size
* 3;
2156 old_buffer
= This
->vertex_buffer
;
2157 This
->vertex_buffer
= HeapAlloc(GetProcessHeap(), 0, This
->buffer_size
);
2160 CopyMemory(This
->vertex_buffer
, old_buffer
, This
->nb_vertices
* This
->vertex_size
);
2161 HeapFree(GetProcessHeap(), 0, old_buffer
);
2165 CopyMemory(This
->vertex_buffer
+ This
->nb_vertices
++ * This
->vertex_size
, Vertex
, This
->vertex_size
);
2167 LeaveCriticalSection(&ddraw_cs
);
2171 static HRESULT WINAPI
IDirect3DDeviceImpl_2_Vertex(IDirect3DDevice2
*iface
, void *lpVertexType
)
2173 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
2175 TRACE("iface %p, vertex %p.\n", iface
, lpVertexType
);
2177 return IDirect3DDevice3_Vertex((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
, lpVertexType
);
2180 /*****************************************************************************
2181 * IDirect3DDevice3::Index
2183 * Specifies an index to a vertex to be drawn. The vertex array has to
2184 * be specified with BeginIndexed first.
2187 * VertexIndex: The index of the vertex to draw
2190 * D3D_OK because it's a stub
2192 *****************************************************************************/
2193 static HRESULT WINAPI
2194 IDirect3DDeviceImpl_3_Index(IDirect3DDevice3
*iface
,
2197 FIXME("iface %p, index %#x stub!\n", iface
, VertexIndex
);
2202 static HRESULT WINAPI
IDirect3DDeviceImpl_2_Index(IDirect3DDevice2
*iface
, WORD wVertexIndex
)
2204 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
2206 TRACE("iface %p, index %#x.\n", iface
, wVertexIndex
);
2208 return IDirect3DDevice3_Index((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
, wVertexIndex
);
2211 /*****************************************************************************
2212 * IDirect3DDevice3::End
2214 * Ends a draw begun with IDirect3DDevice3::Begin or
2215 * IDirect3DDevice::BeginIndexed. The vertices specified with
2216 * IDirect3DDevice::Vertex or IDirect3DDevice::Index are drawn using
2217 * the IDirect3DDevice7::DrawPrimitive method. So far only
2218 * non-indexed mode is supported
2223 * Flags: Some flags, as usual. Don't know which are defined
2226 * The return value of IDirect3DDevice7::DrawPrimitive
2228 *****************************************************************************/
2229 static HRESULT WINAPI
2230 IDirect3DDeviceImpl_3_End(IDirect3DDevice3
*iface
,
2233 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
2235 TRACE("iface %p, flags %#x.\n", iface
, Flags
);
2237 return IDirect3DDevice7_DrawPrimitive((IDirect3DDevice7
*)This
, This
->primitive_type
,
2238 This
->vertex_type
, This
->vertex_buffer
, This
->nb_vertices
, This
->render_flags
);
2241 static HRESULT WINAPI
IDirect3DDeviceImpl_2_End(IDirect3DDevice2
*iface
, DWORD dwFlags
)
2243 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
2245 TRACE("iface %p, flags %#x.\n", iface
, dwFlags
);
2247 return IDirect3DDevice3_End((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
, dwFlags
);
2250 /*****************************************************************************
2251 * IDirect3DDevice7::GetRenderState
2253 * Returns the value of a render state. The possible render states are
2254 * defined in include/d3dtypes.h
2256 * Version 2, 3 and 7
2259 * RenderStateType: Render state to return the current setting of
2260 * Value: Address to store the value at
2263 * D3D_OK on success, for details see IWineD3DDevice::GetRenderState
2264 * DDERR_INVALIDPARAMS if Value == NULL
2266 *****************************************************************************/
2268 IDirect3DDeviceImpl_7_GetRenderState(IDirect3DDevice7
*iface
,
2269 D3DRENDERSTATETYPE RenderStateType
,
2272 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
2275 TRACE("iface %p, state %#x, value %p.\n", iface
, RenderStateType
, Value
);
2278 return DDERR_INVALIDPARAMS
;
2280 EnterCriticalSection(&ddraw_cs
);
2281 switch(RenderStateType
)
2283 case D3DRENDERSTATE_TEXTUREMAG
:
2285 WINED3DTEXTUREFILTERTYPE tex_mag
;
2287 hr
= IWineD3DDevice_GetSamplerState(This
->wineD3DDevice
,
2288 0, WINED3DSAMP_MAGFILTER
,
2293 case WINED3DTEXF_POINT
:
2294 *Value
= D3DFILTER_NEAREST
;
2296 case WINED3DTEXF_LINEAR
:
2297 *Value
= D3DFILTER_LINEAR
;
2300 ERR("Unhandled texture mag %d !\n",tex_mag
);
2306 case D3DRENDERSTATE_TEXTUREMIN
:
2308 WINED3DTEXTUREFILTERTYPE tex_min
;
2309 WINED3DTEXTUREFILTERTYPE tex_mip
;
2311 hr
= IWineD3DDevice_GetSamplerState(This
->wineD3DDevice
,
2312 0, WINED3DSAMP_MINFILTER
, &tex_min
);
2315 LeaveCriticalSection(&ddraw_cs
);
2318 hr
= IWineD3DDevice_GetSamplerState(This
->wineD3DDevice
,
2319 0, WINED3DSAMP_MIPFILTER
, &tex_mip
);
2323 case WINED3DTEXF_POINT
:
2326 case WINED3DTEXF_NONE
:
2327 *Value
= D3DFILTER_NEAREST
;
2329 case WINED3DTEXF_POINT
:
2330 *Value
= D3DFILTER_MIPNEAREST
;
2332 case WINED3DTEXF_LINEAR
:
2333 *Value
= D3DFILTER_LINEARMIPNEAREST
;
2336 ERR("Unhandled mip filter %#x.\n", tex_mip
);
2337 *Value
= D3DFILTER_NEAREST
;
2341 case WINED3DTEXF_LINEAR
:
2344 case WINED3DTEXF_NONE
:
2345 *Value
= D3DFILTER_LINEAR
;
2347 case WINED3DTEXF_POINT
:
2348 *Value
= D3DFILTER_MIPLINEAR
;
2350 case WINED3DTEXF_LINEAR
:
2351 *Value
= D3DFILTER_LINEARMIPLINEAR
;
2354 ERR("Unhandled mip filter %#x.\n", tex_mip
);
2355 *Value
= D3DFILTER_LINEAR
;
2360 ERR("Unhandled texture min filter %#x.\n",tex_min
);
2361 *Value
= D3DFILTER_NEAREST
;
2367 case D3DRENDERSTATE_TEXTUREADDRESS
:
2368 case D3DRENDERSTATE_TEXTUREADDRESSU
:
2369 hr
= IWineD3DDevice_GetSamplerState(This
->wineD3DDevice
,
2370 0, WINED3DSAMP_ADDRESSU
,
2373 case D3DRENDERSTATE_TEXTUREADDRESSV
:
2374 hr
= IWineD3DDevice_GetSamplerState(This
->wineD3DDevice
,
2375 0, WINED3DSAMP_ADDRESSV
,
2379 case D3DRENDERSTATE_BORDERCOLOR
:
2380 FIXME("Unhandled render state D3DRENDERSTATE_BORDERCOLOR.\n");
2384 case D3DRENDERSTATE_TEXTUREHANDLE
:
2385 case D3DRENDERSTATE_TEXTUREMAPBLEND
:
2386 WARN("Render state %#x is invalid in d3d7.\n", RenderStateType
);
2387 hr
= DDERR_INVALIDPARAMS
;
2391 if (RenderStateType
>= D3DRENDERSTATE_STIPPLEPATTERN00
2392 && RenderStateType
<= D3DRENDERSTATE_STIPPLEPATTERN31
)
2394 FIXME("Unhandled stipple pattern render state (%#x).\n",
2399 hr
= IWineD3DDevice_GetRenderState(This
->wineD3DDevice
,
2403 LeaveCriticalSection(&ddraw_cs
);
2407 static HRESULT WINAPI
2408 IDirect3DDeviceImpl_7_GetRenderState_FPUSetup(IDirect3DDevice7
*iface
,
2409 D3DRENDERSTATETYPE RenderStateType
,
2412 return IDirect3DDeviceImpl_7_GetRenderState(iface
, RenderStateType
, Value
);
2415 static HRESULT WINAPI
2416 IDirect3DDeviceImpl_7_GetRenderState_FPUPreserve(IDirect3DDevice7
*iface
,
2417 D3DRENDERSTATETYPE RenderStateType
,
2423 old_fpucw
= d3d_fpu_setup();
2424 hr
= IDirect3DDeviceImpl_7_GetRenderState(iface
, RenderStateType
, Value
);
2425 set_fpu_control_word(old_fpucw
);
2430 static HRESULT WINAPI
2431 IDirect3DDeviceImpl_3_GetRenderState(IDirect3DDevice3
*iface
,
2432 D3DRENDERSTATETYPE dwRenderStateType
,
2433 DWORD
*lpdwRenderState
)
2435 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
2438 TRACE("iface %p, state %#x, value %p.\n", iface
, dwRenderStateType
, lpdwRenderState
);
2440 switch(dwRenderStateType
)
2442 case D3DRENDERSTATE_TEXTUREHANDLE
:
2444 /* This state is wrapped to SetTexture in SetRenderState, so
2445 * it has to be wrapped to GetTexture here
2447 IWineD3DBaseTexture
*tex
= NULL
;
2448 *lpdwRenderState
= 0;
2450 EnterCriticalSection(&ddraw_cs
);
2452 hr
= IWineD3DDevice_GetTexture(This
->wineD3DDevice
, 0, &tex
);
2453 if (SUCCEEDED(hr
) && tex
)
2455 /* The parent of the texture is the IDirectDrawSurface7
2456 * interface of the ddraw surface. */
2457 IDirectDrawSurfaceImpl
*parent
= IWineD3DBaseTexture_GetParent(tex
);
2458 if (parent
) *lpdwRenderState
= parent
->Handle
;
2459 IWineD3DBaseTexture_Release(tex
);
2462 LeaveCriticalSection(&ddraw_cs
);
2467 case D3DRENDERSTATE_TEXTUREMAPBLEND
:
2469 /* D3DRENDERSTATE_TEXTUREMAPBLEND is mapped to texture state stages in SetRenderState; reverse
2470 the mapping to get the value. */
2471 DWORD colorop
, colorarg1
, colorarg2
;
2472 DWORD alphaop
, alphaarg1
, alphaarg2
;
2474 EnterCriticalSection(&ddraw_cs
);
2476 This
->legacyTextureBlending
= TRUE
;
2478 IWineD3DDevice_GetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_COLOROP
, &colorop
);
2479 IWineD3DDevice_GetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_COLORARG1
, &colorarg1
);
2480 IWineD3DDevice_GetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_COLORARG2
, &colorarg2
);
2481 IWineD3DDevice_GetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAOP
, &alphaop
);
2482 IWineD3DDevice_GetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAARG1
, &alphaarg1
);
2483 IWineD3DDevice_GetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAARG2
, &alphaarg2
);
2485 if (colorop
== WINED3DTOP_SELECTARG1
&& colorarg1
== WINED3DTA_TEXTURE
&&
2486 alphaop
== WINED3DTOP_SELECTARG1
&& alphaarg1
== WINED3DTA_TEXTURE
)
2488 *lpdwRenderState
= D3DTBLEND_DECAL
;
2490 else if (colorop
== WINED3DTOP_SELECTARG1
&& colorarg1
== WINED3DTA_TEXTURE
&&
2491 alphaop
== WINED3DTOP_MODULATE
&& alphaarg1
== WINED3DTA_TEXTURE
&& alphaarg2
== WINED3DTA_CURRENT
)
2493 *lpdwRenderState
= D3DTBLEND_DECALALPHA
;
2495 else if (colorop
== WINED3DTOP_MODULATE
&& colorarg1
== WINED3DTA_TEXTURE
&& colorarg2
== WINED3DTA_CURRENT
&&
2496 alphaop
== WINED3DTOP_MODULATE
&& alphaarg1
== WINED3DTA_TEXTURE
&& alphaarg2
== WINED3DTA_CURRENT
)
2498 *lpdwRenderState
= D3DTBLEND_MODULATEALPHA
;
2503 BOOL tex_alpha
= FALSE
;
2504 IWineD3DBaseTexture
*tex
= NULL
;
2505 WINED3DSURFACE_DESC desc
;
2506 DDPIXELFORMAT ddfmt
;
2508 hr
= IWineD3DDevice_GetTexture(This
->wineD3DDevice
,
2512 if(hr
== WINED3D_OK
&& tex
)
2514 hr
= IWineD3DTexture_GetLevelDesc((IWineD3DTexture
*) tex
, 0, &desc
);
2517 ddfmt
.dwSize
= sizeof(ddfmt
);
2518 PixelFormat_WineD3DtoDD(&ddfmt
, desc
.format
);
2519 if (ddfmt
.u5
.dwRGBAlphaBitMask
) tex_alpha
= TRUE
;
2522 IWineD3DBaseTexture_Release(tex
);
2525 if (!(colorop
== WINED3DTOP_MODULATE
&& colorarg1
== WINED3DTA_TEXTURE
&& colorarg2
== WINED3DTA_CURRENT
&&
2526 alphaop
== (tex_alpha
? WINED3DTOP_SELECTARG1
: WINED3DTOP_SELECTARG2
) &&
2527 alphaarg1
== WINED3DTA_TEXTURE
&& alphaarg2
== WINED3DTA_CURRENT
))
2529 ERR("Unexpected texture stage state setup, returning D3DTBLEND_MODULATE - likely erroneous\n");
2532 *lpdwRenderState
= D3DTBLEND_MODULATE
;
2535 LeaveCriticalSection(&ddraw_cs
);
2541 return IDirect3DDevice7_GetRenderState((IDirect3DDevice7
*)This
, dwRenderStateType
, lpdwRenderState
);
2545 static HRESULT WINAPI
IDirect3DDeviceImpl_2_GetRenderState(IDirect3DDevice2
*iface
,
2546 D3DRENDERSTATETYPE dwRenderStateType
, DWORD
*lpdwRenderState
)
2548 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
2550 TRACE("iface %p, state %#x, value %p.\n", iface
, dwRenderStateType
, lpdwRenderState
);
2552 return IDirect3DDevice3_GetRenderState((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
,
2553 dwRenderStateType
, lpdwRenderState
);
2556 /*****************************************************************************
2557 * IDirect3DDevice7::SetRenderState
2559 * Sets a render state. The possible render states are defined in
2560 * include/d3dtypes.h
2562 * Version 2, 3 and 7
2565 * RenderStateType: State to set
2566 * Value: Value to assign to that state
2569 * D3D_OK on success,
2570 * for details see IWineD3DDevice::SetRenderState
2572 *****************************************************************************/
2574 IDirect3DDeviceImpl_7_SetRenderState(IDirect3DDevice7
*iface
,
2575 D3DRENDERSTATETYPE RenderStateType
,
2578 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
2581 TRACE("iface %p, state %#x, value %#x.\n", iface
, RenderStateType
, Value
);
2583 EnterCriticalSection(&ddraw_cs
);
2584 /* Some render states need special care */
2585 switch(RenderStateType
)
2588 * The ddraw texture filter mapping works like this:
2589 * D3DFILTER_NEAREST Point min/mag, no mip
2590 * D3DFILTER_MIPNEAREST Point min/mag, point mip
2591 * D3DFILTER_LINEARMIPNEAREST: Point min/mag, linear mip
2593 * D3DFILTER_LINEAR Linear min/mag, no mip
2594 * D3DFILTER_MIPLINEAR Linear min/mag, point mip
2595 * D3DFILTER_LINEARMIPLINEAR Linear min/mag, linear mip
2597 * This is the opposite of the GL naming convention,
2598 * D3DFILTER_LINEARMIPNEAREST corresponds to GL_NEAREST_MIPMAP_LINEAR.
2600 case D3DRENDERSTATE_TEXTUREMAG
:
2602 WINED3DTEXTUREFILTERTYPE tex_mag
;
2606 case D3DFILTER_NEAREST
:
2607 case D3DFILTER_MIPNEAREST
:
2608 case D3DFILTER_LINEARMIPNEAREST
:
2609 tex_mag
= WINED3DTEXF_POINT
;
2611 case D3DFILTER_LINEAR
:
2612 case D3DFILTER_MIPLINEAR
:
2613 case D3DFILTER_LINEARMIPLINEAR
:
2614 tex_mag
= WINED3DTEXF_LINEAR
;
2617 tex_mag
= WINED3DTEXF_POINT
;
2618 ERR("Unhandled texture mag %d !\n",Value
);
2622 hr
= IWineD3DDevice_SetSamplerState(This
->wineD3DDevice
,
2623 0, WINED3DSAMP_MAGFILTER
,
2628 case D3DRENDERSTATE_TEXTUREMIN
:
2630 WINED3DTEXTUREFILTERTYPE tex_min
;
2631 WINED3DTEXTUREFILTERTYPE tex_mip
;
2633 switch ((D3DTEXTUREFILTER
) Value
)
2635 case D3DFILTER_NEAREST
:
2636 tex_min
= WINED3DTEXF_POINT
;
2637 tex_mip
= WINED3DTEXF_NONE
;
2639 case D3DFILTER_LINEAR
:
2640 tex_min
= WINED3DTEXF_LINEAR
;
2641 tex_mip
= WINED3DTEXF_NONE
;
2643 case D3DFILTER_MIPNEAREST
:
2644 tex_min
= WINED3DTEXF_POINT
;
2645 tex_mip
= WINED3DTEXF_POINT
;
2647 case D3DFILTER_MIPLINEAR
:
2648 tex_min
= WINED3DTEXF_LINEAR
;
2649 tex_mip
= WINED3DTEXF_POINT
;
2651 case D3DFILTER_LINEARMIPNEAREST
:
2652 tex_min
= WINED3DTEXF_POINT
;
2653 tex_mip
= WINED3DTEXF_LINEAR
;
2655 case D3DFILTER_LINEARMIPLINEAR
:
2656 tex_min
= WINED3DTEXF_LINEAR
;
2657 tex_mip
= WINED3DTEXF_LINEAR
;
2661 ERR("Unhandled texture min %d !\n",Value
);
2662 tex_min
= WINED3DTEXF_POINT
;
2663 tex_mip
= WINED3DTEXF_NONE
;
2667 IWineD3DDevice_SetSamplerState(This
->wineD3DDevice
,
2668 0, WINED3DSAMP_MIPFILTER
, tex_mip
);
2669 hr
= IWineD3DDevice_SetSamplerState(This
->wineD3DDevice
,
2670 0, WINED3DSAMP_MINFILTER
,
2675 case D3DRENDERSTATE_TEXTUREADDRESS
:
2676 IWineD3DDevice_SetSamplerState(This
->wineD3DDevice
,
2677 0, WINED3DSAMP_ADDRESSV
,
2680 case D3DRENDERSTATE_TEXTUREADDRESSU
:
2681 hr
= IWineD3DDevice_SetSamplerState(This
->wineD3DDevice
,
2682 0, WINED3DSAMP_ADDRESSU
,
2685 case D3DRENDERSTATE_TEXTUREADDRESSV
:
2686 hr
= IWineD3DDevice_SetSamplerState(This
->wineD3DDevice
,
2687 0, WINED3DSAMP_ADDRESSV
,
2691 case D3DRENDERSTATE_BORDERCOLOR
:
2692 /* This should probably just forward to the corresponding sampler
2693 * state. Needs tests. */
2694 FIXME("Unhandled render state D3DRENDERSTATE_BORDERCOLOR.\n");
2698 case D3DRENDERSTATE_TEXTUREHANDLE
:
2699 case D3DRENDERSTATE_TEXTUREMAPBLEND
:
2700 WARN("Render state %#x is invalid in d3d7.\n", RenderStateType
);
2701 hr
= DDERR_INVALIDPARAMS
;
2705 if (RenderStateType
>= D3DRENDERSTATE_STIPPLEPATTERN00
2706 && RenderStateType
<= D3DRENDERSTATE_STIPPLEPATTERN31
)
2708 FIXME("Unhandled stipple pattern render state (%#x).\n",
2714 hr
= IWineD3DDevice_SetRenderState(This
->wineD3DDevice
,
2719 LeaveCriticalSection(&ddraw_cs
);
2723 static HRESULT WINAPI
2724 IDirect3DDeviceImpl_7_SetRenderState_FPUSetup(IDirect3DDevice7
*iface
,
2725 D3DRENDERSTATETYPE RenderStateType
,
2728 return IDirect3DDeviceImpl_7_SetRenderState(iface
, RenderStateType
, Value
);
2731 static HRESULT WINAPI
2732 IDirect3DDeviceImpl_7_SetRenderState_FPUPreserve(IDirect3DDevice7
*iface
,
2733 D3DRENDERSTATETYPE RenderStateType
,
2739 old_fpucw
= d3d_fpu_setup();
2740 hr
= IDirect3DDeviceImpl_7_SetRenderState(iface
, RenderStateType
, Value
);
2741 set_fpu_control_word(old_fpucw
);
2746 static HRESULT WINAPI
2747 IDirect3DDeviceImpl_3_SetRenderState(IDirect3DDevice3
*iface
,
2748 D3DRENDERSTATETYPE RenderStateType
,
2751 /* Note about D3DRENDERSTATE_TEXTUREMAPBLEND implementation: most of values
2752 for this state can be directly mapped to texture stage colorop and alphaop, but
2753 D3DTBLEND_MODULATE is tricky: it uses alpha from texture when available and alpha
2754 from diffuse otherwise. So changing the texture must be monitored in SetTexture to modify
2755 alphaarg when needed.
2757 Aliens vs Predator 1 depends on accurate D3DTBLEND_MODULATE emulation
2759 Legacy texture blending (TEXTUREMAPBLEND) and texture stage states: directx6 docs state that
2760 TEXTUREMAPBLEND is deprecated, yet can still be used. Games must not use both or results
2761 are undefined. D3DTBLEND_MODULATE mode in particular is dependent on texture pixel format and
2762 requires fixup of stage 0 texture states when texture changes, but this fixup can interfere
2763 with games not using this deprecated state. So a flag 'legacyTextureBlending' has to be kept
2764 in device - TRUE if the app is using TEXTUREMAPBLEND.
2766 Tests show that setting TEXTUREMAPBLEND on native doesn't seem to change values returned by
2767 GetTextureStageState and vice versa. Not so on Wine, but it is 'undefined' anyway so, probably, ok,
2768 unless some broken game will be found that cares. */
2771 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
2773 TRACE("iface %p, state %#x, value %#x.\n", iface
, RenderStateType
, Value
);
2775 EnterCriticalSection(&ddraw_cs
);
2777 switch(RenderStateType
)
2779 case D3DRENDERSTATE_TEXTUREHANDLE
:
2781 IDirectDrawSurfaceImpl
*surf
;
2785 hr
= IWineD3DDevice_SetTexture(This
->wineD3DDevice
,
2791 surf
= ddraw_get_object(&This
->handle_table
, Value
- 1, DDRAW_HANDLE_SURFACE
);
2794 WARN("Invalid texture handle.\n");
2795 hr
= DDERR_INVALIDPARAMS
;
2799 hr
= IDirect3DDevice3_SetTexture(iface
, 0, (IDirect3DTexture2
*)&surf
->IDirect3DTexture2_vtbl
);
2803 case D3DRENDERSTATE_TEXTUREMAPBLEND
:
2805 This
->legacyTextureBlending
= TRUE
;
2807 switch ( (D3DTEXTUREBLEND
) Value
)
2809 case D3DTBLEND_MODULATE
:
2811 BOOL tex_alpha
= FALSE
;
2812 IWineD3DBaseTexture
*tex
= NULL
;
2813 WINED3DSURFACE_DESC desc
;
2814 DDPIXELFORMAT ddfmt
;
2816 hr
= IWineD3DDevice_GetTexture(This
->wineD3DDevice
,
2820 if(hr
== WINED3D_OK
&& tex
)
2822 memset(&desc
, 0, sizeof(desc
));
2823 hr
= IWineD3DTexture_GetLevelDesc((IWineD3DTexture
*) tex
, 0, &desc
);
2826 ddfmt
.dwSize
= sizeof(ddfmt
);
2827 PixelFormat_WineD3DtoDD(&ddfmt
, desc
.format
);
2828 if (ddfmt
.u5
.dwRGBAlphaBitMask
) tex_alpha
= TRUE
;
2831 IWineD3DBaseTexture_Release(tex
);
2835 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAOP
, WINED3DTOP_SELECTARG1
);
2837 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAOP
, WINED3DTOP_SELECTARG2
);
2838 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAARG1
, WINED3DTA_TEXTURE
);
2839 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAARG2
, WINED3DTA_CURRENT
);
2840 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_COLORARG1
, WINED3DTA_TEXTURE
);
2841 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_COLORARG2
, WINED3DTA_CURRENT
);
2842 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_COLOROP
, WINED3DTOP_MODULATE
);
2848 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_COLOROP
, WINED3DTOP_ADD
);
2849 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_COLORARG1
, WINED3DTA_TEXTURE
);
2850 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_COLORARG2
, WINED3DTA_CURRENT
);
2851 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAOP
, WINED3DTOP_SELECTARG2
);
2852 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAARG2
, WINED3DTA_CURRENT
);
2855 case D3DTBLEND_MODULATEALPHA
:
2856 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_COLORARG1
, WINED3DTA_TEXTURE
);
2857 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAARG1
, WINED3DTA_TEXTURE
);
2858 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_COLORARG2
, WINED3DTA_CURRENT
);
2859 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAARG2
, WINED3DTA_CURRENT
);
2860 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_COLOROP
, WINED3DTOP_MODULATE
);
2861 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAOP
, WINED3DTOP_MODULATE
);
2864 case D3DTBLEND_COPY
:
2865 case D3DTBLEND_DECAL
:
2866 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_COLORARG1
, WINED3DTA_TEXTURE
);
2867 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAARG1
, WINED3DTA_TEXTURE
);
2868 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_COLOROP
, WINED3DTOP_SELECTARG1
);
2869 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAOP
, WINED3DTOP_SELECTARG1
);
2872 case D3DTBLEND_DECALALPHA
:
2873 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_COLOROP
, WINED3DTOP_BLENDTEXTUREALPHA
);
2874 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_COLORARG1
, WINED3DTA_TEXTURE
);
2875 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_COLORARG2
, WINED3DTA_CURRENT
);
2876 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAOP
, WINED3DTOP_SELECTARG2
);
2877 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAARG2
, WINED3DTA_CURRENT
);
2881 ERR("Unhandled texture environment %d !\n",Value
);
2889 hr
= IDirect3DDevice7_SetRenderState((IDirect3DDevice7
*)This
, RenderStateType
, Value
);
2893 LeaveCriticalSection(&ddraw_cs
);
2898 static HRESULT WINAPI
IDirect3DDeviceImpl_2_SetRenderState(IDirect3DDevice2
*iface
,
2899 D3DRENDERSTATETYPE RenderStateType
, DWORD Value
)
2901 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
2903 TRACE("iface %p, state %#x, value %#x.\n", iface
, RenderStateType
, Value
);
2905 return IDirect3DDevice3_SetRenderState((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
, RenderStateType
, Value
);
2908 /*****************************************************************************
2909 * Direct3DDevice3::SetLightState
2911 * Sets a light state for Direct3DDevice3 and Direct3DDevice2. The
2912 * light states are forwarded to Direct3DDevice7 render states
2917 * LightStateType: The light state to change
2918 * Value: The value to assign to that light state
2922 * DDERR_INVALIDPARAMS if the parameters were incorrect
2923 * Also check IDirect3DDevice7::SetRenderState
2925 *****************************************************************************/
2926 static HRESULT WINAPI
2927 IDirect3DDeviceImpl_3_SetLightState(IDirect3DDevice3
*iface
,
2928 D3DLIGHTSTATETYPE LightStateType
,
2931 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
2934 TRACE("iface %p, state %#x, value %#x.\n", iface
, LightStateType
, Value
);
2936 if (!LightStateType
|| (LightStateType
> D3DLIGHTSTATE_COLORVERTEX
))
2938 TRACE("Unexpected Light State Type\n");
2939 return DDERR_INVALIDPARAMS
;
2942 EnterCriticalSection(&ddraw_cs
);
2943 if (LightStateType
== D3DLIGHTSTATE_MATERIAL
/* 1 */)
2945 IDirect3DMaterialImpl
*m
= ddraw_get_object(&This
->handle_table
, Value
- 1, DDRAW_HANDLE_MATERIAL
);
2948 WARN("Invalid material handle.\n");
2949 LeaveCriticalSection(&ddraw_cs
);
2950 return DDERR_INVALIDPARAMS
;
2953 TRACE(" activating material %p.\n", m
);
2954 material_activate(m
);
2956 This
->material
= Value
;
2958 else if (LightStateType
== D3DLIGHTSTATE_COLORMODEL
/* 3 */)
2963 ERR("DDCOLOR_MONO should not happen!\n");
2966 /* We are already in this mode */
2967 TRACE("Setting color model to RGB (no-op).\n");
2970 ERR("Unknown color model!\n");
2971 LeaveCriticalSection(&ddraw_cs
);
2972 return DDERR_INVALIDPARAMS
;
2977 D3DRENDERSTATETYPE rs
;
2978 switch (LightStateType
)
2980 case D3DLIGHTSTATE_AMBIENT
: /* 2 */
2981 rs
= D3DRENDERSTATE_AMBIENT
;
2983 case D3DLIGHTSTATE_FOGMODE
: /* 4 */
2984 rs
= D3DRENDERSTATE_FOGVERTEXMODE
;
2986 case D3DLIGHTSTATE_FOGSTART
: /* 5 */
2987 rs
= D3DRENDERSTATE_FOGSTART
;
2989 case D3DLIGHTSTATE_FOGEND
: /* 6 */
2990 rs
= D3DRENDERSTATE_FOGEND
;
2992 case D3DLIGHTSTATE_FOGDENSITY
: /* 7 */
2993 rs
= D3DRENDERSTATE_FOGDENSITY
;
2995 case D3DLIGHTSTATE_COLORVERTEX
: /* 8 */
2996 rs
= D3DRENDERSTATE_COLORVERTEX
;
2999 ERR("Unknown D3DLIGHTSTATETYPE %d.\n", LightStateType
);
3000 LeaveCriticalSection(&ddraw_cs
);
3001 return DDERR_INVALIDPARAMS
;
3004 hr
= IDirect3DDevice7_SetRenderState((IDirect3DDevice7
*)This
, rs
, Value
);
3005 LeaveCriticalSection(&ddraw_cs
);
3009 LeaveCriticalSection(&ddraw_cs
);
3013 static HRESULT WINAPI
IDirect3DDeviceImpl_2_SetLightState(IDirect3DDevice2
*iface
,
3014 D3DLIGHTSTATETYPE LightStateType
, DWORD Value
)
3016 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
3018 TRACE("iface %p, state %#x, value %#x.\n", iface
, LightStateType
, Value
);
3020 return IDirect3DDevice3_SetLightState((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
, LightStateType
, Value
);
3023 /*****************************************************************************
3024 * IDirect3DDevice3::GetLightState
3026 * Returns the current setting of a light state. The state is read from
3027 * the Direct3DDevice7 render state.
3032 * LightStateType: The light state to return
3033 * Value: The address to store the light state setting at
3037 * DDDERR_INVALIDPARAMS if the parameters were incorrect
3038 * Also see IDirect3DDevice7::GetRenderState
3040 *****************************************************************************/
3041 static HRESULT WINAPI
3042 IDirect3DDeviceImpl_3_GetLightState(IDirect3DDevice3
*iface
,
3043 D3DLIGHTSTATETYPE LightStateType
,
3046 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
3049 TRACE("iface %p, state %#x, value %p.\n", iface
, LightStateType
, Value
);
3051 if (!LightStateType
|| (LightStateType
> D3DLIGHTSTATE_COLORVERTEX
))
3053 TRACE("Unexpected Light State Type\n");
3054 return DDERR_INVALIDPARAMS
;
3058 return DDERR_INVALIDPARAMS
;
3060 EnterCriticalSection(&ddraw_cs
);
3061 if (LightStateType
== D3DLIGHTSTATE_MATERIAL
/* 1 */)
3063 *Value
= This
->material
;
3065 else if (LightStateType
== D3DLIGHTSTATE_COLORMODEL
/* 3 */)
3067 *Value
= D3DCOLOR_RGB
;
3071 D3DRENDERSTATETYPE rs
;
3072 switch (LightStateType
)
3074 case D3DLIGHTSTATE_AMBIENT
: /* 2 */
3075 rs
= D3DRENDERSTATE_AMBIENT
;
3077 case D3DLIGHTSTATE_FOGMODE
: /* 4 */
3078 rs
= D3DRENDERSTATE_FOGVERTEXMODE
;
3080 case D3DLIGHTSTATE_FOGSTART
: /* 5 */
3081 rs
= D3DRENDERSTATE_FOGSTART
;
3083 case D3DLIGHTSTATE_FOGEND
: /* 6 */
3084 rs
= D3DRENDERSTATE_FOGEND
;
3086 case D3DLIGHTSTATE_FOGDENSITY
: /* 7 */
3087 rs
= D3DRENDERSTATE_FOGDENSITY
;
3089 case D3DLIGHTSTATE_COLORVERTEX
: /* 8 */
3090 rs
= D3DRENDERSTATE_COLORVERTEX
;
3093 ERR("Unknown D3DLIGHTSTATETYPE %d.\n", LightStateType
);
3094 LeaveCriticalSection(&ddraw_cs
);
3095 return DDERR_INVALIDPARAMS
;
3098 hr
= IDirect3DDevice7_GetRenderState((IDirect3DDevice7
*)This
, rs
, Value
);
3099 LeaveCriticalSection(&ddraw_cs
);
3103 LeaveCriticalSection(&ddraw_cs
);
3107 static HRESULT WINAPI
IDirect3DDeviceImpl_2_GetLightState(IDirect3DDevice2
*iface
,
3108 D3DLIGHTSTATETYPE LightStateType
, DWORD
*Value
)
3110 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
3112 TRACE("iface %p, state %#x, value %p.\n", iface
, LightStateType
, Value
);
3114 return IDirect3DDevice3_GetLightState((IDirect3DDevice3
*)&This
->IDirect3DDevice3_vtbl
, LightStateType
, Value
);
3117 /*****************************************************************************
3118 * IDirect3DDevice7::SetTransform
3120 * Assigns a D3DMATRIX to a transform type. The transform types are defined
3121 * in include/d3dtypes.h.
3122 * The D3DTRANSFORMSTATE_WORLD (=1) is translated to D3DTS_WORLDMATRIX(0)
3123 * (=255) for wined3d, because the 1 transform state was removed in d3d8
3124 * and WineD3D already understands the replacement D3DTS_WORLDMATRIX(0)
3126 * Version 2, 3 and 7
3129 * TransformStateType: transform state to set
3130 * Matrix: Matrix to assign to the state
3134 * DDERR_INVALIDPARAMS if Matrix == NULL
3135 * For details see IWineD3DDevice::SetTransform
3137 *****************************************************************************/
3139 IDirect3DDeviceImpl_7_SetTransform(IDirect3DDevice7
*iface
,
3140 D3DTRANSFORMSTATETYPE TransformStateType
,
3143 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
3144 D3DTRANSFORMSTATETYPE type
;
3147 TRACE("iface %p, state %#x, matrix %p.\n", iface
, TransformStateType
, Matrix
);
3149 switch(TransformStateType
)
3151 case D3DTRANSFORMSTATE_WORLD
: type
= WINED3DTS_WORLDMATRIX(0); break;
3152 case D3DTRANSFORMSTATE_WORLD1
: type
= WINED3DTS_WORLDMATRIX(1); break;
3153 case D3DTRANSFORMSTATE_WORLD2
: type
= WINED3DTS_WORLDMATRIX(2); break;
3154 case D3DTRANSFORMSTATE_WORLD3
: type
= WINED3DTS_WORLDMATRIX(3); break;
3155 default: type
= TransformStateType
;
3159 return DDERR_INVALIDPARAMS
;
3161 /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
3162 EnterCriticalSection(&ddraw_cs
);
3163 hr
= IWineD3DDevice_SetTransform(This
->wineD3DDevice
,
3165 (WINED3DMATRIX
*) Matrix
);
3166 LeaveCriticalSection(&ddraw_cs
);
3170 static HRESULT WINAPI
3171 IDirect3DDeviceImpl_7_SetTransform_FPUSetup(IDirect3DDevice7
*iface
,
3172 D3DTRANSFORMSTATETYPE TransformStateType
,
3175 return IDirect3DDeviceImpl_7_SetTransform(iface
, TransformStateType
, Matrix
);
3178 static HRESULT WINAPI
3179 IDirect3DDeviceImpl_7_SetTransform_FPUPreserve(IDirect3DDevice7
*iface
,
3180 D3DTRANSFORMSTATETYPE TransformStateType
,
3186 old_fpucw
= d3d_fpu_setup();
3187 hr
= IDirect3DDeviceImpl_7_SetTransform(iface
, TransformStateType
, Matrix
);
3188 set_fpu_control_word(old_fpucw
);
3193 static HRESULT WINAPI
IDirect3DDeviceImpl_3_SetTransform(IDirect3DDevice3
*iface
,
3194 D3DTRANSFORMSTATETYPE TransformStateType
, D3DMATRIX
*D3DMatrix
)
3196 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
3198 TRACE("iface %p, state %#x, matrix %p.\n", iface
, TransformStateType
, D3DMatrix
);
3200 return IDirect3DDevice7_SetTransform((IDirect3DDevice7
*)This
, TransformStateType
, D3DMatrix
);
3203 static HRESULT WINAPI
IDirect3DDeviceImpl_2_SetTransform(IDirect3DDevice2
*iface
,
3204 D3DTRANSFORMSTATETYPE TransformStateType
, D3DMATRIX
*D3DMatrix
)
3206 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
3208 TRACE("iface %p, state %#x, matrix %p.\n", iface
, TransformStateType
, D3DMatrix
);
3210 return IDirect3DDevice7_SetTransform((IDirect3DDevice7
*)This
, TransformStateType
, D3DMatrix
);
3213 /*****************************************************************************
3214 * IDirect3DDevice7::GetTransform
3216 * Returns the matrix assigned to a transform state
3217 * D3DTRANSFORMSTATE_WORLD is translated to D3DTS_WORLDMATRIX(0), see
3221 * TransformStateType: State to read the matrix from
3222 * Matrix: Address to store the matrix at
3226 * DDERR_INVALIDPARAMS if Matrix == NULL
3227 * For details, see IWineD3DDevice::GetTransform
3229 *****************************************************************************/
3231 IDirect3DDeviceImpl_7_GetTransform(IDirect3DDevice7
*iface
,
3232 D3DTRANSFORMSTATETYPE TransformStateType
,
3235 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
3236 D3DTRANSFORMSTATETYPE type
;
3239 TRACE("iface %p, state %#x, matrix %p.\n", iface
, TransformStateType
, Matrix
);
3241 switch(TransformStateType
)
3243 case D3DTRANSFORMSTATE_WORLD
: type
= WINED3DTS_WORLDMATRIX(0); break;
3244 case D3DTRANSFORMSTATE_WORLD1
: type
= WINED3DTS_WORLDMATRIX(1); break;
3245 case D3DTRANSFORMSTATE_WORLD2
: type
= WINED3DTS_WORLDMATRIX(2); break;
3246 case D3DTRANSFORMSTATE_WORLD3
: type
= WINED3DTS_WORLDMATRIX(3); break;
3247 default: type
= TransformStateType
;
3251 return DDERR_INVALIDPARAMS
;
3253 /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
3254 EnterCriticalSection(&ddraw_cs
);
3255 hr
= IWineD3DDevice_GetTransform(This
->wineD3DDevice
, type
, (WINED3DMATRIX
*) Matrix
);
3256 LeaveCriticalSection(&ddraw_cs
);
3260 static HRESULT WINAPI
3261 IDirect3DDeviceImpl_7_GetTransform_FPUSetup(IDirect3DDevice7
*iface
,
3262 D3DTRANSFORMSTATETYPE TransformStateType
,
3265 return IDirect3DDeviceImpl_7_GetTransform(iface
, TransformStateType
, Matrix
);
3268 static HRESULT WINAPI
3269 IDirect3DDeviceImpl_7_GetTransform_FPUPreserve(IDirect3DDevice7
*iface
,
3270 D3DTRANSFORMSTATETYPE TransformStateType
,
3276 old_fpucw
= d3d_fpu_setup();
3277 hr
= IDirect3DDeviceImpl_7_GetTransform(iface
, TransformStateType
, Matrix
);
3278 set_fpu_control_word(old_fpucw
);
3283 static HRESULT WINAPI
IDirect3DDeviceImpl_3_GetTransform(IDirect3DDevice3
*iface
,
3284 D3DTRANSFORMSTATETYPE TransformStateType
, D3DMATRIX
*D3DMatrix
)
3286 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
3288 TRACE("iface %p, state %#x, matrix %p.\n", iface
, TransformStateType
, D3DMatrix
);
3290 return IDirect3DDevice7_GetTransform((IDirect3DDevice7
*)This
, TransformStateType
, D3DMatrix
);
3293 static HRESULT WINAPI
IDirect3DDeviceImpl_2_GetTransform(IDirect3DDevice2
*iface
,
3294 D3DTRANSFORMSTATETYPE TransformStateType
, D3DMATRIX
*D3DMatrix
)
3296 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
3298 TRACE("iface %p, state %#x, matrix %p.\n", iface
, TransformStateType
, D3DMatrix
);
3300 return IDirect3DDevice7_GetTransform((IDirect3DDevice7
*)This
, TransformStateType
, D3DMatrix
);
3303 /*****************************************************************************
3304 * IDirect3DDevice7::MultiplyTransform
3306 * Multiplies the already-set transform matrix of a transform state
3307 * with another matrix. For the world matrix, see SetTransform
3309 * Version 2, 3 and 7
3312 * TransformStateType: Transform state to multiply
3313 * D3DMatrix Matrix to multiply with.
3317 * DDERR_INVALIDPARAMS if D3DMatrix is NULL
3318 * For details, see IWineD3DDevice::MultiplyTransform
3320 *****************************************************************************/
3322 IDirect3DDeviceImpl_7_MultiplyTransform(IDirect3DDevice7
*iface
,
3323 D3DTRANSFORMSTATETYPE TransformStateType
,
3324 D3DMATRIX
*D3DMatrix
)
3326 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
3328 D3DTRANSFORMSTATETYPE type
;
3330 TRACE("iface %p, state %#x, matrix %p.\n", iface
, TransformStateType
, D3DMatrix
);
3332 switch(TransformStateType
)
3334 case D3DTRANSFORMSTATE_WORLD
: type
= WINED3DTS_WORLDMATRIX(0); break;
3335 case D3DTRANSFORMSTATE_WORLD1
: type
= WINED3DTS_WORLDMATRIX(1); break;
3336 case D3DTRANSFORMSTATE_WORLD2
: type
= WINED3DTS_WORLDMATRIX(2); break;
3337 case D3DTRANSFORMSTATE_WORLD3
: type
= WINED3DTS_WORLDMATRIX(3); break;
3338 default: type
= TransformStateType
;
3341 /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
3342 EnterCriticalSection(&ddraw_cs
);
3343 hr
= IWineD3DDevice_MultiplyTransform(This
->wineD3DDevice
,
3345 (WINED3DMATRIX
*) D3DMatrix
);
3346 LeaveCriticalSection(&ddraw_cs
);
3350 static HRESULT WINAPI
3351 IDirect3DDeviceImpl_7_MultiplyTransform_FPUSetup(IDirect3DDevice7
*iface
,
3352 D3DTRANSFORMSTATETYPE TransformStateType
,
3353 D3DMATRIX
*D3DMatrix
)
3355 return IDirect3DDeviceImpl_7_MultiplyTransform(iface
, TransformStateType
, D3DMatrix
);
3358 static HRESULT WINAPI
3359 IDirect3DDeviceImpl_7_MultiplyTransform_FPUPreserve(IDirect3DDevice7
*iface
,
3360 D3DTRANSFORMSTATETYPE TransformStateType
,
3361 D3DMATRIX
*D3DMatrix
)
3366 old_fpucw
= d3d_fpu_setup();
3367 hr
= IDirect3DDeviceImpl_7_MultiplyTransform(iface
, TransformStateType
, D3DMatrix
);
3368 set_fpu_control_word(old_fpucw
);
3373 static HRESULT WINAPI
IDirect3DDeviceImpl_3_MultiplyTransform(IDirect3DDevice3
*iface
,
3374 D3DTRANSFORMSTATETYPE TransformStateType
, D3DMATRIX
*D3DMatrix
)
3376 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
3378 TRACE("iface %p, state %#x, matrix %p.\n", iface
, TransformStateType
, D3DMatrix
);
3380 return IDirect3DDevice7_MultiplyTransform((IDirect3DDevice7
*)This
, TransformStateType
, D3DMatrix
);
3383 static HRESULT WINAPI
IDirect3DDeviceImpl_2_MultiplyTransform(IDirect3DDevice2
*iface
,
3384 D3DTRANSFORMSTATETYPE TransformStateType
, D3DMATRIX
*D3DMatrix
)
3386 IDirect3DDeviceImpl
*This
= device_from_device2(iface
);
3388 TRACE("iface %p, state %#x, matrix %p.\n", iface
, TransformStateType
, D3DMatrix
);
3390 return IDirect3DDevice7_MultiplyTransform((IDirect3DDevice7
*)This
, TransformStateType
, D3DMatrix
);
3393 /*****************************************************************************
3394 * IDirect3DDevice7::DrawPrimitive
3396 * Draws primitives based on vertices in an application-provided pointer
3398 * Version 2, 3 and 7. The IDirect3DDevice2 thunk converts the fixed vertex type into
3399 * an FVF format for D3D7
3402 * PrimitiveType: The type of the primitives to draw
3403 * Vertex type: Flexible vertex format vertex description
3404 * Vertices: Pointer to the vertex array
3405 * VertexCount: The number of vertices to draw
3406 * Flags: As usual a few flags
3410 * DDERR_INVALIDPARAMS if Vertices is NULL
3411 * For details, see IWineD3DDevice::DrawPrimitiveUP
3413 *****************************************************************************/
3415 IDirect3DDeviceImpl_7_DrawPrimitive(IDirect3DDevice7
*iface
,
3416 D3DPRIMITIVETYPE PrimitiveType
,
3422 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
3426 TRACE("iface %p, primitive_type %#x, FVF %#x, vertices %p, vertex_count %u, flags %#x.\n",
3427 iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Flags
);
3430 return DDERR_INVALIDPARAMS
;
3432 /* Get the stride */
3433 stride
= get_flexible_vertex_size(VertexType
);
3436 EnterCriticalSection(&ddraw_cs
);
3437 hr
= IWineD3DDevice_SetVertexDeclaration(This
->wineD3DDevice
, ddraw_find_decl(This
->ddraw
, VertexType
));
3440 LeaveCriticalSection(&ddraw_cs
);
3444 /* This method translates to the user pointer draw of WineD3D */
3445 IWineD3DDevice_SetPrimitiveType(This
->wineD3DDevice
, PrimitiveType
);
3446 hr
= IWineD3DDevice_DrawPrimitiveUP(This
->wineD3DDevice
, VertexCount
, Vertices
, stride
);
3447 LeaveCriticalSection(&ddraw_cs
);
3451 static HRESULT WINAPI
3452 IDirect3DDeviceImpl_7_DrawPrimitive_FPUSetup(IDirect3DDevice7
*iface
,
3453 D3DPRIMITIVETYPE PrimitiveType
,
3459 return IDirect3DDeviceImpl_7_DrawPrimitive(iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Flags
);
3462 static HRESULT WINAPI
3463 IDirect3DDeviceImpl_7_DrawPrimitive_FPUPreserve(IDirect3DDevice7
*iface
,
3464 D3DPRIMITIVETYPE PrimitiveType
,
3473 old_fpucw
= d3d_fpu_setup();
3474 hr
= IDirect3DDeviceImpl_7_DrawPrimitive(iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Flags
);
3475 set_fpu_control_word(old_fpucw
);
3480 static HRESULT WINAPI
IDirect3DDeviceImpl_3_DrawPrimitive(IDirect3DDevice3
*iface
,
3481 D3DPRIMITIVETYPE PrimitiveType
, DWORD VertexType
, void *Vertices
, DWORD VertexCount
,
3484 TRACE("iface %p, primitive_type %#x, FVF %#x, vertices %p, vertex_count %u, flags %#x.\n",
3485 iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Flags
);
3487 return IDirect3DDevice7_DrawPrimitive((IDirect3DDevice7
*)device_from_device3(iface
),
3488 PrimitiveType
, VertexType
, Vertices
, VertexCount
, Flags
);
3491 static HRESULT WINAPI
IDirect3DDeviceImpl_2_DrawPrimitive(IDirect3DDevice2
*iface
,
3492 D3DPRIMITIVETYPE PrimitiveType
, D3DVERTEXTYPE VertexType
, void *Vertices
,
3493 DWORD VertexCount
, DWORD Flags
)
3497 TRACE("iface %p, primitive_type %#x, vertex_type %#x, vertices %p, vertex_count %u, flags %#x.\n",
3498 iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Flags
);
3502 case D3DVT_VERTEX
: FVF
= D3DFVF_VERTEX
; break;
3503 case D3DVT_LVERTEX
: FVF
= D3DFVF_LVERTEX
; break;
3504 case D3DVT_TLVERTEX
: FVF
= D3DFVF_TLVERTEX
; break;
3506 ERR("Unexpected vertex type %d\n", VertexType
);
3507 return DDERR_INVALIDPARAMS
; /* Should never happen */
3510 return IDirect3DDevice7_DrawPrimitive((IDirect3DDevice7
*)device_from_device2(iface
),
3511 PrimitiveType
, FVF
, Vertices
, VertexCount
, Flags
);
3514 /*****************************************************************************
3515 * IDirect3DDevice7::DrawIndexedPrimitive
3517 * Draws vertices from an application-provided pointer, based on the index
3518 * numbers in a WORD array.
3520 * Version 2, 3 and 7. The version 7 thunk translates the vertex type into
3521 * an FVF format for D3D7
3524 * PrimitiveType: The primitive type to draw
3525 * VertexType: The FVF vertex description
3526 * Vertices: Pointer to the vertex array
3528 * Indices: Pointer to the index array
3529 * IndexCount: Number of indices = Number of vertices to draw
3530 * Flags: As usual, some flags
3534 * DDERR_INVALIDPARAMS if Vertices or Indices is NULL
3535 * For details, see IWineD3DDevice::DrawIndexedPrimitiveUP
3537 *****************************************************************************/
3539 IDirect3DDeviceImpl_7_DrawIndexedPrimitive(IDirect3DDevice7
*iface
,
3540 D3DPRIMITIVETYPE PrimitiveType
,
3548 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
3551 TRACE("iface %p, primitive_type %#x, FVF %#x, vertices %p, vertex_count %u, indices %p, index_count %u, flags %#x.\n",
3552 iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Indices
, IndexCount
, Flags
);
3554 /* Set the D3DDevice's FVF */
3555 EnterCriticalSection(&ddraw_cs
);
3556 hr
= IWineD3DDevice_SetVertexDeclaration(This
->wineD3DDevice
, ddraw_find_decl(This
->ddraw
, VertexType
));
3559 ERR(" (%p) Setting the FVF failed, hr = %x!\n", This
, hr
);
3560 LeaveCriticalSection(&ddraw_cs
);
3564 IWineD3DDevice_SetPrimitiveType(This
->wineD3DDevice
, PrimitiveType
);
3565 hr
= IWineD3DDevice_DrawIndexedPrimitiveUP(This
->wineD3DDevice
, IndexCount
, Indices
,
3566 WINED3DFMT_R16_UINT
, Vertices
, get_flexible_vertex_size(VertexType
));
3567 LeaveCriticalSection(&ddraw_cs
);
3571 static HRESULT WINAPI
3572 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUSetup(IDirect3DDevice7
*iface
,
3573 D3DPRIMITIVETYPE PrimitiveType
,
3581 return IDirect3DDeviceImpl_7_DrawIndexedPrimitive(iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Indices
, IndexCount
, Flags
);
3584 static HRESULT WINAPI
3585 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUPreserve(IDirect3DDevice7
*iface
,
3586 D3DPRIMITIVETYPE PrimitiveType
,
3597 old_fpucw
= d3d_fpu_setup();
3598 hr
= IDirect3DDeviceImpl_7_DrawIndexedPrimitive(iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Indices
, IndexCount
, Flags
);
3599 set_fpu_control_word(old_fpucw
);
3604 static HRESULT WINAPI
IDirect3DDeviceImpl_3_DrawIndexedPrimitive(IDirect3DDevice3
*iface
,
3605 D3DPRIMITIVETYPE PrimitiveType
, DWORD VertexType
, void *Vertices
, DWORD VertexCount
,
3606 WORD
*Indices
, DWORD IndexCount
, DWORD Flags
)
3608 TRACE("iface %p, primitive_type %#x, FVF %#x, vertices %p, vertex_count %u, indices %p, index_count %u, flags %#x.\n",
3609 iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Indices
, IndexCount
, Flags
);
3611 return IDirect3DDevice7_DrawIndexedPrimitive((IDirect3DDevice7
*)device_from_device3(iface
),
3612 PrimitiveType
, VertexType
, Vertices
, VertexCount
, Indices
, IndexCount
, Flags
);
3615 static HRESULT WINAPI
IDirect3DDeviceImpl_2_DrawIndexedPrimitive(IDirect3DDevice2
*iface
,
3616 D3DPRIMITIVETYPE PrimitiveType
, D3DVERTEXTYPE VertexType
, void *Vertices
,
3617 DWORD VertexCount
, WORD
*Indices
, DWORD IndexCount
, DWORD Flags
)
3621 TRACE("iface %p, primitive_type %#x, vertex_type %#x, vertices %p, vertex_count %u, indices %p, index_count %u, flags %#x.\n",
3622 iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Indices
, IndexCount
, Flags
);
3626 case D3DVT_VERTEX
: FVF
= D3DFVF_VERTEX
; break;
3627 case D3DVT_LVERTEX
: FVF
= D3DFVF_LVERTEX
; break;
3628 case D3DVT_TLVERTEX
: FVF
= D3DFVF_TLVERTEX
; break;
3630 ERR("Unexpected vertex type %d\n", VertexType
);
3631 return DDERR_INVALIDPARAMS
; /* Should never happen */
3634 return IDirect3DDevice7_DrawIndexedPrimitive((IDirect3DDevice7
*)device_from_device2(iface
),
3635 PrimitiveType
, FVF
, Vertices
, VertexCount
, Indices
, IndexCount
, Flags
);
3638 /*****************************************************************************
3639 * IDirect3DDevice7::SetClipStatus
3641 * Sets the clip status. This defines things as clipping conditions and
3642 * the extents of the clipping region.
3644 * Version 2, 3 and 7
3650 * D3D_OK because it's a stub
3651 * (DDERR_INVALIDPARAMS if ClipStatus == NULL)
3653 *****************************************************************************/
3654 static HRESULT WINAPI
3655 IDirect3DDeviceImpl_7_SetClipStatus(IDirect3DDevice7
*iface
,
3656 D3DCLIPSTATUS
*ClipStatus
)
3658 FIXME("iface %p, clip_status %p stub!\n", iface
, ClipStatus
);
3660 /* D3DCLIPSTATUS and WINED3DCLIPSTATUS are different. I don't know how to convert them
3661 * Perhaps this needs a new data type and an additional IWineD3DDevice method
3663 /* return IWineD3DDevice_SetClipStatus(This->wineD3DDevice, ClipStatus);*/
3667 static HRESULT WINAPI
IDirect3DDeviceImpl_3_SetClipStatus(IDirect3DDevice3
*iface
,
3668 D3DCLIPSTATUS
*ClipStatus
)
3670 TRACE("iface %p, clip_status %p.\n", iface
, ClipStatus
);
3672 return IDirect3DDevice7_SetClipStatus((IDirect3DDevice7
*)device_from_device3(iface
), ClipStatus
);
3675 static HRESULT WINAPI
IDirect3DDeviceImpl_2_SetClipStatus(IDirect3DDevice2
*iface
,
3676 D3DCLIPSTATUS
*ClipStatus
)
3678 TRACE("iface %p, clip_status %p.\n", iface
, ClipStatus
);
3680 return IDirect3DDevice7_SetClipStatus((IDirect3DDevice7
*)device_from_device2(iface
), ClipStatus
);
3683 /*****************************************************************************
3684 * IDirect3DDevice7::GetClipStatus
3686 * Returns the clip status
3689 * ClipStatus: Address to write the clip status to
3692 * D3D_OK because it's a stub
3694 *****************************************************************************/
3695 static HRESULT WINAPI
3696 IDirect3DDeviceImpl_7_GetClipStatus(IDirect3DDevice7
*iface
,
3697 D3DCLIPSTATUS
*ClipStatus
)
3699 FIXME("iface %p, clip_status %p stub!\n", iface
, ClipStatus
);
3701 /* D3DCLIPSTATUS and WINED3DCLIPSTATUS are different. I don't know how to convert them */
3702 /* return IWineD3DDevice_GetClipStatus(This->wineD3DDevice, ClipStatus);*/
3706 static HRESULT WINAPI
IDirect3DDeviceImpl_3_GetClipStatus(IDirect3DDevice3
*iface
,
3707 D3DCLIPSTATUS
*ClipStatus
)
3709 TRACE("iface %p, clip_status %p.\n", iface
, ClipStatus
);
3711 return IDirect3DDevice7_GetClipStatus((IDirect3DDevice7
*)device_from_device3(iface
), ClipStatus
);
3714 static HRESULT WINAPI
IDirect3DDeviceImpl_2_GetClipStatus(IDirect3DDevice2
*iface
,
3715 D3DCLIPSTATUS
*ClipStatus
)
3717 TRACE("iface %p, clip_status %p.\n", iface
, ClipStatus
);
3719 return IDirect3DDevice7_GetClipStatus((IDirect3DDevice7
*)device_from_device2(iface
), ClipStatus
);
3722 /*****************************************************************************
3723 * IDirect3DDevice::DrawPrimitiveStrided
3725 * Draws vertices described by a D3DDRAWPRIMITIVESTRIDEDDATA structure.
3730 * PrimitiveType: The primitive type to draw
3731 * VertexType: The FVF description of the vertices to draw (for the stride??)
3732 * D3DDrawPrimStrideData: A D3DDRAWPRIMITIVESTRIDEDDATA structure describing
3733 * the vertex data locations
3734 * VertexCount: The number of vertices to draw
3738 * D3D_OK, because it's a stub
3739 * (DDERR_INVALIDPARAMS if D3DDrawPrimStrideData is NULL)
3740 * (For details, see IWineD3DDevice::DrawPrimitiveStrided)
3742 *****************************************************************************/
3744 IDirect3DDeviceImpl_7_DrawPrimitiveStrided(IDirect3DDevice7
*iface
,
3745 D3DPRIMITIVETYPE PrimitiveType
,
3747 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
,
3751 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
3752 WineDirect3DVertexStridedData WineD3DStrided
;
3756 TRACE("iface %p, primitive_type %#x, FVF %#x, strided_data %p, vertex_count %u, flags %#x.\n",
3757 iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Flags
);
3759 memset(&WineD3DStrided
, 0, sizeof(WineD3DStrided
));
3760 /* Get the strided data right. the wined3d structure is a bit bigger
3761 * Watch out: The contents of the strided data are determined by the fvf,
3762 * not by the members set in D3DDrawPrimStrideData. So it's valid
3763 * to have diffuse.lpvData set to 0xdeadbeef if the diffuse flag is
3764 * not set in the fvf.
3766 if(VertexType
& D3DFVF_POSITION_MASK
)
3768 WineD3DStrided
.position
.format
= WINED3DFMT_R32G32B32_FLOAT
;
3769 WineD3DStrided
.position
.lpData
= D3DDrawPrimStrideData
->position
.lpvData
;
3770 WineD3DStrided
.position
.dwStride
= D3DDrawPrimStrideData
->position
.dwStride
;
3771 if (VertexType
& D3DFVF_XYZRHW
)
3773 WineD3DStrided
.position
.format
= WINED3DFMT_R32G32B32A32_FLOAT
;
3774 WineD3DStrided
.position_transformed
= TRUE
;
3776 WineD3DStrided
.position_transformed
= FALSE
;
3779 if(VertexType
& D3DFVF_NORMAL
)
3781 WineD3DStrided
.normal
.format
= WINED3DFMT_R32G32B32_FLOAT
;
3782 WineD3DStrided
.normal
.lpData
= D3DDrawPrimStrideData
->normal
.lpvData
;
3783 WineD3DStrided
.normal
.dwStride
= D3DDrawPrimStrideData
->normal
.dwStride
;
3786 if(VertexType
& D3DFVF_DIFFUSE
)
3788 WineD3DStrided
.diffuse
.format
= WINED3DFMT_B8G8R8A8_UNORM
;
3789 WineD3DStrided
.diffuse
.lpData
= D3DDrawPrimStrideData
->diffuse
.lpvData
;
3790 WineD3DStrided
.diffuse
.dwStride
= D3DDrawPrimStrideData
->diffuse
.dwStride
;
3793 if(VertexType
& D3DFVF_SPECULAR
)
3795 WineD3DStrided
.specular
.format
= WINED3DFMT_B8G8R8A8_UNORM
;
3796 WineD3DStrided
.specular
.lpData
= D3DDrawPrimStrideData
->specular
.lpvData
;
3797 WineD3DStrided
.specular
.dwStride
= D3DDrawPrimStrideData
->specular
.dwStride
;
3800 for( i
= 0; i
< GET_TEXCOUNT_FROM_FVF(VertexType
); i
++)
3802 switch(GET_TEXCOORD_SIZE_FROM_FVF(VertexType
, i
))
3804 case 1: WineD3DStrided
.texCoords
[i
].format
= WINED3DFMT_R32_FLOAT
; break;
3805 case 2: WineD3DStrided
.texCoords
[i
].format
= WINED3DFMT_R32G32_FLOAT
; break;
3806 case 3: WineD3DStrided
.texCoords
[i
].format
= WINED3DFMT_R32G32B32_FLOAT
; break;
3807 case 4: WineD3DStrided
.texCoords
[i
].format
= WINED3DFMT_R32G32B32A32_FLOAT
; break;
3808 default: ERR("Unexpected texture coordinate size %d\n",
3809 GET_TEXCOORD_SIZE_FROM_FVF(VertexType
, i
));
3811 WineD3DStrided
.texCoords
[i
].lpData
= D3DDrawPrimStrideData
->textureCoords
[i
].lpvData
;
3812 WineD3DStrided
.texCoords
[i
].dwStride
= D3DDrawPrimStrideData
->textureCoords
[i
].dwStride
;
3815 /* WineD3D doesn't need the FVF here */
3816 EnterCriticalSection(&ddraw_cs
);
3817 IWineD3DDevice_SetPrimitiveType(This
->wineD3DDevice
, PrimitiveType
);
3818 hr
= IWineD3DDevice_DrawPrimitiveStrided(This
->wineD3DDevice
, VertexCount
, &WineD3DStrided
);
3819 LeaveCriticalSection(&ddraw_cs
);
3823 static HRESULT WINAPI
3824 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUSetup(IDirect3DDevice7
*iface
,
3825 D3DPRIMITIVETYPE PrimitiveType
,
3827 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
,
3831 return IDirect3DDeviceImpl_7_DrawPrimitiveStrided(iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Flags
);
3834 static HRESULT WINAPI
3835 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUPreserve(IDirect3DDevice7
*iface
,
3836 D3DPRIMITIVETYPE PrimitiveType
,
3838 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
,
3845 old_fpucw
= d3d_fpu_setup();
3846 hr
= IDirect3DDeviceImpl_7_DrawPrimitiveStrided(iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Flags
);
3847 set_fpu_control_word(old_fpucw
);
3852 static HRESULT WINAPI
IDirect3DDeviceImpl_3_DrawPrimitiveStrided(IDirect3DDevice3
*iface
,
3853 D3DPRIMITIVETYPE PrimitiveType
, DWORD VertexType
,
3854 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
, DWORD VertexCount
, DWORD Flags
)
3856 TRACE("iface %p, primitive_type %#x, FVF %#x, strided_data %p, vertex_count %u, flags %#x.\n",
3857 iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Flags
);
3859 return IDirect3DDevice7_DrawPrimitiveStrided((IDirect3DDevice7
*)device_from_device3(iface
),
3860 PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Flags
);
3863 /*****************************************************************************
3864 * IDirect3DDevice7::DrawIndexedPrimitiveStrided
3866 * Draws primitives specified by strided data locations based on indices
3874 * D3D_OK, because it's a stub
3875 * (DDERR_INVALIDPARAMS if D3DDrawPrimStrideData is NULL)
3876 * (DDERR_INVALIDPARAMS if Indices is NULL)
3877 * (For more details, see IWineD3DDevice::DrawIndexedPrimitiveStrided)
3879 *****************************************************************************/
3881 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided(IDirect3DDevice7
*iface
,
3882 D3DPRIMITIVETYPE PrimitiveType
,
3884 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
,
3890 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
3891 WineDirect3DVertexStridedData WineD3DStrided
;
3895 TRACE("iface %p, primitive_type %#x, FVF %#x, strided_data %p, vertex_count %u, indices %p, index_count %u, flags %#x.\n",
3896 iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Indices
, IndexCount
, Flags
);
3898 memset(&WineD3DStrided
, 0, sizeof(WineD3DStrided
));
3899 /* Get the strided data right. the wined3d structure is a bit bigger
3900 * Watch out: The contents of the strided data are determined by the fvf,
3901 * not by the members set in D3DDrawPrimStrideData. So it's valid
3902 * to have diffuse.lpvData set to 0xdeadbeef if the diffuse flag is
3903 * not set in the fvf.
3905 if(VertexType
& D3DFVF_POSITION_MASK
)
3907 WineD3DStrided
.position
.format
= WINED3DFMT_R32G32B32_FLOAT
;
3908 WineD3DStrided
.position
.lpData
= D3DDrawPrimStrideData
->position
.lpvData
;
3909 WineD3DStrided
.position
.dwStride
= D3DDrawPrimStrideData
->position
.dwStride
;
3910 if (VertexType
& D3DFVF_XYZRHW
)
3912 WineD3DStrided
.position
.format
= WINED3DFMT_R32G32B32A32_FLOAT
;
3913 WineD3DStrided
.position_transformed
= TRUE
;
3915 WineD3DStrided
.position_transformed
= FALSE
;
3918 if(VertexType
& D3DFVF_NORMAL
)
3920 WineD3DStrided
.normal
.format
= WINED3DFMT_R32G32B32_FLOAT
;
3921 WineD3DStrided
.normal
.lpData
= D3DDrawPrimStrideData
->normal
.lpvData
;
3922 WineD3DStrided
.normal
.dwStride
= D3DDrawPrimStrideData
->normal
.dwStride
;
3925 if(VertexType
& D3DFVF_DIFFUSE
)
3927 WineD3DStrided
.diffuse
.format
= WINED3DFMT_B8G8R8A8_UNORM
;
3928 WineD3DStrided
.diffuse
.lpData
= D3DDrawPrimStrideData
->diffuse
.lpvData
;
3929 WineD3DStrided
.diffuse
.dwStride
= D3DDrawPrimStrideData
->diffuse
.dwStride
;
3932 if(VertexType
& D3DFVF_SPECULAR
)
3934 WineD3DStrided
.specular
.format
= WINED3DFMT_B8G8R8A8_UNORM
;
3935 WineD3DStrided
.specular
.lpData
= D3DDrawPrimStrideData
->specular
.lpvData
;
3936 WineD3DStrided
.specular
.dwStride
= D3DDrawPrimStrideData
->specular
.dwStride
;
3939 for( i
= 0; i
< GET_TEXCOUNT_FROM_FVF(VertexType
); i
++)
3941 switch(GET_TEXCOORD_SIZE_FROM_FVF(VertexType
, i
))
3943 case 1: WineD3DStrided
.texCoords
[i
].format
= WINED3DFMT_R32_FLOAT
; break;
3944 case 2: WineD3DStrided
.texCoords
[i
].format
= WINED3DFMT_R32G32_FLOAT
; break;
3945 case 3: WineD3DStrided
.texCoords
[i
].format
= WINED3DFMT_R32G32B32_FLOAT
; break;
3946 case 4: WineD3DStrided
.texCoords
[i
].format
= WINED3DFMT_R32G32B32A32_FLOAT
; break;
3947 default: ERR("Unexpected texture coordinate size %d\n",
3948 GET_TEXCOORD_SIZE_FROM_FVF(VertexType
, i
));
3950 WineD3DStrided
.texCoords
[i
].lpData
= D3DDrawPrimStrideData
->textureCoords
[i
].lpvData
;
3951 WineD3DStrided
.texCoords
[i
].dwStride
= D3DDrawPrimStrideData
->textureCoords
[i
].dwStride
;
3954 /* WineD3D doesn't need the FVF here */
3955 EnterCriticalSection(&ddraw_cs
);
3956 IWineD3DDevice_SetPrimitiveType(This
->wineD3DDevice
, PrimitiveType
);
3957 hr
= IWineD3DDevice_DrawIndexedPrimitiveStrided(This
->wineD3DDevice
,
3958 IndexCount
, &WineD3DStrided
, VertexCount
, Indices
, WINED3DFMT_R16_UINT
);
3959 LeaveCriticalSection(&ddraw_cs
);
3963 static HRESULT WINAPI
3964 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUSetup(IDirect3DDevice7
*iface
,
3965 D3DPRIMITIVETYPE PrimitiveType
,
3967 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
,
3973 return IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided(iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Indices
, IndexCount
, Flags
);
3976 static HRESULT WINAPI
3977 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUPreserve(IDirect3DDevice7
*iface
,
3978 D3DPRIMITIVETYPE PrimitiveType
,
3980 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
,
3989 old_fpucw
= d3d_fpu_setup();
3990 hr
= IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided(iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Indices
, IndexCount
, Flags
);
3991 set_fpu_control_word(old_fpucw
);
3996 static HRESULT WINAPI
IDirect3DDeviceImpl_3_DrawIndexedPrimitiveStrided(IDirect3DDevice3
*iface
,
3997 D3DPRIMITIVETYPE PrimitiveType
, DWORD VertexType
,
3998 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
, DWORD VertexCount
, WORD
*Indices
,
3999 DWORD IndexCount
, DWORD Flags
)
4001 TRACE("iface %p, primitive_type %#x, FVF %#x, strided_data %p, vertex_count %u, indices %p, index_count %u, flags %#x.\n",
4002 iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Indices
, IndexCount
, Flags
);
4004 return IDirect3DDevice7_DrawIndexedPrimitiveStrided((IDirect3DDevice7
*)device_from_device3(iface
),
4005 PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Indices
, IndexCount
, Flags
);
4008 /*****************************************************************************
4009 * IDirect3DDevice7::DrawPrimitiveVB
4011 * Draws primitives from a vertex buffer to the screen.
4016 * PrimitiveType: Type of primitive to be rendered.
4017 * D3DVertexBuf: Source Vertex Buffer
4018 * StartVertex: Index of the first vertex from the buffer to be rendered
4019 * NumVertices: Number of vertices to be rendered
4020 * Flags: Can be D3DDP_WAIT to wait until rendering has finished
4024 * DDERR_INVALIDPARAMS if D3DVertexBuf is NULL
4026 *****************************************************************************/
4028 IDirect3DDeviceImpl_7_DrawPrimitiveVB(IDirect3DDevice7
*iface
,
4029 D3DPRIMITIVETYPE PrimitiveType
,
4030 IDirect3DVertexBuffer7
*D3DVertexBuf
,
4035 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
4036 IDirect3DVertexBufferImpl
*vb
= (IDirect3DVertexBufferImpl
*)D3DVertexBuf
;
4040 TRACE("iface %p, primitive_type %#x, vb %p, start_vertex %u, vertex_count %u, flags %#x.\n",
4041 iface
, PrimitiveType
, D3DVertexBuf
, StartVertex
, NumVertices
, Flags
);
4046 ERR("(%p) No Vertex buffer specified\n", This
);
4047 return DDERR_INVALIDPARAMS
;
4049 stride
= get_flexible_vertex_size(vb
->fvf
);
4051 EnterCriticalSection(&ddraw_cs
);
4052 hr
= IWineD3DDevice_SetVertexDeclaration(This
->wineD3DDevice
,
4053 vb
->wineD3DVertexDeclaration
);
4056 ERR(" (%p) Setting the FVF failed, hr = %x!\n", This
, hr
);
4057 LeaveCriticalSection(&ddraw_cs
);
4061 /* Set the vertex stream source */
4062 hr
= IWineD3DDevice_SetStreamSource(This
->wineD3DDevice
,
4063 0 /* StreamNumber */,
4064 vb
->wineD3DVertexBuffer
,
4065 0 /* StartVertex - we pass this to DrawPrimitive */,
4069 ERR("(%p) IDirect3DDevice::SetStreamSource failed with hr = %08x\n", This
, hr
);
4070 LeaveCriticalSection(&ddraw_cs
);
4074 /* Now draw the primitives */
4075 IWineD3DDevice_SetPrimitiveType(This
->wineD3DDevice
, PrimitiveType
);
4076 hr
= IWineD3DDevice_DrawPrimitive(This
->wineD3DDevice
, StartVertex
, NumVertices
);
4077 LeaveCriticalSection(&ddraw_cs
);
4081 static HRESULT WINAPI
4082 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUSetup(IDirect3DDevice7
*iface
,
4083 D3DPRIMITIVETYPE PrimitiveType
,
4084 IDirect3DVertexBuffer7
*D3DVertexBuf
,
4089 return IDirect3DDeviceImpl_7_DrawPrimitiveVB(iface
, PrimitiveType
, D3DVertexBuf
, StartVertex
, NumVertices
, Flags
);
4092 static HRESULT WINAPI
4093 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUPreserve(IDirect3DDevice7
*iface
,
4094 D3DPRIMITIVETYPE PrimitiveType
,
4095 IDirect3DVertexBuffer7
*D3DVertexBuf
,
4103 old_fpucw
= d3d_fpu_setup();
4104 hr
= IDirect3DDeviceImpl_7_DrawPrimitiveVB(iface
, PrimitiveType
, D3DVertexBuf
, StartVertex
, NumVertices
, Flags
);
4105 set_fpu_control_word(old_fpucw
);
4110 static HRESULT WINAPI
IDirect3DDeviceImpl_3_DrawPrimitiveVB(IDirect3DDevice3
*iface
,
4111 D3DPRIMITIVETYPE PrimitiveType
, IDirect3DVertexBuffer
*D3DVertexBuf
, DWORD StartVertex
,
4112 DWORD NumVertices
, DWORD Flags
)
4114 IDirect3DVertexBufferImpl
*vb
= D3DVertexBuf
? vb_from_vb1(D3DVertexBuf
) : NULL
;
4116 TRACE("iface %p, primitive_type %#x, vb %p, start_vertex %u, vertex_count %u, flags %#x.\n",
4117 iface
, PrimitiveType
, D3DVertexBuf
, StartVertex
, NumVertices
, Flags
);
4119 return IDirect3DDevice7_DrawPrimitiveVB((IDirect3DDevice7
*)device_from_device3(iface
),
4120 PrimitiveType
, (IDirect3DVertexBuffer7
*)vb
, StartVertex
, NumVertices
, Flags
);
4124 /*****************************************************************************
4125 * IDirect3DDevice7::DrawIndexedPrimitiveVB
4127 * Draws primitives from a vertex buffer to the screen
4130 * PrimitiveType: Type of primitive to be rendered.
4131 * D3DVertexBuf: Source Vertex Buffer
4132 * StartVertex: Index of the first vertex from the buffer to be rendered
4133 * NumVertices: Number of vertices to be rendered
4134 * Indices: Array of DWORDs used to index into the Vertices
4135 * IndexCount: Number of indices in Indices
4136 * Flags: Can be D3DDP_WAIT to wait until rendering has finished
4140 *****************************************************************************/
4142 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB(IDirect3DDevice7
*iface
,
4143 D3DPRIMITIVETYPE PrimitiveType
,
4144 IDirect3DVertexBuffer7
*D3DVertexBuf
,
4151 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
4152 IDirect3DVertexBufferImpl
*vb
= (IDirect3DVertexBufferImpl
*)D3DVertexBuf
;
4153 DWORD stride
= get_flexible_vertex_size(vb
->fvf
);
4154 WORD
*LockedIndices
;
4156 WINED3DBUFFER_DESC desc
;
4158 TRACE("iface %p, primitive_type %#x, vb %p, start_vertex %u, vertex_count %u, indices %p, index_count %u, flags %#x.\n",
4159 iface
, PrimitiveType
, D3DVertexBuf
, StartVertex
, NumVertices
, Indices
, IndexCount
, Flags
);
4162 * 1) Upload the Indices to the index buffer
4163 * 2) Set the index source
4164 * 3) Set the Vertex Buffer as the Stream source
4165 * 4) Call IWineD3DDevice::DrawIndexedPrimitive
4168 EnterCriticalSection(&ddraw_cs
);
4170 hr
= IWineD3DDevice_SetVertexDeclaration(This
->wineD3DDevice
,
4171 vb
->wineD3DVertexDeclaration
);
4174 ERR(" (%p) Setting the FVF failed, hr = %x!\n", This
, hr
);
4175 LeaveCriticalSection(&ddraw_cs
);
4179 /* check that the buffer is large enough to hold the indices,
4180 * reallocate if necessary. */
4181 IWineD3DBuffer_GetDesc(This
->indexbuffer
, &desc
);
4182 if (desc
.Size
< IndexCount
* sizeof(WORD
))
4184 UINT size
= max(desc
.Size
* 2, IndexCount
* sizeof(WORD
));
4185 IWineD3DBuffer
*buffer
;
4186 IParentImpl
*parent
;
4188 TRACE("Growing index buffer to %u bytes\n", size
);
4190 parent
= IWineD3DBuffer_GetParent(This
->indexbuffer
);
4191 hr
= IWineD3DDevice_CreateIndexBuffer(This
->wineD3DDevice
, size
, WINED3DUSAGE_DYNAMIC
/* Usage */,
4192 WINED3DPOOL_DEFAULT
, parent
, &ddraw_null_wined3d_parent_ops
, &buffer
);
4195 ERR("(%p) IWineD3DDevice::CreateIndexBuffer failed with hr = %08x\n", This
, hr
);
4196 LeaveCriticalSection(&ddraw_cs
);
4200 IWineD3DBuffer_Release(This
->indexbuffer
);
4201 This
->indexbuffer
= buffer
;
4203 parent
->child
= (IUnknown
*)buffer
;
4206 /* copy the index stream into the index buffer.
4207 * A new IWineD3DDevice method could be created
4208 * which takes an user pointer containing the indices
4209 * or a SetData-Method for the index buffer, which
4210 * overrides the index buffer data with our pointer.
4212 hr
= IWineD3DBuffer_Map(This
->indexbuffer
,
4213 0 /* OffSetToLock */,
4214 IndexCount
* sizeof(WORD
),
4215 (BYTE
**) &LockedIndices
,
4219 ERR("(%p) IWineD3DBuffer::Map failed with hr = %08x\n", This
, hr
);
4220 LeaveCriticalSection(&ddraw_cs
);
4223 memcpy(LockedIndices
, Indices
, IndexCount
* sizeof(WORD
));
4224 IWineD3DBuffer_Unmap(This
->indexbuffer
);
4226 /* Set the index stream */
4227 IWineD3DDevice_SetBaseVertexIndex(This
->wineD3DDevice
, StartVertex
);
4228 hr
= IWineD3DDevice_SetIndexBuffer(This
->wineD3DDevice
, This
->indexbuffer
,
4229 WINED3DFMT_R16_UINT
);
4231 /* Set the vertex stream source */
4232 hr
= IWineD3DDevice_SetStreamSource(This
->wineD3DDevice
,
4233 0 /* StreamNumber */,
4234 vb
->wineD3DVertexBuffer
,
4235 0 /* offset, we pass this to DrawIndexedPrimitive */,
4239 ERR("(%p) IDirect3DDevice::SetStreamSource failed with hr = %08x\n", This
, hr
);
4240 LeaveCriticalSection(&ddraw_cs
);
4245 IWineD3DDevice_SetPrimitiveType(This
->wineD3DDevice
, PrimitiveType
);
4246 hr
= IWineD3DDevice_DrawIndexedPrimitive(This
->wineD3DDevice
, 0 /* StartIndex */, IndexCount
);
4248 LeaveCriticalSection(&ddraw_cs
);
4252 static HRESULT WINAPI
4253 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUSetup(IDirect3DDevice7
*iface
,
4254 D3DPRIMITIVETYPE PrimitiveType
,
4255 IDirect3DVertexBuffer7
*D3DVertexBuf
,
4262 return IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB(iface
, PrimitiveType
, D3DVertexBuf
, StartVertex
, NumVertices
, Indices
, IndexCount
, Flags
);
4265 static HRESULT WINAPI
4266 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUPreserve(IDirect3DDevice7
*iface
,
4267 D3DPRIMITIVETYPE PrimitiveType
,
4268 IDirect3DVertexBuffer7
*D3DVertexBuf
,
4278 old_fpucw
= d3d_fpu_setup();
4279 hr
= IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB(iface
, PrimitiveType
, D3DVertexBuf
, StartVertex
, NumVertices
, Indices
, IndexCount
, Flags
);
4280 set_fpu_control_word(old_fpucw
);
4285 static HRESULT WINAPI
IDirect3DDeviceImpl_3_DrawIndexedPrimitiveVB(IDirect3DDevice3
*iface
,
4286 D3DPRIMITIVETYPE PrimitiveType
, IDirect3DVertexBuffer
*D3DVertexBuf
, WORD
*Indices
,
4287 DWORD IndexCount
, DWORD Flags
)
4289 IDirect3DVertexBufferImpl
*VB
= vb_from_vb1(D3DVertexBuf
);
4291 TRACE("iface %p, primitive_type %#x, vb %p, indices %p, index_count %u, flags %#x.\n",
4292 iface
, PrimitiveType
, D3DVertexBuf
, Indices
, IndexCount
, Flags
);
4294 return IDirect3DDevice7_DrawIndexedPrimitiveVB((IDirect3DDevice7
*)device_from_device3(iface
),
4295 PrimitiveType
, (IDirect3DVertexBuffer7
*)VB
, 0, IndexCount
, Indices
, IndexCount
, Flags
);
4298 /*****************************************************************************
4299 * IDirect3DDevice7::ComputeSphereVisibility
4301 * Calculates the visibility of spheres in the current viewport. The spheres
4302 * are passed in the Centers and Radii arrays, the results are passed back
4303 * in the ReturnValues array. Return values are either completely visible,
4304 * partially visible or completely invisible.
4305 * The return value consist of a combination of D3DCLIP_* flags, or it's
4306 * 0 if the sphere is completely visible(according to the SDK, not checked)
4311 * Centers: Array containing the sphere centers
4312 * Radii: Array containing the sphere radii
4313 * NumSpheres: The number of centers and radii in the arrays
4315 * ReturnValues: Array to write the results to
4319 * (DDERR_INVALIDPARAMS if Centers, Radii or ReturnValues are NULL)
4320 * (D3DERR_INVALIDMATRIX if the combined world, view and proj matrix
4323 *****************************************************************************/
4325 static DWORD
in_plane(UINT plane
, D3DVECTOR normal
, D3DVALUE origin_plane
, D3DVECTOR center
, D3DVALUE radius
)
4327 float distance
, norm
;
4329 norm
= sqrt( normal
.u1
.x
* normal
.u1
.x
+ normal
.u2
.y
* normal
.u2
.y
+ normal
.u3
.z
* normal
.u3
.z
);
4330 distance
= ( origin_plane
+ normal
.u1
.x
* center
.u1
.x
+ normal
.u2
.y
* center
.u2
.y
+ normal
.u3
.z
* center
.u3
.z
) / norm
;
4332 if ( fabs( distance
) < radius
) return D3DSTATUS_CLIPUNIONLEFT
<< plane
;
4333 if ( distance
< -radius
) return (D3DSTATUS_CLIPUNIONLEFT
| D3DSTATUS_CLIPINTERSECTIONLEFT
) << plane
;
4337 static HRESULT WINAPI
4338 IDirect3DDeviceImpl_7_ComputeSphereVisibility(IDirect3DDevice7
*iface
,
4343 DWORD
*ReturnValues
)
4346 D3DVALUE origin_plane
[6];
4351 TRACE("iface %p, centers %p, radii %p, sphere_count %u, flags %#x, return_values %p.\n",
4352 iface
, Centers
, Radii
, NumSpheres
, Flags
, ReturnValues
);
4354 hr
= IDirect3DDeviceImpl_7_GetTransform(iface
, D3DTRANSFORMSTATE_WORLD
, &m
);
4355 if ( hr
!= DD_OK
) return DDERR_INVALIDPARAMS
;
4356 hr
= IDirect3DDeviceImpl_7_GetTransform(iface
, D3DTRANSFORMSTATE_VIEW
, &temp
);
4357 if ( hr
!= DD_OK
) return DDERR_INVALIDPARAMS
;
4358 multiply_matrix(&m
, &temp
, &m
);
4360 hr
= IDirect3DDeviceImpl_7_GetTransform(iface
, D3DTRANSFORMSTATE_PROJECTION
, &temp
);
4361 if ( hr
!= DD_OK
) return DDERR_INVALIDPARAMS
;
4362 multiply_matrix(&m
, &temp
, &m
);
4365 vec
[0].u1
.x
= m
._14
+ m
._11
;
4366 vec
[0].u2
.y
= m
._24
+ m
._21
;
4367 vec
[0].u3
.z
= m
._34
+ m
._31
;
4368 origin_plane
[0] = m
._44
+ m
._41
;
4371 vec
[1].u1
.x
= m
._14
- m
._11
;
4372 vec
[1].u2
.y
= m
._24
- m
._21
;
4373 vec
[1].u3
.z
= m
._34
- m
._31
;
4374 origin_plane
[1] = m
._44
- m
._41
;
4377 vec
[2].u1
.x
= m
._14
- m
._12
;
4378 vec
[2].u2
.y
= m
._24
- m
._22
;
4379 vec
[2].u3
.z
= m
._34
- m
._32
;
4380 origin_plane
[2] = m
._44
- m
._42
;
4383 vec
[3].u1
.x
= m
._14
+ m
._12
;
4384 vec
[3].u2
.y
= m
._24
+ m
._22
;
4385 vec
[3].u3
.z
= m
._34
+ m
._32
;
4386 origin_plane
[3] = m
._44
+ m
._42
;
4389 vec
[4].u1
.x
= m
._13
;
4390 vec
[4].u2
.y
= m
._23
;
4391 vec
[4].u3
.z
= m
._33
;
4392 origin_plane
[4] = m
._43
;
4395 vec
[5].u1
.x
= m
._14
- m
._13
;
4396 vec
[5].u2
.y
= m
._24
- m
._23
;
4397 vec
[5].u3
.z
= m
._34
- m
._33
;
4398 origin_plane
[5] = m
._44
- m
._43
;
4400 for(i
=0; i
<NumSpheres
; i
++)
4402 ReturnValues
[i
] = 0;
4403 for(j
=0; j
<6; j
++) ReturnValues
[i
] |= in_plane(j
, vec
[j
], origin_plane
[j
], Centers
[i
], Radii
[i
]);
4409 static HRESULT WINAPI
IDirect3DDeviceImpl_3_ComputeSphereVisibility(IDirect3DDevice3
*iface
,
4410 D3DVECTOR
*Centers
, D3DVALUE
*Radii
, DWORD NumSpheres
, DWORD Flags
, DWORD
*ReturnValues
)
4412 TRACE("iface %p, centers %p, radii %p, sphere_count %u, flags %#x, return_values %p.\n",
4413 iface
, Centers
, Radii
, NumSpheres
, Flags
, ReturnValues
);
4415 return IDirect3DDevice7_ComputeSphereVisibility((IDirect3DDevice7
*)device_from_device3(iface
),
4416 Centers
, Radii
, NumSpheres
, Flags
, ReturnValues
);
4419 /*****************************************************************************
4420 * IDirect3DDevice7::GetTexture
4422 * Returns the texture interface handle assigned to a texture stage.
4423 * The returned texture is AddRefed. This is taken from old ddraw,
4424 * not checked in Windows.
4429 * Stage: Texture stage to read the texture from
4430 * Texture: Address to store the interface pointer at
4434 * DDERR_INVALIDPARAMS if Texture is NULL
4435 * For details, see IWineD3DDevice::GetTexture
4437 *****************************************************************************/
4439 IDirect3DDeviceImpl_7_GetTexture(IDirect3DDevice7
*iface
,
4441 IDirectDrawSurface7
**Texture
)
4443 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
4444 IWineD3DBaseTexture
*Surf
;
4447 TRACE("iface %p, stage %u, texture %p.\n", iface
, Stage
, Texture
);
4451 TRACE("Texture == NULL, failing with DDERR_INVALIDPARAMS\n");
4452 return DDERR_INVALIDPARAMS
;
4455 EnterCriticalSection(&ddraw_cs
);
4456 hr
= IWineD3DDevice_GetTexture(This
->wineD3DDevice
, Stage
, &Surf
);
4457 if( (hr
!= D3D_OK
) || (!Surf
) )
4460 LeaveCriticalSection(&ddraw_cs
);
4464 *Texture
= IWineD3DBaseTexture_GetParent(Surf
);
4465 IDirectDrawSurface7_AddRef(*Texture
);
4466 LeaveCriticalSection(&ddraw_cs
);
4470 static HRESULT WINAPI
4471 IDirect3DDeviceImpl_7_GetTexture_FPUSetup(IDirect3DDevice7
*iface
,
4473 IDirectDrawSurface7
**Texture
)
4475 return IDirect3DDeviceImpl_7_GetTexture(iface
, Stage
, Texture
);
4478 static HRESULT WINAPI
4479 IDirect3DDeviceImpl_7_GetTexture_FPUPreserve(IDirect3DDevice7
*iface
,
4481 IDirectDrawSurface7
**Texture
)
4486 old_fpucw
= d3d_fpu_setup();
4487 hr
= IDirect3DDeviceImpl_7_GetTexture(iface
, Stage
, Texture
);
4488 set_fpu_control_word(old_fpucw
);
4493 static HRESULT WINAPI
IDirect3DDeviceImpl_3_GetTexture(IDirect3DDevice3
*iface
, DWORD Stage
,
4494 IDirect3DTexture2
**Texture2
)
4497 IDirectDrawSurface7
*ret_val
;
4499 TRACE("iface %p, stage %u, texture %p.\n", iface
, Stage
, Texture2
);
4501 ret
= IDirect3DDevice7_GetTexture((IDirect3DDevice7
*)device_from_device3(iface
), Stage
, &ret_val
);
4503 *Texture2
= ret_val
? (IDirect3DTexture2
*)&((IDirectDrawSurfaceImpl
*)ret_val
)->IDirect3DTexture2_vtbl
: NULL
;
4505 TRACE("Returning texture %p.\n", *Texture2
);
4510 /*****************************************************************************
4511 * IDirect3DDevice7::SetTexture
4513 * Assigns a texture to a texture stage. Is the texture AddRef-ed?
4518 * Stage: The stage to assign the texture to
4519 * Texture: Interface pointer to the texture surface
4523 * For details, see IWineD3DDevice::SetTexture
4525 *****************************************************************************/
4527 IDirect3DDeviceImpl_7_SetTexture(IDirect3DDevice7
*iface
,
4529 IDirectDrawSurface7
*Texture
)
4531 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
4532 IDirectDrawSurfaceImpl
*surf
= (IDirectDrawSurfaceImpl
*)Texture
;
4535 TRACE("iface %p, stage %u, texture %p.\n", iface
, Stage
, Texture
);
4537 /* Texture may be NULL here */
4538 EnterCriticalSection(&ddraw_cs
);
4539 hr
= IWineD3DDevice_SetTexture(This
->wineD3DDevice
,
4541 surf
? surf
->wineD3DTexture
: NULL
);
4542 LeaveCriticalSection(&ddraw_cs
);
4546 static HRESULT WINAPI
4547 IDirect3DDeviceImpl_7_SetTexture_FPUSetup(IDirect3DDevice7
*iface
,
4549 IDirectDrawSurface7
*Texture
)
4551 return IDirect3DDeviceImpl_7_SetTexture(iface
, Stage
, Texture
);
4554 static HRESULT WINAPI
4555 IDirect3DDeviceImpl_7_SetTexture_FPUPreserve(IDirect3DDevice7
*iface
,
4557 IDirectDrawSurface7
*Texture
)
4562 old_fpucw
= d3d_fpu_setup();
4563 hr
= IDirect3DDeviceImpl_7_SetTexture(iface
, Stage
, Texture
);
4564 set_fpu_control_word(old_fpucw
);
4569 static HRESULT WINAPI
4570 IDirect3DDeviceImpl_3_SetTexture(IDirect3DDevice3
*iface
,
4572 IDirect3DTexture2
*Texture2
)
4574 IDirect3DDeviceImpl
*This
= device_from_device3(iface
);
4575 IDirectDrawSurfaceImpl
*tex
= Texture2
? surface_from_texture2(Texture2
) : NULL
;
4579 TRACE("iface %p, stage %u, texture %p.\n", iface
, Stage
, Texture2
);
4581 EnterCriticalSection(&ddraw_cs
);
4583 if (This
->legacyTextureBlending
)
4584 IDirect3DDevice3_GetRenderState(iface
, D3DRENDERSTATE_TEXTUREMAPBLEND
, &texmapblend
);
4586 hr
= IDirect3DDevice7_SetTexture((IDirect3DDevice7
*)This
, Stage
, (IDirectDrawSurface7
*)tex
);
4588 if (This
->legacyTextureBlending
&& texmapblend
== D3DTBLEND_MODULATE
)
4590 /* This fixup is required by the way D3DTBLEND_MODULATE maps to texture stage states.
4591 See IDirect3DDeviceImpl_3_SetRenderState for details. */
4592 BOOL tex_alpha
= FALSE
;
4593 IWineD3DBaseTexture
*tex
= NULL
;
4594 WINED3DSURFACE_DESC desc
;
4595 DDPIXELFORMAT ddfmt
;
4598 result
= IWineD3DDevice_GetTexture(This
->wineD3DDevice
,
4602 if(result
== WINED3D_OK
&& tex
)
4604 memset(&desc
, 0, sizeof(desc
));
4605 result
= IWineD3DTexture_GetLevelDesc((IWineD3DTexture
*) tex
, 0, &desc
);
4606 if (SUCCEEDED(result
))
4608 ddfmt
.dwSize
= sizeof(ddfmt
);
4609 PixelFormat_WineD3DtoDD(&ddfmt
, desc
.format
);
4610 if (ddfmt
.u5
.dwRGBAlphaBitMask
) tex_alpha
= TRUE
;
4613 IWineD3DBaseTexture_Release(tex
);
4616 /* Arg 1/2 are already set to WINED3DTA_TEXTURE/WINED3DTA_CURRENT in case of D3DTBLEND_MODULATE */
4618 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAOP
, WINED3DTOP_SELECTARG1
);
4620 IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, 0, WINED3DTSS_ALPHAOP
, WINED3DTOP_SELECTARG2
);
4623 LeaveCriticalSection(&ddraw_cs
);
4628 static const struct tss_lookup
4635 {FALSE
, WINED3DTSS_FORCE_DWORD
}, /* 0, unused */
4636 {FALSE
, WINED3DTSS_COLOROP
}, /* 1, D3DTSS_COLOROP */
4637 {FALSE
, WINED3DTSS_COLORARG1
}, /* 2, D3DTSS_COLORARG1 */
4638 {FALSE
, WINED3DTSS_COLORARG2
}, /* 3, D3DTSS_COLORARG2 */
4639 {FALSE
, WINED3DTSS_ALPHAOP
}, /* 4, D3DTSS_ALPHAOP */
4640 {FALSE
, WINED3DTSS_ALPHAARG1
}, /* 5, D3DTSS_ALPHAARG1 */
4641 {FALSE
, WINED3DTSS_ALPHAARG2
}, /* 6, D3DTSS_ALPHAARG2 */
4642 {FALSE
, WINED3DTSS_BUMPENVMAT00
}, /* 7, D3DTSS_BUMPENVMAT00 */
4643 {FALSE
, WINED3DTSS_BUMPENVMAT01
}, /* 8, D3DTSS_BUMPENVMAT01 */
4644 {FALSE
, WINED3DTSS_BUMPENVMAT10
}, /* 9, D3DTSS_BUMPENVMAT10 */
4645 {FALSE
, WINED3DTSS_BUMPENVMAT11
}, /* 10, D3DTSS_BUMPENVMAT11 */
4646 {FALSE
, WINED3DTSS_TEXCOORDINDEX
}, /* 11, D3DTSS_TEXCOORDINDEX */
4647 {TRUE
, WINED3DSAMP_ADDRESSU
}, /* 12, D3DTSS_ADDRESS */
4648 {TRUE
, WINED3DSAMP_ADDRESSU
}, /* 13, D3DTSS_ADDRESSU */
4649 {TRUE
, WINED3DSAMP_ADDRESSV
}, /* 14, D3DTSS_ADDRESSV */
4650 {TRUE
, WINED3DSAMP_BORDERCOLOR
}, /* 15, D3DTSS_BORDERCOLOR */
4651 {TRUE
, WINED3DSAMP_MAGFILTER
}, /* 16, D3DTSS_MAGFILTER */
4652 {TRUE
, WINED3DSAMP_MINFILTER
}, /* 17, D3DTSS_MINFILTER */
4653 {TRUE
, WINED3DSAMP_MIPFILTER
}, /* 18, D3DTSS_MIPFILTER */
4654 {TRUE
, WINED3DSAMP_MIPMAPLODBIAS
}, /* 19, D3DTSS_MIPMAPLODBIAS */
4655 {TRUE
, WINED3DSAMP_MAXMIPLEVEL
}, /* 20, D3DTSS_MAXMIPLEVEL */
4656 {TRUE
, WINED3DSAMP_MAXANISOTROPY
}, /* 21, D3DTSS_MAXANISOTROPY */
4657 {FALSE
, WINED3DTSS_BUMPENVLSCALE
}, /* 22, D3DTSS_BUMPENVLSCALE */
4658 {FALSE
, WINED3DTSS_BUMPENVLOFFSET
}, /* 23, D3DTSS_BUMPENVLOFFSET */
4659 {FALSE
, WINED3DTSS_TEXTURETRANSFORMFLAGS
}, /* 24, D3DTSS_TEXTURETRANSFORMFLAGS */
4662 /*****************************************************************************
4663 * IDirect3DDevice7::GetTextureStageState
4665 * Retrieves a state from a texture stage.
4670 * Stage: The stage to retrieve the state from
4671 * TexStageStateType: The state type to retrieve
4672 * State: Address to store the state's value at
4676 * DDERR_INVALIDPARAMS if State is NULL
4677 * For details, see IWineD3DDevice::GetTextureStageState
4679 *****************************************************************************/
4681 IDirect3DDeviceImpl_7_GetTextureStageState(IDirect3DDevice7
*iface
,
4683 D3DTEXTURESTAGESTATETYPE TexStageStateType
,
4686 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
4688 const struct tss_lookup
*l
;
4690 TRACE("iface %p, stage %u, state %#x, value %p.\n",
4691 iface
, Stage
, TexStageStateType
, State
);
4694 return DDERR_INVALIDPARAMS
;
4696 if (TexStageStateType
> D3DTSS_TEXTURETRANSFORMFLAGS
)
4698 WARN("Invalid TexStageStateType %#x passed.\n", TexStageStateType
);
4702 l
= &tss_lookup
[TexStageStateType
];
4704 EnterCriticalSection(&ddraw_cs
);
4706 if (l
->sampler_state
)
4708 hr
= IWineD3DDevice_GetSamplerState(This
->wineD3DDevice
, Stage
, l
->state
, State
);
4710 switch(TexStageStateType
)
4712 /* Mipfilter is a sampler state with different values */
4713 case D3DTSS_MIPFILTER
:
4717 case WINED3DTEXF_NONE
: *State
= D3DTFP_NONE
; break;
4718 case WINED3DTEXF_POINT
: *State
= D3DTFP_POINT
; break;
4719 case WINED3DTEXF_LINEAR
: *State
= D3DTFP_LINEAR
; break;
4721 ERR("Unexpected mipfilter value %#x\n", *State
);
4722 *State
= D3DTFP_NONE
;
4728 /* Magfilter has slightly different values */
4729 case D3DTSS_MAGFILTER
:
4733 case WINED3DTEXF_POINT
: *State
= D3DTFG_POINT
; break;
4734 case WINED3DTEXF_LINEAR
: *State
= D3DTFG_LINEAR
; break;
4735 case WINED3DTEXF_ANISOTROPIC
: *State
= D3DTFG_ANISOTROPIC
; break;
4736 case WINED3DTEXF_FLATCUBIC
: *State
= D3DTFG_FLATCUBIC
; break;
4737 case WINED3DTEXF_GAUSSIANCUBIC
: *State
= D3DTFG_GAUSSIANCUBIC
; break;
4739 ERR("Unexpected wined3d mag filter value %#x\n", *State
);
4740 *State
= D3DTFG_POINT
;
4752 hr
= IWineD3DDevice_GetTextureStageState(This
->wineD3DDevice
, Stage
, l
->state
, State
);
4755 LeaveCriticalSection(&ddraw_cs
);
4759 static HRESULT WINAPI
4760 IDirect3DDeviceImpl_7_GetTextureStageState_FPUSetup(IDirect3DDevice7
*iface
,
4762 D3DTEXTURESTAGESTATETYPE TexStageStateType
,
4765 return IDirect3DDeviceImpl_7_GetTextureStageState(iface
, Stage
, TexStageStateType
, State
);
4768 static HRESULT WINAPI
4769 IDirect3DDeviceImpl_7_GetTextureStageState_FPUPreserve(IDirect3DDevice7
*iface
,
4771 D3DTEXTURESTAGESTATETYPE TexStageStateType
,
4777 old_fpucw
= d3d_fpu_setup();
4778 hr
= IDirect3DDeviceImpl_7_GetTextureStageState(iface
, Stage
, TexStageStateType
, State
);
4779 set_fpu_control_word(old_fpucw
);
4784 static HRESULT WINAPI
IDirect3DDeviceImpl_3_GetTextureStageState(IDirect3DDevice3
*iface
,
4785 DWORD Stage
, D3DTEXTURESTAGESTATETYPE TexStageStateType
, DWORD
*State
)
4787 TRACE("iface %p, stage %u, state %#x, value %p.\n",
4788 iface
, Stage
, TexStageStateType
, State
);
4790 return IDirect3DDevice7_GetTextureStageState((IDirect3DDevice7
*)device_from_device3(iface
),
4791 Stage
, TexStageStateType
, State
);
4794 /*****************************************************************************
4795 * IDirect3DDevice7::SetTextureStageState
4797 * Sets a texture stage state. Some stage types need to be handled specially,
4798 * because they do not exist in WineD3D and were moved to another place
4803 * Stage: The stage to modify
4804 * TexStageStateType: The state to change
4805 * State: The new value for the state
4809 * For details, see IWineD3DDevice::SetTextureStageState
4811 *****************************************************************************/
4813 IDirect3DDeviceImpl_7_SetTextureStageState(IDirect3DDevice7
*iface
,
4815 D3DTEXTURESTAGESTATETYPE TexStageStateType
,
4818 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
4819 const struct tss_lookup
*l
;
4822 TRACE("iface %p, stage %u, state %#x, value %#x.\n",
4823 iface
, Stage
, TexStageStateType
, State
);
4825 if (TexStageStateType
> D3DTSS_TEXTURETRANSFORMFLAGS
)
4827 WARN("Invalid TexStageStateType %#x passed.\n", TexStageStateType
);
4831 l
= &tss_lookup
[TexStageStateType
];
4833 EnterCriticalSection(&ddraw_cs
);
4835 if (l
->sampler_state
)
4837 switch(TexStageStateType
)
4839 /* Mipfilter is a sampler state with different values */
4840 case D3DTSS_MIPFILTER
:
4844 case D3DTFP_NONE
: State
= WINED3DTEXF_NONE
; break;
4845 case D3DTFP_POINT
: State
= WINED3DTEXF_POINT
; break;
4846 case 0: /* Unchecked */
4847 case D3DTFP_LINEAR
: State
= WINED3DTEXF_LINEAR
; break;
4849 ERR("Unexpected mipfilter value %d\n", State
);
4850 State
= WINED3DTEXF_NONE
;
4856 /* Magfilter has slightly different values */
4857 case D3DTSS_MAGFILTER
:
4861 case D3DTFG_POINT
: State
= WINED3DTEXF_POINT
; break;
4862 case D3DTFG_LINEAR
: State
= WINED3DTEXF_LINEAR
; break;
4863 case D3DTFG_FLATCUBIC
: State
= WINED3DTEXF_FLATCUBIC
; break;
4864 case D3DTFG_GAUSSIANCUBIC
: State
= WINED3DTEXF_GAUSSIANCUBIC
; break;
4865 case D3DTFG_ANISOTROPIC
: State
= WINED3DTEXF_ANISOTROPIC
; break;
4867 ERR("Unexpected d3d7 mag filter type %d\n", State
);
4868 State
= WINED3DTEXF_POINT
;
4874 case D3DTSS_ADDRESS
:
4875 IWineD3DDevice_SetSamplerState(This
->wineD3DDevice
, Stage
, WINED3DSAMP_ADDRESSV
, State
);
4882 hr
= IWineD3DDevice_SetSamplerState(This
->wineD3DDevice
, Stage
, l
->state
, State
);
4886 hr
= IWineD3DDevice_SetTextureStageState(This
->wineD3DDevice
, Stage
, l
->state
, State
);
4889 LeaveCriticalSection(&ddraw_cs
);
4893 static HRESULT WINAPI
4894 IDirect3DDeviceImpl_7_SetTextureStageState_FPUSetup(IDirect3DDevice7
*iface
,
4896 D3DTEXTURESTAGESTATETYPE TexStageStateType
,
4899 return IDirect3DDeviceImpl_7_SetTextureStageState(iface
, Stage
, TexStageStateType
, State
);
4902 static HRESULT WINAPI
4903 IDirect3DDeviceImpl_7_SetTextureStageState_FPUPreserve(IDirect3DDevice7
*iface
,
4905 D3DTEXTURESTAGESTATETYPE TexStageStateType
,
4911 old_fpucw
= d3d_fpu_setup();
4912 hr
= IDirect3DDeviceImpl_7_SetTextureStageState(iface
, Stage
, TexStageStateType
, State
);
4913 set_fpu_control_word(old_fpucw
);
4918 static HRESULT WINAPI
IDirect3DDeviceImpl_3_SetTextureStageState(IDirect3DDevice3
*iface
,
4919 DWORD Stage
, D3DTEXTURESTAGESTATETYPE TexStageStateType
, DWORD State
)
4921 TRACE("iface %p, stage %u, state %#x, value %#x.\n",
4922 iface
, Stage
, TexStageStateType
, State
);
4924 return IDirect3DDevice7_SetTextureStageState((IDirect3DDevice7
*)device_from_device3(iface
),
4925 Stage
, TexStageStateType
, State
);
4928 /*****************************************************************************
4929 * IDirect3DDevice7::ValidateDevice
4931 * SDK: "Reports the device's ability to render the currently set
4932 * texture-blending operations in a single pass". Whatever that means
4938 * NumPasses: Address to write the number of necessary passes for the
4939 * desired effect to.
4943 * See IWineD3DDevice::ValidateDevice for more details
4945 *****************************************************************************/
4947 IDirect3DDeviceImpl_7_ValidateDevice(IDirect3DDevice7
*iface
,
4950 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
4953 TRACE("iface %p, pass_count %p.\n", iface
, NumPasses
);
4955 EnterCriticalSection(&ddraw_cs
);
4956 hr
= IWineD3DDevice_ValidateDevice(This
->wineD3DDevice
, NumPasses
);
4957 LeaveCriticalSection(&ddraw_cs
);
4961 static HRESULT WINAPI
4962 IDirect3DDeviceImpl_7_ValidateDevice_FPUSetup(IDirect3DDevice7
*iface
,
4965 return IDirect3DDeviceImpl_7_ValidateDevice(iface
, NumPasses
);
4968 static HRESULT WINAPI
4969 IDirect3DDeviceImpl_7_ValidateDevice_FPUPreserve(IDirect3DDevice7
*iface
,
4975 old_fpucw
= d3d_fpu_setup();
4976 hr
= IDirect3DDeviceImpl_7_ValidateDevice(iface
, NumPasses
);
4977 set_fpu_control_word(old_fpucw
);
4982 static HRESULT WINAPI
IDirect3DDeviceImpl_3_ValidateDevice(IDirect3DDevice3
*iface
, DWORD
*Passes
)
4984 TRACE("iface %p, pass_count %p.\n", iface
, Passes
);
4986 return IDirect3DDevice7_ValidateDevice((IDirect3DDevice7
*)device_from_device3(iface
), Passes
);
4989 /*****************************************************************************
4990 * IDirect3DDevice7::Clear
4992 * Fills the render target, the z buffer and the stencil buffer with a
4993 * clear color / value
4998 * Count: Number of rectangles in Rects must be 0 if Rects is NULL
4999 * Rects: Rectangles to clear. If NULL, the whole surface is cleared
5000 * Flags: Some flags, as usual
5001 * Color: Clear color for the render target
5002 * Z: Clear value for the Z buffer
5003 * Stencil: Clear value to store in each stencil buffer entry
5007 * For details, see IWineD3DDevice::Clear
5009 *****************************************************************************/
5011 IDirect3DDeviceImpl_7_Clear(IDirect3DDevice7
*iface
,
5019 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
5022 TRACE("iface %p, count %u, rects %p, flags %#x, color 0x%08x, z %.8e, stencil %#x.\n",
5023 iface
, Count
, Rects
, Flags
, Color
, Z
, Stencil
);
5025 EnterCriticalSection(&ddraw_cs
);
5026 hr
= IWineD3DDevice_Clear(This
->wineD3DDevice
, Count
, (RECT
*)Rects
, Flags
, Color
, Z
, Stencil
);
5027 LeaveCriticalSection(&ddraw_cs
);
5031 static HRESULT WINAPI
5032 IDirect3DDeviceImpl_7_Clear_FPUSetup(IDirect3DDevice7
*iface
,
5040 return IDirect3DDeviceImpl_7_Clear(iface
, Count
, Rects
, Flags
, Color
, Z
, Stencil
);
5043 static HRESULT WINAPI
5044 IDirect3DDeviceImpl_7_Clear_FPUPreserve(IDirect3DDevice7
*iface
,
5055 old_fpucw
= d3d_fpu_setup();
5056 hr
= IDirect3DDeviceImpl_7_Clear(iface
, Count
, Rects
, Flags
, Color
, Z
, Stencil
);
5057 set_fpu_control_word(old_fpucw
);
5062 /*****************************************************************************
5063 * IDirect3DDevice7::SetViewport
5065 * Sets the current viewport.
5067 * Version 7 only, but IDirect3DViewport uses this call for older
5071 * Data: The new viewport to set
5075 * DDERR_INVALIDPARAMS if Data is NULL
5076 * For more details, see IWineDDDevice::SetViewport
5078 *****************************************************************************/
5080 IDirect3DDeviceImpl_7_SetViewport(IDirect3DDevice7
*iface
,
5083 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
5086 TRACE("iface %p, viewport %p.\n", iface
, Data
);
5089 return DDERR_INVALIDPARAMS
;
5091 /* Note: D3DVIEWPORT7 is compatible with WINED3DVIEWPORT */
5092 EnterCriticalSection(&ddraw_cs
);
5093 hr
= IWineD3DDevice_SetViewport(This
->wineD3DDevice
,
5094 (WINED3DVIEWPORT
*) Data
);
5095 LeaveCriticalSection(&ddraw_cs
);
5099 static HRESULT WINAPI
5100 IDirect3DDeviceImpl_7_SetViewport_FPUSetup(IDirect3DDevice7
*iface
,
5103 return IDirect3DDeviceImpl_7_SetViewport(iface
, Data
);
5106 static HRESULT WINAPI
5107 IDirect3DDeviceImpl_7_SetViewport_FPUPreserve(IDirect3DDevice7
*iface
,
5113 old_fpucw
= d3d_fpu_setup();
5114 hr
= IDirect3DDeviceImpl_7_SetViewport(iface
, Data
);
5115 set_fpu_control_word(old_fpucw
);
5120 /*****************************************************************************
5121 * IDirect3DDevice::GetViewport
5123 * Returns the current viewport
5128 * Data: D3D7Viewport structure to write the viewport information to
5132 * DDERR_INVALIDPARAMS if Data is NULL
5133 * For more details, see IWineD3DDevice::GetViewport
5135 *****************************************************************************/
5137 IDirect3DDeviceImpl_7_GetViewport(IDirect3DDevice7
*iface
,
5140 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
5143 TRACE("iface %p, viewport %p.\n", iface
, Data
);
5146 return DDERR_INVALIDPARAMS
;
5148 /* Note: D3DVIEWPORT7 is compatible with WINED3DVIEWPORT */
5149 EnterCriticalSection(&ddraw_cs
);
5150 hr
= IWineD3DDevice_GetViewport(This
->wineD3DDevice
,
5151 (WINED3DVIEWPORT
*) Data
);
5153 LeaveCriticalSection(&ddraw_cs
);
5154 return hr_ddraw_from_wined3d(hr
);
5157 static HRESULT WINAPI
5158 IDirect3DDeviceImpl_7_GetViewport_FPUSetup(IDirect3DDevice7
*iface
,
5161 return IDirect3DDeviceImpl_7_GetViewport(iface
, Data
);
5164 static HRESULT WINAPI
5165 IDirect3DDeviceImpl_7_GetViewport_FPUPreserve(IDirect3DDevice7
*iface
,
5171 old_fpucw
= d3d_fpu_setup();
5172 hr
= IDirect3DDeviceImpl_7_GetViewport(iface
, Data
);
5173 set_fpu_control_word(old_fpucw
);
5178 /*****************************************************************************
5179 * IDirect3DDevice7::SetMaterial
5186 * Mat: The material to set
5190 * DDERR_INVALIDPARAMS if Mat is NULL.
5191 * For more details, see IWineD3DDevice::SetMaterial
5193 *****************************************************************************/
5195 IDirect3DDeviceImpl_7_SetMaterial(IDirect3DDevice7
*iface
,
5198 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
5201 TRACE("iface %p, material %p.\n", iface
, Mat
);
5203 if (!Mat
) return DDERR_INVALIDPARAMS
;
5204 /* Note: D3DMATERIAL7 is compatible with WINED3DMATERIAL */
5205 EnterCriticalSection(&ddraw_cs
);
5206 hr
= IWineD3DDevice_SetMaterial(This
->wineD3DDevice
,
5207 (WINED3DMATERIAL
*) Mat
);
5208 LeaveCriticalSection(&ddraw_cs
);
5209 return hr_ddraw_from_wined3d(hr
);
5212 static HRESULT WINAPI
5213 IDirect3DDeviceImpl_7_SetMaterial_FPUSetup(IDirect3DDevice7
*iface
,
5216 return IDirect3DDeviceImpl_7_SetMaterial(iface
, Mat
);
5219 static HRESULT WINAPI
5220 IDirect3DDeviceImpl_7_SetMaterial_FPUPreserve(IDirect3DDevice7
*iface
,
5226 old_fpucw
= d3d_fpu_setup();
5227 hr
= IDirect3DDeviceImpl_7_SetMaterial(iface
, Mat
);
5228 set_fpu_control_word(old_fpucw
);
5233 /*****************************************************************************
5234 * IDirect3DDevice7::GetMaterial
5236 * Returns the current material
5241 * Mat: D3DMATERIAL7 structure to write the material parameters to
5245 * DDERR_INVALIDPARAMS if Mat is NULL
5246 * For more details, see IWineD3DDevice::GetMaterial
5248 *****************************************************************************/
5250 IDirect3DDeviceImpl_7_GetMaterial(IDirect3DDevice7
*iface
,
5253 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
5256 TRACE("iface %p, material %p.\n", iface
, Mat
);
5258 EnterCriticalSection(&ddraw_cs
);
5259 /* Note: D3DMATERIAL7 is compatible with WINED3DMATERIAL */
5260 hr
= IWineD3DDevice_GetMaterial(This
->wineD3DDevice
,
5261 (WINED3DMATERIAL
*) Mat
);
5262 LeaveCriticalSection(&ddraw_cs
);
5263 return hr_ddraw_from_wined3d(hr
);
5266 static HRESULT WINAPI
5267 IDirect3DDeviceImpl_7_GetMaterial_FPUSetup(IDirect3DDevice7
*iface
,
5270 return IDirect3DDeviceImpl_7_GetMaterial(iface
, Mat
);
5273 static HRESULT WINAPI
5274 IDirect3DDeviceImpl_7_GetMaterial_FPUPreserve(IDirect3DDevice7
*iface
,
5280 old_fpucw
= d3d_fpu_setup();
5281 hr
= IDirect3DDeviceImpl_7_GetMaterial(iface
, Mat
);
5282 set_fpu_control_word(old_fpucw
);
5287 /*****************************************************************************
5288 * IDirect3DDevice7::SetLight
5290 * Assigns a light to a light index, but doesn't activate it yet.
5292 * Version 7, IDirect3DLight uses this method for older versions
5295 * LightIndex: The index of the new light
5296 * Light: A D3DLIGHT7 structure describing the light
5300 * For more details, see IWineD3DDevice::SetLight
5302 *****************************************************************************/
5304 IDirect3DDeviceImpl_7_SetLight(IDirect3DDevice7
*iface
,
5308 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
5311 TRACE("iface %p, light_idx %u, light %p.\n", iface
, LightIndex
, Light
);
5313 EnterCriticalSection(&ddraw_cs
);
5314 /* Note: D3DLIGHT7 is compatible with WINED3DLIGHT */
5315 hr
= IWineD3DDevice_SetLight(This
->wineD3DDevice
,
5317 (WINED3DLIGHT
*) Light
);
5318 LeaveCriticalSection(&ddraw_cs
);
5319 return hr_ddraw_from_wined3d(hr
);
5322 static HRESULT WINAPI
5323 IDirect3DDeviceImpl_7_SetLight_FPUSetup(IDirect3DDevice7
*iface
,
5327 return IDirect3DDeviceImpl_7_SetLight(iface
, LightIndex
, Light
);
5330 static HRESULT WINAPI
5331 IDirect3DDeviceImpl_7_SetLight_FPUPreserve(IDirect3DDevice7
*iface
,
5338 old_fpucw
= d3d_fpu_setup();
5339 hr
= IDirect3DDeviceImpl_7_SetLight(iface
, LightIndex
, Light
);
5340 set_fpu_control_word(old_fpucw
);
5345 /*****************************************************************************
5346 * IDirect3DDevice7::GetLight
5348 * Returns the light assigned to a light index
5351 * Light: Structure to write the light information to
5355 * DDERR_INVALIDPARAMS if Light is NULL
5356 * For details, see IWineD3DDevice::GetLight
5358 *****************************************************************************/
5360 IDirect3DDeviceImpl_7_GetLight(IDirect3DDevice7
*iface
,
5364 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
5367 TRACE("iface %p, light_idx %u, light %p.\n", iface
, LightIndex
, Light
);
5369 EnterCriticalSection(&ddraw_cs
);
5370 /* Note: D3DLIGHT7 is compatible with WINED3DLIGHT */
5371 rc
= IWineD3DDevice_GetLight(This
->wineD3DDevice
,
5373 (WINED3DLIGHT
*) Light
);
5375 /* Translate the result. WineD3D returns other values than D3D7 */
5376 LeaveCriticalSection(&ddraw_cs
);
5377 return hr_ddraw_from_wined3d(rc
);
5380 static HRESULT WINAPI
5381 IDirect3DDeviceImpl_7_GetLight_FPUSetup(IDirect3DDevice7
*iface
,
5385 return IDirect3DDeviceImpl_7_GetLight(iface
, LightIndex
, Light
);
5388 static HRESULT WINAPI
5389 IDirect3DDeviceImpl_7_GetLight_FPUPreserve(IDirect3DDevice7
*iface
,
5396 old_fpucw
= d3d_fpu_setup();
5397 hr
= IDirect3DDeviceImpl_7_GetLight(iface
, LightIndex
, Light
);
5398 set_fpu_control_word(old_fpucw
);
5403 /*****************************************************************************
5404 * IDirect3DDevice7::BeginStateBlock
5406 * Begins recording to a stateblock
5412 * For details see IWineD3DDevice::BeginStateBlock
5414 *****************************************************************************/
5416 IDirect3DDeviceImpl_7_BeginStateBlock(IDirect3DDevice7
*iface
)
5418 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
5421 TRACE("iface %p.\n", iface
);
5423 EnterCriticalSection(&ddraw_cs
);
5424 hr
= IWineD3DDevice_BeginStateBlock(This
->wineD3DDevice
);
5425 LeaveCriticalSection(&ddraw_cs
);
5426 return hr_ddraw_from_wined3d(hr
);
5429 static HRESULT WINAPI
5430 IDirect3DDeviceImpl_7_BeginStateBlock_FPUSetup(IDirect3DDevice7
*iface
)
5432 return IDirect3DDeviceImpl_7_BeginStateBlock(iface
);
5435 static HRESULT WINAPI
5436 IDirect3DDeviceImpl_7_BeginStateBlock_FPUPreserve(IDirect3DDevice7
*iface
)
5441 old_fpucw
= d3d_fpu_setup();
5442 hr
= IDirect3DDeviceImpl_7_BeginStateBlock(iface
);
5443 set_fpu_control_word(old_fpucw
);
5448 /*****************************************************************************
5449 * IDirect3DDevice7::EndStateBlock
5451 * Stops recording to a state block and returns the created stateblock
5457 * BlockHandle: Address to store the stateblock's handle to
5461 * DDERR_INVALIDPARAMS if BlockHandle is NULL
5462 * See IWineD3DDevice::EndStateBlock for more details
5464 *****************************************************************************/
5466 IDirect3DDeviceImpl_7_EndStateBlock(IDirect3DDevice7
*iface
,
5469 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
5470 struct wined3d_stateblock
*wined3d_sb
;
5474 TRACE("iface %p, stateblock %p.\n", iface
, BlockHandle
);
5478 WARN("BlockHandle == NULL, returning DDERR_INVALIDPARAMS\n");
5479 return DDERR_INVALIDPARAMS
;
5482 EnterCriticalSection(&ddraw_cs
);
5484 hr
= IWineD3DDevice_EndStateBlock(This
->wineD3DDevice
, &wined3d_sb
);
5487 WARN("Failed to end stateblock, hr %#x.\n", hr
);
5488 LeaveCriticalSection(&ddraw_cs
);
5490 return hr_ddraw_from_wined3d(hr
);
5493 h
= ddraw_allocate_handle(&This
->handle_table
, wined3d_sb
, DDRAW_HANDLE_STATEBLOCK
);
5494 if (h
== DDRAW_INVALID_HANDLE
)
5496 ERR("Failed to allocate a stateblock handle.\n");
5497 wined3d_stateblock_decref(wined3d_sb
);
5498 LeaveCriticalSection(&ddraw_cs
);
5500 return DDERR_OUTOFMEMORY
;
5503 LeaveCriticalSection(&ddraw_cs
);
5504 *BlockHandle
= h
+ 1;
5506 return hr_ddraw_from_wined3d(hr
);
5509 static HRESULT WINAPI
5510 IDirect3DDeviceImpl_7_EndStateBlock_FPUSetup(IDirect3DDevice7
*iface
,
5513 return IDirect3DDeviceImpl_7_EndStateBlock(iface
, BlockHandle
);
5516 static HRESULT WINAPI
5517 IDirect3DDeviceImpl_7_EndStateBlock_FPUPreserve(IDirect3DDevice7
*iface
,
5523 old_fpucw
= d3d_fpu_setup();
5524 hr
= IDirect3DDeviceImpl_7_EndStateBlock(iface
, BlockHandle
);
5525 set_fpu_control_word(old_fpucw
);
5530 /*****************************************************************************
5531 * IDirect3DDevice7::PreLoad
5533 * Allows the app to signal that a texture will be used soon, to allow
5534 * the Direct3DDevice to load it to the video card in the meantime.
5539 * Texture: The texture to preload
5543 * DDERR_INVALIDPARAMS if Texture is NULL
5544 * See IWineD3DSurface::PreLoad for details
5546 *****************************************************************************/
5548 IDirect3DDeviceImpl_7_PreLoad(IDirect3DDevice7
*iface
,
5549 IDirectDrawSurface7
*Texture
)
5551 IDirectDrawSurfaceImpl
*surf
= (IDirectDrawSurfaceImpl
*)Texture
;
5553 TRACE("iface %p, texture %p.\n", iface
, Texture
);
5556 return DDERR_INVALIDPARAMS
;
5558 EnterCriticalSection(&ddraw_cs
);
5559 IWineD3DSurface_PreLoad(surf
->WineD3DSurface
);
5560 LeaveCriticalSection(&ddraw_cs
);
5564 static HRESULT WINAPI
5565 IDirect3DDeviceImpl_7_PreLoad_FPUSetup(IDirect3DDevice7
*iface
,
5566 IDirectDrawSurface7
*Texture
)
5568 return IDirect3DDeviceImpl_7_PreLoad(iface
, Texture
);
5571 static HRESULT WINAPI
5572 IDirect3DDeviceImpl_7_PreLoad_FPUPreserve(IDirect3DDevice7
*iface
,
5573 IDirectDrawSurface7
*Texture
)
5578 old_fpucw
= d3d_fpu_setup();
5579 hr
= IDirect3DDeviceImpl_7_PreLoad(iface
, Texture
);
5580 set_fpu_control_word(old_fpucw
);
5585 /*****************************************************************************
5586 * IDirect3DDevice7::ApplyStateBlock
5588 * Activates the state stored in a state block handle.
5591 * BlockHandle: The stateblock handle to activate
5595 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is NULL
5597 *****************************************************************************/
5599 IDirect3DDeviceImpl_7_ApplyStateBlock(IDirect3DDevice7
*iface
,
5602 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
5603 struct wined3d_stateblock
*wined3d_sb
;
5606 TRACE("iface %p, stateblock %#x.\n", iface
, BlockHandle
);
5608 EnterCriticalSection(&ddraw_cs
);
5610 wined3d_sb
= ddraw_get_object(&This
->handle_table
, BlockHandle
- 1, DDRAW_HANDLE_STATEBLOCK
);
5613 WARN("Invalid stateblock handle.\n");
5614 LeaveCriticalSection(&ddraw_cs
);
5615 return D3DERR_INVALIDSTATEBLOCK
;
5618 hr
= wined3d_stateblock_apply(wined3d_sb
);
5619 LeaveCriticalSection(&ddraw_cs
);
5621 return hr_ddraw_from_wined3d(hr
);
5624 static HRESULT WINAPI
5625 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUSetup(IDirect3DDevice7
*iface
,
5628 return IDirect3DDeviceImpl_7_ApplyStateBlock(iface
, BlockHandle
);
5631 static HRESULT WINAPI
5632 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUPreserve(IDirect3DDevice7
*iface
,
5638 old_fpucw
= d3d_fpu_setup();
5639 hr
= IDirect3DDeviceImpl_7_ApplyStateBlock(iface
, BlockHandle
);
5640 set_fpu_control_word(old_fpucw
);
5645 /*****************************************************************************
5646 * IDirect3DDevice7::CaptureStateBlock
5648 * Updates a stateblock's values to the values currently set for the device
5653 * BlockHandle: Stateblock to update
5657 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is NULL
5658 * See IWineD3DDevice::CaptureStateBlock for more details
5660 *****************************************************************************/
5662 IDirect3DDeviceImpl_7_CaptureStateBlock(IDirect3DDevice7
*iface
,
5665 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
5666 struct wined3d_stateblock
*wined3d_sb
;
5669 TRACE("iface %p, stateblock %#x.\n", iface
, BlockHandle
);
5671 EnterCriticalSection(&ddraw_cs
);
5673 wined3d_sb
= ddraw_get_object(&This
->handle_table
, BlockHandle
- 1, DDRAW_HANDLE_STATEBLOCK
);
5676 WARN("Invalid stateblock handle.\n");
5677 LeaveCriticalSection(&ddraw_cs
);
5678 return D3DERR_INVALIDSTATEBLOCK
;
5681 hr
= wined3d_stateblock_capture(wined3d_sb
);
5682 LeaveCriticalSection(&ddraw_cs
);
5683 return hr_ddraw_from_wined3d(hr
);
5686 static HRESULT WINAPI
5687 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUSetup(IDirect3DDevice7
*iface
,
5690 return IDirect3DDeviceImpl_7_CaptureStateBlock(iface
, BlockHandle
);
5693 static HRESULT WINAPI
5694 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUPreserve(IDirect3DDevice7
*iface
,
5700 old_fpucw
= d3d_fpu_setup();
5701 hr
= IDirect3DDeviceImpl_7_CaptureStateBlock(iface
, BlockHandle
);
5702 set_fpu_control_word(old_fpucw
);
5707 /*****************************************************************************
5708 * IDirect3DDevice7::DeleteStateBlock
5710 * Deletes a stateblock handle. This means releasing the WineD3DStateBlock
5715 * BlockHandle: Stateblock handle to delete
5719 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is 0
5721 *****************************************************************************/
5723 IDirect3DDeviceImpl_7_DeleteStateBlock(IDirect3DDevice7
*iface
,
5726 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
5727 struct wined3d_stateblock
*wined3d_sb
;
5730 TRACE("iface %p, stateblock %#x.\n", iface
, BlockHandle
);
5732 EnterCriticalSection(&ddraw_cs
);
5734 wined3d_sb
= ddraw_free_handle(&This
->handle_table
, BlockHandle
- 1, DDRAW_HANDLE_STATEBLOCK
);
5737 WARN("Invalid stateblock handle.\n");
5738 LeaveCriticalSection(&ddraw_cs
);
5739 return D3DERR_INVALIDSTATEBLOCK
;
5742 if ((ref
= wined3d_stateblock_decref(wined3d_sb
)))
5744 ERR("Something is still holding stateblock %p (refcount %u).\n", wined3d_sb
, ref
);
5747 LeaveCriticalSection(&ddraw_cs
);
5751 static HRESULT WINAPI
5752 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUSetup(IDirect3DDevice7
*iface
,
5755 return IDirect3DDeviceImpl_7_DeleteStateBlock(iface
, BlockHandle
);
5758 static HRESULT WINAPI
5759 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUPreserve(IDirect3DDevice7
*iface
,
5765 old_fpucw
= d3d_fpu_setup();
5766 hr
= IDirect3DDeviceImpl_7_DeleteStateBlock(iface
, BlockHandle
);
5767 set_fpu_control_word(old_fpucw
);
5772 /*****************************************************************************
5773 * IDirect3DDevice7::CreateStateBlock
5775 * Creates a new state block handle.
5780 * Type: The state block type
5781 * BlockHandle: Address to write the created handle to
5785 * DDERR_INVALIDPARAMS if BlockHandle is NULL
5787 *****************************************************************************/
5789 IDirect3DDeviceImpl_7_CreateStateBlock(IDirect3DDevice7
*iface
,
5790 D3DSTATEBLOCKTYPE Type
,
5793 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
5794 struct wined3d_stateblock
*wined3d_sb
;
5798 TRACE("iface %p, type %#x, stateblock %p.\n", iface
, Type
, BlockHandle
);
5802 WARN("BlockHandle == NULL, returning DDERR_INVALIDPARAMS\n");
5803 return DDERR_INVALIDPARAMS
;
5805 if(Type
!= D3DSBT_ALL
&& Type
!= D3DSBT_PIXELSTATE
&&
5806 Type
!= D3DSBT_VERTEXSTATE
) {
5807 WARN("Unexpected stateblock type, returning DDERR_INVALIDPARAMS\n");
5808 return DDERR_INVALIDPARAMS
;
5811 EnterCriticalSection(&ddraw_cs
);
5813 /* The D3DSTATEBLOCKTYPE enum is fine here. */
5814 hr
= IWineD3DDevice_CreateStateBlock(This
->wineD3DDevice
, Type
, &wined3d_sb
);
5817 WARN("Failed to create stateblock, hr %#x.\n", hr
);
5818 LeaveCriticalSection(&ddraw_cs
);
5819 return hr_ddraw_from_wined3d(hr
);
5822 h
= ddraw_allocate_handle(&This
->handle_table
, wined3d_sb
, DDRAW_HANDLE_STATEBLOCK
);
5823 if (h
== DDRAW_INVALID_HANDLE
)
5825 ERR("Failed to allocate stateblock handle.\n");
5826 wined3d_stateblock_decref(wined3d_sb
);
5827 LeaveCriticalSection(&ddraw_cs
);
5828 return DDERR_OUTOFMEMORY
;
5831 *BlockHandle
= h
+ 1;
5832 LeaveCriticalSection(&ddraw_cs
);
5834 return hr_ddraw_from_wined3d(hr
);
5837 static HRESULT WINAPI
5838 IDirect3DDeviceImpl_7_CreateStateBlock_FPUSetup(IDirect3DDevice7
*iface
,
5839 D3DSTATEBLOCKTYPE Type
,
5842 return IDirect3DDeviceImpl_7_CreateStateBlock(iface
, Type
, BlockHandle
);
5845 static HRESULT WINAPI
5846 IDirect3DDeviceImpl_7_CreateStateBlock_FPUPreserve(IDirect3DDevice7
*iface
,
5847 D3DSTATEBLOCKTYPE Type
,
5853 old_fpucw
= d3d_fpu_setup();
5854 hr
=IDirect3DDeviceImpl_7_CreateStateBlock(iface
, Type
, BlockHandle
);
5855 set_fpu_control_word(old_fpucw
);
5860 /* Helper function for IDirect3DDeviceImpl_7_Load. */
5861 static BOOL
is_mip_level_subset(IDirectDrawSurfaceImpl
*dest
,
5862 IDirectDrawSurfaceImpl
*src
)
5864 IDirectDrawSurfaceImpl
*src_level
, *dest_level
;
5865 IDirectDrawSurface7
*temp
;
5866 DDSURFACEDESC2 ddsd
;
5867 BOOL levelFound
; /* at least one suitable sublevel in dest found */
5869 /* To satisfy "destination is mip level subset of source" criteria (regular texture counts as 1 level),
5870 * 1) there must be at least one mip level in destination that matched dimensions of some mip level in source and
5871 * 2) there must be no destination levels that don't match any levels in source. Otherwise it's INVALIDPARAMS.
5878 for (;src_level
&& dest_level
;)
5880 if (src_level
->surface_desc
.dwWidth
== dest_level
->surface_desc
.dwWidth
&&
5881 src_level
->surface_desc
.dwHeight
== dest_level
->surface_desc
.dwHeight
)
5885 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
5886 ddsd
.ddsCaps
.dwCaps2
= DDSCAPS2_MIPMAPSUBLEVEL
;
5887 IDirectDrawSurface7_GetAttachedSurface((IDirectDrawSurface7
*)dest_level
, &ddsd
.ddsCaps
, &temp
);
5889 if (dest_level
!= dest
) IDirectDrawSurface7_Release((IDirectDrawSurface7
*)dest_level
);
5891 dest_level
= (IDirectDrawSurfaceImpl
*)temp
;
5894 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
5895 ddsd
.ddsCaps
.dwCaps2
= DDSCAPS2_MIPMAPSUBLEVEL
;
5896 IDirectDrawSurface7_GetAttachedSurface((IDirectDrawSurface7
*)src_level
, &ddsd
.ddsCaps
, &temp
);
5898 if (src_level
!= src
) IDirectDrawSurface7_Release((IDirectDrawSurface7
*)src_level
);
5900 src_level
= (IDirectDrawSurfaceImpl
*)temp
;
5903 if (src_level
&& src_level
!= src
) IDirectDrawSurface7_Release((IDirectDrawSurface7
*)src_level
);
5904 if (dest_level
&& dest_level
!= dest
) IDirectDrawSurface7_Release((IDirectDrawSurface7
*)dest_level
);
5906 return !dest_level
&& levelFound
;
5909 /* Helper function for IDirect3DDeviceImpl_7_Load. */
5910 static void copy_mipmap_chain(IDirect3DDeviceImpl
*device
,
5911 IDirectDrawSurfaceImpl
*dest
,
5912 IDirectDrawSurfaceImpl
*src
,
5913 const POINT
*DestPoint
,
5914 const RECT
*SrcRect
)
5916 IDirectDrawSurfaceImpl
*src_level
, *dest_level
;
5917 IDirectDrawSurface7
*temp
;
5918 DDSURFACEDESC2 ddsd
;
5922 IDirectDrawPalette
*pal
= NULL
, *pal_src
= NULL
;
5925 BOOL palette_missing
= FALSE
;
5927 /* Copy palette, if possible. */
5928 IDirectDrawSurface7_GetPalette((IDirectDrawSurface7
*)src
, &pal_src
);
5929 IDirectDrawSurface7_GetPalette((IDirectDrawSurface7
*)dest
, &pal
);
5931 if (pal_src
!= NULL
&& pal
!= NULL
)
5933 PALETTEENTRY palent
[256];
5935 IDirectDrawPalette_GetEntries(pal_src
, 0, 0, 256, palent
);
5936 IDirectDrawPalette_SetEntries(pal
, 0, 0, 256, palent
);
5939 if (dest
->surface_desc
.u4
.ddpfPixelFormat
.dwFlags
& (DDPF_PALETTEINDEXED1
| DDPF_PALETTEINDEXED2
|
5940 DDPF_PALETTEINDEXED4
| DDPF_PALETTEINDEXED8
| DDPF_PALETTEINDEXEDTO8
) && !pal
)
5942 palette_missing
= TRUE
;
5945 if (pal
) IDirectDrawPalette_Release(pal
);
5946 if (pal_src
) IDirectDrawPalette_Release(pal_src
);
5948 /* Copy colorkeys, if present. */
5949 for (ckeyflag
= DDCKEY_DESTBLT
; ckeyflag
<= DDCKEY_SRCOVERLAY
; ckeyflag
<<= 1)
5951 hr
= IDirectDrawSurface7_GetColorKey((IDirectDrawSurface7
*)src
, ckeyflag
, &ddckey
);
5955 IDirectDrawSurface7_SetColorKey((IDirectDrawSurface7
*)dest
, ckeyflag
, &ddckey
);
5965 for (;src_level
&& dest_level
;)
5967 if (src_level
->surface_desc
.dwWidth
== dest_level
->surface_desc
.dwWidth
&&
5968 src_level
->surface_desc
.dwHeight
== dest_level
->surface_desc
.dwHeight
)
5970 /* Try UpdateSurface that may perform a more direct opengl loading. But skip this if destination is paletted texture and has no palette.
5971 * Some games like Sacrifice set palette after Load, and it is a waste of effort to try to load texture without palette and generates
5972 * warnings in wined3d. */
5973 if (!palette_missing
)
5974 hr
= IWineD3DDevice_UpdateSurface(device
->wineD3DDevice
, src_level
->WineD3DSurface
, &rect
, dest_level
->WineD3DSurface
,
5977 if (palette_missing
|| FAILED(hr
))
5979 /* UpdateSurface may fail e.g. if dest is in system memory. Fall back to BltFast that is less strict. */
5980 IWineD3DSurface_BltFast(dest_level
->WineD3DSurface
,
5982 src_level
->WineD3DSurface
, &rect
, 0);
5985 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
5986 ddsd
.ddsCaps
.dwCaps2
= DDSCAPS2_MIPMAPSUBLEVEL
;
5987 IDirectDrawSurface7_GetAttachedSurface((IDirectDrawSurface7
*)dest_level
, &ddsd
.ddsCaps
, &temp
);
5989 if (dest_level
!= dest
) IDirectDrawSurface7_Release((IDirectDrawSurface7
*)dest_level
);
5991 dest_level
= (IDirectDrawSurfaceImpl
*)temp
;
5994 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
5995 ddsd
.ddsCaps
.dwCaps2
= DDSCAPS2_MIPMAPSUBLEVEL
;
5996 IDirectDrawSurface7_GetAttachedSurface((IDirectDrawSurface7
*)src_level
, &ddsd
.ddsCaps
, &temp
);
5998 if (src_level
!= src
) IDirectDrawSurface7_Release((IDirectDrawSurface7
*)src_level
);
6000 src_level
= (IDirectDrawSurfaceImpl
*)temp
;
6007 rect
.right
= (rect
.right
+ 1) / 2;
6008 rect
.bottom
= (rect
.bottom
+ 1) / 2;
6011 if (src_level
&& src_level
!= src
) IDirectDrawSurface7_Release((IDirectDrawSurface7
*)src_level
);
6012 if (dest_level
&& dest_level
!= dest
) IDirectDrawSurface7_Release((IDirectDrawSurface7
*)dest_level
);
6015 /*****************************************************************************
6016 * IDirect3DDevice7::Load
6018 * Loads a rectangular area from the source into the destination texture.
6019 * It can also copy the source to the faces of a cubic environment map
6024 * DestTex: Destination texture
6025 * DestPoint: Point in the destination where the source image should be
6027 * SrcTex: Source texture
6028 * SrcRect: Source rectangle
6029 * Flags: Cubemap faces to load (DDSCAPS2_CUBEMAP_ALLFACES, DDSCAPS2_CUBEMAP_POSITIVEX,
6030 * DDSCAPS2_CUBEMAP_NEGATIVEX, DDSCAPS2_CUBEMAP_POSITIVEY, DDSCAPS2_CUBEMAP_NEGATIVEY,
6031 * DDSCAPS2_CUBEMAP_POSITIVEZ, DDSCAPS2_CUBEMAP_NEGATIVEZ)
6035 * DDERR_INVALIDPARAMS if DestTex or SrcTex are NULL, broken coordinates or anything unexpected.
6038 *****************************************************************************/
6041 IDirect3DDeviceImpl_7_Load(IDirect3DDevice7
*iface
,
6042 IDirectDrawSurface7
*DestTex
,
6044 IDirectDrawSurface7
*SrcTex
,
6048 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
6049 IDirectDrawSurfaceImpl
*dest
= (IDirectDrawSurfaceImpl
*)DestTex
;
6050 IDirectDrawSurfaceImpl
*src
= (IDirectDrawSurfaceImpl
*)SrcTex
;
6054 TRACE("iface %p, dst_texture %p, dst_pos %s, src_texture %p, src_rect %s, flags %#x.\n",
6055 iface
, DestTex
, wine_dbgstr_point(DestPoint
), SrcTex
, wine_dbgstr_rect(SrcRect
), Flags
);
6057 if( (!src
) || (!dest
) )
6058 return DDERR_INVALIDPARAMS
;
6060 EnterCriticalSection(&ddraw_cs
);
6062 if (SrcRect
) srcrect
= *SrcRect
;
6065 srcrect
.left
= srcrect
.top
= 0;
6066 srcrect
.right
= src
->surface_desc
.dwWidth
;
6067 srcrect
.bottom
= src
->surface_desc
.dwHeight
;
6070 if (DestPoint
) destpoint
= *DestPoint
;
6073 destpoint
.x
= destpoint
.y
= 0;
6075 /* Check bad dimensions. DestPoint is validated against src, not dest, because
6076 * destination can be a subset of mip levels, in which case actual coordinates used
6077 * for it may be divided. If any dimension of dest is larger than source, it can't be
6078 * mip level subset, so an error can be returned early.
6080 if (srcrect
.left
>= srcrect
.right
|| srcrect
.top
>= srcrect
.bottom
||
6081 srcrect
.right
> src
->surface_desc
.dwWidth
||
6082 srcrect
.bottom
> src
->surface_desc
.dwHeight
||
6083 destpoint
.x
+ srcrect
.right
- srcrect
.left
> src
->surface_desc
.dwWidth
||
6084 destpoint
.y
+ srcrect
.bottom
- srcrect
.top
> src
->surface_desc
.dwHeight
||
6085 dest
->surface_desc
.dwWidth
> src
->surface_desc
.dwWidth
||
6086 dest
->surface_desc
.dwHeight
> src
->surface_desc
.dwHeight
)
6088 LeaveCriticalSection(&ddraw_cs
);
6089 return DDERR_INVALIDPARAMS
;
6092 /* Must be top level surfaces. */
6093 if (src
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_MIPMAPSUBLEVEL
||
6094 dest
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_MIPMAPSUBLEVEL
)
6096 LeaveCriticalSection(&ddraw_cs
);
6097 return DDERR_INVALIDPARAMS
;
6100 if (src
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_CUBEMAP
)
6102 DWORD src_face_flag
, dest_face_flag
;
6103 IDirectDrawSurfaceImpl
*src_face
, *dest_face
;
6104 IDirectDrawSurface7
*temp
;
6105 DDSURFACEDESC2 ddsd
;
6108 if (!(dest
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_CUBEMAP
))
6110 LeaveCriticalSection(&ddraw_cs
);
6111 return DDERR_INVALIDPARAMS
;
6114 /* Iterate through cube faces 2 times. First time is just to check INVALIDPARAMS conditions, second
6115 * time it's actual surface loading. */
6116 for (i
= 0; i
< 2; i
++)
6121 for (;dest_face
&& src_face
;)
6123 src_face_flag
= src_face
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_CUBEMAP_ALLFACES
;
6124 dest_face_flag
= dest_face
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_CUBEMAP_ALLFACES
;
6126 if (src_face_flag
== dest_face_flag
)
6130 /* Destination mip levels must be subset of source mip levels. */
6131 if (!is_mip_level_subset(dest_face
, src_face
))
6133 LeaveCriticalSection(&ddraw_cs
);
6134 return DDERR_INVALIDPARAMS
;
6137 else if (Flags
& dest_face_flag
)
6139 copy_mipmap_chain(This
, dest_face
, src_face
, &destpoint
, &srcrect
);
6142 if (src_face_flag
< DDSCAPS2_CUBEMAP_NEGATIVEZ
)
6144 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
6145 ddsd
.ddsCaps
.dwCaps2
= DDSCAPS2_CUBEMAP
| (src_face_flag
<< 1);
6146 IDirectDrawSurface7_GetAttachedSurface((IDirectDrawSurface7
*)src
, &ddsd
.ddsCaps
, &temp
);
6148 if (src_face
!= src
) IDirectDrawSurface7_Release((IDirectDrawSurface7
*)src_face
);
6150 src_face
= (IDirectDrawSurfaceImpl
*)temp
;
6154 if (src_face
!= src
) IDirectDrawSurface7_Release((IDirectDrawSurface7
*)src_face
);
6160 if (dest_face_flag
< DDSCAPS2_CUBEMAP_NEGATIVEZ
)
6162 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
6163 ddsd
.ddsCaps
.dwCaps2
= DDSCAPS2_CUBEMAP
| (dest_face_flag
<< 1);
6164 IDirectDrawSurface7_GetAttachedSurface((IDirectDrawSurface7
*)dest
, &ddsd
.ddsCaps
, &temp
);
6166 if (dest_face
!= dest
) IDirectDrawSurface7_Release((IDirectDrawSurface7
*)dest_face
);
6168 dest_face
= (IDirectDrawSurfaceImpl
*)temp
;
6172 if (dest_face
!= dest
) IDirectDrawSurface7_Release((IDirectDrawSurface7
*)dest_face
);
6180 /* Native returns error if src faces are not subset of dest faces. */
6183 LeaveCriticalSection(&ddraw_cs
);
6184 return DDERR_INVALIDPARAMS
;
6189 LeaveCriticalSection(&ddraw_cs
);
6192 else if (dest
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_CUBEMAP
)
6194 LeaveCriticalSection(&ddraw_cs
);
6195 return DDERR_INVALIDPARAMS
;
6198 /* Handle non cube map textures. */
6200 /* Destination mip levels must be subset of source mip levels. */
6201 if (!is_mip_level_subset(dest
, src
))
6203 LeaveCriticalSection(&ddraw_cs
);
6204 return DDERR_INVALIDPARAMS
;
6207 copy_mipmap_chain(This
, dest
, src
, &destpoint
, &srcrect
);
6209 LeaveCriticalSection(&ddraw_cs
);
6213 static HRESULT WINAPI
6214 IDirect3DDeviceImpl_7_Load_FPUSetup(IDirect3DDevice7
*iface
,
6215 IDirectDrawSurface7
*DestTex
,
6217 IDirectDrawSurface7
*SrcTex
,
6221 return IDirect3DDeviceImpl_7_Load(iface
, DestTex
, DestPoint
, SrcTex
, SrcRect
, Flags
);
6224 static HRESULT WINAPI
6225 IDirect3DDeviceImpl_7_Load_FPUPreserve(IDirect3DDevice7
*iface
,
6226 IDirectDrawSurface7
*DestTex
,
6228 IDirectDrawSurface7
*SrcTex
,
6235 old_fpucw
= d3d_fpu_setup();
6236 hr
= IDirect3DDeviceImpl_7_Load(iface
, DestTex
, DestPoint
, SrcTex
, SrcRect
, Flags
);
6237 set_fpu_control_word(old_fpucw
);
6242 /*****************************************************************************
6243 * IDirect3DDevice7::LightEnable
6245 * Enables or disables a light
6247 * Version 7, IDirect3DLight uses this method too.
6250 * LightIndex: The index of the light to enable / disable
6251 * Enable: Enable or disable the light
6255 * For more details, see IWineD3DDevice::SetLightEnable
6257 *****************************************************************************/
6259 IDirect3DDeviceImpl_7_LightEnable(IDirect3DDevice7
*iface
,
6263 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
6266 TRACE("iface %p, light_idx %u, enabled %#x.\n", iface
, LightIndex
, Enable
);
6268 EnterCriticalSection(&ddraw_cs
);
6269 hr
= IWineD3DDevice_SetLightEnable(This
->wineD3DDevice
, LightIndex
, Enable
);
6270 LeaveCriticalSection(&ddraw_cs
);
6271 return hr_ddraw_from_wined3d(hr
);
6274 static HRESULT WINAPI
6275 IDirect3DDeviceImpl_7_LightEnable_FPUSetup(IDirect3DDevice7
*iface
,
6279 return IDirect3DDeviceImpl_7_LightEnable(iface
, LightIndex
, Enable
);
6282 static HRESULT WINAPI
6283 IDirect3DDeviceImpl_7_LightEnable_FPUPreserve(IDirect3DDevice7
*iface
,
6290 old_fpucw
= d3d_fpu_setup();
6291 hr
= IDirect3DDeviceImpl_7_LightEnable(iface
, LightIndex
, Enable
);
6292 set_fpu_control_word(old_fpucw
);
6297 /*****************************************************************************
6298 * IDirect3DDevice7::GetLightEnable
6300 * Retrieves if the light with the given index is enabled or not
6305 * LightIndex: Index of desired light
6306 * Enable: Pointer to a BOOL which contains the result
6310 * DDERR_INVALIDPARAMS if Enable is NULL
6311 * See IWineD3DDevice::GetLightEnable for more details
6313 *****************************************************************************/
6315 IDirect3DDeviceImpl_7_GetLightEnable(IDirect3DDevice7
*iface
,
6319 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
6322 TRACE("iface %p, light_idx %u, enabled %p.\n", iface
, LightIndex
, Enable
);
6325 return DDERR_INVALIDPARAMS
;
6327 EnterCriticalSection(&ddraw_cs
);
6328 hr
= IWineD3DDevice_GetLightEnable(This
->wineD3DDevice
, LightIndex
, Enable
);
6329 LeaveCriticalSection(&ddraw_cs
);
6330 return hr_ddraw_from_wined3d(hr
);
6333 static HRESULT WINAPI
6334 IDirect3DDeviceImpl_7_GetLightEnable_FPUSetup(IDirect3DDevice7
*iface
,
6338 return IDirect3DDeviceImpl_7_GetLightEnable(iface
, LightIndex
, Enable
);
6341 static HRESULT WINAPI
6342 IDirect3DDeviceImpl_7_GetLightEnable_FPUPreserve(IDirect3DDevice7
*iface
,
6349 old_fpucw
= d3d_fpu_setup();
6350 hr
= IDirect3DDeviceImpl_7_GetLightEnable(iface
, LightIndex
, Enable
);
6351 set_fpu_control_word(old_fpucw
);
6356 /*****************************************************************************
6357 * IDirect3DDevice7::SetClipPlane
6359 * Sets custom clipping plane
6364 * Index: The index of the clipping plane
6365 * PlaneEquation: An equation defining the clipping plane
6369 * DDERR_INVALIDPARAMS if PlaneEquation is NULL
6370 * See IWineD3DDevice::SetClipPlane for more details
6372 *****************************************************************************/
6374 IDirect3DDeviceImpl_7_SetClipPlane(IDirect3DDevice7
*iface
,
6376 D3DVALUE
* PlaneEquation
)
6378 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
6381 TRACE("iface %p, idx %u, plane %p.\n", iface
, Index
, PlaneEquation
);
6384 return DDERR_INVALIDPARAMS
;
6386 EnterCriticalSection(&ddraw_cs
);
6387 hr
= IWineD3DDevice_SetClipPlane(This
->wineD3DDevice
, Index
, PlaneEquation
);
6388 LeaveCriticalSection(&ddraw_cs
);
6392 static HRESULT WINAPI
6393 IDirect3DDeviceImpl_7_SetClipPlane_FPUSetup(IDirect3DDevice7
*iface
,
6395 D3DVALUE
* PlaneEquation
)
6397 return IDirect3DDeviceImpl_7_SetClipPlane(iface
, Index
, PlaneEquation
);
6400 static HRESULT WINAPI
6401 IDirect3DDeviceImpl_7_SetClipPlane_FPUPreserve(IDirect3DDevice7
*iface
,
6403 D3DVALUE
* PlaneEquation
)
6408 old_fpucw
= d3d_fpu_setup();
6409 hr
= IDirect3DDeviceImpl_7_SetClipPlane(iface
, Index
, PlaneEquation
);
6410 set_fpu_control_word(old_fpucw
);
6415 /*****************************************************************************
6416 * IDirect3DDevice7::GetClipPlane
6418 * Returns the clipping plane with a specific index
6421 * Index: The index of the desired plane
6422 * PlaneEquation: Address to store the plane equation to
6426 * DDERR_INVALIDPARAMS if PlaneEquation is NULL
6427 * See IWineD3DDevice::GetClipPlane for more details
6429 *****************************************************************************/
6431 IDirect3DDeviceImpl_7_GetClipPlane(IDirect3DDevice7
*iface
,
6433 D3DVALUE
* PlaneEquation
)
6435 IDirect3DDeviceImpl
*This
= (IDirect3DDeviceImpl
*)iface
;
6438 TRACE("iface %p, idx %u, plane %p.\n", iface
, Index
, PlaneEquation
);
6441 return DDERR_INVALIDPARAMS
;
6443 EnterCriticalSection(&ddraw_cs
);
6444 hr
= IWineD3DDevice_GetClipPlane(This
->wineD3DDevice
, Index
, PlaneEquation
);
6445 LeaveCriticalSection(&ddraw_cs
);
6449 static HRESULT WINAPI
6450 IDirect3DDeviceImpl_7_GetClipPlane_FPUSetup(IDirect3DDevice7
*iface
,
6452 D3DVALUE
* PlaneEquation
)
6454 return IDirect3DDeviceImpl_7_GetClipPlane(iface
, Index
, PlaneEquation
);
6457 static HRESULT WINAPI
6458 IDirect3DDeviceImpl_7_GetClipPlane_FPUPreserve(IDirect3DDevice7
*iface
,
6460 D3DVALUE
* PlaneEquation
)
6465 old_fpucw
= d3d_fpu_setup();
6466 hr
= IDirect3DDeviceImpl_7_GetClipPlane(iface
, Index
, PlaneEquation
);
6467 set_fpu_control_word(old_fpucw
);
6472 /*****************************************************************************
6473 * IDirect3DDevice7::GetInfo
6475 * Retrieves some information about the device. The DirectX sdk says that
6476 * this version returns S_FALSE for all retail builds of DirectX, that's what
6477 * this implementation does.
6480 * DevInfoID: Information type requested
6481 * DevInfoStruct: Pointer to a structure to store the info to
6482 * Size: Size of the structure
6485 * S_FALSE, because it's a non-debug driver
6487 *****************************************************************************/
6488 static HRESULT WINAPI
6489 IDirect3DDeviceImpl_7_GetInfo(IDirect3DDevice7
*iface
,
6491 void *DevInfoStruct
,
6494 TRACE("iface %p, info_id %#x, info %p, info_size %u.\n",
6495 iface
, DevInfoID
, DevInfoStruct
, Size
);
6497 if (TRACE_ON(ddraw
))
6499 TRACE(" info requested : ");
6502 case D3DDEVINFOID_TEXTUREMANAGER
: TRACE("D3DDEVINFOID_TEXTUREMANAGER\n"); break;
6503 case D3DDEVINFOID_D3DTEXTUREMANAGER
: TRACE("D3DDEVINFOID_D3DTEXTUREMANAGER\n"); break;
6504 case D3DDEVINFOID_TEXTURING
: TRACE("D3DDEVINFOID_TEXTURING\n"); break;
6505 default: ERR(" invalid flag !!!\n"); return DDERR_INVALIDPARAMS
;
6509 return S_FALSE
; /* According to MSDN, this is valid for a non-debug driver */
6512 /* For performance optimization, devices created in FPUSETUP and FPUPRESERVE modes
6513 * have separate vtables. Simple functions where this doesn't matter like GetDirect3D
6514 * are not duplicated.
6516 * Device created with DDSCL_FPUSETUP (d3d7 default) - device methods assume that FPU
6517 * has already been setup for optimal d3d operation.
6519 * Device created with DDSCL_FPUPRESERVE - resets and restores FPU mode when necessary in
6520 * d3d calls (FPU may be in a mode non-suitable for d3d when the app calls d3d). Required
6521 * by Sacrifice (game). */
6522 static const struct IDirect3DDevice7Vtbl d3d_device7_fpu_setup_vtbl
=
6524 /*** IUnknown Methods ***/
6525 IDirect3DDeviceImpl_7_QueryInterface
,
6526 IDirect3DDeviceImpl_7_AddRef
,
6527 IDirect3DDeviceImpl_7_Release
,
6528 /*** IDirect3DDevice7 ***/
6529 IDirect3DDeviceImpl_7_GetCaps_FPUSetup
,
6530 IDirect3DDeviceImpl_7_EnumTextureFormats_FPUSetup
,
6531 IDirect3DDeviceImpl_7_BeginScene_FPUSetup
,
6532 IDirect3DDeviceImpl_7_EndScene_FPUSetup
,
6533 IDirect3DDeviceImpl_7_GetDirect3D
,
6534 IDirect3DDeviceImpl_7_SetRenderTarget_FPUSetup
,
6535 IDirect3DDeviceImpl_7_GetRenderTarget
,
6536 IDirect3DDeviceImpl_7_Clear_FPUSetup
,
6537 IDirect3DDeviceImpl_7_SetTransform_FPUSetup
,
6538 IDirect3DDeviceImpl_7_GetTransform_FPUSetup
,
6539 IDirect3DDeviceImpl_7_SetViewport_FPUSetup
,
6540 IDirect3DDeviceImpl_7_MultiplyTransform_FPUSetup
,
6541 IDirect3DDeviceImpl_7_GetViewport_FPUSetup
,
6542 IDirect3DDeviceImpl_7_SetMaterial_FPUSetup
,
6543 IDirect3DDeviceImpl_7_GetMaterial_FPUSetup
,
6544 IDirect3DDeviceImpl_7_SetLight_FPUSetup
,
6545 IDirect3DDeviceImpl_7_GetLight_FPUSetup
,
6546 IDirect3DDeviceImpl_7_SetRenderState_FPUSetup
,
6547 IDirect3DDeviceImpl_7_GetRenderState_FPUSetup
,
6548 IDirect3DDeviceImpl_7_BeginStateBlock_FPUSetup
,
6549 IDirect3DDeviceImpl_7_EndStateBlock_FPUSetup
,
6550 IDirect3DDeviceImpl_7_PreLoad_FPUSetup
,
6551 IDirect3DDeviceImpl_7_DrawPrimitive_FPUSetup
,
6552 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUSetup
,
6553 IDirect3DDeviceImpl_7_SetClipStatus
,
6554 IDirect3DDeviceImpl_7_GetClipStatus
,
6555 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUSetup
,
6556 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUSetup
,
6557 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUSetup
,
6558 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUSetup
,
6559 IDirect3DDeviceImpl_7_ComputeSphereVisibility
,
6560 IDirect3DDeviceImpl_7_GetTexture_FPUSetup
,
6561 IDirect3DDeviceImpl_7_SetTexture_FPUSetup
,
6562 IDirect3DDeviceImpl_7_GetTextureStageState_FPUSetup
,
6563 IDirect3DDeviceImpl_7_SetTextureStageState_FPUSetup
,
6564 IDirect3DDeviceImpl_7_ValidateDevice_FPUSetup
,
6565 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUSetup
,
6566 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUSetup
,
6567 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUSetup
,
6568 IDirect3DDeviceImpl_7_CreateStateBlock_FPUSetup
,
6569 IDirect3DDeviceImpl_7_Load_FPUSetup
,
6570 IDirect3DDeviceImpl_7_LightEnable_FPUSetup
,
6571 IDirect3DDeviceImpl_7_GetLightEnable_FPUSetup
,
6572 IDirect3DDeviceImpl_7_SetClipPlane_FPUSetup
,
6573 IDirect3DDeviceImpl_7_GetClipPlane_FPUSetup
,
6574 IDirect3DDeviceImpl_7_GetInfo
6577 static const struct IDirect3DDevice7Vtbl d3d_device7_fpu_preserve_vtbl
=
6579 /*** IUnknown Methods ***/
6580 IDirect3DDeviceImpl_7_QueryInterface
,
6581 IDirect3DDeviceImpl_7_AddRef
,
6582 IDirect3DDeviceImpl_7_Release
,
6583 /*** IDirect3DDevice7 ***/
6584 IDirect3DDeviceImpl_7_GetCaps_FPUPreserve
,
6585 IDirect3DDeviceImpl_7_EnumTextureFormats_FPUPreserve
,
6586 IDirect3DDeviceImpl_7_BeginScene_FPUPreserve
,
6587 IDirect3DDeviceImpl_7_EndScene_FPUPreserve
,
6588 IDirect3DDeviceImpl_7_GetDirect3D
,
6589 IDirect3DDeviceImpl_7_SetRenderTarget_FPUPreserve
,
6590 IDirect3DDeviceImpl_7_GetRenderTarget
,
6591 IDirect3DDeviceImpl_7_Clear_FPUPreserve
,
6592 IDirect3DDeviceImpl_7_SetTransform_FPUPreserve
,
6593 IDirect3DDeviceImpl_7_GetTransform_FPUPreserve
,
6594 IDirect3DDeviceImpl_7_SetViewport_FPUPreserve
,
6595 IDirect3DDeviceImpl_7_MultiplyTransform_FPUPreserve
,
6596 IDirect3DDeviceImpl_7_GetViewport_FPUPreserve
,
6597 IDirect3DDeviceImpl_7_SetMaterial_FPUPreserve
,
6598 IDirect3DDeviceImpl_7_GetMaterial_FPUPreserve
,
6599 IDirect3DDeviceImpl_7_SetLight_FPUPreserve
,
6600 IDirect3DDeviceImpl_7_GetLight_FPUPreserve
,
6601 IDirect3DDeviceImpl_7_SetRenderState_FPUPreserve
,
6602 IDirect3DDeviceImpl_7_GetRenderState_FPUPreserve
,
6603 IDirect3DDeviceImpl_7_BeginStateBlock_FPUPreserve
,
6604 IDirect3DDeviceImpl_7_EndStateBlock_FPUPreserve
,
6605 IDirect3DDeviceImpl_7_PreLoad_FPUPreserve
,
6606 IDirect3DDeviceImpl_7_DrawPrimitive_FPUPreserve
,
6607 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUPreserve
,
6608 IDirect3DDeviceImpl_7_SetClipStatus
,
6609 IDirect3DDeviceImpl_7_GetClipStatus
,
6610 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUPreserve
,
6611 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUPreserve
,
6612 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUPreserve
,
6613 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUPreserve
,
6614 IDirect3DDeviceImpl_7_ComputeSphereVisibility
,
6615 IDirect3DDeviceImpl_7_GetTexture_FPUPreserve
,
6616 IDirect3DDeviceImpl_7_SetTexture_FPUPreserve
,
6617 IDirect3DDeviceImpl_7_GetTextureStageState_FPUPreserve
,
6618 IDirect3DDeviceImpl_7_SetTextureStageState_FPUPreserve
,
6619 IDirect3DDeviceImpl_7_ValidateDevice_FPUPreserve
,
6620 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUPreserve
,
6621 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUPreserve
,
6622 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUPreserve
,
6623 IDirect3DDeviceImpl_7_CreateStateBlock_FPUPreserve
,
6624 IDirect3DDeviceImpl_7_Load_FPUPreserve
,
6625 IDirect3DDeviceImpl_7_LightEnable_FPUPreserve
,
6626 IDirect3DDeviceImpl_7_GetLightEnable_FPUPreserve
,
6627 IDirect3DDeviceImpl_7_SetClipPlane_FPUPreserve
,
6628 IDirect3DDeviceImpl_7_GetClipPlane_FPUPreserve
,
6629 IDirect3DDeviceImpl_7_GetInfo
6632 static const struct IDirect3DDevice3Vtbl d3d_device3_vtbl
=
6634 /*** IUnknown Methods ***/
6635 IDirect3DDeviceImpl_3_QueryInterface
,
6636 IDirect3DDeviceImpl_3_AddRef
,
6637 IDirect3DDeviceImpl_3_Release
,
6638 /*** IDirect3DDevice3 ***/
6639 IDirect3DDeviceImpl_3_GetCaps
,
6640 IDirect3DDeviceImpl_3_GetStats
,
6641 IDirect3DDeviceImpl_3_AddViewport
,
6642 IDirect3DDeviceImpl_3_DeleteViewport
,
6643 IDirect3DDeviceImpl_3_NextViewport
,
6644 IDirect3DDeviceImpl_3_EnumTextureFormats
,
6645 IDirect3DDeviceImpl_3_BeginScene
,
6646 IDirect3DDeviceImpl_3_EndScene
,
6647 IDirect3DDeviceImpl_3_GetDirect3D
,
6648 IDirect3DDeviceImpl_3_SetCurrentViewport
,
6649 IDirect3DDeviceImpl_3_GetCurrentViewport
,
6650 IDirect3DDeviceImpl_3_SetRenderTarget
,
6651 IDirect3DDeviceImpl_3_GetRenderTarget
,
6652 IDirect3DDeviceImpl_3_Begin
,
6653 IDirect3DDeviceImpl_3_BeginIndexed
,
6654 IDirect3DDeviceImpl_3_Vertex
,
6655 IDirect3DDeviceImpl_3_Index
,
6656 IDirect3DDeviceImpl_3_End
,
6657 IDirect3DDeviceImpl_3_GetRenderState
,
6658 IDirect3DDeviceImpl_3_SetRenderState
,
6659 IDirect3DDeviceImpl_3_GetLightState
,
6660 IDirect3DDeviceImpl_3_SetLightState
,
6661 IDirect3DDeviceImpl_3_SetTransform
,
6662 IDirect3DDeviceImpl_3_GetTransform
,
6663 IDirect3DDeviceImpl_3_MultiplyTransform
,
6664 IDirect3DDeviceImpl_3_DrawPrimitive
,
6665 IDirect3DDeviceImpl_3_DrawIndexedPrimitive
,
6666 IDirect3DDeviceImpl_3_SetClipStatus
,
6667 IDirect3DDeviceImpl_3_GetClipStatus
,
6668 IDirect3DDeviceImpl_3_DrawPrimitiveStrided
,
6669 IDirect3DDeviceImpl_3_DrawIndexedPrimitiveStrided
,
6670 IDirect3DDeviceImpl_3_DrawPrimitiveVB
,
6671 IDirect3DDeviceImpl_3_DrawIndexedPrimitiveVB
,
6672 IDirect3DDeviceImpl_3_ComputeSphereVisibility
,
6673 IDirect3DDeviceImpl_3_GetTexture
,
6674 IDirect3DDeviceImpl_3_SetTexture
,
6675 IDirect3DDeviceImpl_3_GetTextureStageState
,
6676 IDirect3DDeviceImpl_3_SetTextureStageState
,
6677 IDirect3DDeviceImpl_3_ValidateDevice
6680 static const struct IDirect3DDevice2Vtbl d3d_device2_vtbl
=
6682 /*** IUnknown Methods ***/
6683 IDirect3DDeviceImpl_2_QueryInterface
,
6684 IDirect3DDeviceImpl_2_AddRef
,
6685 IDirect3DDeviceImpl_2_Release
,
6686 /*** IDirect3DDevice2 ***/
6687 IDirect3DDeviceImpl_2_GetCaps
,
6688 IDirect3DDeviceImpl_2_SwapTextureHandles
,
6689 IDirect3DDeviceImpl_2_GetStats
,
6690 IDirect3DDeviceImpl_2_AddViewport
,
6691 IDirect3DDeviceImpl_2_DeleteViewport
,
6692 IDirect3DDeviceImpl_2_NextViewport
,
6693 IDirect3DDeviceImpl_2_EnumTextureFormats
,
6694 IDirect3DDeviceImpl_2_BeginScene
,
6695 IDirect3DDeviceImpl_2_EndScene
,
6696 IDirect3DDeviceImpl_2_GetDirect3D
,
6697 IDirect3DDeviceImpl_2_SetCurrentViewport
,
6698 IDirect3DDeviceImpl_2_GetCurrentViewport
,
6699 IDirect3DDeviceImpl_2_SetRenderTarget
,
6700 IDirect3DDeviceImpl_2_GetRenderTarget
,
6701 IDirect3DDeviceImpl_2_Begin
,
6702 IDirect3DDeviceImpl_2_BeginIndexed
,
6703 IDirect3DDeviceImpl_2_Vertex
,
6704 IDirect3DDeviceImpl_2_Index
,
6705 IDirect3DDeviceImpl_2_End
,
6706 IDirect3DDeviceImpl_2_GetRenderState
,
6707 IDirect3DDeviceImpl_2_SetRenderState
,
6708 IDirect3DDeviceImpl_2_GetLightState
,
6709 IDirect3DDeviceImpl_2_SetLightState
,
6710 IDirect3DDeviceImpl_2_SetTransform
,
6711 IDirect3DDeviceImpl_2_GetTransform
,
6712 IDirect3DDeviceImpl_2_MultiplyTransform
,
6713 IDirect3DDeviceImpl_2_DrawPrimitive
,
6714 IDirect3DDeviceImpl_2_DrawIndexedPrimitive
,
6715 IDirect3DDeviceImpl_2_SetClipStatus
,
6716 IDirect3DDeviceImpl_2_GetClipStatus
6719 static const struct IDirect3DDeviceVtbl d3d_device1_vtbl
=
6721 /*** IUnknown Methods ***/
6722 IDirect3DDeviceImpl_1_QueryInterface
,
6723 IDirect3DDeviceImpl_1_AddRef
,
6724 IDirect3DDeviceImpl_1_Release
,
6725 /*** IDirect3DDevice1 ***/
6726 IDirect3DDeviceImpl_1_Initialize
,
6727 IDirect3DDeviceImpl_1_GetCaps
,
6728 IDirect3DDeviceImpl_1_SwapTextureHandles
,
6729 IDirect3DDeviceImpl_1_CreateExecuteBuffer
,
6730 IDirect3DDeviceImpl_1_GetStats
,
6731 IDirect3DDeviceImpl_1_Execute
,
6732 IDirect3DDeviceImpl_1_AddViewport
,
6733 IDirect3DDeviceImpl_1_DeleteViewport
,
6734 IDirect3DDeviceImpl_1_NextViewport
,
6735 IDirect3DDeviceImpl_1_Pick
,
6736 IDirect3DDeviceImpl_1_GetPickRecords
,
6737 IDirect3DDeviceImpl_1_EnumTextureFormats
,
6738 IDirect3DDeviceImpl_1_CreateMatrix
,
6739 IDirect3DDeviceImpl_1_SetMatrix
,
6740 IDirect3DDeviceImpl_1_GetMatrix
,
6741 IDirect3DDeviceImpl_1_DeleteMatrix
,
6742 IDirect3DDeviceImpl_1_BeginScene
,
6743 IDirect3DDeviceImpl_1_EndScene
,
6744 IDirect3DDeviceImpl_1_GetDirect3D
6747 /*****************************************************************************
6748 * IDirect3DDeviceImpl_UpdateDepthStencil
6750 * Checks the current render target for attached depth stencils and sets the
6751 * WineD3D depth stencil accordingly.
6754 * The depth stencil state to set if creating the device
6756 *****************************************************************************/
6758 IDirect3DDeviceImpl_UpdateDepthStencil(IDirect3DDeviceImpl
*This
)
6760 IDirectDrawSurface7
*depthStencil
= NULL
;
6761 IDirectDrawSurfaceImpl
*dsi
;
6762 static DDSCAPS2 depthcaps
= { DDSCAPS_ZBUFFER
, 0, 0, 0 };
6764 IDirectDrawSurface7_GetAttachedSurface((IDirectDrawSurface7
*)This
->target
, &depthcaps
, &depthStencil
);
6767 TRACE("Setting wined3d depth stencil to NULL\n");
6768 IWineD3DDevice_SetDepthStencilSurface(This
->wineD3DDevice
,
6770 return WINED3DZB_FALSE
;
6773 dsi
= (IDirectDrawSurfaceImpl
*)depthStencil
;
6774 TRACE("Setting wined3d depth stencil to %p (wined3d %p)\n", dsi
, dsi
->WineD3DSurface
);
6775 IWineD3DDevice_SetDepthStencilSurface(This
->wineD3DDevice
,
6776 dsi
->WineD3DSurface
);
6778 IDirectDrawSurface7_Release(depthStencil
);
6779 return WINED3DZB_TRUE
;
6782 HRESULT
d3d_device_init(IDirect3DDeviceImpl
*device
, IDirectDrawImpl
*ddraw
, IDirectDrawSurfaceImpl
*target
)
6784 IParentImpl
*index_buffer_parent
;
6787 if (ddraw
->cooperative_level
& DDSCL_FPUPRESERVE
)
6788 device
->lpVtbl
= &d3d_device7_fpu_preserve_vtbl
;
6790 device
->lpVtbl
= &d3d_device7_fpu_setup_vtbl
;
6792 device
->IDirect3DDevice3_vtbl
= &d3d_device3_vtbl
;
6793 device
->IDirect3DDevice2_vtbl
= &d3d_device2_vtbl
;
6794 device
->IDirect3DDevice_vtbl
= &d3d_device1_vtbl
;
6796 device
->ddraw
= ddraw
;
6797 device
->target
= target
;
6799 if (!ddraw_handle_table_init(&device
->handle_table
, 64))
6801 ERR("Failed to initialize handle table.\n");
6802 return DDERR_OUTOFMEMORY
;
6805 device
->legacyTextureBlending
= FALSE
;
6807 /* Create an index buffer, it's needed for indexed drawing */
6808 index_buffer_parent
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*index_buffer_parent
));
6809 if (!index_buffer_parent
)
6811 ERR("Failed to allocate index buffer parent memory.\n");
6812 ddraw_handle_table_destroy(&device
->handle_table
);
6813 return DDERR_OUTOFMEMORY
;
6816 ddraw_parent_init(index_buffer_parent
);
6818 hr
= IWineD3DDevice_CreateIndexBuffer(ddraw
->wineD3DDevice
, 0x40000 /* Length. Don't know how long it should be */,
6819 WINED3DUSAGE_DYNAMIC
/* Usage */, WINED3DPOOL_DEFAULT
, index_buffer_parent
,
6820 &ddraw_null_wined3d_parent_ops
, &device
->indexbuffer
);
6823 ERR("Failed to create an index buffer, hr %#x.\n", hr
);
6824 HeapFree(GetProcessHeap(), 0, index_buffer_parent
);
6825 ddraw_handle_table_destroy(&device
->handle_table
);
6828 index_buffer_parent
->child
= (IUnknown
*)device
->indexbuffer
;
6830 /* This is for convenience. */
6831 device
->wineD3DDevice
= ddraw
->wineD3DDevice
;
6832 IWineD3DDevice_AddRef(ddraw
->wineD3DDevice
);
6834 /* Render to the back buffer */
6835 hr
= IWineD3DDevice_SetRenderTarget(ddraw
->wineD3DDevice
, 0, target
->WineD3DSurface
, TRUE
);
6838 ERR("Failed to set render target, hr %#x.\n", hr
);
6839 IParent_Release((IParent
*)index_buffer_parent
);
6840 ddraw_handle_table_destroy(&device
->handle_table
);
6844 /* FIXME: This is broken. The target AddRef() makes some sense, because
6845 * we store a pointer during initialization, but then that's also where
6846 * the AddRef() should be. We don't store ddraw->d3d_target anywhere. */
6847 /* AddRef the render target. Also AddRef the render target from ddraw,
6848 * because if it is released before the app releases the D3D device, the
6849 * D3D capabilities of wined3d will be uninitialized, which has bad effects.
6851 * In most cases, those surfaces are the same anyway, but this will simply
6852 * add another ref which is released when the device is destroyed. */
6853 IDirectDrawSurface7_AddRef((IDirectDrawSurface7
*)target
);
6854 IDirectDrawSurface7_AddRef((IDirectDrawSurface7
*)ddraw
->d3d_target
);
6856 ddraw
->d3ddevice
= device
;
6858 IWineD3DDevice_SetRenderState(ddraw
->wineD3DDevice
, WINED3DRS_ZENABLE
,
6859 IDirect3DDeviceImpl_UpdateDepthStencil(device
));