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
= impl_from_IDirect3DDevice7(iface
);
106 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(refiid
), obj
);
108 /* According to COM docs, if the QueryInterface fails, obj should be set to NULL */
112 return DDERR_INVALIDPARAMS
;
114 if ( IsEqualGUID( &IID_IUnknown
, refiid
) )
119 /* Check DirectDraw Interfaces. */
120 else if( IsEqualGUID( &IID_IDirectDraw7
, refiid
) )
122 *obj
= &This
->ddraw
->IDirectDraw7_iface
;
123 TRACE("(%p) Returning IDirectDraw7 interface at %p\n", This
, *obj
);
125 else if ( IsEqualGUID( &IID_IDirectDraw4
, refiid
) )
127 *obj
= &This
->ddraw
->IDirectDraw4_iface
;
128 TRACE("(%p) Returning IDirectDraw4 interface at %p\n", This
, *obj
);
130 else if ( IsEqualGUID( &IID_IDirectDraw2
, refiid
) )
132 *obj
= &This
->ddraw
->IDirectDraw2_iface
;
133 TRACE("(%p) Returning IDirectDraw2 interface at %p\n", This
, *obj
);
135 else if( IsEqualGUID( &IID_IDirectDraw
, refiid
) )
137 *obj
= &This
->ddraw
->IDirectDraw_iface
;
138 TRACE("(%p) Returning IDirectDraw interface at %p\n", This
, *obj
);
142 else if ( IsEqualGUID( &IID_IDirect3D
, refiid
) )
144 *obj
= &This
->ddraw
->IDirect3D_iface
;
145 TRACE("(%p) Returning IDirect3D interface at %p\n", This
, *obj
);
147 else if ( IsEqualGUID( &IID_IDirect3D2
, refiid
) )
149 *obj
= &This
->ddraw
->IDirect3D2_iface
;
150 TRACE("(%p) Returning IDirect3D2 interface at %p\n", This
, *obj
);
152 else if ( IsEqualGUID( &IID_IDirect3D3
, refiid
) )
154 *obj
= &This
->ddraw
->IDirect3D3_iface
;
155 TRACE("(%p) Returning IDirect3D3 interface at %p\n", This
, *obj
);
157 else if ( IsEqualGUID( &IID_IDirect3D7
, refiid
) )
159 *obj
= &This
->ddraw
->IDirect3D7_iface
;
160 TRACE("(%p) Returning IDirect3D7 interface at %p\n", This
, *obj
);
164 else if ( IsEqualGUID( &IID_IDirect3DDevice
, refiid
) )
166 *obj
= &This
->IDirect3DDevice_iface
;
167 TRACE("(%p) Returning IDirect3DDevice interface at %p\n", This
, *obj
);
169 else if ( IsEqualGUID( &IID_IDirect3DDevice2
, refiid
) ) {
170 *obj
= &This
->IDirect3DDevice2_iface
;
171 TRACE("(%p) Returning IDirect3DDevice2 interface at %p\n", This
, *obj
);
173 else if ( IsEqualGUID( &IID_IDirect3DDevice3
, refiid
) ) {
174 *obj
= &This
->IDirect3DDevice3_iface
;
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 /* DirectDrawSurface */
183 else if (IsEqualGUID(&IID_IDirectDrawSurface
, refiid
) && This
->from_surface
)
185 *obj
= &This
->target
->IDirectDrawSurface_iface
;
186 TRACE("Returning IDirectDrawSurface interface %p.\n", *obj
);
189 /* Unknown interface */
192 ERR("(%p)->(%s, %p): No interface found\n", This
, debugstr_guid(refiid
), obj
);
193 return E_NOINTERFACE
;
196 /* AddRef the returned interface */
197 IUnknown_AddRef( (IUnknown
*) *obj
);
201 static HRESULT WINAPI
IDirect3DDeviceImpl_3_QueryInterface(IDirect3DDevice3
*iface
, REFIID riid
,
204 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
205 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), obj
);
207 return IDirect3DDevice7_QueryInterface(&This
->IDirect3DDevice7_iface
, riid
, obj
);
210 static HRESULT WINAPI
IDirect3DDeviceImpl_2_QueryInterface(IDirect3DDevice2
*iface
, REFIID riid
,
213 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
214 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), obj
);
216 return IDirect3DDevice7_QueryInterface(&This
->IDirect3DDevice7_iface
, riid
, obj
);
219 static HRESULT WINAPI
IDirect3DDeviceImpl_1_QueryInterface(IDirect3DDevice
*iface
, REFIID riid
,
222 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
223 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), obp
);
225 return IDirect3DDevice7_QueryInterface(&This
->IDirect3DDevice7_iface
, riid
, obp
);
228 /*****************************************************************************
229 * IDirect3DDevice7::AddRef
231 * Increases the refcount....
232 * The most exciting Method, definitely
234 * Exists in Version 1, 2, 3 and 7
239 *****************************************************************************/
241 IDirect3DDeviceImpl_7_AddRef(IDirect3DDevice7
*iface
)
243 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
244 ULONG ref
= InterlockedIncrement(&This
->ref
);
246 TRACE("%p increasing refcount to %u.\n", This
, ref
);
251 static ULONG WINAPI
IDirect3DDeviceImpl_3_AddRef(IDirect3DDevice3
*iface
)
253 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
254 TRACE("iface %p.\n", iface
);
256 return IDirect3DDevice7_AddRef(&This
->IDirect3DDevice7_iface
);
259 static ULONG WINAPI
IDirect3DDeviceImpl_2_AddRef(IDirect3DDevice2
*iface
)
261 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
262 TRACE("iface %p.\n", iface
);
264 return IDirect3DDevice7_AddRef(&This
->IDirect3DDevice7_iface
);
267 static ULONG WINAPI
IDirect3DDeviceImpl_1_AddRef(IDirect3DDevice
*iface
)
269 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
270 TRACE("iface %p.\n", iface
);
272 return IDirect3DDevice7_AddRef(&This
->IDirect3DDevice7_iface
);
275 /*****************************************************************************
276 * IDirect3DDevice7::Release
278 * Decreases the refcount of the interface
279 * When the refcount is reduced to 0, the object is destroyed.
281 * Exists in Version 1, 2, 3 and 7
286 *****************************************************************************/
288 IDirect3DDeviceImpl_7_Release(IDirect3DDevice7
*iface
)
290 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
291 ULONG ref
= InterlockedDecrement(&This
->ref
);
293 TRACE("%p decreasing refcount to %u.\n", This
, ref
);
295 /* This method doesn't destroy the WineD3DDevice, because it's still in use for
296 * 2D rendering. IDirectDrawSurface7::Release will destroy the WineD3DDevice
297 * when the render target is released
303 wined3d_mutex_lock();
305 /* There is no need to unset any resources here, wined3d will take
306 * care of that on Uninit3D(). */
308 /* Free the index buffer. */
309 wined3d_buffer_decref(This
->indexbuffer
);
311 /* Set the device up to render to the front buffer since the back
312 * buffer will vanish soon. */
313 wined3d_device_set_render_target(This
->wined3d_device
, 0,
314 This
->ddraw
->wined3d_frontbuffer
, TRUE
);
316 /* Release the WineD3DDevice. This won't destroy it. */
317 if (!wined3d_device_decref(This
->wined3d_device
))
318 ERR("The wined3d device (%p) was destroyed unexpectedly.\n", This
->wined3d_device
);
320 /* The texture handles should be unset by now, but there might be some bits
321 * missing in our reference counting(needs test). Do a sanity check. */
322 for (i
= 0; i
< This
->handle_table
.entry_count
; ++i
)
324 struct ddraw_handle_entry
*entry
= &This
->handle_table
.entries
[i
];
328 case DDRAW_HANDLE_FREE
:
331 case DDRAW_HANDLE_MATERIAL
:
333 IDirect3DMaterialImpl
*m
= entry
->object
;
334 FIXME("Material handle %#x (%p) not unset properly.\n", i
+ 1, m
);
339 case DDRAW_HANDLE_MATRIX
:
341 /* No FIXME here because this might happen because of sloppy applications. */
342 WARN("Leftover matrix handle %#x (%p), deleting.\n", i
+ 1, entry
->object
);
343 IDirect3DDevice_DeleteMatrix(&This
->IDirect3DDevice_iface
, i
+ 1);
347 case DDRAW_HANDLE_STATEBLOCK
:
349 /* No FIXME here because this might happen because of sloppy applications. */
350 WARN("Leftover stateblock handle %#x (%p), deleting.\n", i
+ 1, entry
->object
);
351 IDirect3DDevice7_DeleteStateBlock(iface
, i
+ 1);
355 case DDRAW_HANDLE_SURFACE
:
357 IDirectDrawSurfaceImpl
*surf
= entry
->object
;
358 FIXME("Texture handle %#x (%p) not unset properly.\n", i
+ 1, surf
);
364 FIXME("Handle %#x (%p) has unknown type %#x.\n", i
+ 1, entry
->object
, entry
->type
);
369 ddraw_handle_table_destroy(&This
->handle_table
);
371 TRACE("Releasing target %p.\n", This
->target
);
372 /* Release the render target and the WineD3D render target
373 * (See IDirect3D7::CreateDevice for more comments on this)
375 IDirectDrawSurface7_Release(&This
->target
->IDirectDrawSurface7_iface
);
376 TRACE("Target release done\n");
378 This
->ddraw
->d3ddevice
= NULL
;
380 /* Now free the structure */
381 HeapFree(GetProcessHeap(), 0, This
);
382 wined3d_mutex_unlock();
389 static ULONG WINAPI
IDirect3DDeviceImpl_3_Release(IDirect3DDevice3
*iface
)
391 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
392 TRACE("iface %p.\n", iface
);
394 return IDirect3DDevice7_Release(&This
->IDirect3DDevice7_iface
);
397 static ULONG WINAPI
IDirect3DDeviceImpl_2_Release(IDirect3DDevice2
*iface
)
399 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
400 TRACE("iface %p.\n", iface
);
402 return IDirect3DDevice7_Release(&This
->IDirect3DDevice7_iface
);
405 static ULONG WINAPI
IDirect3DDeviceImpl_1_Release(IDirect3DDevice
*iface
)
407 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
408 TRACE("iface %p.\n", iface
);
410 return IDirect3DDevice7_Release(&This
->IDirect3DDevice7_iface
);
413 /*****************************************************************************
414 * IDirect3DDevice Methods
415 *****************************************************************************/
417 /*****************************************************************************
418 * IDirect3DDevice::Initialize
420 * Initializes a Direct3DDevice. This implementation is a no-op, as all
421 * initialization is done at create time.
423 * Exists in Version 1
426 * No idea what they mean, as the MSDN page is gone
430 *****************************************************************************/
431 static HRESULT WINAPI
432 IDirect3DDeviceImpl_1_Initialize(IDirect3DDevice
*iface
,
433 IDirect3D
*Direct3D
, GUID
*guid
,
436 /* It shouldn't be crucial, but print a FIXME, I'm interested if
437 * any game calls it and when. */
438 FIXME("iface %p, d3d %p, guid %s, device_desc %p nop!\n",
439 iface
, Direct3D
, debugstr_guid(guid
), Desc
);
444 /*****************************************************************************
445 * IDirect3DDevice7::GetCaps
447 * Retrieves the device's capabilities
449 * This implementation is used for Version 7 only, the older versions have
450 * their own implementation.
453 * Desc: Pointer to a D3DDEVICEDESC7 structure to fill
457 * D3DERR_* if a problem occurs. See WineD3D
459 *****************************************************************************/
461 IDirect3DDeviceImpl_7_GetCaps(IDirect3DDevice7
*iface
,
462 D3DDEVICEDESC7
*Desc
)
464 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
465 D3DDEVICEDESC OldDesc
;
467 TRACE("iface %p, device_desc %p.\n", iface
, Desc
);
471 WARN("Desc is NULL, returning DDERR_INVALIDPARAMS.\n");
472 return DDERR_INVALIDPARAMS
;
475 /* Call the same function used by IDirect3D, this saves code */
476 return IDirect3DImpl_GetCaps(This
->ddraw
->wined3d
, &OldDesc
, Desc
);
479 static HRESULT WINAPI
480 IDirect3DDeviceImpl_7_GetCaps_FPUSetup(IDirect3DDevice7
*iface
,
481 D3DDEVICEDESC7
*Desc
)
483 return IDirect3DDeviceImpl_7_GetCaps(iface
, Desc
);
486 static HRESULT WINAPI
487 IDirect3DDeviceImpl_7_GetCaps_FPUPreserve(IDirect3DDevice7
*iface
,
488 D3DDEVICEDESC7
*Desc
)
493 old_fpucw
= d3d_fpu_setup();
494 hr
= IDirect3DDeviceImpl_7_GetCaps(iface
, Desc
);
495 set_fpu_control_word(old_fpucw
);
499 /*****************************************************************************
500 * IDirect3DDevice3::GetCaps
502 * Retrieves the capabilities of the hardware device and the emulation
503 * device. For Wine, hardware and emulation are the same (it's all HW).
505 * This implementation is used for Version 1, 2, and 3. Version 7 has its own
508 * HWDesc: Structure to fill with the HW caps
509 * HelDesc: Structure to fill with the hardware emulation caps
513 * D3DERR_* if a problem occurs. See WineD3D
515 *****************************************************************************/
517 /* There are 3 versions of D3DDEVICEDESC. All 3 share the same name because
518 * Microsoft just expanded the existing structure without naming them
519 * D3DDEVICEDESC2 and D3DDEVICEDESC3. Which version is used have depends
520 * on the version of the DirectX SDK. DirectX 6+ and Wine use the latest
521 * one with 252 bytes.
523 * All 3 versions are allowed as parameters and only the specified amount of
526 * Note that Direct3D7 and earlier are not available in native Win64
527 * ddraw.dll builds, so possible size differences between 32 bit and
528 * 64 bit are a non-issue.
530 static inline BOOL
check_d3ddevicedesc_size(DWORD size
)
532 if (size
== FIELD_OFFSET(D3DDEVICEDESC
, dwMinTextureWidth
) /* 172 */
533 || size
== FIELD_OFFSET(D3DDEVICEDESC
, dwMaxTextureRepeat
) /* 204 */
534 || size
== sizeof(D3DDEVICEDESC
) /* 252 */) return TRUE
;
538 static HRESULT WINAPI
539 IDirect3DDeviceImpl_3_GetCaps(IDirect3DDevice3
*iface
,
540 D3DDEVICEDESC
*HWDesc
,
541 D3DDEVICEDESC
*HelDesc
)
543 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
544 D3DDEVICEDESC oldDesc
;
545 D3DDEVICEDESC7 newDesc
;
548 TRACE("iface %p, hw_desc %p, hel_desc %p.\n", iface
, HWDesc
, HelDesc
);
552 WARN("HWDesc is NULL, returning DDERR_INVALIDPARAMS.\n");
553 return DDERR_INVALIDPARAMS
;
555 if (!check_d3ddevicedesc_size(HWDesc
->dwSize
))
557 WARN("HWDesc->dwSize is %u, returning DDERR_INVALIDPARAMS.\n", HWDesc
->dwSize
);
558 return DDERR_INVALIDPARAMS
;
562 WARN("HelDesc is NULL, returning DDERR_INVALIDPARAMS.\n");
563 return DDERR_INVALIDPARAMS
;
565 if (!check_d3ddevicedesc_size(HelDesc
->dwSize
))
567 WARN("HelDesc->dwSize is %u, returning DDERR_INVALIDPARAMS.\n", HelDesc
->dwSize
);
568 return DDERR_INVALIDPARAMS
;
571 hr
= IDirect3DImpl_GetCaps(This
->ddraw
->wined3d
, &oldDesc
, &newDesc
);
572 if(hr
!= D3D_OK
) return hr
;
574 DD_STRUCT_COPY_BYSIZE(HWDesc
, &oldDesc
);
575 DD_STRUCT_COPY_BYSIZE(HelDesc
, &oldDesc
);
579 static HRESULT WINAPI
IDirect3DDeviceImpl_2_GetCaps(IDirect3DDevice2
*iface
,
580 D3DDEVICEDESC
*D3DHWDevDesc
, D3DDEVICEDESC
*D3DHELDevDesc
)
582 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
583 TRACE("iface %p, hw_desc %p, hel_desc %p.\n", iface
, D3DHWDevDesc
, D3DHELDevDesc
);
584 return IDirect3DDevice3_GetCaps(&This
->IDirect3DDevice3_iface
, D3DHWDevDesc
, D3DHELDevDesc
);
587 static HRESULT WINAPI
IDirect3DDeviceImpl_1_GetCaps(IDirect3DDevice
*iface
,
588 D3DDEVICEDESC
*D3DHWDevDesc
, D3DDEVICEDESC
*D3DHELDevDesc
)
590 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
591 TRACE("iface %p, hw_desc %p, hel_desc %p.\n", iface
, D3DHWDevDesc
, D3DHELDevDesc
);
592 return IDirect3DDevice3_GetCaps(&This
->IDirect3DDevice3_iface
, D3DHWDevDesc
, D3DHELDevDesc
);
595 /*****************************************************************************
596 * IDirect3DDevice2::SwapTextureHandles
598 * Swaps the texture handles of 2 Texture interfaces. Version 1 and 2
601 * Tex1, Tex2: The 2 Textures to swap
606 *****************************************************************************/
607 static HRESULT WINAPI
608 IDirect3DDeviceImpl_2_SwapTextureHandles(IDirect3DDevice2
*iface
,
609 IDirect3DTexture2
*Tex1
,
610 IDirect3DTexture2
*Tex2
)
612 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
613 IDirectDrawSurfaceImpl
*surf1
= unsafe_impl_from_IDirect3DTexture2(Tex1
);
614 IDirectDrawSurfaceImpl
*surf2
= unsafe_impl_from_IDirect3DTexture2(Tex2
);
617 TRACE("iface %p, tex1 %p, tex2 %p.\n", iface
, Tex1
, Tex2
);
619 wined3d_mutex_lock();
621 h1
= surf1
->Handle
- 1;
622 h2
= surf2
->Handle
- 1;
623 This
->handle_table
.entries
[h1
].object
= surf2
;
624 This
->handle_table
.entries
[h2
].object
= surf1
;
625 surf2
->Handle
= h1
+ 1;
626 surf1
->Handle
= h2
+ 1;
628 wined3d_mutex_unlock();
633 static HRESULT WINAPI
IDirect3DDeviceImpl_1_SwapTextureHandles(IDirect3DDevice
*iface
,
634 IDirect3DTexture
*D3DTex1
, IDirect3DTexture
*D3DTex2
)
636 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
637 IDirectDrawSurfaceImpl
*surf1
= unsafe_impl_from_IDirect3DTexture(D3DTex1
);
638 IDirectDrawSurfaceImpl
*surf2
= unsafe_impl_from_IDirect3DTexture(D3DTex2
);
639 IDirect3DTexture2
*t1
= surf1
? &surf1
->IDirect3DTexture2_iface
: NULL
;
640 IDirect3DTexture2
*t2
= surf2
? &surf2
->IDirect3DTexture2_iface
: NULL
;
642 TRACE("iface %p, tex1 %p, tex2 %p.\n", iface
, D3DTex1
, D3DTex2
);
644 return IDirect3DDevice2_SwapTextureHandles(&This
->IDirect3DDevice2_iface
, t1
, t2
);
647 /*****************************************************************************
648 * IDirect3DDevice3::GetStats
650 * This method seems to retrieve some stats from the device.
651 * The MSDN documentation doesn't exist any more, but the D3DSTATS
652 * structure suggests that the amount of drawn primitives and processed
653 * vertices is returned.
655 * Exists in Version 1, 2 and 3
658 * Stats: Pointer to a D3DSTATS structure to be filled
662 * DDERR_INVALIDPARAMS if Stats == NULL
664 *****************************************************************************/
665 static HRESULT WINAPI
666 IDirect3DDeviceImpl_3_GetStats(IDirect3DDevice3
*iface
,
669 FIXME("iface %p, stats %p stub!\n", iface
, Stats
);
672 return DDERR_INVALIDPARAMS
;
674 /* Fill the Stats with 0 */
675 Stats
->dwTrianglesDrawn
= 0;
676 Stats
->dwLinesDrawn
= 0;
677 Stats
->dwPointsDrawn
= 0;
678 Stats
->dwSpansDrawn
= 0;
679 Stats
->dwVerticesProcessed
= 0;
684 static HRESULT WINAPI
IDirect3DDeviceImpl_2_GetStats(IDirect3DDevice2
*iface
, D3DSTATS
*Stats
)
686 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
688 TRACE("iface %p, stats %p.\n", iface
, Stats
);
690 return IDirect3DDevice3_GetStats(&This
->IDirect3DDevice3_iface
, Stats
);
693 static HRESULT WINAPI
IDirect3DDeviceImpl_1_GetStats(IDirect3DDevice
*iface
, D3DSTATS
*Stats
)
695 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
697 TRACE("iface %p, stats %p.\n", iface
, Stats
);
699 return IDirect3DDevice3_GetStats(&This
->IDirect3DDevice3_iface
, Stats
);
702 /*****************************************************************************
703 * IDirect3DDevice::CreateExecuteBuffer
705 * Creates an IDirect3DExecuteBuffer, used for rendering with a
711 * Desc: Buffer description
712 * ExecuteBuffer: Address to return the Interface pointer at
713 * UnkOuter: Must be NULL. Basically for aggregation, which ddraw doesn't
717 * CLASS_E_NOAGGREGATION if UnkOuter != NULL
718 * DDERR_OUTOFMEMORY if we ran out of memory
721 *****************************************************************************/
722 static HRESULT WINAPI
723 IDirect3DDeviceImpl_1_CreateExecuteBuffer(IDirect3DDevice
*iface
,
724 D3DEXECUTEBUFFERDESC
*Desc
,
725 IDirect3DExecuteBuffer
**ExecuteBuffer
,
728 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
729 IDirect3DExecuteBufferImpl
* object
;
732 TRACE("iface %p, buffer_desc %p, buffer %p, outer_unknown %p.\n",
733 iface
, Desc
, ExecuteBuffer
, UnkOuter
);
736 return CLASS_E_NOAGGREGATION
;
738 /* Allocate the new Execute Buffer */
739 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirect3DExecuteBufferImpl
));
742 ERR("Out of memory when allocating a IDirect3DExecuteBufferImpl structure\n");
743 return DDERR_OUTOFMEMORY
;
746 hr
= d3d_execute_buffer_init(object
, This
, Desc
);
749 WARN("Failed to initialize execute buffer, hr %#x.\n", hr
);
750 HeapFree(GetProcessHeap(), 0, object
);
754 *ExecuteBuffer
= &object
->IDirect3DExecuteBuffer_iface
;
756 TRACE(" Returning IDirect3DExecuteBuffer at %p, implementation is at %p\n", *ExecuteBuffer
, object
);
761 /*****************************************************************************
762 * IDirect3DDevice::Execute
764 * Executes all the stuff in an execute buffer.
767 * ExecuteBuffer: The buffer to execute
768 * Viewport: The viewport used for rendering
772 * DDERR_INVALIDPARAMS if ExecuteBuffer == NULL
775 *****************************************************************************/
776 static HRESULT WINAPI
IDirect3DDeviceImpl_1_Execute(IDirect3DDevice
*iface
,
777 IDirect3DExecuteBuffer
*ExecuteBuffer
, IDirect3DViewport
*Viewport
, DWORD Flags
)
779 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
780 IDirect3DExecuteBufferImpl
*buffer
= unsafe_impl_from_IDirect3DExecuteBuffer(ExecuteBuffer
);
781 IDirect3DViewportImpl
*Direct3DViewportImpl
= unsafe_impl_from_IDirect3DViewport(Viewport
);
784 TRACE("iface %p, buffer %p, viewport %p, flags %#x.\n", iface
, ExecuteBuffer
, Viewport
, Flags
);
787 return DDERR_INVALIDPARAMS
;
790 wined3d_mutex_lock();
791 hr
= d3d_execute_buffer_execute(buffer
, This
, Direct3DViewportImpl
);
792 wined3d_mutex_unlock();
797 /*****************************************************************************
798 * IDirect3DDevice3::AddViewport
800 * Add a Direct3DViewport to the device's viewport list. These viewports
801 * are wrapped to IDirect3DDevice7 viewports in viewport.c
803 * Exists in Version 1, 2 and 3. Note that IDirect3DViewport 1, 2 and 3
804 * are the same interfaces.
807 * Viewport: The viewport to add
810 * DDERR_INVALIDPARAMS if Viewport == NULL
813 *****************************************************************************/
814 static HRESULT WINAPI
815 IDirect3DDeviceImpl_3_AddViewport(IDirect3DDevice3
*iface
,
816 IDirect3DViewport3
*Viewport
)
818 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
819 IDirect3DViewportImpl
*vp
= unsafe_impl_from_IDirect3DViewport3(Viewport
);
821 TRACE("iface %p, viewport %p.\n", iface
, Viewport
);
825 return DDERR_INVALIDPARAMS
;
827 wined3d_mutex_lock();
828 list_add_head(&This
->viewport_list
, &vp
->entry
);
829 vp
->active_device
= This
; /* Viewport must be usable for Clear() after AddViewport,
830 so set active_device here. */
831 wined3d_mutex_unlock();
836 static HRESULT WINAPI
IDirect3DDeviceImpl_2_AddViewport(IDirect3DDevice2
*iface
,
837 IDirect3DViewport2
*Direct3DViewport2
)
839 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
840 IDirect3DViewportImpl
*vp
= unsafe_impl_from_IDirect3DViewport2(Direct3DViewport2
);
842 TRACE("iface %p, viewport %p.\n", iface
, Direct3DViewport2
);
844 return IDirect3DDevice3_AddViewport(&This
->IDirect3DDevice3_iface
, &vp
->IDirect3DViewport3_iface
);
847 static HRESULT WINAPI
IDirect3DDeviceImpl_1_AddViewport(IDirect3DDevice
*iface
,
848 IDirect3DViewport
*Direct3DViewport
)
850 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
851 IDirect3DViewportImpl
*vp
= unsafe_impl_from_IDirect3DViewport(Direct3DViewport
);
853 TRACE("iface %p, viewport %p.\n", iface
, Direct3DViewport
);
855 return IDirect3DDevice3_AddViewport(&This
->IDirect3DDevice3_iface
, &vp
->IDirect3DViewport3_iface
);
858 /*****************************************************************************
859 * IDirect3DDevice3::DeleteViewport
861 * Deletes a Direct3DViewport from the device's viewport list.
863 * Exists in Version 1, 2 and 3. Note that all Viewport interface versions
867 * Viewport: The viewport to delete
871 * DDERR_INVALIDPARAMS if the viewport wasn't found in the list
873 *****************************************************************************/
874 static HRESULT WINAPI
IDirect3DDeviceImpl_3_DeleteViewport(IDirect3DDevice3
*iface
, IDirect3DViewport3
*viewport
)
876 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
877 IDirect3DViewportImpl
*vp
= unsafe_impl_from_IDirect3DViewport3(viewport
);
879 TRACE("iface %p, viewport %p.\n", iface
, viewport
);
881 wined3d_mutex_lock();
883 if (vp
->active_device
!= This
)
885 WARN("Viewport %p active device is %p.\n", vp
, vp
->active_device
);
886 wined3d_mutex_unlock();
887 return DDERR_INVALIDPARAMS
;
890 vp
->active_device
= NULL
;
891 list_remove(&vp
->entry
);
893 wined3d_mutex_unlock();
898 static HRESULT WINAPI
IDirect3DDeviceImpl_2_DeleteViewport(IDirect3DDevice2
*iface
,
899 IDirect3DViewport2
*Direct3DViewport2
)
901 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
902 IDirect3DViewportImpl
*vp
= unsafe_impl_from_IDirect3DViewport2(Direct3DViewport2
);
904 TRACE("iface %p, viewport %p.\n", iface
, Direct3DViewport2
);
906 return IDirect3DDevice3_DeleteViewport(&This
->IDirect3DDevice3_iface
, &vp
->IDirect3DViewport3_iface
);
909 static HRESULT WINAPI
IDirect3DDeviceImpl_1_DeleteViewport(IDirect3DDevice
*iface
,
910 IDirect3DViewport
*Direct3DViewport
)
912 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
913 IDirect3DViewportImpl
*vp
= unsafe_impl_from_IDirect3DViewport(Direct3DViewport
);
915 TRACE("iface %p, viewport %p.\n", iface
, Direct3DViewport
);
917 return IDirect3DDevice3_DeleteViewport(&This
->IDirect3DDevice3_iface
, &vp
->IDirect3DViewport3_iface
);
920 /*****************************************************************************
921 * IDirect3DDevice3::NextViewport
923 * Returns a viewport from the viewport list, depending on the
924 * passed viewport and the flags.
926 * Exists in Version 1, 2 and 3. Note that all Viewport interface versions
930 * Viewport: Viewport to use for beginning the search
931 * Flags: D3DNEXT_NEXT, D3DNEXT_HEAD or D3DNEXT_TAIL
935 * DDERR_INVALIDPARAMS if the flags were wrong, or Viewport was NULL
937 *****************************************************************************/
938 static HRESULT WINAPI
939 IDirect3DDeviceImpl_3_NextViewport(IDirect3DDevice3
*iface
,
940 IDirect3DViewport3
*Viewport3
,
941 IDirect3DViewport3
**lplpDirect3DViewport3
,
944 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
945 IDirect3DViewportImpl
*vp
= unsafe_impl_from_IDirect3DViewport3(Viewport3
);
946 IDirect3DViewportImpl
*next
;
949 TRACE("iface %p, viewport %p, next %p, flags %#x.\n",
950 iface
, Viewport3
, lplpDirect3DViewport3
, Flags
);
954 *lplpDirect3DViewport3
= NULL
;
955 return DDERR_INVALIDPARAMS
;
959 wined3d_mutex_lock();
963 entry
= list_next(&This
->viewport_list
, &vp
->entry
);
967 entry
= list_head(&This
->viewport_list
);
971 entry
= list_tail(&This
->viewport_list
);
975 WARN("Invalid flags %#x.\n", Flags
);
976 *lplpDirect3DViewport3
= NULL
;
977 wined3d_mutex_unlock();
978 return DDERR_INVALIDPARAMS
;
983 next
= LIST_ENTRY(entry
, IDirect3DViewportImpl
, entry
);
984 *lplpDirect3DViewport3
= &next
->IDirect3DViewport3_iface
;
987 *lplpDirect3DViewport3
= NULL
;
989 wined3d_mutex_unlock();
994 static HRESULT WINAPI
IDirect3DDeviceImpl_2_NextViewport(IDirect3DDevice2
*iface
,
995 IDirect3DViewport2
*Viewport2
, IDirect3DViewport2
**lplpDirect3DViewport2
, DWORD Flags
)
997 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
998 IDirect3DViewportImpl
*vp
= unsafe_impl_from_IDirect3DViewport2(Viewport2
);
999 IDirect3DViewport3
*res
;
1002 TRACE("iface %p, viewport %p, next %p, flags %#x.\n",
1003 iface
, Viewport2
, lplpDirect3DViewport2
, Flags
);
1005 hr
= IDirect3DDevice3_NextViewport(&This
->IDirect3DDevice3_iface
,
1006 &vp
->IDirect3DViewport3_iface
, &res
, Flags
);
1007 *lplpDirect3DViewport2
= (IDirect3DViewport2
*)res
;
1011 static HRESULT WINAPI
IDirect3DDeviceImpl_1_NextViewport(IDirect3DDevice
*iface
,
1012 IDirect3DViewport
*Viewport
, IDirect3DViewport
**lplpDirect3DViewport
, DWORD Flags
)
1014 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
1015 IDirect3DViewportImpl
*vp
= unsafe_impl_from_IDirect3DViewport(Viewport
);
1016 IDirect3DViewport3
*res
;
1019 TRACE("iface %p, viewport %p, next %p, flags %#x.\n",
1020 iface
, Viewport
, lplpDirect3DViewport
, Flags
);
1022 hr
= IDirect3DDevice3_NextViewport(&This
->IDirect3DDevice3_iface
,
1023 &vp
->IDirect3DViewport3_iface
, &res
, Flags
);
1024 *lplpDirect3DViewport
= (IDirect3DViewport
*)res
;
1028 /*****************************************************************************
1029 * IDirect3DDevice::Pick
1031 * Executes an execute buffer without performing rendering. Instead, a
1032 * list of primitives that intersect with (x1,y1) of the passed rectangle
1033 * is created. IDirect3DDevice::GetPickRecords can be used to retrieve
1039 * ExecuteBuffer: Buffer to execute
1040 * Viewport: Viewport to use for execution
1041 * Flags: None are defined, according to the SDK
1042 * Rect: Specifies the coordinates to be picked. Only x1 and y2 are used,
1043 * x2 and y2 are ignored.
1046 * D3D_OK because it's a stub
1048 *****************************************************************************/
1049 static HRESULT WINAPI
1050 IDirect3DDeviceImpl_1_Pick(IDirect3DDevice
*iface
,
1051 IDirect3DExecuteBuffer
*ExecuteBuffer
,
1052 IDirect3DViewport
*Viewport
,
1056 FIXME("iface %p, buffer %p, viewport %p, flags %#x, rect %s stub!\n",
1057 iface
, ExecuteBuffer
, Viewport
, Flags
, wine_dbgstr_rect((RECT
*)Rect
));
1062 /*****************************************************************************
1063 * IDirect3DDevice::GetPickRecords
1065 * Retrieves the pick records generated by IDirect3DDevice::GetPickRecords
1070 * Count: Pointer to a DWORD containing the numbers of pick records to
1072 * D3DPickRec: Address to store the resulting D3DPICKRECORD array.
1075 * D3D_OK, because it's a stub
1077 *****************************************************************************/
1078 static HRESULT WINAPI
1079 IDirect3DDeviceImpl_1_GetPickRecords(IDirect3DDevice
*iface
,
1081 D3DPICKRECORD
*D3DPickRec
)
1083 FIXME("iface %p, count %p, records %p stub!\n", iface
, Count
, D3DPickRec
);
1088 /*****************************************************************************
1089 * IDirect3DDevice7::EnumTextureformats
1091 * Enumerates the supported texture formats. It has a list of all possible
1092 * formats and calls IWineD3D::CheckDeviceFormat for each format to see if
1093 * WineD3D supports it. If so, then it is passed to the app.
1095 * This is for Version 7 and 3, older versions have a different
1096 * callback function and their own implementation
1099 * Callback: Callback to call for each enumerated format
1100 * Arg: Argument to pass to the callback
1104 * DDERR_INVALIDPARAMS if Callback == NULL
1106 *****************************************************************************/
1108 IDirect3DDeviceImpl_7_EnumTextureFormats(IDirect3DDevice7
*iface
,
1109 LPD3DENUMPIXELFORMATSCALLBACK Callback
,
1112 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
1113 struct wined3d_display_mode mode
;
1117 static const enum wined3d_format_id FormatList
[] =
1120 WINED3DFMT_B5G5R5X1_UNORM
,
1121 WINED3DFMT_B5G5R5A1_UNORM
,
1122 WINED3DFMT_B4G4R4A4_UNORM
,
1123 WINED3DFMT_B5G6R5_UNORM
,
1125 WINED3DFMT_B8G8R8X8_UNORM
,
1126 WINED3DFMT_B8G8R8A8_UNORM
,
1128 WINED3DFMT_B2G3R3_UNORM
,
1136 static const enum wined3d_format_id BumpFormatList
[] =
1138 WINED3DFMT_R8G8_SNORM
,
1139 WINED3DFMT_R5G5_SNORM_L6_UNORM
,
1140 WINED3DFMT_R8G8_SNORM_L8X8_UNORM
,
1141 WINED3DFMT_R16G16_SNORM
,
1142 WINED3DFMT_R10G11B11_SNORM
,
1143 WINED3DFMT_R10G10B10_SNORM_A2_UNORM
1146 TRACE("iface %p, callback %p, context %p.\n", iface
, Callback
, Arg
);
1149 return DDERR_INVALIDPARAMS
;
1151 wined3d_mutex_lock();
1153 memset(&mode
, 0, sizeof(mode
));
1154 hr
= wined3d_device_get_display_mode(This
->ddraw
->wined3d_device
, 0, &mode
);
1157 wined3d_mutex_unlock();
1158 WARN("Cannot get the current adapter format\n");
1162 for (i
= 0; i
< sizeof(FormatList
) / sizeof(*FormatList
); ++i
)
1164 hr
= wined3d_check_device_format(This
->ddraw
->wined3d
, WINED3DADAPTER_DEFAULT
, WINED3D_DEVICE_TYPE_HAL
,
1165 mode
.format_id
, 0, WINED3D_RTYPE_TEXTURE
, FormatList
[i
], WINED3D_SURFACE_TYPE_OPENGL
);
1168 DDPIXELFORMAT pformat
;
1170 memset(&pformat
, 0, sizeof(pformat
));
1171 pformat
.dwSize
= sizeof(pformat
);
1172 PixelFormat_WineD3DtoDD(&pformat
, FormatList
[i
]);
1174 TRACE("Enumerating WineD3DFormat %d\n", FormatList
[i
]);
1175 hr
= Callback(&pformat
, Arg
);
1176 if(hr
!= DDENUMRET_OK
)
1178 TRACE("Format enumeration cancelled by application\n");
1179 wined3d_mutex_unlock();
1185 for (i
= 0; i
< sizeof(BumpFormatList
) / sizeof(*BumpFormatList
); ++i
)
1187 hr
= wined3d_check_device_format(This
->ddraw
->wined3d
, WINED3DADAPTER_DEFAULT
,
1188 WINED3D_DEVICE_TYPE_HAL
, mode
.format_id
, WINED3DUSAGE_QUERY_LEGACYBUMPMAP
,
1189 WINED3D_RTYPE_TEXTURE
, BumpFormatList
[i
], WINED3D_SURFACE_TYPE_OPENGL
);
1192 DDPIXELFORMAT pformat
;
1194 memset(&pformat
, 0, sizeof(pformat
));
1195 pformat
.dwSize
= sizeof(pformat
);
1196 PixelFormat_WineD3DtoDD(&pformat
, BumpFormatList
[i
]);
1198 TRACE("Enumerating WineD3DFormat %d\n", BumpFormatList
[i
]);
1199 hr
= Callback(&pformat
, Arg
);
1200 if(hr
!= DDENUMRET_OK
)
1202 TRACE("Format enumeration cancelled by application\n");
1203 wined3d_mutex_unlock();
1208 TRACE("End of enumeration\n");
1209 wined3d_mutex_unlock();
1214 static HRESULT WINAPI
1215 IDirect3DDeviceImpl_7_EnumTextureFormats_FPUSetup(IDirect3DDevice7
*iface
,
1216 LPD3DENUMPIXELFORMATSCALLBACK Callback
,
1219 return IDirect3DDeviceImpl_7_EnumTextureFormats(iface
, Callback
, Arg
);
1222 static HRESULT WINAPI
1223 IDirect3DDeviceImpl_7_EnumTextureFormats_FPUPreserve(IDirect3DDevice7
*iface
,
1224 LPD3DENUMPIXELFORMATSCALLBACK Callback
,
1230 old_fpucw
= d3d_fpu_setup();
1231 hr
= IDirect3DDeviceImpl_7_EnumTextureFormats(iface
, Callback
, Arg
);
1232 set_fpu_control_word(old_fpucw
);
1237 static HRESULT WINAPI
IDirect3DDeviceImpl_3_EnumTextureFormats(IDirect3DDevice3
*iface
,
1238 LPD3DENUMPIXELFORMATSCALLBACK Callback
, void *Arg
)
1240 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
1242 TRACE("iface %p, callback %p, context %p.\n", iface
, Callback
, Arg
);
1244 return IDirect3DDevice7_EnumTextureFormats(&This
->IDirect3DDevice7_iface
, Callback
, Arg
);
1247 /*****************************************************************************
1248 * IDirect3DDevice2::EnumTextureformats
1250 * EnumTextureFormats for Version 1 and 2, see
1251 * IDirect3DDevice7::EnumTexureFormats for a more detailed description.
1253 * This version has a different callback and does not enumerate FourCC
1256 *****************************************************************************/
1257 static HRESULT WINAPI
1258 IDirect3DDeviceImpl_2_EnumTextureFormats(IDirect3DDevice2
*iface
,
1259 LPD3DENUMTEXTUREFORMATSCALLBACK Callback
,
1262 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
1263 struct wined3d_display_mode mode
;
1267 static const enum wined3d_format_id FormatList
[] =
1270 WINED3DFMT_B5G5R5X1_UNORM
,
1271 WINED3DFMT_B5G5R5A1_UNORM
,
1272 WINED3DFMT_B4G4R4A4_UNORM
,
1273 WINED3DFMT_B5G6R5_UNORM
,
1275 WINED3DFMT_B8G8R8X8_UNORM
,
1276 WINED3DFMT_B8G8R8A8_UNORM
,
1278 WINED3DFMT_B2G3R3_UNORM
,
1280 /* FOURCC codes - Not in this version*/
1283 TRACE("iface %p, callback %p, context %p.\n", iface
, Callback
, Arg
);
1286 return DDERR_INVALIDPARAMS
;
1288 wined3d_mutex_lock();
1290 memset(&mode
, 0, sizeof(mode
));
1291 hr
= wined3d_device_get_display_mode(This
->ddraw
->wined3d_device
, 0, &mode
);
1294 wined3d_mutex_unlock();
1295 WARN("Cannot get the current adapter format\n");
1299 for (i
= 0; i
< sizeof(FormatList
) / sizeof(*FormatList
); ++i
)
1301 hr
= wined3d_check_device_format(This
->ddraw
->wined3d
, 0, WINED3D_DEVICE_TYPE_HAL
,
1302 mode
.format_id
, 0, WINED3D_RTYPE_TEXTURE
, FormatList
[i
], WINED3D_SURFACE_TYPE_OPENGL
);
1305 DDSURFACEDESC sdesc
;
1307 memset(&sdesc
, 0, sizeof(sdesc
));
1308 sdesc
.dwSize
= sizeof(sdesc
);
1309 sdesc
.dwFlags
= DDSD_PIXELFORMAT
| DDSD_CAPS
;
1310 sdesc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
1311 sdesc
.ddpfPixelFormat
.dwSize
= sizeof(sdesc
.ddpfPixelFormat
);
1312 PixelFormat_WineD3DtoDD(&sdesc
.ddpfPixelFormat
, FormatList
[i
]);
1314 TRACE("Enumerating WineD3DFormat %d\n", FormatList
[i
]);
1315 hr
= Callback(&sdesc
, Arg
);
1316 if(hr
!= DDENUMRET_OK
)
1318 TRACE("Format enumeration cancelled by application\n");
1319 wined3d_mutex_unlock();
1324 TRACE("End of enumeration\n");
1325 wined3d_mutex_unlock();
1330 static HRESULT WINAPI
IDirect3DDeviceImpl_1_EnumTextureFormats(IDirect3DDevice
*iface
,
1331 LPD3DENUMTEXTUREFORMATSCALLBACK Callback
, void *Arg
)
1333 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
1335 TRACE("iface %p, callback %p, context %p.\n", iface
, Callback
, Arg
);
1337 return IDirect3DDevice2_EnumTextureFormats(&This
->IDirect3DDevice2_iface
, Callback
, Arg
);
1340 /*****************************************************************************
1341 * IDirect3DDevice::CreateMatrix
1343 * Creates a matrix handle. A handle is created and memory for a D3DMATRIX is
1344 * allocated for the handle.
1349 * D3DMatHandle: Address to return the handle at
1353 * DDERR_INVALIDPARAMS if D3DMatHandle = NULL
1355 *****************************************************************************/
1356 static HRESULT WINAPI
1357 IDirect3DDeviceImpl_1_CreateMatrix(IDirect3DDevice
*iface
, D3DMATRIXHANDLE
*D3DMatHandle
)
1359 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
1363 TRACE("iface %p, matrix_handle %p.\n", iface
, D3DMatHandle
);
1366 return DDERR_INVALIDPARAMS
;
1368 Matrix
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(D3DMATRIX
));
1371 ERR("Out of memory when allocating a D3DMATRIX\n");
1372 return DDERR_OUTOFMEMORY
;
1375 wined3d_mutex_lock();
1377 h
= ddraw_allocate_handle(&This
->handle_table
, Matrix
, DDRAW_HANDLE_MATRIX
);
1378 if (h
== DDRAW_INVALID_HANDLE
)
1380 ERR("Failed to allocate a matrix handle.\n");
1381 HeapFree(GetProcessHeap(), 0, Matrix
);
1382 wined3d_mutex_unlock();
1383 return DDERR_OUTOFMEMORY
;
1386 *D3DMatHandle
= h
+ 1;
1388 TRACE(" returning matrix handle %d\n", *D3DMatHandle
);
1390 wined3d_mutex_unlock();
1395 /*****************************************************************************
1396 * IDirect3DDevice::SetMatrix
1398 * Sets a matrix for a matrix handle. The matrix is copied into the memory
1399 * allocated for the handle
1404 * D3DMatHandle: Handle to set the matrix to
1405 * D3DMatrix: Matrix to set
1409 * DDERR_INVALIDPARAMS if the handle of the matrix is invalid or the matrix
1412 *****************************************************************************/
1413 static HRESULT WINAPI
1414 IDirect3DDeviceImpl_1_SetMatrix(IDirect3DDevice
*iface
,
1415 D3DMATRIXHANDLE D3DMatHandle
,
1416 D3DMATRIX
*D3DMatrix
)
1418 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
1421 TRACE("iface %p, matrix_handle %#x, matrix %p.\n", iface
, D3DMatHandle
, D3DMatrix
);
1423 if (!D3DMatrix
) return DDERR_INVALIDPARAMS
;
1425 wined3d_mutex_lock();
1427 m
= ddraw_get_object(&This
->handle_table
, D3DMatHandle
- 1, DDRAW_HANDLE_MATRIX
);
1430 WARN("Invalid matrix handle.\n");
1431 wined3d_mutex_unlock();
1432 return DDERR_INVALIDPARAMS
;
1435 if (TRACE_ON(ddraw
))
1436 dump_D3DMATRIX(D3DMatrix
);
1440 if (D3DMatHandle
== This
->world
)
1441 wined3d_device_set_transform(This
->wined3d_device
,
1442 WINED3D_TS_WORLD_MATRIX(0), (struct wined3d_matrix
*)D3DMatrix
);
1444 if (D3DMatHandle
== This
->view
)
1445 wined3d_device_set_transform(This
->wined3d_device
,
1446 WINED3D_TS_VIEW
, (struct wined3d_matrix
*)D3DMatrix
);
1448 if (D3DMatHandle
== This
->proj
)
1449 wined3d_device_set_transform(This
->wined3d_device
,
1450 WINED3D_TS_PROJECTION
, (struct wined3d_matrix
*)D3DMatrix
);
1452 wined3d_mutex_unlock();
1457 /*****************************************************************************
1458 * IDirect3DDevice::GetMatrix
1460 * Returns the content of a D3DMATRIX handle
1465 * D3DMatHandle: Matrix handle to read the content from
1466 * D3DMatrix: Address to store the content at
1470 * DDERR_INVALIDPARAMS if D3DMatHandle is invalid or D3DMatrix is NULL
1472 *****************************************************************************/
1473 static HRESULT WINAPI
1474 IDirect3DDeviceImpl_1_GetMatrix(IDirect3DDevice
*iface
,
1475 D3DMATRIXHANDLE D3DMatHandle
,
1476 D3DMATRIX
*D3DMatrix
)
1478 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
1481 TRACE("iface %p, matrix_handle %#x, matrix %p.\n", iface
, D3DMatHandle
, D3DMatrix
);
1483 if (!D3DMatrix
) return DDERR_INVALIDPARAMS
;
1485 wined3d_mutex_lock();
1487 m
= ddraw_get_object(&This
->handle_table
, D3DMatHandle
- 1, DDRAW_HANDLE_MATRIX
);
1490 WARN("Invalid matrix handle.\n");
1491 wined3d_mutex_unlock();
1492 return DDERR_INVALIDPARAMS
;
1497 wined3d_mutex_unlock();
1502 /*****************************************************************************
1503 * IDirect3DDevice::DeleteMatrix
1505 * Destroys a Matrix handle. Frees the memory and unsets the handle data
1510 * D3DMatHandle: Handle to destroy
1514 * DDERR_INVALIDPARAMS if D3DMatHandle is invalid
1516 *****************************************************************************/
1517 static HRESULT WINAPI
1518 IDirect3DDeviceImpl_1_DeleteMatrix(IDirect3DDevice
*iface
,
1519 D3DMATRIXHANDLE D3DMatHandle
)
1521 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
1524 TRACE("iface %p, matrix_handle %#x.\n", iface
, D3DMatHandle
);
1526 wined3d_mutex_lock();
1528 m
= ddraw_free_handle(&This
->handle_table
, D3DMatHandle
- 1, DDRAW_HANDLE_MATRIX
);
1531 WARN("Invalid matrix handle.\n");
1532 wined3d_mutex_unlock();
1533 return DDERR_INVALIDPARAMS
;
1536 wined3d_mutex_unlock();
1538 HeapFree(GetProcessHeap(), 0, m
);
1543 /*****************************************************************************
1544 * IDirect3DDevice7::BeginScene
1546 * This method must be called before any rendering is performed.
1547 * IDirect3DDevice::EndScene has to be called after the scene is complete
1549 * Version 1, 2, 3 and 7
1552 * D3D_OK on success, for details see IWineD3DDevice::BeginScene
1553 * D3DERR_SCENE_IN_SCENE if WineD3D returns an error(Only in case of an already
1556 *****************************************************************************/
1558 IDirect3DDeviceImpl_7_BeginScene(IDirect3DDevice7
*iface
)
1560 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
1563 TRACE("iface %p.\n", iface
);
1565 wined3d_mutex_lock();
1566 hr
= wined3d_device_begin_scene(This
->wined3d_device
);
1567 wined3d_mutex_unlock();
1569 if(hr
== WINED3D_OK
) return D3D_OK
;
1570 else return D3DERR_SCENE_IN_SCENE
; /* TODO: Other possible causes of failure */
1573 static HRESULT WINAPI
1574 IDirect3DDeviceImpl_7_BeginScene_FPUSetup(IDirect3DDevice7
*iface
)
1576 return IDirect3DDeviceImpl_7_BeginScene(iface
);
1579 static HRESULT WINAPI
1580 IDirect3DDeviceImpl_7_BeginScene_FPUPreserve(IDirect3DDevice7
*iface
)
1585 old_fpucw
= d3d_fpu_setup();
1586 hr
= IDirect3DDeviceImpl_7_BeginScene(iface
);
1587 set_fpu_control_word(old_fpucw
);
1592 static HRESULT WINAPI
IDirect3DDeviceImpl_3_BeginScene(IDirect3DDevice3
*iface
)
1594 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
1595 TRACE("iface %p.\n", iface
);
1597 return IDirect3DDevice7_BeginScene(&This
->IDirect3DDevice7_iface
);
1600 static HRESULT WINAPI
IDirect3DDeviceImpl_2_BeginScene(IDirect3DDevice2
*iface
)
1602 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
1603 TRACE("iface %p.\n", iface
);
1605 return IDirect3DDevice7_BeginScene(&This
->IDirect3DDevice7_iface
);
1608 static HRESULT WINAPI
IDirect3DDeviceImpl_1_BeginScene(IDirect3DDevice
*iface
)
1610 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
1611 TRACE("iface %p.\n", iface
);
1613 return IDirect3DDevice7_BeginScene(&This
->IDirect3DDevice7_iface
);
1616 /*****************************************************************************
1617 * IDirect3DDevice7::EndScene
1619 * Ends a scene that has been begun with IDirect3DDevice7::BeginScene.
1620 * This method must be called after rendering is finished.
1622 * Version 1, 2, 3 and 7
1625 * D3D_OK on success, for details see IWineD3DDevice::EndScene
1626 * D3DERR_SCENE_NOT_IN_SCENE is returned if WineD3D returns an error. It does
1627 * that only if the scene was already ended.
1629 *****************************************************************************/
1631 IDirect3DDeviceImpl_7_EndScene(IDirect3DDevice7
*iface
)
1633 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
1636 TRACE("iface %p.\n", iface
);
1638 wined3d_mutex_lock();
1639 hr
= wined3d_device_end_scene(This
->wined3d_device
);
1640 wined3d_mutex_unlock();
1642 if(hr
== WINED3D_OK
) return D3D_OK
;
1643 else return D3DERR_SCENE_NOT_IN_SCENE
;
1646 static HRESULT WINAPI DECLSPEC_HOTPATCH
1647 IDirect3DDeviceImpl_7_EndScene_FPUSetup(IDirect3DDevice7
*iface
)
1649 return IDirect3DDeviceImpl_7_EndScene(iface
);
1652 static HRESULT WINAPI DECLSPEC_HOTPATCH
1653 IDirect3DDeviceImpl_7_EndScene_FPUPreserve(IDirect3DDevice7
*iface
)
1658 old_fpucw
= d3d_fpu_setup();
1659 hr
= IDirect3DDeviceImpl_7_EndScene(iface
);
1660 set_fpu_control_word(old_fpucw
);
1665 static HRESULT WINAPI DECLSPEC_HOTPATCH
IDirect3DDeviceImpl_3_EndScene(IDirect3DDevice3
*iface
)
1667 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
1668 TRACE("iface %p.\n", iface
);
1670 return IDirect3DDevice7_EndScene(&This
->IDirect3DDevice7_iface
);
1673 static HRESULT WINAPI DECLSPEC_HOTPATCH
IDirect3DDeviceImpl_2_EndScene(IDirect3DDevice2
*iface
)
1675 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
1676 TRACE("iface %p.\n", iface
);
1678 return IDirect3DDevice7_EndScene(&This
->IDirect3DDevice7_iface
);
1681 static HRESULT WINAPI DECLSPEC_HOTPATCH
IDirect3DDeviceImpl_1_EndScene(IDirect3DDevice
*iface
)
1683 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
1684 TRACE("iface %p.\n", iface
);
1686 return IDirect3DDevice7_EndScene(&This
->IDirect3DDevice7_iface
);
1689 /*****************************************************************************
1690 * IDirect3DDevice7::GetDirect3D
1692 * Returns the IDirect3D(= interface to the DirectDraw object) used to create
1696 * Direct3D7: Address to store the interface pointer at
1700 * DDERR_INVALIDPARAMS if Direct3D7 == NULL
1702 *****************************************************************************/
1703 static HRESULT WINAPI
1704 IDirect3DDeviceImpl_7_GetDirect3D(IDirect3DDevice7
*iface
,
1705 IDirect3D7
**Direct3D7
)
1707 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
1709 TRACE("iface %p, d3d %p.\n", iface
, Direct3D7
);
1712 return DDERR_INVALIDPARAMS
;
1714 *Direct3D7
= &This
->ddraw
->IDirect3D7_iface
;
1715 IDirect3D7_AddRef(*Direct3D7
);
1717 TRACE(" returning interface %p\n", *Direct3D7
);
1721 static HRESULT WINAPI
IDirect3DDeviceImpl_3_GetDirect3D(IDirect3DDevice3
*iface
,
1722 IDirect3D3
**Direct3D3
)
1724 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
1726 TRACE("iface %p, d3d %p.\n", iface
, Direct3D3
);
1729 return DDERR_INVALIDPARAMS
;
1731 IDirect3D3_AddRef(&This
->ddraw
->IDirect3D3_iface
);
1732 *Direct3D3
= &This
->ddraw
->IDirect3D3_iface
;
1733 TRACE(" returning interface %p\n", *Direct3D3
);
1737 static HRESULT WINAPI
IDirect3DDeviceImpl_2_GetDirect3D(IDirect3DDevice2
*iface
,
1738 IDirect3D2
**Direct3D2
)
1740 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
1742 TRACE("iface %p, d3d %p.\n", iface
, Direct3D2
);
1745 return DDERR_INVALIDPARAMS
;
1747 IDirect3D2_AddRef(&This
->ddraw
->IDirect3D2_iface
);
1748 *Direct3D2
= &This
->ddraw
->IDirect3D2_iface
;
1749 TRACE(" returning interface %p\n", *Direct3D2
);
1753 static HRESULT WINAPI
IDirect3DDeviceImpl_1_GetDirect3D(IDirect3DDevice
*iface
,
1754 IDirect3D
**Direct3D
)
1756 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
1758 TRACE("iface %p, d3d %p.\n", iface
, Direct3D
);
1761 return DDERR_INVALIDPARAMS
;
1763 IDirect3D_AddRef(&This
->ddraw
->IDirect3D_iface
);
1764 *Direct3D
= &This
->ddraw
->IDirect3D_iface
;
1765 TRACE(" returning interface %p\n", *Direct3D
);
1769 /*****************************************************************************
1770 * IDirect3DDevice3::SetCurrentViewport
1772 * Sets a Direct3DViewport as the current viewport.
1773 * For the thunks note that all viewport interface versions are equal
1776 * Direct3DViewport3: The viewport to set
1782 * (Is a NULL viewport valid?)
1784 *****************************************************************************/
1785 static HRESULT WINAPI
1786 IDirect3DDeviceImpl_3_SetCurrentViewport(IDirect3DDevice3
*iface
,
1787 IDirect3DViewport3
*Direct3DViewport3
)
1789 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
1790 IDirect3DViewportImpl
*vp
= unsafe_impl_from_IDirect3DViewport3(Direct3DViewport3
);
1792 TRACE("iface %p, viewport %p.\n", iface
, Direct3DViewport3
);
1794 wined3d_mutex_lock();
1795 /* Do nothing if the specified viewport is the same as the current one */
1796 if (This
->current_viewport
== vp
)
1798 wined3d_mutex_unlock();
1802 if (vp
->active_device
!= This
)
1804 WARN("Viewport %p active device is %p.\n", vp
, vp
->active_device
);
1805 wined3d_mutex_unlock();
1806 return DDERR_INVALIDPARAMS
;
1809 /* Release previous viewport and AddRef the new one */
1810 if (This
->current_viewport
)
1812 TRACE("ViewportImpl is at %p, interface is at %p\n", This
->current_viewport
,
1813 &This
->current_viewport
->IDirect3DViewport3_iface
);
1814 IDirect3DViewport3_Release(&This
->current_viewport
->IDirect3DViewport3_iface
);
1816 IDirect3DViewport3_AddRef(Direct3DViewport3
);
1818 /* Set this viewport as the current viewport */
1819 This
->current_viewport
= vp
;
1821 /* Activate this viewport */
1822 viewport_activate(This
->current_viewport
, FALSE
);
1824 wined3d_mutex_unlock();
1829 static HRESULT WINAPI
IDirect3DDeviceImpl_2_SetCurrentViewport(IDirect3DDevice2
*iface
,
1830 IDirect3DViewport2
*Direct3DViewport2
)
1832 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
1833 IDirect3DViewportImpl
*vp
= unsafe_impl_from_IDirect3DViewport2(Direct3DViewport2
);
1835 TRACE("iface %p, viewport %p.\n", iface
, Direct3DViewport2
);
1837 return IDirect3DDevice3_SetCurrentViewport(&This
->IDirect3DDevice3_iface
,
1838 &vp
->IDirect3DViewport3_iface
);
1841 /*****************************************************************************
1842 * IDirect3DDevice3::GetCurrentViewport
1844 * Returns the currently active viewport.
1849 * Direct3DViewport3: Address to return the interface pointer at
1853 * DDERR_INVALIDPARAMS if Direct3DViewport == NULL
1855 *****************************************************************************/
1856 static HRESULT WINAPI
1857 IDirect3DDeviceImpl_3_GetCurrentViewport(IDirect3DDevice3
*iface
,
1858 IDirect3DViewport3
**Direct3DViewport3
)
1860 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
1862 TRACE("iface %p, viewport %p.\n", iface
, Direct3DViewport3
);
1864 if(!Direct3DViewport3
)
1865 return DDERR_INVALIDPARAMS
;
1867 wined3d_mutex_lock();
1868 *Direct3DViewport3
= &This
->current_viewport
->IDirect3DViewport3_iface
;
1870 /* AddRef the returned viewport */
1871 if(*Direct3DViewport3
) IDirect3DViewport3_AddRef(*Direct3DViewport3
);
1873 TRACE(" returning interface %p\n", *Direct3DViewport3
);
1875 wined3d_mutex_unlock();
1880 static HRESULT WINAPI
IDirect3DDeviceImpl_2_GetCurrentViewport(IDirect3DDevice2
*iface
,
1881 IDirect3DViewport2
**Direct3DViewport2
)
1883 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
1886 TRACE("iface %p, viewport %p.\n", iface
, Direct3DViewport2
);
1888 hr
= IDirect3DDevice3_GetCurrentViewport(&This
->IDirect3DDevice3_iface
,
1889 (IDirect3DViewport3
**)Direct3DViewport2
);
1890 if(hr
!= D3D_OK
) return hr
;
1894 /*****************************************************************************
1895 * IDirect3DDevice7::SetRenderTarget
1897 * Sets the render target for the Direct3DDevice.
1898 * For the thunks note that IDirectDrawSurface7 == IDirectDrawSurface4 and
1899 * IDirectDrawSurface3 == IDirectDrawSurface
1901 * Version 2, 3 and 7
1904 * NewTarget: Pointer to an IDirectDrawSurface7 interface to set as the new
1909 * D3D_OK on success, for details see IWineD3DDevice::SetRenderTarget
1911 *****************************************************************************/
1912 static HRESULT
d3d_device_set_render_target(IDirect3DDeviceImpl
*This
, IDirectDrawSurfaceImpl
*Target
)
1916 wined3d_mutex_lock();
1918 if(This
->target
== Target
)
1920 TRACE("No-op SetRenderTarget operation, not doing anything\n");
1921 wined3d_mutex_unlock();
1924 This
->target
= Target
;
1925 hr
= wined3d_device_set_render_target(This
->wined3d_device
, 0,
1926 Target
? Target
->wined3d_surface
: NULL
, FALSE
);
1929 wined3d_mutex_unlock();
1932 IDirect3DDeviceImpl_UpdateDepthStencil(This
);
1934 wined3d_mutex_unlock();
1940 IDirect3DDeviceImpl_7_SetRenderTarget(IDirect3DDevice7
*iface
,
1941 IDirectDrawSurface7
*NewTarget
,
1944 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
1945 IDirectDrawSurfaceImpl
*Target
= unsafe_impl_from_IDirectDrawSurface7(NewTarget
);
1947 TRACE("iface %p, target %p, flags %#x.\n", iface
, NewTarget
, Flags
);
1948 /* Flags: Not used */
1950 IDirectDrawSurface7_AddRef(NewTarget
);
1951 IDirectDrawSurface7_Release(&This
->target
->IDirectDrawSurface7_iface
);
1952 return d3d_device_set_render_target(This
, Target
);
1955 static HRESULT WINAPI
1956 IDirect3DDeviceImpl_7_SetRenderTarget_FPUSetup(IDirect3DDevice7
*iface
,
1957 IDirectDrawSurface7
*NewTarget
,
1960 return IDirect3DDeviceImpl_7_SetRenderTarget(iface
, NewTarget
, Flags
);
1963 static HRESULT WINAPI
1964 IDirect3DDeviceImpl_7_SetRenderTarget_FPUPreserve(IDirect3DDevice7
*iface
,
1965 IDirectDrawSurface7
*NewTarget
,
1971 old_fpucw
= d3d_fpu_setup();
1972 hr
= IDirect3DDeviceImpl_7_SetRenderTarget(iface
, NewTarget
, Flags
);
1973 set_fpu_control_word(old_fpucw
);
1978 static HRESULT WINAPI
IDirect3DDeviceImpl_3_SetRenderTarget(IDirect3DDevice3
*iface
,
1979 IDirectDrawSurface4
*NewRenderTarget
, DWORD Flags
)
1981 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
1982 IDirectDrawSurfaceImpl
*Target
= unsafe_impl_from_IDirectDrawSurface4(NewRenderTarget
);
1984 TRACE("iface %p, target %p, flags %#x.\n", iface
, NewRenderTarget
, Flags
);
1986 IDirectDrawSurface4_AddRef(NewRenderTarget
);
1987 IDirectDrawSurface4_Release(&This
->target
->IDirectDrawSurface4_iface
);
1988 return d3d_device_set_render_target(This
, Target
);
1991 static HRESULT WINAPI
IDirect3DDeviceImpl_2_SetRenderTarget(IDirect3DDevice2
*iface
,
1992 IDirectDrawSurface
*NewRenderTarget
, DWORD Flags
)
1994 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
1995 IDirectDrawSurfaceImpl
*Target
= unsafe_impl_from_IDirectDrawSurface(NewRenderTarget
);
1997 TRACE("iface %p, target %p, flags %#x.\n", iface
, NewRenderTarget
, Flags
);
1999 IDirectDrawSurface_AddRef(NewRenderTarget
);
2000 IDirectDrawSurface_Release(&This
->target
->IDirectDrawSurface_iface
);
2001 return d3d_device_set_render_target(This
, Target
);
2004 /*****************************************************************************
2005 * IDirect3DDevice7::GetRenderTarget
2007 * Returns the current render target.
2008 * This is handled locally, because the WineD3D render target's parent
2011 * Version 2, 3 and 7
2014 * RenderTarget: Address to store the surface interface pointer
2018 * DDERR_INVALIDPARAMS if RenderTarget == NULL
2020 *****************************************************************************/
2021 static HRESULT WINAPI
2022 IDirect3DDeviceImpl_7_GetRenderTarget(IDirect3DDevice7
*iface
,
2023 IDirectDrawSurface7
**RenderTarget
)
2025 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
2027 TRACE("iface %p, target %p.\n", iface
, RenderTarget
);
2030 return DDERR_INVALIDPARAMS
;
2032 wined3d_mutex_lock();
2033 *RenderTarget
= &This
->target
->IDirectDrawSurface7_iface
;
2034 IDirectDrawSurface7_AddRef(*RenderTarget
);
2035 wined3d_mutex_unlock();
2040 static HRESULT WINAPI
IDirect3DDeviceImpl_3_GetRenderTarget(IDirect3DDevice3
*iface
,
2041 IDirectDrawSurface4
**RenderTarget
)
2043 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
2044 IDirectDrawSurface7
*RenderTarget7
;
2045 IDirectDrawSurfaceImpl
*RenderTargetImpl
;
2048 TRACE("iface %p, target %p.\n", iface
, RenderTarget
);
2051 return DDERR_INVALIDPARAMS
;
2053 hr
= IDirect3DDevice7_GetRenderTarget(&This
->IDirect3DDevice7_iface
, &RenderTarget7
);
2054 if(hr
!= D3D_OK
) return hr
;
2055 RenderTargetImpl
= impl_from_IDirectDrawSurface7(RenderTarget7
);
2056 *RenderTarget
= &RenderTargetImpl
->IDirectDrawSurface4_iface
;
2057 IDirectDrawSurface4_AddRef(*RenderTarget
);
2058 IDirectDrawSurface7_Release(RenderTarget7
);
2062 static HRESULT WINAPI
IDirect3DDeviceImpl_2_GetRenderTarget(IDirect3DDevice2
*iface
,
2063 IDirectDrawSurface
**RenderTarget
)
2065 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
2066 IDirectDrawSurface7
*RenderTarget7
;
2067 IDirectDrawSurfaceImpl
*RenderTargetImpl
;
2070 TRACE("iface %p, target %p.\n", iface
, RenderTarget
);
2073 return DDERR_INVALIDPARAMS
;
2075 hr
= IDirect3DDevice7_GetRenderTarget(&This
->IDirect3DDevice7_iface
, &RenderTarget7
);
2076 if(hr
!= D3D_OK
) return hr
;
2077 RenderTargetImpl
= impl_from_IDirectDrawSurface7(RenderTarget7
);
2078 *RenderTarget
= &RenderTargetImpl
->IDirectDrawSurface_iface
;
2079 IDirectDrawSurface_AddRef(*RenderTarget
);
2080 IDirectDrawSurface7_Release(RenderTarget7
);
2084 /*****************************************************************************
2085 * IDirect3DDevice3::Begin
2087 * Begins a description block of vertices. This is similar to glBegin()
2088 * and glEnd(). After a call to IDirect3DDevice3::End, the vertices
2089 * described with IDirect3DDevice::Vertex are drawn.
2094 * PrimitiveType: The type of primitives to draw
2095 * VertexTypeDesc: A flexible vertex format description of the vertices
2096 * Flags: Some flags..
2101 *****************************************************************************/
2102 static HRESULT WINAPI
2103 IDirect3DDeviceImpl_3_Begin(IDirect3DDevice3
*iface
,
2104 D3DPRIMITIVETYPE PrimitiveType
,
2105 DWORD VertexTypeDesc
,
2108 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
2110 TRACE("iface %p, primitive_type %#x, FVF %#x, flags %#x.\n",
2111 iface
, PrimitiveType
, VertexTypeDesc
, Flags
);
2113 wined3d_mutex_lock();
2114 This
->primitive_type
= PrimitiveType
;
2115 This
->vertex_type
= VertexTypeDesc
;
2116 This
->render_flags
= Flags
;
2117 This
->vertex_size
= get_flexible_vertex_size(This
->vertex_type
);
2118 This
->nb_vertices
= 0;
2119 wined3d_mutex_unlock();
2124 static HRESULT WINAPI
IDirect3DDeviceImpl_2_Begin(IDirect3DDevice2
*iface
, D3DPRIMITIVETYPE d3dpt
,
2125 D3DVERTEXTYPE dwVertexTypeDesc
, DWORD dwFlags
)
2128 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
2130 TRACE("iface %p, primitive_type %#x, vertex_type %#x, flags %#x.\n",
2131 iface
, d3dpt
, dwVertexTypeDesc
, dwFlags
);
2133 switch(dwVertexTypeDesc
)
2135 case D3DVT_VERTEX
: FVF
= D3DFVF_VERTEX
; break;
2136 case D3DVT_LVERTEX
: FVF
= D3DFVF_LVERTEX
; break;
2137 case D3DVT_TLVERTEX
: FVF
= D3DFVF_TLVERTEX
; break;
2139 ERR("Unexpected vertex type %d\n", dwVertexTypeDesc
);
2140 return DDERR_INVALIDPARAMS
; /* Should never happen */
2143 return IDirect3DDevice3_Begin(&This
->IDirect3DDevice3_iface
, d3dpt
, FVF
, dwFlags
);
2146 /*****************************************************************************
2147 * IDirect3DDevice3::BeginIndexed
2149 * Draws primitives based on vertices in a vertex array which are specified
2155 * PrimitiveType: Primitive type to draw
2156 * VertexType: A FVF description of the vertex format
2157 * Vertices: pointer to an array containing the vertices
2158 * NumVertices: The number of vertices in the vertex array
2159 * Flags: Some flags ...
2162 * D3D_OK, because it's a stub
2164 *****************************************************************************/
2165 static HRESULT WINAPI
2166 IDirect3DDeviceImpl_3_BeginIndexed(IDirect3DDevice3
*iface
,
2167 D3DPRIMITIVETYPE PrimitiveType
,
2173 FIXME("iface %p, primitive_type %#x, FVF %#x, vertices %p, vertex_count %u, flags %#x stub!\n",
2174 iface
, PrimitiveType
, VertexType
, Vertices
, NumVertices
, Flags
);
2180 static HRESULT WINAPI
IDirect3DDeviceImpl_2_BeginIndexed(IDirect3DDevice2
*iface
,
2181 D3DPRIMITIVETYPE d3dptPrimitiveType
, D3DVERTEXTYPE d3dvtVertexType
,
2182 void *lpvVertices
, DWORD dwNumVertices
, DWORD dwFlags
)
2185 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
2187 TRACE("iface %p, primitive_type %#x, vertex_type %#x, vertices %p, vertex_count %u, flags %#x stub!\n",
2188 iface
, d3dptPrimitiveType
, d3dvtVertexType
, lpvVertices
, dwNumVertices
, dwFlags
);
2190 switch(d3dvtVertexType
)
2192 case D3DVT_VERTEX
: FVF
= D3DFVF_VERTEX
; break;
2193 case D3DVT_LVERTEX
: FVF
= D3DFVF_LVERTEX
; break;
2194 case D3DVT_TLVERTEX
: FVF
= D3DFVF_TLVERTEX
; break;
2196 ERR("Unexpected vertex type %d\n", d3dvtVertexType
);
2197 return DDERR_INVALIDPARAMS
; /* Should never happen */
2200 return IDirect3DDevice3_BeginIndexed(&This
->IDirect3DDevice3_iface
,
2201 d3dptPrimitiveType
, FVF
, lpvVertices
, dwNumVertices
, dwFlags
);
2204 /*****************************************************************************
2205 * IDirect3DDevice3::Vertex
2207 * Draws a vertex as described by IDirect3DDevice3::Begin. It places all
2208 * drawn vertices in a vertex buffer. If the buffer is too small, its
2209 * size is increased.
2214 * Vertex: Pointer to the vertex
2217 * D3D_OK, on success
2218 * DDERR_INVALIDPARAMS if Vertex is NULL
2220 *****************************************************************************/
2221 static HRESULT WINAPI
2222 IDirect3DDeviceImpl_3_Vertex(IDirect3DDevice3
*iface
,
2225 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
2227 TRACE("iface %p, vertex %p.\n", iface
, Vertex
);
2230 return DDERR_INVALIDPARAMS
;
2232 wined3d_mutex_lock();
2233 if ((This
->nb_vertices
+1)*This
->vertex_size
> This
->buffer_size
)
2236 This
->buffer_size
= This
->buffer_size
? This
->buffer_size
* 2 : This
->vertex_size
* 3;
2237 old_buffer
= This
->vertex_buffer
;
2238 This
->vertex_buffer
= HeapAlloc(GetProcessHeap(), 0, This
->buffer_size
);
2241 CopyMemory(This
->vertex_buffer
, old_buffer
, This
->nb_vertices
* This
->vertex_size
);
2242 HeapFree(GetProcessHeap(), 0, old_buffer
);
2246 CopyMemory(This
->vertex_buffer
+ This
->nb_vertices
++ * This
->vertex_size
, Vertex
, This
->vertex_size
);
2247 wined3d_mutex_unlock();
2252 static HRESULT WINAPI
IDirect3DDeviceImpl_2_Vertex(IDirect3DDevice2
*iface
, void *lpVertexType
)
2254 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
2256 TRACE("iface %p, vertex %p.\n", iface
, lpVertexType
);
2258 return IDirect3DDevice3_Vertex(&This
->IDirect3DDevice3_iface
, lpVertexType
);
2261 /*****************************************************************************
2262 * IDirect3DDevice3::Index
2264 * Specifies an index to a vertex to be drawn. The vertex array has to
2265 * be specified with BeginIndexed first.
2268 * VertexIndex: The index of the vertex to draw
2271 * D3D_OK because it's a stub
2273 *****************************************************************************/
2274 static HRESULT WINAPI
2275 IDirect3DDeviceImpl_3_Index(IDirect3DDevice3
*iface
,
2278 FIXME("iface %p, index %#x stub!\n", iface
, VertexIndex
);
2283 static HRESULT WINAPI
IDirect3DDeviceImpl_2_Index(IDirect3DDevice2
*iface
, WORD wVertexIndex
)
2285 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
2287 TRACE("iface %p, index %#x.\n", iface
, wVertexIndex
);
2289 return IDirect3DDevice3_Index(&This
->IDirect3DDevice3_iface
, wVertexIndex
);
2292 /*****************************************************************************
2293 * IDirect3DDevice3::End
2295 * Ends a draw begun with IDirect3DDevice3::Begin or
2296 * IDirect3DDevice::BeginIndexed. The vertices specified with
2297 * IDirect3DDevice::Vertex or IDirect3DDevice::Index are drawn using
2298 * the IDirect3DDevice7::DrawPrimitive method. So far only
2299 * non-indexed mode is supported
2304 * Flags: Some flags, as usual. Don't know which are defined
2307 * The return value of IDirect3DDevice7::DrawPrimitive
2309 *****************************************************************************/
2310 static HRESULT WINAPI
2311 IDirect3DDeviceImpl_3_End(IDirect3DDevice3
*iface
,
2314 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
2316 TRACE("iface %p, flags %#x.\n", iface
, Flags
);
2318 return IDirect3DDevice7_DrawPrimitive(&This
->IDirect3DDevice7_iface
, This
->primitive_type
,
2319 This
->vertex_type
, This
->vertex_buffer
, This
->nb_vertices
, This
->render_flags
);
2322 static HRESULT WINAPI
IDirect3DDeviceImpl_2_End(IDirect3DDevice2
*iface
, DWORD dwFlags
)
2324 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
2326 TRACE("iface %p, flags %#x.\n", iface
, dwFlags
);
2328 return IDirect3DDevice3_End(&This
->IDirect3DDevice3_iface
, dwFlags
);
2331 /*****************************************************************************
2332 * IDirect3DDevice7::GetRenderState
2334 * Returns the value of a render state. The possible render states are
2335 * defined in include/d3dtypes.h
2337 * Version 2, 3 and 7
2340 * RenderStateType: Render state to return the current setting of
2341 * Value: Address to store the value at
2344 * D3D_OK on success, for details see IWineD3DDevice::GetRenderState
2345 * DDERR_INVALIDPARAMS if Value == NULL
2347 *****************************************************************************/
2348 static HRESULT
IDirect3DDeviceImpl_7_GetRenderState(IDirect3DDevice7
*iface
,
2349 D3DRENDERSTATETYPE RenderStateType
, DWORD
*Value
)
2351 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
2354 TRACE("iface %p, state %#x, value %p.\n", iface
, RenderStateType
, Value
);
2357 return DDERR_INVALIDPARAMS
;
2359 wined3d_mutex_lock();
2360 switch(RenderStateType
)
2362 case D3DRENDERSTATE_TEXTUREMAG
:
2364 enum wined3d_texture_filter_type tex_mag
;
2366 hr
= wined3d_device_get_sampler_state(This
->wined3d_device
, 0, WINED3D_SAMP_MAG_FILTER
, &tex_mag
);
2370 case WINED3D_TEXF_POINT
:
2371 *Value
= D3DFILTER_NEAREST
;
2373 case WINED3D_TEXF_LINEAR
:
2374 *Value
= D3DFILTER_LINEAR
;
2377 ERR("Unhandled texture mag %d !\n",tex_mag
);
2383 case D3DRENDERSTATE_TEXTUREMIN
:
2385 enum wined3d_texture_filter_type tex_min
;
2386 enum wined3d_texture_filter_type tex_mip
;
2388 hr
= wined3d_device_get_sampler_state(This
->wined3d_device
,
2389 0, WINED3D_SAMP_MIN_FILTER
, &tex_min
);
2392 wined3d_mutex_unlock();
2395 hr
= wined3d_device_get_sampler_state(This
->wined3d_device
,
2396 0, WINED3D_SAMP_MIP_FILTER
, &tex_mip
);
2400 case WINED3D_TEXF_POINT
:
2403 case WINED3D_TEXF_NONE
:
2404 *Value
= D3DFILTER_NEAREST
;
2406 case WINED3D_TEXF_POINT
:
2407 *Value
= D3DFILTER_MIPNEAREST
;
2409 case WINED3D_TEXF_LINEAR
:
2410 *Value
= D3DFILTER_LINEARMIPNEAREST
;
2413 ERR("Unhandled mip filter %#x.\n", tex_mip
);
2414 *Value
= D3DFILTER_NEAREST
;
2418 case WINED3D_TEXF_LINEAR
:
2421 case WINED3D_TEXF_NONE
:
2422 *Value
= D3DFILTER_LINEAR
;
2424 case WINED3D_TEXF_POINT
:
2425 *Value
= D3DFILTER_MIPLINEAR
;
2427 case WINED3D_TEXF_LINEAR
:
2428 *Value
= D3DFILTER_LINEARMIPLINEAR
;
2431 ERR("Unhandled mip filter %#x.\n", tex_mip
);
2432 *Value
= D3DFILTER_LINEAR
;
2437 ERR("Unhandled texture min filter %#x.\n",tex_min
);
2438 *Value
= D3DFILTER_NEAREST
;
2444 case D3DRENDERSTATE_TEXTUREADDRESS
:
2445 case D3DRENDERSTATE_TEXTUREADDRESSU
:
2446 hr
= wined3d_device_get_sampler_state(This
->wined3d_device
,
2447 0, WINED3D_SAMP_ADDRESS_U
, Value
);
2449 case D3DRENDERSTATE_TEXTUREADDRESSV
:
2450 hr
= wined3d_device_get_sampler_state(This
->wined3d_device
,
2451 0, WINED3D_SAMP_ADDRESS_V
, Value
);
2454 case D3DRENDERSTATE_BORDERCOLOR
:
2455 FIXME("Unhandled render state D3DRENDERSTATE_BORDERCOLOR.\n");
2459 case D3DRENDERSTATE_TEXTUREHANDLE
:
2460 case D3DRENDERSTATE_TEXTUREMAPBLEND
:
2461 WARN("Render state %#x is invalid in d3d7.\n", RenderStateType
);
2462 hr
= DDERR_INVALIDPARAMS
;
2465 case D3DRENDERSTATE_ZBIAS
:
2466 hr
= wined3d_device_get_render_state(This
->wined3d_device
, WINED3D_RS_DEPTHBIAS
, Value
);
2470 if (RenderStateType
>= D3DRENDERSTATE_STIPPLEPATTERN00
2471 && RenderStateType
<= D3DRENDERSTATE_STIPPLEPATTERN31
)
2473 FIXME("Unhandled stipple pattern render state (%#x).\n",
2478 hr
= wined3d_device_get_render_state(This
->wined3d_device
, RenderStateType
, Value
);
2480 wined3d_mutex_unlock();
2485 static HRESULT WINAPI
2486 IDirect3DDeviceImpl_7_GetRenderState_FPUSetup(IDirect3DDevice7
*iface
,
2487 D3DRENDERSTATETYPE RenderStateType
,
2490 return IDirect3DDeviceImpl_7_GetRenderState(iface
, RenderStateType
, Value
);
2493 static HRESULT WINAPI
2494 IDirect3DDeviceImpl_7_GetRenderState_FPUPreserve(IDirect3DDevice7
*iface
,
2495 D3DRENDERSTATETYPE RenderStateType
,
2501 old_fpucw
= d3d_fpu_setup();
2502 hr
= IDirect3DDeviceImpl_7_GetRenderState(iface
, RenderStateType
, Value
);
2503 set_fpu_control_word(old_fpucw
);
2508 static HRESULT WINAPI
2509 IDirect3DDeviceImpl_3_GetRenderState(IDirect3DDevice3
*iface
,
2510 D3DRENDERSTATETYPE dwRenderStateType
,
2511 DWORD
*lpdwRenderState
)
2513 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
2516 TRACE("iface %p, state %#x, value %p.\n", iface
, dwRenderStateType
, lpdwRenderState
);
2518 switch(dwRenderStateType
)
2520 case D3DRENDERSTATE_TEXTUREHANDLE
:
2522 /* This state is wrapped to SetTexture in SetRenderState, so
2523 * it has to be wrapped to GetTexture here. */
2524 struct wined3d_texture
*tex
= NULL
;
2525 *lpdwRenderState
= 0;
2527 wined3d_mutex_lock();
2528 hr
= wined3d_device_get_texture(This
->wined3d_device
, 0, &tex
);
2529 if (SUCCEEDED(hr
) && tex
)
2531 /* The parent of the texture is the IDirectDrawSurface7
2532 * interface of the ddraw surface. */
2533 IDirectDrawSurfaceImpl
*parent
= wined3d_texture_get_parent(tex
);
2534 if (parent
) *lpdwRenderState
= parent
->Handle
;
2535 wined3d_texture_decref(tex
);
2537 wined3d_mutex_unlock();
2542 case D3DRENDERSTATE_TEXTUREMAPBLEND
:
2544 /* D3DRENDERSTATE_TEXTUREMAPBLEND is mapped to texture state stages in SetRenderState; reverse
2545 the mapping to get the value. */
2546 DWORD colorop
, colorarg1
, colorarg2
;
2547 DWORD alphaop
, alphaarg1
, alphaarg2
;
2549 wined3d_mutex_lock();
2551 This
->legacyTextureBlending
= TRUE
;
2553 wined3d_device_get_texture_stage_state(This
->wined3d_device
, 0, WINED3D_TSS_COLOR_OP
, &colorop
);
2554 wined3d_device_get_texture_stage_state(This
->wined3d_device
, 0, WINED3D_TSS_COLOR_ARG1
, &colorarg1
);
2555 wined3d_device_get_texture_stage_state(This
->wined3d_device
, 0, WINED3D_TSS_COLOR_ARG2
, &colorarg2
);
2556 wined3d_device_get_texture_stage_state(This
->wined3d_device
, 0, WINED3D_TSS_ALPHA_OP
, &alphaop
);
2557 wined3d_device_get_texture_stage_state(This
->wined3d_device
, 0, WINED3D_TSS_ALPHA_ARG1
, &alphaarg1
);
2558 wined3d_device_get_texture_stage_state(This
->wined3d_device
, 0, WINED3D_TSS_ALPHA_ARG2
, &alphaarg2
);
2560 if (colorop
== WINED3D_TOP_SELECT_ARG1
&& colorarg1
== WINED3DTA_TEXTURE
2561 && alphaop
== WINED3D_TOP_SELECT_ARG1
&& alphaarg1
== WINED3DTA_TEXTURE
)
2562 *lpdwRenderState
= D3DTBLEND_DECAL
;
2563 else if (colorop
== WINED3D_TOP_SELECT_ARG1
&& colorarg1
== WINED3DTA_TEXTURE
2564 && alphaop
== WINED3D_TOP_MODULATE
2565 && alphaarg1
== WINED3DTA_TEXTURE
&& alphaarg2
== WINED3DTA_CURRENT
)
2566 *lpdwRenderState
= D3DTBLEND_DECALALPHA
;
2567 else if (colorop
== WINED3D_TOP_MODULATE
2568 && colorarg1
== WINED3DTA_TEXTURE
&& colorarg2
== WINED3DTA_CURRENT
2569 && alphaop
== WINED3D_TOP_MODULATE
2570 && alphaarg1
== WINED3DTA_TEXTURE
&& alphaarg2
== WINED3DTA_CURRENT
)
2571 *lpdwRenderState
= D3DTBLEND_MODULATEALPHA
;
2574 struct wined3d_texture
*tex
= NULL
;
2576 BOOL tex_alpha
= FALSE
;
2577 DDPIXELFORMAT ddfmt
;
2579 hr
= wined3d_device_get_texture(This
->wined3d_device
, 0, &tex
);
2581 if(hr
== WINED3D_OK
&& tex
)
2583 struct wined3d_resource
*sub_resource
;
2585 if ((sub_resource
= wined3d_texture_get_sub_resource(tex
, 0)))
2587 struct wined3d_resource_desc desc
;
2589 wined3d_resource_get_desc(sub_resource
, &desc
);
2590 ddfmt
.dwSize
= sizeof(ddfmt
);
2591 PixelFormat_WineD3DtoDD(&ddfmt
, desc
.format
);
2592 if (ddfmt
.u5
.dwRGBAlphaBitMask
) tex_alpha
= TRUE
;
2595 wined3d_texture_decref(tex
);
2598 if (!(colorop
== WINED3D_TOP_MODULATE
2599 && colorarg1
== WINED3DTA_TEXTURE
&& colorarg2
== WINED3DTA_CURRENT
2600 && alphaop
== (tex_alpha
? WINED3D_TOP_SELECT_ARG1
: WINED3D_TOP_SELECT_ARG2
)
2601 && alphaarg1
== WINED3DTA_TEXTURE
&& alphaarg2
== WINED3DTA_CURRENT
))
2602 ERR("Unexpected texture stage state setup, returning D3DTBLEND_MODULATE - likely erroneous.\n");
2604 *lpdwRenderState
= D3DTBLEND_MODULATE
;
2607 wined3d_mutex_unlock();
2613 return IDirect3DDevice7_GetRenderState(&This
->IDirect3DDevice7_iface
, dwRenderStateType
, lpdwRenderState
);
2617 static HRESULT WINAPI
IDirect3DDeviceImpl_2_GetRenderState(IDirect3DDevice2
*iface
,
2618 D3DRENDERSTATETYPE dwRenderStateType
, DWORD
*lpdwRenderState
)
2620 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
2622 TRACE("iface %p, state %#x, value %p.\n", iface
, dwRenderStateType
, lpdwRenderState
);
2624 return IDirect3DDevice3_GetRenderState(&This
->IDirect3DDevice3_iface
,
2625 dwRenderStateType
, lpdwRenderState
);
2628 /*****************************************************************************
2629 * IDirect3DDevice7::SetRenderState
2631 * Sets a render state. The possible render states are defined in
2632 * include/d3dtypes.h
2634 * Version 2, 3 and 7
2637 * RenderStateType: State to set
2638 * Value: Value to assign to that state
2641 * D3D_OK on success,
2642 * for details see IWineD3DDevice::SetRenderState
2644 *****************************************************************************/
2646 IDirect3DDeviceImpl_7_SetRenderState(IDirect3DDevice7
*iface
,
2647 D3DRENDERSTATETYPE RenderStateType
,
2650 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
2653 TRACE("iface %p, state %#x, value %#x.\n", iface
, RenderStateType
, Value
);
2655 wined3d_mutex_lock();
2656 /* Some render states need special care */
2657 switch(RenderStateType
)
2660 * The ddraw texture filter mapping works like this:
2661 * D3DFILTER_NEAREST Point min/mag, no mip
2662 * D3DFILTER_MIPNEAREST Point min/mag, point mip
2663 * D3DFILTER_LINEARMIPNEAREST: Point min/mag, linear mip
2665 * D3DFILTER_LINEAR Linear min/mag, no mip
2666 * D3DFILTER_MIPLINEAR Linear min/mag, point mip
2667 * D3DFILTER_LINEARMIPLINEAR Linear min/mag, linear mip
2669 * This is the opposite of the GL naming convention,
2670 * D3DFILTER_LINEARMIPNEAREST corresponds to GL_NEAREST_MIPMAP_LINEAR.
2672 case D3DRENDERSTATE_TEXTUREMAG
:
2674 enum wined3d_texture_filter_type tex_mag
;
2678 case D3DFILTER_NEAREST
:
2679 case D3DFILTER_MIPNEAREST
:
2680 case D3DFILTER_LINEARMIPNEAREST
:
2681 tex_mag
= WINED3D_TEXF_POINT
;
2683 case D3DFILTER_LINEAR
:
2684 case D3DFILTER_MIPLINEAR
:
2685 case D3DFILTER_LINEARMIPLINEAR
:
2686 tex_mag
= WINED3D_TEXF_LINEAR
;
2689 tex_mag
= WINED3D_TEXF_POINT
;
2690 ERR("Unhandled texture mag %d !\n",Value
);
2694 hr
= wined3d_device_set_sampler_state(This
->wined3d_device
, 0, WINED3D_SAMP_MAG_FILTER
, tex_mag
);
2698 case D3DRENDERSTATE_TEXTUREMIN
:
2700 enum wined3d_texture_filter_type tex_min
;
2701 enum wined3d_texture_filter_type tex_mip
;
2703 switch ((D3DTEXTUREFILTER
)Value
)
2705 case D3DFILTER_NEAREST
:
2706 tex_min
= WINED3D_TEXF_POINT
;
2707 tex_mip
= WINED3D_TEXF_NONE
;
2709 case D3DFILTER_LINEAR
:
2710 tex_min
= WINED3D_TEXF_LINEAR
;
2711 tex_mip
= WINED3D_TEXF_NONE
;
2713 case D3DFILTER_MIPNEAREST
:
2714 tex_min
= WINED3D_TEXF_POINT
;
2715 tex_mip
= WINED3D_TEXF_POINT
;
2717 case D3DFILTER_MIPLINEAR
:
2718 tex_min
= WINED3D_TEXF_LINEAR
;
2719 tex_mip
= WINED3D_TEXF_POINT
;
2721 case D3DFILTER_LINEARMIPNEAREST
:
2722 tex_min
= WINED3D_TEXF_POINT
;
2723 tex_mip
= WINED3D_TEXF_LINEAR
;
2725 case D3DFILTER_LINEARMIPLINEAR
:
2726 tex_min
= WINED3D_TEXF_LINEAR
;
2727 tex_mip
= WINED3D_TEXF_LINEAR
;
2731 ERR("Unhandled texture min %d !\n",Value
);
2732 tex_min
= WINED3D_TEXF_POINT
;
2733 tex_mip
= WINED3D_TEXF_NONE
;
2737 wined3d_device_set_sampler_state(This
->wined3d_device
,
2738 0, WINED3D_SAMP_MIP_FILTER
, tex_mip
);
2739 hr
= wined3d_device_set_sampler_state(This
->wined3d_device
,
2740 0, WINED3D_SAMP_MIN_FILTER
, tex_min
);
2744 case D3DRENDERSTATE_TEXTUREADDRESS
:
2745 wined3d_device_set_sampler_state(This
->wined3d_device
,
2746 0, WINED3D_SAMP_ADDRESS_V
, Value
);
2748 case D3DRENDERSTATE_TEXTUREADDRESSU
:
2749 hr
= wined3d_device_set_sampler_state(This
->wined3d_device
,
2750 0, WINED3D_SAMP_ADDRESS_U
, Value
);
2752 case D3DRENDERSTATE_TEXTUREADDRESSV
:
2753 hr
= wined3d_device_set_sampler_state(This
->wined3d_device
,
2754 0, WINED3D_SAMP_ADDRESS_V
, Value
);
2757 case D3DRENDERSTATE_BORDERCOLOR
:
2758 /* This should probably just forward to the corresponding sampler
2759 * state. Needs tests. */
2760 FIXME("Unhandled render state D3DRENDERSTATE_BORDERCOLOR.\n");
2764 case D3DRENDERSTATE_TEXTUREHANDLE
:
2765 case D3DRENDERSTATE_TEXTUREMAPBLEND
:
2766 WARN("Render state %#x is invalid in d3d7.\n", RenderStateType
);
2767 hr
= DDERR_INVALIDPARAMS
;
2770 case D3DRENDERSTATE_ZBIAS
:
2771 hr
= wined3d_device_set_render_state(This
->wined3d_device
, WINED3D_RS_DEPTHBIAS
, Value
);
2775 if (RenderStateType
>= D3DRENDERSTATE_STIPPLEPATTERN00
2776 && RenderStateType
<= D3DRENDERSTATE_STIPPLEPATTERN31
)
2778 FIXME("Unhandled stipple pattern render state (%#x).\n",
2784 hr
= wined3d_device_set_render_state(This
->wined3d_device
, RenderStateType
, Value
);
2787 wined3d_mutex_unlock();
2792 static HRESULT WINAPI
2793 IDirect3DDeviceImpl_7_SetRenderState_FPUSetup(IDirect3DDevice7
*iface
,
2794 D3DRENDERSTATETYPE RenderStateType
,
2797 return IDirect3DDeviceImpl_7_SetRenderState(iface
, RenderStateType
, Value
);
2800 static HRESULT WINAPI
2801 IDirect3DDeviceImpl_7_SetRenderState_FPUPreserve(IDirect3DDevice7
*iface
,
2802 D3DRENDERSTATETYPE RenderStateType
,
2808 old_fpucw
= d3d_fpu_setup();
2809 hr
= IDirect3DDeviceImpl_7_SetRenderState(iface
, RenderStateType
, Value
);
2810 set_fpu_control_word(old_fpucw
);
2815 static HRESULT WINAPI
2816 IDirect3DDeviceImpl_3_SetRenderState(IDirect3DDevice3
*iface
,
2817 D3DRENDERSTATETYPE RenderStateType
,
2820 /* Note about D3DRENDERSTATE_TEXTUREMAPBLEND implementation: most of values
2821 for this state can be directly mapped to texture stage colorop and alphaop, but
2822 D3DTBLEND_MODULATE is tricky: it uses alpha from texture when available and alpha
2823 from diffuse otherwise. So changing the texture must be monitored in SetTexture to modify
2824 alphaarg when needed.
2826 Aliens vs Predator 1 depends on accurate D3DTBLEND_MODULATE emulation
2828 Legacy texture blending (TEXTUREMAPBLEND) and texture stage states: directx6 docs state that
2829 TEXTUREMAPBLEND is deprecated, yet can still be used. Games must not use both or results
2830 are undefined. D3DTBLEND_MODULATE mode in particular is dependent on texture pixel format and
2831 requires fixup of stage 0 texture states when texture changes, but this fixup can interfere
2832 with games not using this deprecated state. So a flag 'legacyTextureBlending' has to be kept
2833 in device - TRUE if the app is using TEXTUREMAPBLEND.
2835 Tests show that setting TEXTUREMAPBLEND on native doesn't seem to change values returned by
2836 GetTextureStageState and vice versa. Not so on Wine, but it is 'undefined' anyway so, probably, ok,
2837 unless some broken game will be found that cares. */
2840 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
2842 TRACE("iface %p, state %#x, value %#x.\n", iface
, RenderStateType
, Value
);
2844 wined3d_mutex_lock();
2846 switch(RenderStateType
)
2848 case D3DRENDERSTATE_TEXTUREHANDLE
:
2850 IDirectDrawSurfaceImpl
*surf
;
2854 hr
= wined3d_device_set_texture(This
->wined3d_device
, 0, NULL
);
2858 surf
= ddraw_get_object(&This
->handle_table
, Value
- 1, DDRAW_HANDLE_SURFACE
);
2861 WARN("Invalid texture handle.\n");
2862 hr
= DDERR_INVALIDPARAMS
;
2866 hr
= IDirect3DDevice3_SetTexture(iface
, 0, &surf
->IDirect3DTexture2_iface
);
2870 case D3DRENDERSTATE_TEXTUREMAPBLEND
:
2872 This
->legacyTextureBlending
= TRUE
;
2874 switch ( (D3DTEXTUREBLEND
) Value
)
2876 case D3DTBLEND_MODULATE
:
2878 struct wined3d_texture
*tex
= NULL
;
2879 BOOL tex_alpha
= FALSE
;
2880 DDPIXELFORMAT ddfmt
;
2882 hr
= wined3d_device_get_texture(This
->wined3d_device
, 0, &tex
);
2884 if(hr
== WINED3D_OK
&& tex
)
2886 struct wined3d_resource
*sub_resource
;
2888 if ((sub_resource
= wined3d_texture_get_sub_resource(tex
, 0)))
2890 struct wined3d_resource_desc desc
;
2892 wined3d_resource_get_desc(sub_resource
, &desc
);
2893 ddfmt
.dwSize
= sizeof(ddfmt
);
2894 PixelFormat_WineD3DtoDD(&ddfmt
, desc
.format
);
2895 if (ddfmt
.u5
.dwRGBAlphaBitMask
) tex_alpha
= TRUE
;
2898 wined3d_texture_decref(tex
);
2902 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2903 0, WINED3D_TSS_ALPHA_OP
, WINED3D_TOP_SELECT_ARG1
);
2905 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2906 0, WINED3D_TSS_ALPHA_OP
, WINED3D_TOP_SELECT_ARG2
);
2907 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2908 0, WINED3D_TSS_ALPHA_ARG1
, WINED3DTA_TEXTURE
);
2909 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2910 0, WINED3D_TSS_ALPHA_ARG2
, WINED3DTA_CURRENT
);
2911 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2912 0, WINED3D_TSS_COLOR_ARG1
, WINED3DTA_TEXTURE
);
2913 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2914 0, WINED3D_TSS_COLOR_ARG2
, WINED3DTA_CURRENT
);
2915 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2916 0, WINED3D_TSS_COLOR_OP
, WINED3D_TOP_MODULATE
);
2921 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2922 0, WINED3D_TSS_COLOR_OP
, WINED3D_TOP_ADD
);
2923 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2924 0, WINED3D_TSS_COLOR_ARG1
, WINED3DTA_TEXTURE
);
2925 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2926 0, WINED3D_TSS_COLOR_ARG2
, WINED3DTA_CURRENT
);
2927 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2928 0, WINED3D_TSS_ALPHA_OP
, WINED3D_TOP_SELECT_ARG2
);
2929 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2930 0, WINED3D_TSS_ALPHA_ARG2
, WINED3DTA_CURRENT
);
2933 case D3DTBLEND_MODULATEALPHA
:
2934 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2935 0, WINED3D_TSS_COLOR_ARG1
, WINED3DTA_TEXTURE
);
2936 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2937 0, WINED3D_TSS_ALPHA_ARG1
, WINED3DTA_TEXTURE
);
2938 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2939 0, WINED3D_TSS_COLOR_ARG2
, WINED3DTA_CURRENT
);
2940 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2941 0, WINED3D_TSS_ALPHA_ARG2
, WINED3DTA_CURRENT
);
2942 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2943 0, WINED3D_TSS_COLOR_OP
, WINED3D_TOP_MODULATE
);
2944 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2945 0, WINED3D_TSS_ALPHA_OP
, WINED3D_TOP_MODULATE
);
2948 case D3DTBLEND_COPY
:
2949 case D3DTBLEND_DECAL
:
2950 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2951 0, WINED3D_TSS_COLOR_ARG1
, WINED3DTA_TEXTURE
);
2952 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2953 0, WINED3D_TSS_ALPHA_ARG1
, WINED3DTA_TEXTURE
);
2954 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2955 0, WINED3D_TSS_COLOR_OP
, WINED3D_TOP_SELECT_ARG1
);
2956 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2957 0, WINED3D_TSS_ALPHA_OP
, WINED3D_TOP_SELECT_ARG1
);
2960 case D3DTBLEND_DECALALPHA
:
2961 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2962 0, WINED3D_TSS_COLOR_OP
, WINED3D_TOP_BLEND_TEXTURE_ALPHA
);
2963 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2964 0, WINED3D_TSS_COLOR_ARG1
, WINED3DTA_TEXTURE
);
2965 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2966 0, WINED3D_TSS_COLOR_ARG2
, WINED3DTA_CURRENT
);
2967 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2968 0, WINED3D_TSS_ALPHA_OP
, WINED3D_TOP_SELECT_ARG2
);
2969 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2970 0, WINED3D_TSS_ALPHA_ARG2
, WINED3DTA_CURRENT
);
2974 ERR("Unhandled texture environment %d !\n",Value
);
2982 hr
= IDirect3DDevice7_SetRenderState(&This
->IDirect3DDevice7_iface
, RenderStateType
, Value
);
2985 wined3d_mutex_unlock();
2990 static HRESULT WINAPI
IDirect3DDeviceImpl_2_SetRenderState(IDirect3DDevice2
*iface
,
2991 D3DRENDERSTATETYPE RenderStateType
, DWORD Value
)
2993 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
2995 TRACE("iface %p, state %#x, value %#x.\n", iface
, RenderStateType
, Value
);
2997 return IDirect3DDevice3_SetRenderState(&This
->IDirect3DDevice3_iface
, RenderStateType
, Value
);
3000 /*****************************************************************************
3001 * Direct3DDevice3::SetLightState
3003 * Sets a light state for Direct3DDevice3 and Direct3DDevice2. The
3004 * light states are forwarded to Direct3DDevice7 render states
3009 * LightStateType: The light state to change
3010 * Value: The value to assign to that light state
3014 * DDERR_INVALIDPARAMS if the parameters were incorrect
3015 * Also check IDirect3DDevice7::SetRenderState
3017 *****************************************************************************/
3018 static HRESULT WINAPI
3019 IDirect3DDeviceImpl_3_SetLightState(IDirect3DDevice3
*iface
,
3020 D3DLIGHTSTATETYPE LightStateType
,
3023 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
3026 TRACE("iface %p, state %#x, value %#x.\n", iface
, LightStateType
, Value
);
3028 if (!LightStateType
|| (LightStateType
> D3DLIGHTSTATE_COLORVERTEX
))
3030 TRACE("Unexpected Light State Type\n");
3031 return DDERR_INVALIDPARAMS
;
3034 wined3d_mutex_lock();
3035 if (LightStateType
== D3DLIGHTSTATE_MATERIAL
/* 1 */)
3037 IDirect3DMaterialImpl
*m
= ddraw_get_object(&This
->handle_table
, Value
- 1, DDRAW_HANDLE_MATERIAL
);
3040 WARN("Invalid material handle.\n");
3041 wined3d_mutex_unlock();
3042 return DDERR_INVALIDPARAMS
;
3045 TRACE(" activating material %p.\n", m
);
3046 material_activate(m
);
3048 This
->material
= Value
;
3050 else if (LightStateType
== D3DLIGHTSTATE_COLORMODEL
/* 3 */)
3055 ERR("DDCOLOR_MONO should not happen!\n");
3058 /* We are already in this mode */
3059 TRACE("Setting color model to RGB (no-op).\n");
3062 ERR("Unknown color model!\n");
3063 wined3d_mutex_unlock();
3064 return DDERR_INVALIDPARAMS
;
3069 D3DRENDERSTATETYPE rs
;
3070 switch (LightStateType
)
3072 case D3DLIGHTSTATE_AMBIENT
: /* 2 */
3073 rs
= D3DRENDERSTATE_AMBIENT
;
3075 case D3DLIGHTSTATE_FOGMODE
: /* 4 */
3076 rs
= D3DRENDERSTATE_FOGVERTEXMODE
;
3078 case D3DLIGHTSTATE_FOGSTART
: /* 5 */
3079 rs
= D3DRENDERSTATE_FOGSTART
;
3081 case D3DLIGHTSTATE_FOGEND
: /* 6 */
3082 rs
= D3DRENDERSTATE_FOGEND
;
3084 case D3DLIGHTSTATE_FOGDENSITY
: /* 7 */
3085 rs
= D3DRENDERSTATE_FOGDENSITY
;
3087 case D3DLIGHTSTATE_COLORVERTEX
: /* 8 */
3088 rs
= D3DRENDERSTATE_COLORVERTEX
;
3091 ERR("Unknown D3DLIGHTSTATETYPE %d.\n", LightStateType
);
3092 wined3d_mutex_unlock();
3093 return DDERR_INVALIDPARAMS
;
3096 hr
= IDirect3DDevice7_SetRenderState(&This
->IDirect3DDevice7_iface
, rs
, Value
);
3097 wined3d_mutex_unlock();
3100 wined3d_mutex_unlock();
3105 static HRESULT WINAPI
IDirect3DDeviceImpl_2_SetLightState(IDirect3DDevice2
*iface
,
3106 D3DLIGHTSTATETYPE LightStateType
, DWORD Value
)
3108 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
3110 TRACE("iface %p, state %#x, value %#x.\n", iface
, LightStateType
, Value
);
3112 return IDirect3DDevice3_SetLightState(&This
->IDirect3DDevice3_iface
, LightStateType
, Value
);
3115 /*****************************************************************************
3116 * IDirect3DDevice3::GetLightState
3118 * Returns the current setting of a light state. The state is read from
3119 * the Direct3DDevice7 render state.
3124 * LightStateType: The light state to return
3125 * Value: The address to store the light state setting at
3129 * DDDERR_INVALIDPARAMS if the parameters were incorrect
3130 * Also see IDirect3DDevice7::GetRenderState
3132 *****************************************************************************/
3133 static HRESULT WINAPI
3134 IDirect3DDeviceImpl_3_GetLightState(IDirect3DDevice3
*iface
,
3135 D3DLIGHTSTATETYPE LightStateType
,
3138 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
3141 TRACE("iface %p, state %#x, value %p.\n", iface
, LightStateType
, Value
);
3143 if (!LightStateType
|| (LightStateType
> D3DLIGHTSTATE_COLORVERTEX
))
3145 TRACE("Unexpected Light State Type\n");
3146 return DDERR_INVALIDPARAMS
;
3150 return DDERR_INVALIDPARAMS
;
3152 wined3d_mutex_lock();
3153 if (LightStateType
== D3DLIGHTSTATE_MATERIAL
/* 1 */)
3155 *Value
= This
->material
;
3157 else if (LightStateType
== D3DLIGHTSTATE_COLORMODEL
/* 3 */)
3159 *Value
= D3DCOLOR_RGB
;
3163 D3DRENDERSTATETYPE rs
;
3164 switch (LightStateType
)
3166 case D3DLIGHTSTATE_AMBIENT
: /* 2 */
3167 rs
= D3DRENDERSTATE_AMBIENT
;
3169 case D3DLIGHTSTATE_FOGMODE
: /* 4 */
3170 rs
= D3DRENDERSTATE_FOGVERTEXMODE
;
3172 case D3DLIGHTSTATE_FOGSTART
: /* 5 */
3173 rs
= D3DRENDERSTATE_FOGSTART
;
3175 case D3DLIGHTSTATE_FOGEND
: /* 6 */
3176 rs
= D3DRENDERSTATE_FOGEND
;
3178 case D3DLIGHTSTATE_FOGDENSITY
: /* 7 */
3179 rs
= D3DRENDERSTATE_FOGDENSITY
;
3181 case D3DLIGHTSTATE_COLORVERTEX
: /* 8 */
3182 rs
= D3DRENDERSTATE_COLORVERTEX
;
3185 ERR("Unknown D3DLIGHTSTATETYPE %d.\n", LightStateType
);
3186 wined3d_mutex_unlock();
3187 return DDERR_INVALIDPARAMS
;
3190 hr
= IDirect3DDevice7_GetRenderState(&This
->IDirect3DDevice7_iface
, rs
, Value
);
3191 wined3d_mutex_unlock();
3194 wined3d_mutex_unlock();
3199 static HRESULT WINAPI
IDirect3DDeviceImpl_2_GetLightState(IDirect3DDevice2
*iface
,
3200 D3DLIGHTSTATETYPE LightStateType
, DWORD
*Value
)
3202 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
3204 TRACE("iface %p, state %#x, value %p.\n", iface
, LightStateType
, Value
);
3206 return IDirect3DDevice3_GetLightState(&This
->IDirect3DDevice3_iface
, LightStateType
, Value
);
3209 /*****************************************************************************
3210 * IDirect3DDevice7::SetTransform
3212 * Assigns a D3DMATRIX to a transform type. The transform types are defined
3213 * in include/d3dtypes.h.
3214 * The D3DTRANSFORMSTATE_WORLD (=1) is translated to D3DTS_WORLDMATRIX(0)
3215 * (=255) for wined3d, because the 1 transform state was removed in d3d8
3216 * and WineD3D already understands the replacement D3DTS_WORLDMATRIX(0)
3218 * Version 2, 3 and 7
3221 * TransformStateType: transform state to set
3222 * Matrix: Matrix to assign to the state
3226 * DDERR_INVALIDPARAMS if Matrix == NULL
3227 * For details see IWineD3DDevice::SetTransform
3229 *****************************************************************************/
3231 IDirect3DDeviceImpl_7_SetTransform(IDirect3DDevice7
*iface
,
3232 D3DTRANSFORMSTATETYPE TransformStateType
,
3235 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
3236 D3DTRANSFORMSTATETYPE type
;
3239 TRACE("iface %p, state %#x, matrix %p.\n", iface
, TransformStateType
, Matrix
);
3241 switch (TransformStateType
)
3243 case D3DTRANSFORMSTATE_WORLD
:
3244 type
= WINED3D_TS_WORLD_MATRIX(0);
3246 case D3DTRANSFORMSTATE_WORLD1
:
3247 type
= WINED3D_TS_WORLD_MATRIX(1);
3249 case D3DTRANSFORMSTATE_WORLD2
:
3250 type
= WINED3D_TS_WORLD_MATRIX(2);
3252 case D3DTRANSFORMSTATE_WORLD3
:
3253 type
= WINED3D_TS_WORLD_MATRIX(3);
3256 type
= TransformStateType
;
3260 return DDERR_INVALIDPARAMS
;
3262 /* Note: D3DMATRIX is compatible with struct wined3d_matrix. */
3263 wined3d_mutex_lock();
3264 hr
= wined3d_device_set_transform(This
->wined3d_device
, type
, (struct wined3d_matrix
*)Matrix
);
3265 wined3d_mutex_unlock();
3270 static HRESULT WINAPI
3271 IDirect3DDeviceImpl_7_SetTransform_FPUSetup(IDirect3DDevice7
*iface
,
3272 D3DTRANSFORMSTATETYPE TransformStateType
,
3275 return IDirect3DDeviceImpl_7_SetTransform(iface
, TransformStateType
, Matrix
);
3278 static HRESULT WINAPI
3279 IDirect3DDeviceImpl_7_SetTransform_FPUPreserve(IDirect3DDevice7
*iface
,
3280 D3DTRANSFORMSTATETYPE TransformStateType
,
3286 old_fpucw
= d3d_fpu_setup();
3287 hr
= IDirect3DDeviceImpl_7_SetTransform(iface
, TransformStateType
, Matrix
);
3288 set_fpu_control_word(old_fpucw
);
3293 static HRESULT WINAPI
IDirect3DDeviceImpl_3_SetTransform(IDirect3DDevice3
*iface
,
3294 D3DTRANSFORMSTATETYPE state
, D3DMATRIX
*matrix
)
3296 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
3298 TRACE("iface %p, state %#x, matrix %p.\n", iface
, state
, matrix
);
3301 return DDERR_INVALIDPARAMS
;
3303 if (state
== D3DTRANSFORMSTATE_PROJECTION
)
3305 D3DMATRIX projection
;
3308 wined3d_mutex_lock();
3309 multiply_matrix(&projection
, &This
->legacy_clipspace
, matrix
);
3310 hr
= wined3d_device_set_transform(This
->wined3d_device
,
3311 WINED3D_TS_PROJECTION
, (struct wined3d_matrix
*)&projection
);
3313 This
->legacy_projection
= *matrix
;
3314 wined3d_mutex_unlock();
3319 return IDirect3DDevice7_SetTransform(&This
->IDirect3DDevice7_iface
, state
, matrix
);
3322 static HRESULT WINAPI
IDirect3DDeviceImpl_2_SetTransform(IDirect3DDevice2
*iface
,
3323 D3DTRANSFORMSTATETYPE TransformStateType
, D3DMATRIX
*D3DMatrix
)
3325 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
3327 TRACE("iface %p, state %#x, matrix %p.\n", iface
, TransformStateType
, D3DMatrix
);
3329 return IDirect3DDevice7_SetTransform(&This
->IDirect3DDevice7_iface
, TransformStateType
, D3DMatrix
);
3332 /*****************************************************************************
3333 * IDirect3DDevice7::GetTransform
3335 * Returns the matrix assigned to a transform state
3336 * D3DTRANSFORMSTATE_WORLD is translated to D3DTS_WORLDMATRIX(0), see
3340 * TransformStateType: State to read the matrix from
3341 * Matrix: Address to store the matrix at
3345 * DDERR_INVALIDPARAMS if Matrix == NULL
3346 * For details, see IWineD3DDevice::GetTransform
3348 *****************************************************************************/
3350 IDirect3DDeviceImpl_7_GetTransform(IDirect3DDevice7
*iface
,
3351 D3DTRANSFORMSTATETYPE TransformStateType
,
3354 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
3355 D3DTRANSFORMSTATETYPE type
;
3358 TRACE("iface %p, state %#x, matrix %p.\n", iface
, TransformStateType
, Matrix
);
3360 switch(TransformStateType
)
3362 case D3DTRANSFORMSTATE_WORLD
:
3363 type
= WINED3D_TS_WORLD_MATRIX(0);
3365 case D3DTRANSFORMSTATE_WORLD1
:
3366 type
= WINED3D_TS_WORLD_MATRIX(1);
3368 case D3DTRANSFORMSTATE_WORLD2
:
3369 type
= WINED3D_TS_WORLD_MATRIX(2);
3371 case D3DTRANSFORMSTATE_WORLD3
:
3372 type
= WINED3D_TS_WORLD_MATRIX(3);
3375 type
= TransformStateType
;
3379 return DDERR_INVALIDPARAMS
;
3381 /* Note: D3DMATRIX is compatible with struct wined3d_matrix. */
3382 wined3d_mutex_lock();
3383 hr
= wined3d_device_get_transform(This
->wined3d_device
, type
, (struct wined3d_matrix
*)Matrix
);
3384 wined3d_mutex_unlock();
3389 static HRESULT WINAPI
3390 IDirect3DDeviceImpl_7_GetTransform_FPUSetup(IDirect3DDevice7
*iface
,
3391 D3DTRANSFORMSTATETYPE TransformStateType
,
3394 return IDirect3DDeviceImpl_7_GetTransform(iface
, TransformStateType
, Matrix
);
3397 static HRESULT WINAPI
3398 IDirect3DDeviceImpl_7_GetTransform_FPUPreserve(IDirect3DDevice7
*iface
,
3399 D3DTRANSFORMSTATETYPE TransformStateType
,
3405 old_fpucw
= d3d_fpu_setup();
3406 hr
= IDirect3DDeviceImpl_7_GetTransform(iface
, TransformStateType
, Matrix
);
3407 set_fpu_control_word(old_fpucw
);
3412 static HRESULT WINAPI
IDirect3DDeviceImpl_3_GetTransform(IDirect3DDevice3
*iface
,
3413 D3DTRANSFORMSTATETYPE state
, D3DMATRIX
*matrix
)
3415 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
3417 TRACE("iface %p, state %#x, matrix %p.\n", iface
, state
, matrix
);
3420 return DDERR_INVALIDPARAMS
;
3422 if (state
== D3DTRANSFORMSTATE_PROJECTION
)
3424 wined3d_mutex_lock();
3425 *matrix
= This
->legacy_projection
;
3426 wined3d_mutex_unlock();
3430 return IDirect3DDevice7_GetTransform(&This
->IDirect3DDevice7_iface
, state
, matrix
);
3433 static HRESULT WINAPI
IDirect3DDeviceImpl_2_GetTransform(IDirect3DDevice2
*iface
,
3434 D3DTRANSFORMSTATETYPE TransformStateType
, D3DMATRIX
*D3DMatrix
)
3436 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
3438 TRACE("iface %p, state %#x, matrix %p.\n", iface
, TransformStateType
, D3DMatrix
);
3440 return IDirect3DDevice7_GetTransform(&This
->IDirect3DDevice7_iface
, TransformStateType
, D3DMatrix
);
3443 /*****************************************************************************
3444 * IDirect3DDevice7::MultiplyTransform
3446 * Multiplies the already-set transform matrix of a transform state
3447 * with another matrix. For the world matrix, see SetTransform
3449 * Version 2, 3 and 7
3452 * TransformStateType: Transform state to multiply
3453 * D3DMatrix Matrix to multiply with.
3457 * DDERR_INVALIDPARAMS if D3DMatrix is NULL
3458 * For details, see IWineD3DDevice::MultiplyTransform
3460 *****************************************************************************/
3462 IDirect3DDeviceImpl_7_MultiplyTransform(IDirect3DDevice7
*iface
,
3463 D3DTRANSFORMSTATETYPE TransformStateType
,
3464 D3DMATRIX
*D3DMatrix
)
3466 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
3468 D3DTRANSFORMSTATETYPE type
;
3470 TRACE("iface %p, state %#x, matrix %p.\n", iface
, TransformStateType
, D3DMatrix
);
3472 switch(TransformStateType
)
3474 case D3DTRANSFORMSTATE_WORLD
:
3475 type
= WINED3D_TS_WORLD_MATRIX(0);
3477 case D3DTRANSFORMSTATE_WORLD1
:
3478 type
= WINED3D_TS_WORLD_MATRIX(1);
3480 case D3DTRANSFORMSTATE_WORLD2
:
3481 type
= WINED3D_TS_WORLD_MATRIX(2);
3483 case D3DTRANSFORMSTATE_WORLD3
:
3484 type
= WINED3D_TS_WORLD_MATRIX(3);
3487 type
= TransformStateType
;
3490 /* Note: D3DMATRIX is compatible with struct wined3d_matrix. */
3491 wined3d_mutex_lock();
3492 hr
= wined3d_device_multiply_transform(This
->wined3d_device
,
3493 type
, (struct wined3d_matrix
*)D3DMatrix
);
3494 wined3d_mutex_unlock();
3499 static HRESULT WINAPI
3500 IDirect3DDeviceImpl_7_MultiplyTransform_FPUSetup(IDirect3DDevice7
*iface
,
3501 D3DTRANSFORMSTATETYPE TransformStateType
,
3502 D3DMATRIX
*D3DMatrix
)
3504 return IDirect3DDeviceImpl_7_MultiplyTransform(iface
, TransformStateType
, D3DMatrix
);
3507 static HRESULT WINAPI
3508 IDirect3DDeviceImpl_7_MultiplyTransform_FPUPreserve(IDirect3DDevice7
*iface
,
3509 D3DTRANSFORMSTATETYPE TransformStateType
,
3510 D3DMATRIX
*D3DMatrix
)
3515 old_fpucw
= d3d_fpu_setup();
3516 hr
= IDirect3DDeviceImpl_7_MultiplyTransform(iface
, TransformStateType
, D3DMatrix
);
3517 set_fpu_control_word(old_fpucw
);
3522 static HRESULT WINAPI
IDirect3DDeviceImpl_3_MultiplyTransform(IDirect3DDevice3
*iface
,
3523 D3DTRANSFORMSTATETYPE state
, D3DMATRIX
*matrix
)
3525 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
3527 TRACE("iface %p, state %#x, matrix %p.\n", iface
, state
, matrix
);
3529 if (state
== D3DTRANSFORMSTATE_PROJECTION
)
3531 D3DMATRIX projection
, tmp
;
3534 wined3d_mutex_lock();
3535 multiply_matrix(&tmp
, &This
->legacy_projection
, matrix
);
3536 multiply_matrix(&projection
, &This
->legacy_clipspace
, &tmp
);
3537 hr
= wined3d_device_set_transform(This
->wined3d_device
,
3538 WINED3D_TS_PROJECTION
, (struct wined3d_matrix
*)&projection
);
3540 This
->legacy_projection
= tmp
;
3541 wined3d_mutex_unlock();
3546 return IDirect3DDevice7_MultiplyTransform(&This
->IDirect3DDevice7_iface
, state
, matrix
);
3549 static HRESULT WINAPI
IDirect3DDeviceImpl_2_MultiplyTransform(IDirect3DDevice2
*iface
,
3550 D3DTRANSFORMSTATETYPE TransformStateType
, D3DMATRIX
*D3DMatrix
)
3552 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
3554 TRACE("iface %p, state %#x, matrix %p.\n", iface
, TransformStateType
, D3DMatrix
);
3556 return IDirect3DDevice7_MultiplyTransform(&This
->IDirect3DDevice7_iface
, TransformStateType
, D3DMatrix
);
3559 /*****************************************************************************
3560 * IDirect3DDevice7::DrawPrimitive
3562 * Draws primitives based on vertices in an application-provided pointer
3564 * Version 2, 3 and 7. The IDirect3DDevice2 thunk converts the fixed vertex type into
3565 * an FVF format for D3D7
3568 * PrimitiveType: The type of the primitives to draw
3569 * Vertex type: Flexible vertex format vertex description
3570 * Vertices: Pointer to the vertex array
3571 * VertexCount: The number of vertices to draw
3572 * Flags: As usual a few flags
3576 * DDERR_INVALIDPARAMS if Vertices is NULL
3577 * For details, see IWineD3DDevice::DrawPrimitiveUP
3579 *****************************************************************************/
3581 IDirect3DDeviceImpl_7_DrawPrimitive(IDirect3DDevice7
*iface
,
3582 D3DPRIMITIVETYPE PrimitiveType
,
3588 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
3592 TRACE("iface %p, primitive_type %#x, FVF %#x, vertices %p, vertex_count %u, flags %#x.\n",
3593 iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Flags
);
3596 return DDERR_INVALIDPARAMS
;
3598 /* Get the stride */
3599 stride
= get_flexible_vertex_size(VertexType
);
3602 wined3d_mutex_lock();
3603 hr
= wined3d_device_set_vertex_declaration(This
->wined3d_device
, ddraw_find_decl(This
->ddraw
, VertexType
));
3606 wined3d_mutex_unlock();
3610 /* This method translates to the user pointer draw of WineD3D */
3611 wined3d_device_set_primitive_type(This
->wined3d_device
, PrimitiveType
);
3612 hr
= wined3d_device_draw_primitive_up(This
->wined3d_device
, VertexCount
, Vertices
, stride
);
3613 wined3d_mutex_unlock();
3618 static HRESULT WINAPI
3619 IDirect3DDeviceImpl_7_DrawPrimitive_FPUSetup(IDirect3DDevice7
*iface
,
3620 D3DPRIMITIVETYPE PrimitiveType
,
3626 return IDirect3DDeviceImpl_7_DrawPrimitive(iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Flags
);
3629 static HRESULT WINAPI
3630 IDirect3DDeviceImpl_7_DrawPrimitive_FPUPreserve(IDirect3DDevice7
*iface
,
3631 D3DPRIMITIVETYPE PrimitiveType
,
3640 old_fpucw
= d3d_fpu_setup();
3641 hr
= IDirect3DDeviceImpl_7_DrawPrimitive(iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Flags
);
3642 set_fpu_control_word(old_fpucw
);
3647 static HRESULT WINAPI
IDirect3DDeviceImpl_3_DrawPrimitive(IDirect3DDevice3
*iface
,
3648 D3DPRIMITIVETYPE PrimitiveType
, DWORD VertexType
, void *Vertices
, DWORD VertexCount
,
3651 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
3652 TRACE("iface %p, primitive_type %#x, FVF %#x, vertices %p, vertex_count %u, flags %#x.\n",
3653 iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Flags
);
3655 return IDirect3DDevice7_DrawPrimitive(&This
->IDirect3DDevice7_iface
,
3656 PrimitiveType
, VertexType
, Vertices
, VertexCount
, Flags
);
3659 static HRESULT WINAPI
IDirect3DDeviceImpl_2_DrawPrimitive(IDirect3DDevice2
*iface
,
3660 D3DPRIMITIVETYPE PrimitiveType
, D3DVERTEXTYPE VertexType
, void *Vertices
,
3661 DWORD VertexCount
, DWORD Flags
)
3663 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
3666 TRACE("iface %p, primitive_type %#x, vertex_type %#x, vertices %p, vertex_count %u, flags %#x.\n",
3667 iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Flags
);
3671 case D3DVT_VERTEX
: FVF
= D3DFVF_VERTEX
; break;
3672 case D3DVT_LVERTEX
: FVF
= D3DFVF_LVERTEX
; break;
3673 case D3DVT_TLVERTEX
: FVF
= D3DFVF_TLVERTEX
; break;
3675 ERR("Unexpected vertex type %d\n", VertexType
);
3676 return DDERR_INVALIDPARAMS
; /* Should never happen */
3679 return IDirect3DDevice7_DrawPrimitive(&This
->IDirect3DDevice7_iface
,
3680 PrimitiveType
, FVF
, Vertices
, VertexCount
, Flags
);
3683 /*****************************************************************************
3684 * IDirect3DDevice7::DrawIndexedPrimitive
3686 * Draws vertices from an application-provided pointer, based on the index
3687 * numbers in a WORD array.
3689 * Version 2, 3 and 7. The version 7 thunk translates the vertex type into
3690 * an FVF format for D3D7
3693 * PrimitiveType: The primitive type to draw
3694 * VertexType: The FVF vertex description
3695 * Vertices: Pointer to the vertex array
3697 * Indices: Pointer to the index array
3698 * IndexCount: Number of indices = Number of vertices to draw
3699 * Flags: As usual, some flags
3703 * DDERR_INVALIDPARAMS if Vertices or Indices is NULL
3704 * For details, see IWineD3DDevice::DrawIndexedPrimitiveUP
3706 *****************************************************************************/
3708 IDirect3DDeviceImpl_7_DrawIndexedPrimitive(IDirect3DDevice7
*iface
,
3709 D3DPRIMITIVETYPE PrimitiveType
,
3717 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
3720 TRACE("iface %p, primitive_type %#x, FVF %#x, vertices %p, vertex_count %u, indices %p, index_count %u, flags %#x.\n",
3721 iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Indices
, IndexCount
, Flags
);
3723 /* Set the D3DDevice's FVF */
3724 wined3d_mutex_lock();
3725 hr
= wined3d_device_set_vertex_declaration(This
->wined3d_device
, ddraw_find_decl(This
->ddraw
, VertexType
));
3728 ERR(" (%p) Setting the FVF failed, hr = %x!\n", This
, hr
);
3729 wined3d_mutex_unlock();
3733 wined3d_device_set_primitive_type(This
->wined3d_device
, PrimitiveType
);
3734 hr
= wined3d_device_draw_indexed_primitive_up(This
->wined3d_device
, IndexCount
, Indices
,
3735 WINED3DFMT_R16_UINT
, Vertices
, get_flexible_vertex_size(VertexType
));
3736 wined3d_mutex_unlock();
3741 static HRESULT WINAPI
3742 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUSetup(IDirect3DDevice7
*iface
,
3743 D3DPRIMITIVETYPE PrimitiveType
,
3751 return IDirect3DDeviceImpl_7_DrawIndexedPrimitive(iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Indices
, IndexCount
, Flags
);
3754 static HRESULT WINAPI
3755 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUPreserve(IDirect3DDevice7
*iface
,
3756 D3DPRIMITIVETYPE PrimitiveType
,
3767 old_fpucw
= d3d_fpu_setup();
3768 hr
= IDirect3DDeviceImpl_7_DrawIndexedPrimitive(iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Indices
, IndexCount
, Flags
);
3769 set_fpu_control_word(old_fpucw
);
3774 static HRESULT WINAPI
IDirect3DDeviceImpl_3_DrawIndexedPrimitive(IDirect3DDevice3
*iface
,
3775 D3DPRIMITIVETYPE PrimitiveType
, DWORD VertexType
, void *Vertices
, DWORD VertexCount
,
3776 WORD
*Indices
, DWORD IndexCount
, DWORD Flags
)
3778 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
3779 TRACE("iface %p, primitive_type %#x, FVF %#x, vertices %p, vertex_count %u, indices %p, index_count %u, flags %#x.\n",
3780 iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Indices
, IndexCount
, Flags
);
3782 return IDirect3DDevice7_DrawIndexedPrimitive(&This
->IDirect3DDevice7_iface
,
3783 PrimitiveType
, VertexType
, Vertices
, VertexCount
, Indices
, IndexCount
, Flags
);
3786 static HRESULT WINAPI
IDirect3DDeviceImpl_2_DrawIndexedPrimitive(IDirect3DDevice2
*iface
,
3787 D3DPRIMITIVETYPE PrimitiveType
, D3DVERTEXTYPE VertexType
, void *Vertices
,
3788 DWORD VertexCount
, WORD
*Indices
, DWORD IndexCount
, DWORD Flags
)
3790 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
3793 TRACE("iface %p, primitive_type %#x, vertex_type %#x, vertices %p, vertex_count %u, indices %p, index_count %u, flags %#x.\n",
3794 iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Indices
, IndexCount
, Flags
);
3798 case D3DVT_VERTEX
: FVF
= D3DFVF_VERTEX
; break;
3799 case D3DVT_LVERTEX
: FVF
= D3DFVF_LVERTEX
; break;
3800 case D3DVT_TLVERTEX
: FVF
= D3DFVF_TLVERTEX
; break;
3802 ERR("Unexpected vertex type %d\n", VertexType
);
3803 return DDERR_INVALIDPARAMS
; /* Should never happen */
3806 return IDirect3DDevice7_DrawIndexedPrimitive(&This
->IDirect3DDevice7_iface
,
3807 PrimitiveType
, FVF
, Vertices
, VertexCount
, Indices
, IndexCount
, Flags
);
3810 /*****************************************************************************
3811 * IDirect3DDevice7::SetClipStatus
3813 * Sets the clip status. This defines things as clipping conditions and
3814 * the extents of the clipping region.
3816 * Version 2, 3 and 7
3822 * D3D_OK because it's a stub
3823 * (DDERR_INVALIDPARAMS if ClipStatus == NULL)
3825 *****************************************************************************/
3826 static HRESULT WINAPI
3827 IDirect3DDeviceImpl_7_SetClipStatus(IDirect3DDevice7
*iface
,
3828 D3DCLIPSTATUS
*ClipStatus
)
3830 FIXME("iface %p, clip_status %p stub!\n", iface
, ClipStatus
);
3832 /* D3DCLIPSTATUS and WINED3DCLIPSTATUS are different. I don't know how to convert them
3833 * Perhaps this needs a new data type and an additional IWineD3DDevice method
3835 /* return IWineD3DDevice_SetClipStatus(This->wineD3DDevice, ClipStatus);*/
3839 static HRESULT WINAPI
IDirect3DDeviceImpl_3_SetClipStatus(IDirect3DDevice3
*iface
,
3840 D3DCLIPSTATUS
*ClipStatus
)
3842 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
3843 TRACE("iface %p, clip_status %p.\n", iface
, ClipStatus
);
3845 return IDirect3DDevice7_SetClipStatus(&This
->IDirect3DDevice7_iface
, ClipStatus
);
3848 static HRESULT WINAPI
IDirect3DDeviceImpl_2_SetClipStatus(IDirect3DDevice2
*iface
,
3849 D3DCLIPSTATUS
*ClipStatus
)
3851 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
3852 TRACE("iface %p, clip_status %p.\n", iface
, ClipStatus
);
3854 return IDirect3DDevice7_SetClipStatus(&This
->IDirect3DDevice7_iface
, ClipStatus
);
3857 /*****************************************************************************
3858 * IDirect3DDevice7::GetClipStatus
3860 * Returns the clip status
3863 * ClipStatus: Address to write the clip status to
3866 * D3D_OK because it's a stub
3868 *****************************************************************************/
3869 static HRESULT WINAPI
3870 IDirect3DDeviceImpl_7_GetClipStatus(IDirect3DDevice7
*iface
,
3871 D3DCLIPSTATUS
*ClipStatus
)
3873 FIXME("iface %p, clip_status %p stub!\n", iface
, ClipStatus
);
3875 /* D3DCLIPSTATUS and WINED3DCLIPSTATUS are different. I don't know how to convert them */
3876 /* return IWineD3DDevice_GetClipStatus(This->wineD3DDevice, ClipStatus);*/
3880 static HRESULT WINAPI
IDirect3DDeviceImpl_3_GetClipStatus(IDirect3DDevice3
*iface
,
3881 D3DCLIPSTATUS
*ClipStatus
)
3883 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
3884 TRACE("iface %p, clip_status %p.\n", iface
, ClipStatus
);
3886 return IDirect3DDevice7_GetClipStatus(&This
->IDirect3DDevice7_iface
, ClipStatus
);
3889 static HRESULT WINAPI
IDirect3DDeviceImpl_2_GetClipStatus(IDirect3DDevice2
*iface
,
3890 D3DCLIPSTATUS
*ClipStatus
)
3892 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
3893 TRACE("iface %p, clip_status %p.\n", iface
, ClipStatus
);
3895 return IDirect3DDevice7_GetClipStatus(&This
->IDirect3DDevice7_iface
, ClipStatus
);
3898 /*****************************************************************************
3899 * IDirect3DDevice::DrawPrimitiveStrided
3901 * Draws vertices described by a D3DDRAWPRIMITIVESTRIDEDDATA structure.
3906 * PrimitiveType: The primitive type to draw
3907 * VertexType: The FVF description of the vertices to draw (for the stride??)
3908 * D3DDrawPrimStrideData: A D3DDRAWPRIMITIVESTRIDEDDATA structure describing
3909 * the vertex data locations
3910 * VertexCount: The number of vertices to draw
3914 * D3D_OK, because it's a stub
3915 * (DDERR_INVALIDPARAMS if D3DDrawPrimStrideData is NULL)
3916 * (For details, see IWineD3DDevice::DrawPrimitiveStrided)
3918 *****************************************************************************/
3920 IDirect3DDeviceImpl_7_DrawPrimitiveStrided(IDirect3DDevice7
*iface
,
3921 D3DPRIMITIVETYPE PrimitiveType
,
3923 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
,
3927 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
3928 struct wined3d_strided_data wined3d_strided
;
3932 TRACE("iface %p, primitive_type %#x, FVF %#x, strided_data %p, vertex_count %u, flags %#x.\n",
3933 iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Flags
);
3935 memset(&wined3d_strided
, 0, sizeof(wined3d_strided
));
3936 /* Get the strided data right. the wined3d structure is a bit bigger
3937 * Watch out: The contents of the strided data are determined by the fvf,
3938 * not by the members set in D3DDrawPrimStrideData. So it's valid
3939 * to have diffuse.lpvData set to 0xdeadbeef if the diffuse flag is
3940 * not set in the fvf.
3942 if(VertexType
& D3DFVF_POSITION_MASK
)
3944 wined3d_strided
.position
.format
= WINED3DFMT_R32G32B32_FLOAT
;
3945 wined3d_strided
.position
.data
= D3DDrawPrimStrideData
->position
.lpvData
;
3946 wined3d_strided
.position
.stride
= D3DDrawPrimStrideData
->position
.dwStride
;
3947 if (VertexType
& D3DFVF_XYZRHW
)
3949 wined3d_strided
.position
.format
= WINED3DFMT_R32G32B32A32_FLOAT
;
3950 wined3d_strided
.position_transformed
= TRUE
;
3954 wined3d_strided
.position_transformed
= FALSE
;
3958 if (VertexType
& D3DFVF_NORMAL
)
3960 wined3d_strided
.normal
.format
= WINED3DFMT_R32G32B32_FLOAT
;
3961 wined3d_strided
.normal
.data
= D3DDrawPrimStrideData
->normal
.lpvData
;
3962 wined3d_strided
.normal
.stride
= D3DDrawPrimStrideData
->normal
.dwStride
;
3965 if (VertexType
& D3DFVF_DIFFUSE
)
3967 wined3d_strided
.diffuse
.format
= WINED3DFMT_B8G8R8A8_UNORM
;
3968 wined3d_strided
.diffuse
.data
= D3DDrawPrimStrideData
->diffuse
.lpvData
;
3969 wined3d_strided
.diffuse
.stride
= D3DDrawPrimStrideData
->diffuse
.dwStride
;
3972 if (VertexType
& D3DFVF_SPECULAR
)
3974 wined3d_strided
.specular
.format
= WINED3DFMT_B8G8R8A8_UNORM
;
3975 wined3d_strided
.specular
.data
= D3DDrawPrimStrideData
->specular
.lpvData
;
3976 wined3d_strided
.specular
.stride
= D3DDrawPrimStrideData
->specular
.dwStride
;
3979 for (i
= 0; i
< GET_TEXCOUNT_FROM_FVF(VertexType
); ++i
)
3981 switch (GET_TEXCOORD_SIZE_FROM_FVF(VertexType
, i
))
3983 case 1: wined3d_strided
.tex_coords
[i
].format
= WINED3DFMT_R32_FLOAT
; break;
3984 case 2: wined3d_strided
.tex_coords
[i
].format
= WINED3DFMT_R32G32_FLOAT
; break;
3985 case 3: wined3d_strided
.tex_coords
[i
].format
= WINED3DFMT_R32G32B32_FLOAT
; break;
3986 case 4: wined3d_strided
.tex_coords
[i
].format
= WINED3DFMT_R32G32B32A32_FLOAT
; break;
3987 default: ERR("Unexpected texture coordinate size %d\n",
3988 GET_TEXCOORD_SIZE_FROM_FVF(VertexType
, i
));
3990 wined3d_strided
.tex_coords
[i
].data
= D3DDrawPrimStrideData
->textureCoords
[i
].lpvData
;
3991 wined3d_strided
.tex_coords
[i
].stride
= D3DDrawPrimStrideData
->textureCoords
[i
].dwStride
;
3994 /* WineD3D doesn't need the FVF here */
3995 wined3d_mutex_lock();
3996 wined3d_device_set_primitive_type(This
->wined3d_device
, PrimitiveType
);
3997 hr
= wined3d_device_draw_primitive_strided(This
->wined3d_device
, VertexCount
, &wined3d_strided
);
3998 wined3d_mutex_unlock();
4003 static HRESULT WINAPI
4004 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUSetup(IDirect3DDevice7
*iface
,
4005 D3DPRIMITIVETYPE PrimitiveType
,
4007 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
,
4011 return IDirect3DDeviceImpl_7_DrawPrimitiveStrided(iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Flags
);
4014 static HRESULT WINAPI
4015 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUPreserve(IDirect3DDevice7
*iface
,
4016 D3DPRIMITIVETYPE PrimitiveType
,
4018 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
,
4025 old_fpucw
= d3d_fpu_setup();
4026 hr
= IDirect3DDeviceImpl_7_DrawPrimitiveStrided(iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Flags
);
4027 set_fpu_control_word(old_fpucw
);
4032 static HRESULT WINAPI
IDirect3DDeviceImpl_3_DrawPrimitiveStrided(IDirect3DDevice3
*iface
,
4033 D3DPRIMITIVETYPE PrimitiveType
, DWORD VertexType
,
4034 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
, DWORD VertexCount
, DWORD Flags
)
4036 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
4038 TRACE("iface %p, primitive_type %#x, FVF %#x, strided_data %p, vertex_count %u, flags %#x.\n",
4039 iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Flags
);
4041 return IDirect3DDevice7_DrawPrimitiveStrided(&This
->IDirect3DDevice7_iface
,
4042 PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Flags
);
4045 /*****************************************************************************
4046 * IDirect3DDevice7::DrawIndexedPrimitiveStrided
4048 * Draws primitives specified by strided data locations based on indices
4056 * D3D_OK, because it's a stub
4057 * (DDERR_INVALIDPARAMS if D3DDrawPrimStrideData is NULL)
4058 * (DDERR_INVALIDPARAMS if Indices is NULL)
4059 * (For more details, see IWineD3DDevice::DrawIndexedPrimitiveStrided)
4061 *****************************************************************************/
4063 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided(IDirect3DDevice7
*iface
,
4064 D3DPRIMITIVETYPE PrimitiveType
,
4066 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
,
4072 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
4073 struct wined3d_strided_data wined3d_strided
;
4077 TRACE("iface %p, primitive_type %#x, FVF %#x, strided_data %p, vertex_count %u, indices %p, index_count %u, flags %#x.\n",
4078 iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Indices
, IndexCount
, Flags
);
4080 memset(&wined3d_strided
, 0, sizeof(wined3d_strided
));
4081 /* Get the strided data right. the wined3d structure is a bit bigger
4082 * Watch out: The contents of the strided data are determined by the fvf,
4083 * not by the members set in D3DDrawPrimStrideData. So it's valid
4084 * to have diffuse.lpvData set to 0xdeadbeef if the diffuse flag is
4085 * not set in the fvf. */
4086 if (VertexType
& D3DFVF_POSITION_MASK
)
4088 wined3d_strided
.position
.format
= WINED3DFMT_R32G32B32_FLOAT
;
4089 wined3d_strided
.position
.data
= D3DDrawPrimStrideData
->position
.lpvData
;
4090 wined3d_strided
.position
.stride
= D3DDrawPrimStrideData
->position
.dwStride
;
4091 if (VertexType
& D3DFVF_XYZRHW
)
4093 wined3d_strided
.position
.format
= WINED3DFMT_R32G32B32A32_FLOAT
;
4094 wined3d_strided
.position_transformed
= TRUE
;
4098 wined3d_strided
.position_transformed
= FALSE
;
4102 if (VertexType
& D3DFVF_NORMAL
)
4104 wined3d_strided
.normal
.format
= WINED3DFMT_R32G32B32_FLOAT
;
4105 wined3d_strided
.normal
.data
= D3DDrawPrimStrideData
->normal
.lpvData
;
4106 wined3d_strided
.normal
.stride
= D3DDrawPrimStrideData
->normal
.dwStride
;
4109 if (VertexType
& D3DFVF_DIFFUSE
)
4111 wined3d_strided
.diffuse
.format
= WINED3DFMT_B8G8R8A8_UNORM
;
4112 wined3d_strided
.diffuse
.data
= D3DDrawPrimStrideData
->diffuse
.lpvData
;
4113 wined3d_strided
.diffuse
.stride
= D3DDrawPrimStrideData
->diffuse
.dwStride
;
4116 if (VertexType
& D3DFVF_SPECULAR
)
4118 wined3d_strided
.specular
.format
= WINED3DFMT_B8G8R8A8_UNORM
;
4119 wined3d_strided
.specular
.data
= D3DDrawPrimStrideData
->specular
.lpvData
;
4120 wined3d_strided
.specular
.stride
= D3DDrawPrimStrideData
->specular
.dwStride
;
4123 for (i
= 0; i
< GET_TEXCOUNT_FROM_FVF(VertexType
); ++i
)
4125 switch (GET_TEXCOORD_SIZE_FROM_FVF(VertexType
, i
))
4127 case 1: wined3d_strided
.tex_coords
[i
].format
= WINED3DFMT_R32_FLOAT
; break;
4128 case 2: wined3d_strided
.tex_coords
[i
].format
= WINED3DFMT_R32G32_FLOAT
; break;
4129 case 3: wined3d_strided
.tex_coords
[i
].format
= WINED3DFMT_R32G32B32_FLOAT
; break;
4130 case 4: wined3d_strided
.tex_coords
[i
].format
= WINED3DFMT_R32G32B32A32_FLOAT
; break;
4131 default: ERR("Unexpected texture coordinate size %d\n",
4132 GET_TEXCOORD_SIZE_FROM_FVF(VertexType
, i
));
4134 wined3d_strided
.tex_coords
[i
].data
= D3DDrawPrimStrideData
->textureCoords
[i
].lpvData
;
4135 wined3d_strided
.tex_coords
[i
].stride
= D3DDrawPrimStrideData
->textureCoords
[i
].dwStride
;
4138 /* WineD3D doesn't need the FVF here */
4139 wined3d_mutex_lock();
4140 wined3d_device_set_primitive_type(This
->wined3d_device
, PrimitiveType
);
4141 hr
= wined3d_device_draw_indexed_primitive_strided(This
->wined3d_device
,
4142 IndexCount
, &wined3d_strided
, VertexCount
, Indices
, WINED3DFMT_R16_UINT
);
4143 wined3d_mutex_unlock();
4148 static HRESULT WINAPI
4149 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUSetup(IDirect3DDevice7
*iface
,
4150 D3DPRIMITIVETYPE PrimitiveType
,
4152 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
,
4158 return IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided(iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Indices
, IndexCount
, Flags
);
4161 static HRESULT WINAPI
4162 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUPreserve(IDirect3DDevice7
*iface
,
4163 D3DPRIMITIVETYPE PrimitiveType
,
4165 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
,
4174 old_fpucw
= d3d_fpu_setup();
4175 hr
= IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided(iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Indices
, IndexCount
, Flags
);
4176 set_fpu_control_word(old_fpucw
);
4181 static HRESULT WINAPI
IDirect3DDeviceImpl_3_DrawIndexedPrimitiveStrided(IDirect3DDevice3
*iface
,
4182 D3DPRIMITIVETYPE PrimitiveType
, DWORD VertexType
,
4183 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
, DWORD VertexCount
, WORD
*Indices
,
4184 DWORD IndexCount
, DWORD Flags
)
4186 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
4188 TRACE("iface %p, primitive_type %#x, FVF %#x, strided_data %p, vertex_count %u, indices %p, index_count %u, flags %#x.\n",
4189 iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Indices
, IndexCount
, Flags
);
4191 return IDirect3DDevice7_DrawIndexedPrimitiveStrided(&This
->IDirect3DDevice7_iface
,
4192 PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Indices
, IndexCount
, Flags
);
4195 /*****************************************************************************
4196 * IDirect3DDevice7::DrawPrimitiveVB
4198 * Draws primitives from a vertex buffer to the screen.
4203 * PrimitiveType: Type of primitive to be rendered.
4204 * D3DVertexBuf: Source Vertex Buffer
4205 * StartVertex: Index of the first vertex from the buffer to be rendered
4206 * NumVertices: Number of vertices to be rendered
4207 * Flags: Can be D3DDP_WAIT to wait until rendering has finished
4211 * DDERR_INVALIDPARAMS if D3DVertexBuf is NULL
4213 *****************************************************************************/
4215 IDirect3DDeviceImpl_7_DrawPrimitiveVB(IDirect3DDevice7
*iface
,
4216 D3DPRIMITIVETYPE PrimitiveType
,
4217 IDirect3DVertexBuffer7
*D3DVertexBuf
,
4222 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
4223 IDirect3DVertexBufferImpl
*vb
= unsafe_impl_from_IDirect3DVertexBuffer7(D3DVertexBuf
);
4227 TRACE("iface %p, primitive_type %#x, vb %p, start_vertex %u, vertex_count %u, flags %#x.\n",
4228 iface
, PrimitiveType
, D3DVertexBuf
, StartVertex
, NumVertices
, Flags
);
4233 ERR("(%p) No Vertex buffer specified\n", This
);
4234 return DDERR_INVALIDPARAMS
;
4236 stride
= get_flexible_vertex_size(vb
->fvf
);
4238 wined3d_mutex_lock();
4239 hr
= wined3d_device_set_vertex_declaration(This
->wined3d_device
, vb
->wineD3DVertexDeclaration
);
4242 ERR(" (%p) Setting the FVF failed, hr = %x!\n", This
, hr
);
4243 wined3d_mutex_unlock();
4247 /* Set the vertex stream source */
4248 hr
= wined3d_device_set_stream_source(This
->wined3d_device
, 0, vb
->wineD3DVertexBuffer
, 0, stride
);
4251 ERR("(%p) IDirect3DDevice::SetStreamSource failed with hr = %08x\n", This
, hr
);
4252 wined3d_mutex_unlock();
4256 /* Now draw the primitives */
4257 wined3d_device_set_primitive_type(This
->wined3d_device
, PrimitiveType
);
4258 hr
= wined3d_device_draw_primitive(This
->wined3d_device
, StartVertex
, NumVertices
);
4259 wined3d_mutex_unlock();
4264 static HRESULT WINAPI
4265 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUSetup(IDirect3DDevice7
*iface
,
4266 D3DPRIMITIVETYPE PrimitiveType
,
4267 IDirect3DVertexBuffer7
*D3DVertexBuf
,
4272 return IDirect3DDeviceImpl_7_DrawPrimitiveVB(iface
, PrimitiveType
, D3DVertexBuf
, StartVertex
, NumVertices
, Flags
);
4275 static HRESULT WINAPI
4276 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUPreserve(IDirect3DDevice7
*iface
,
4277 D3DPRIMITIVETYPE PrimitiveType
,
4278 IDirect3DVertexBuffer7
*D3DVertexBuf
,
4286 old_fpucw
= d3d_fpu_setup();
4287 hr
= IDirect3DDeviceImpl_7_DrawPrimitiveVB(iface
, PrimitiveType
, D3DVertexBuf
, StartVertex
, NumVertices
, Flags
);
4288 set_fpu_control_word(old_fpucw
);
4293 static HRESULT WINAPI
IDirect3DDeviceImpl_3_DrawPrimitiveVB(IDirect3DDevice3
*iface
,
4294 D3DPRIMITIVETYPE PrimitiveType
, IDirect3DVertexBuffer
*D3DVertexBuf
, DWORD StartVertex
,
4295 DWORD NumVertices
, DWORD Flags
)
4297 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
4298 IDirect3DVertexBufferImpl
*vb
= unsafe_impl_from_IDirect3DVertexBuffer(D3DVertexBuf
);
4300 TRACE("iface %p, primitive_type %#x, vb %p, start_vertex %u, vertex_count %u, flags %#x.\n",
4301 iface
, PrimitiveType
, D3DVertexBuf
, StartVertex
, NumVertices
, Flags
);
4303 return IDirect3DDevice7_DrawPrimitiveVB(&This
->IDirect3DDevice7_iface
,
4304 PrimitiveType
, &vb
->IDirect3DVertexBuffer7_iface
, StartVertex
, NumVertices
, Flags
);
4308 /*****************************************************************************
4309 * IDirect3DDevice7::DrawIndexedPrimitiveVB
4311 * Draws primitives from a vertex buffer to the screen
4314 * PrimitiveType: Type of primitive to be rendered.
4315 * D3DVertexBuf: Source Vertex Buffer
4316 * StartVertex: Index of the first vertex from the buffer to be rendered
4317 * NumVertices: Number of vertices to be rendered
4318 * Indices: Array of DWORDs used to index into the Vertices
4319 * IndexCount: Number of indices in Indices
4320 * Flags: Can be D3DDP_WAIT to wait until rendering has finished
4324 *****************************************************************************/
4326 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB(IDirect3DDevice7
*iface
,
4327 D3DPRIMITIVETYPE PrimitiveType
,
4328 IDirect3DVertexBuffer7
*D3DVertexBuf
,
4335 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
4336 IDirect3DVertexBufferImpl
*vb
= unsafe_impl_from_IDirect3DVertexBuffer7(D3DVertexBuf
);
4337 DWORD stride
= get_flexible_vertex_size(vb
->fvf
);
4338 struct wined3d_resource
*wined3d_resource
;
4339 struct wined3d_resource_desc desc
;
4340 WORD
*LockedIndices
;
4343 TRACE("iface %p, primitive_type %#x, vb %p, start_vertex %u, vertex_count %u, indices %p, index_count %u, flags %#x.\n",
4344 iface
, PrimitiveType
, D3DVertexBuf
, StartVertex
, NumVertices
, Indices
, IndexCount
, Flags
);
4347 * 1) Upload the Indices to the index buffer
4348 * 2) Set the index source
4349 * 3) Set the Vertex Buffer as the Stream source
4350 * 4) Call IWineD3DDevice::DrawIndexedPrimitive
4353 wined3d_mutex_lock();
4355 hr
= wined3d_device_set_vertex_declaration(This
->wined3d_device
, vb
->wineD3DVertexDeclaration
);
4358 ERR(" (%p) Setting the FVF failed, hr = %x!\n", This
, hr
);
4359 wined3d_mutex_unlock();
4363 /* check that the buffer is large enough to hold the indices,
4364 * reallocate if necessary. */
4365 wined3d_resource
= wined3d_buffer_get_resource(This
->indexbuffer
);
4366 wined3d_resource_get_desc(wined3d_resource
, &desc
);
4367 if (desc
.size
< IndexCount
* sizeof(WORD
))
4369 UINT size
= max(desc
.size
* 2, IndexCount
* sizeof(WORD
));
4370 struct wined3d_buffer
*buffer
;
4372 TRACE("Growing index buffer to %u bytes\n", size
);
4374 hr
= wined3d_buffer_create_ib(This
->wined3d_device
, size
, WINED3DUSAGE_DYNAMIC
/* Usage */,
4375 WINED3D_POOL_DEFAULT
, NULL
, &ddraw_null_wined3d_parent_ops
, &buffer
);
4378 ERR("(%p) IWineD3DDevice::CreateIndexBuffer failed with hr = %08x\n", This
, hr
);
4379 wined3d_mutex_unlock();
4383 wined3d_buffer_decref(This
->indexbuffer
);
4384 This
->indexbuffer
= buffer
;
4387 /* Copy the index stream into the index buffer. A new IWineD3DDevice
4388 * method could be created which takes an user pointer containing the
4389 * indices or a SetData-Method for the index buffer, which overrides the
4390 * index buffer data with our pointer. */
4391 hr
= wined3d_buffer_map(This
->indexbuffer
, 0, IndexCount
* sizeof(WORD
),
4392 (BYTE
**)&LockedIndices
, 0);
4395 ERR("Failed to map buffer, hr %#x.\n", hr
);
4396 wined3d_mutex_unlock();
4399 memcpy(LockedIndices
, Indices
, IndexCount
* sizeof(WORD
));
4400 wined3d_buffer_unmap(This
->indexbuffer
);
4402 /* Set the index stream */
4403 wined3d_device_set_base_vertex_index(This
->wined3d_device
, StartVertex
);
4404 hr
= wined3d_device_set_index_buffer(This
->wined3d_device
, This
->indexbuffer
, WINED3DFMT_R16_UINT
);
4406 /* Set the vertex stream source */
4407 hr
= wined3d_device_set_stream_source(This
->wined3d_device
, 0, vb
->wineD3DVertexBuffer
, 0, stride
);
4410 ERR("(%p) IDirect3DDevice::SetStreamSource failed with hr = %08x\n", This
, hr
);
4411 wined3d_mutex_unlock();
4416 wined3d_device_set_primitive_type(This
->wined3d_device
, PrimitiveType
);
4417 hr
= wined3d_device_draw_indexed_primitive(This
->wined3d_device
, 0, IndexCount
);
4419 wined3d_mutex_unlock();
4424 static HRESULT WINAPI
4425 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUSetup(IDirect3DDevice7
*iface
,
4426 D3DPRIMITIVETYPE PrimitiveType
,
4427 IDirect3DVertexBuffer7
*D3DVertexBuf
,
4434 return IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB(iface
, PrimitiveType
, D3DVertexBuf
, StartVertex
, NumVertices
, Indices
, IndexCount
, Flags
);
4437 static HRESULT WINAPI
4438 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUPreserve(IDirect3DDevice7
*iface
,
4439 D3DPRIMITIVETYPE PrimitiveType
,
4440 IDirect3DVertexBuffer7
*D3DVertexBuf
,
4450 old_fpucw
= d3d_fpu_setup();
4451 hr
= IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB(iface
, PrimitiveType
, D3DVertexBuf
, StartVertex
, NumVertices
, Indices
, IndexCount
, Flags
);
4452 set_fpu_control_word(old_fpucw
);
4457 static HRESULT WINAPI
IDirect3DDeviceImpl_3_DrawIndexedPrimitiveVB(IDirect3DDevice3
*iface
,
4458 D3DPRIMITIVETYPE PrimitiveType
, IDirect3DVertexBuffer
*D3DVertexBuf
, WORD
*Indices
,
4459 DWORD IndexCount
, DWORD Flags
)
4461 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
4462 IDirect3DVertexBufferImpl
*vb
= unsafe_impl_from_IDirect3DVertexBuffer(D3DVertexBuf
);
4464 TRACE("iface %p, primitive_type %#x, vb %p, indices %p, index_count %u, flags %#x.\n",
4465 iface
, PrimitiveType
, D3DVertexBuf
, Indices
, IndexCount
, Flags
);
4467 return IDirect3DDevice7_DrawIndexedPrimitiveVB(&This
->IDirect3DDevice7_iface
,
4468 PrimitiveType
, &vb
->IDirect3DVertexBuffer7_iface
, 0, IndexCount
, Indices
, IndexCount
,
4472 /*****************************************************************************
4473 * IDirect3DDevice7::ComputeSphereVisibility
4475 * Calculates the visibility of spheres in the current viewport. The spheres
4476 * are passed in the Centers and Radii arrays, the results are passed back
4477 * in the ReturnValues array. Return values are either completely visible,
4478 * partially visible or completely invisible.
4479 * The return value consist of a combination of D3DCLIP_* flags, or it's
4480 * 0 if the sphere is completely visible(according to the SDK, not checked)
4485 * Centers: Array containing the sphere centers
4486 * Radii: Array containing the sphere radii
4487 * NumSpheres: The number of centers and radii in the arrays
4489 * ReturnValues: Array to write the results to
4493 * (DDERR_INVALIDPARAMS if Centers, Radii or ReturnValues are NULL)
4494 * (D3DERR_INVALIDMATRIX if the combined world, view and proj matrix
4497 *****************************************************************************/
4499 static DWORD
in_plane(UINT plane
, D3DVECTOR normal
, D3DVALUE origin_plane
, D3DVECTOR center
, D3DVALUE radius
)
4501 float distance
, norm
;
4503 norm
= sqrt( normal
.u1
.x
* normal
.u1
.x
+ normal
.u2
.y
* normal
.u2
.y
+ normal
.u3
.z
* normal
.u3
.z
);
4504 distance
= ( origin_plane
+ normal
.u1
.x
* center
.u1
.x
+ normal
.u2
.y
* center
.u2
.y
+ normal
.u3
.z
* center
.u3
.z
) / norm
;
4506 if ( fabs( distance
) < radius
) return D3DSTATUS_CLIPUNIONLEFT
<< plane
;
4507 if ( distance
< -radius
) return (D3DSTATUS_CLIPUNIONLEFT
| D3DSTATUS_CLIPINTERSECTIONLEFT
) << plane
;
4511 static HRESULT WINAPI
4512 IDirect3DDeviceImpl_7_ComputeSphereVisibility(IDirect3DDevice7
*iface
,
4517 DWORD
*ReturnValues
)
4520 D3DVALUE origin_plane
[6];
4525 TRACE("iface %p, centers %p, radii %p, sphere_count %u, flags %#x, return_values %p.\n",
4526 iface
, Centers
, Radii
, NumSpheres
, Flags
, ReturnValues
);
4528 hr
= IDirect3DDeviceImpl_7_GetTransform(iface
, D3DTRANSFORMSTATE_WORLD
, &m
);
4529 if ( hr
!= DD_OK
) return DDERR_INVALIDPARAMS
;
4530 hr
= IDirect3DDeviceImpl_7_GetTransform(iface
, D3DTRANSFORMSTATE_VIEW
, &temp
);
4531 if ( hr
!= DD_OK
) return DDERR_INVALIDPARAMS
;
4532 multiply_matrix(&m
, &temp
, &m
);
4534 hr
= IDirect3DDeviceImpl_7_GetTransform(iface
, D3DTRANSFORMSTATE_PROJECTION
, &temp
);
4535 if ( hr
!= DD_OK
) return DDERR_INVALIDPARAMS
;
4536 multiply_matrix(&m
, &temp
, &m
);
4539 vec
[0].u1
.x
= m
._14
+ m
._11
;
4540 vec
[0].u2
.y
= m
._24
+ m
._21
;
4541 vec
[0].u3
.z
= m
._34
+ m
._31
;
4542 origin_plane
[0] = m
._44
+ m
._41
;
4545 vec
[1].u1
.x
= m
._14
- m
._11
;
4546 vec
[1].u2
.y
= m
._24
- m
._21
;
4547 vec
[1].u3
.z
= m
._34
- m
._31
;
4548 origin_plane
[1] = m
._44
- m
._41
;
4551 vec
[2].u1
.x
= m
._14
- m
._12
;
4552 vec
[2].u2
.y
= m
._24
- m
._22
;
4553 vec
[2].u3
.z
= m
._34
- m
._32
;
4554 origin_plane
[2] = m
._44
- m
._42
;
4557 vec
[3].u1
.x
= m
._14
+ m
._12
;
4558 vec
[3].u2
.y
= m
._24
+ m
._22
;
4559 vec
[3].u3
.z
= m
._34
+ m
._32
;
4560 origin_plane
[3] = m
._44
+ m
._42
;
4563 vec
[4].u1
.x
= m
._13
;
4564 vec
[4].u2
.y
= m
._23
;
4565 vec
[4].u3
.z
= m
._33
;
4566 origin_plane
[4] = m
._43
;
4569 vec
[5].u1
.x
= m
._14
- m
._13
;
4570 vec
[5].u2
.y
= m
._24
- m
._23
;
4571 vec
[5].u3
.z
= m
._34
- m
._33
;
4572 origin_plane
[5] = m
._44
- m
._43
;
4574 for(i
=0; i
<NumSpheres
; i
++)
4576 ReturnValues
[i
] = 0;
4577 for(j
=0; j
<6; j
++) ReturnValues
[i
] |= in_plane(j
, vec
[j
], origin_plane
[j
], Centers
[i
], Radii
[i
]);
4583 static HRESULT WINAPI
IDirect3DDeviceImpl_3_ComputeSphereVisibility(IDirect3DDevice3
*iface
,
4584 D3DVECTOR
*Centers
, D3DVALUE
*Radii
, DWORD NumSpheres
, DWORD Flags
, DWORD
*ReturnValues
)
4586 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
4588 TRACE("iface %p, centers %p, radii %p, sphere_count %u, flags %#x, return_values %p.\n",
4589 iface
, Centers
, Radii
, NumSpheres
, Flags
, ReturnValues
);
4591 return IDirect3DDevice7_ComputeSphereVisibility(&This
->IDirect3DDevice7_iface
,
4592 Centers
, Radii
, NumSpheres
, Flags
, ReturnValues
);
4595 /*****************************************************************************
4596 * IDirect3DDevice7::GetTexture
4598 * Returns the texture interface handle assigned to a texture stage.
4599 * The returned texture is AddRefed. This is taken from old ddraw,
4600 * not checked in Windows.
4605 * Stage: Texture stage to read the texture from
4606 * Texture: Address to store the interface pointer at
4610 * DDERR_INVALIDPARAMS if Texture is NULL
4611 * For details, see IWineD3DDevice::GetTexture
4613 *****************************************************************************/
4615 IDirect3DDeviceImpl_7_GetTexture(IDirect3DDevice7
*iface
,
4617 IDirectDrawSurface7
**Texture
)
4619 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
4620 struct wined3d_texture
*wined3d_texture
;
4623 TRACE("iface %p, stage %u, texture %p.\n", iface
, Stage
, Texture
);
4627 TRACE("Texture == NULL, failing with DDERR_INVALIDPARAMS\n");
4628 return DDERR_INVALIDPARAMS
;
4631 wined3d_mutex_lock();
4632 hr
= wined3d_device_get_texture(This
->wined3d_device
, Stage
, &wined3d_texture
);
4633 if (FAILED(hr
) || !wined3d_texture
)
4636 wined3d_mutex_unlock();
4640 *Texture
= wined3d_texture_get_parent(wined3d_texture
);
4641 IDirectDrawSurface7_AddRef(*Texture
);
4642 wined3d_texture_decref(wined3d_texture
);
4643 wined3d_mutex_unlock();
4648 static HRESULT WINAPI
4649 IDirect3DDeviceImpl_7_GetTexture_FPUSetup(IDirect3DDevice7
*iface
,
4651 IDirectDrawSurface7
**Texture
)
4653 return IDirect3DDeviceImpl_7_GetTexture(iface
, Stage
, Texture
);
4656 static HRESULT WINAPI
4657 IDirect3DDeviceImpl_7_GetTexture_FPUPreserve(IDirect3DDevice7
*iface
,
4659 IDirectDrawSurface7
**Texture
)
4664 old_fpucw
= d3d_fpu_setup();
4665 hr
= IDirect3DDeviceImpl_7_GetTexture(iface
, Stage
, Texture
);
4666 set_fpu_control_word(old_fpucw
);
4671 static HRESULT WINAPI
IDirect3DDeviceImpl_3_GetTexture(IDirect3DDevice3
*iface
, DWORD Stage
,
4672 IDirect3DTexture2
**Texture2
)
4674 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
4676 IDirectDrawSurface7
*ret_val
;
4677 IDirectDrawSurfaceImpl
*ret_val_impl
;
4679 TRACE("iface %p, stage %u, texture %p.\n", iface
, Stage
, Texture2
);
4681 ret
= IDirect3DDevice7_GetTexture(&This
->IDirect3DDevice7_iface
, Stage
, &ret_val
);
4683 ret_val_impl
= unsafe_impl_from_IDirectDrawSurface7(ret_val
);
4684 *Texture2
= ret_val_impl
? &ret_val_impl
->IDirect3DTexture2_iface
: NULL
;
4686 TRACE("Returning texture %p.\n", *Texture2
);
4691 /*****************************************************************************
4692 * IDirect3DDevice7::SetTexture
4694 * Assigns a texture to a texture stage. Is the texture AddRef-ed?
4699 * Stage: The stage to assign the texture to
4700 * Texture: Interface pointer to the texture surface
4704 * For details, see IWineD3DDevice::SetTexture
4706 *****************************************************************************/
4708 IDirect3DDeviceImpl_7_SetTexture(IDirect3DDevice7
*iface
,
4710 IDirectDrawSurface7
*Texture
)
4712 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
4713 IDirectDrawSurfaceImpl
*surf
= unsafe_impl_from_IDirectDrawSurface7(Texture
);
4716 TRACE("iface %p, stage %u, texture %p.\n", iface
, Stage
, Texture
);
4718 /* Texture may be NULL here */
4719 wined3d_mutex_lock();
4720 hr
= wined3d_device_set_texture(This
->wined3d_device
,
4721 Stage
, surf
? surf
->wined3d_texture
: NULL
);
4722 wined3d_mutex_unlock();
4727 static HRESULT WINAPI
4728 IDirect3DDeviceImpl_7_SetTexture_FPUSetup(IDirect3DDevice7
*iface
,
4730 IDirectDrawSurface7
*Texture
)
4732 return IDirect3DDeviceImpl_7_SetTexture(iface
, Stage
, Texture
);
4735 static HRESULT WINAPI
4736 IDirect3DDeviceImpl_7_SetTexture_FPUPreserve(IDirect3DDevice7
*iface
,
4738 IDirectDrawSurface7
*Texture
)
4743 old_fpucw
= d3d_fpu_setup();
4744 hr
= IDirect3DDeviceImpl_7_SetTexture(iface
, Stage
, Texture
);
4745 set_fpu_control_word(old_fpucw
);
4750 static HRESULT WINAPI
4751 IDirect3DDeviceImpl_3_SetTexture(IDirect3DDevice3
*iface
,
4753 IDirect3DTexture2
*Texture2
)
4755 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
4756 IDirectDrawSurfaceImpl
*tex
= unsafe_impl_from_IDirect3DTexture2(Texture2
);
4760 TRACE("iface %p, stage %u, texture %p.\n", iface
, Stage
, Texture2
);
4762 wined3d_mutex_lock();
4764 if (This
->legacyTextureBlending
)
4765 IDirect3DDevice3_GetRenderState(iface
, D3DRENDERSTATE_TEXTUREMAPBLEND
, &texmapblend
);
4767 hr
= IDirect3DDevice7_SetTexture(&This
->IDirect3DDevice7_iface
, Stage
, &tex
->IDirectDrawSurface7_iface
);
4769 if (This
->legacyTextureBlending
&& texmapblend
== D3DTBLEND_MODULATE
)
4771 /* This fixup is required by the way D3DTBLEND_MODULATE maps to texture stage states.
4772 See IDirect3DDeviceImpl_3_SetRenderState for details. */
4773 struct wined3d_texture
*tex
= NULL
;
4774 BOOL tex_alpha
= FALSE
;
4775 DDPIXELFORMAT ddfmt
;
4778 result
= wined3d_device_get_texture(This
->wined3d_device
, 0, &tex
);
4779 if (result
== WINED3D_OK
&& tex
)
4781 struct wined3d_resource
*sub_resource
;
4783 if ((sub_resource
= wined3d_texture_get_sub_resource(tex
, 0)))
4785 struct wined3d_resource_desc desc
;
4787 wined3d_resource_get_desc(sub_resource
, &desc
);
4788 ddfmt
.dwSize
= sizeof(ddfmt
);
4789 PixelFormat_WineD3DtoDD(&ddfmt
, desc
.format
);
4790 if (ddfmt
.u5
.dwRGBAlphaBitMask
) tex_alpha
= TRUE
;
4793 wined3d_texture_decref(tex
);
4796 /* Arg 1/2 are already set to WINED3DTA_TEXTURE/WINED3DTA_CURRENT in case of D3DTBLEND_MODULATE */
4798 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
4799 0, WINED3D_TSS_ALPHA_OP
, WINED3D_TOP_SELECT_ARG1
);
4801 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
4802 0, WINED3D_TSS_ALPHA_OP
, WINED3D_TOP_SELECT_ARG2
);
4805 wined3d_mutex_unlock();
4810 static const struct tss_lookup
4813 enum wined3d_texture_stage_state state
;
4817 {FALSE
, WINED3D_TSS_INVALID
}, /* 0, unused */
4818 {FALSE
, WINED3D_TSS_COLOR_OP
}, /* 1, D3DTSS_COLOROP */
4819 {FALSE
, WINED3D_TSS_COLOR_ARG1
}, /* 2, D3DTSS_COLORARG1 */
4820 {FALSE
, WINED3D_TSS_COLOR_ARG2
}, /* 3, D3DTSS_COLORARG2 */
4821 {FALSE
, WINED3D_TSS_ALPHA_OP
}, /* 4, D3DTSS_ALPHAOP */
4822 {FALSE
, WINED3D_TSS_ALPHA_ARG1
}, /* 5, D3DTSS_ALPHAARG1 */
4823 {FALSE
, WINED3D_TSS_ALPHA_ARG2
}, /* 6, D3DTSS_ALPHAARG2 */
4824 {FALSE
, WINED3D_TSS_BUMPENV_MAT00
}, /* 7, D3DTSS_BUMPENVMAT00 */
4825 {FALSE
, WINED3D_TSS_BUMPENV_MAT01
}, /* 8, D3DTSS_BUMPENVMAT01 */
4826 {FALSE
, WINED3D_TSS_BUMPENV_MAT10
}, /* 9, D3DTSS_BUMPENVMAT10 */
4827 {FALSE
, WINED3D_TSS_BUMPENV_MAT11
}, /* 10, D3DTSS_BUMPENVMAT11 */
4828 {FALSE
, WINED3D_TSS_TEXCOORD_INDEX
}, /* 11, D3DTSS_TEXCOORDINDEX */
4829 {TRUE
, WINED3D_SAMP_ADDRESS_U
}, /* 12, D3DTSS_ADDRESS */
4830 {TRUE
, WINED3D_SAMP_ADDRESS_U
}, /* 13, D3DTSS_ADDRESSU */
4831 {TRUE
, WINED3D_SAMP_ADDRESS_V
}, /* 14, D3DTSS_ADDRESSV */
4832 {TRUE
, WINED3D_SAMP_BORDER_COLOR
}, /* 15, D3DTSS_BORDERCOLOR */
4833 {TRUE
, WINED3D_SAMP_MAG_FILTER
}, /* 16, D3DTSS_MAGFILTER */
4834 {TRUE
, WINED3D_SAMP_MIN_FILTER
}, /* 17, D3DTSS_MINFILTER */
4835 {TRUE
, WINED3D_SAMP_MIP_FILTER
}, /* 18, D3DTSS_MIPFILTER */
4836 {TRUE
, WINED3D_SAMP_MIPMAP_LOD_BIAS
}, /* 19, D3DTSS_MIPMAPLODBIAS */
4837 {TRUE
, WINED3D_SAMP_MAX_MIP_LEVEL
}, /* 20, D3DTSS_MAXMIPLEVEL */
4838 {TRUE
, WINED3D_SAMP_MAX_ANISOTROPY
}, /* 21, D3DTSS_MAXANISOTROPY */
4839 {FALSE
, WINED3D_TSS_BUMPENV_LSCALE
}, /* 22, D3DTSS_BUMPENVLSCALE */
4840 {FALSE
, WINED3D_TSS_BUMPENV_LOFFSET
}, /* 23, D3DTSS_BUMPENVLOFFSET */
4841 {FALSE
, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS
}, /* 24, D3DTSS_TEXTURETRANSFORMFLAGS */
4844 /*****************************************************************************
4845 * IDirect3DDevice7::GetTextureStageState
4847 * Retrieves a state from a texture stage.
4852 * Stage: The stage to retrieve the state from
4853 * TexStageStateType: The state type to retrieve
4854 * State: Address to store the state's value at
4858 * DDERR_INVALIDPARAMS if State is NULL
4859 * For details, see IWineD3DDevice::GetTextureStageState
4861 *****************************************************************************/
4863 IDirect3DDeviceImpl_7_GetTextureStageState(IDirect3DDevice7
*iface
,
4865 D3DTEXTURESTAGESTATETYPE TexStageStateType
,
4868 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
4870 const struct tss_lookup
*l
;
4872 TRACE("iface %p, stage %u, state %#x, value %p.\n",
4873 iface
, Stage
, TexStageStateType
, State
);
4876 return DDERR_INVALIDPARAMS
;
4878 if (TexStageStateType
> D3DTSS_TEXTURETRANSFORMFLAGS
)
4880 WARN("Invalid TexStageStateType %#x passed.\n", TexStageStateType
);
4884 l
= &tss_lookup
[TexStageStateType
];
4886 wined3d_mutex_lock();
4888 if (l
->sampler_state
)
4890 hr
= wined3d_device_get_sampler_state(This
->wined3d_device
, Stage
, l
->state
, State
);
4892 switch(TexStageStateType
)
4894 /* Mipfilter is a sampler state with different values */
4895 case D3DTSS_MIPFILTER
:
4899 case WINED3D_TEXF_NONE
:
4900 *State
= D3DTFP_NONE
;
4902 case WINED3D_TEXF_POINT
:
4903 *State
= D3DTFP_POINT
;
4905 case WINED3D_TEXF_LINEAR
:
4906 *State
= D3DTFP_LINEAR
;
4909 ERR("Unexpected mipfilter value %#x\n", *State
);
4910 *State
= D3DTFP_NONE
;
4916 /* Magfilter has slightly different values */
4917 case D3DTSS_MAGFILTER
:
4921 case WINED3D_TEXF_POINT
:
4922 *State
= D3DTFG_POINT
;
4924 case WINED3D_TEXF_LINEAR
:
4925 *State
= D3DTFG_LINEAR
;
4927 case WINED3D_TEXF_ANISOTROPIC
:
4928 *State
= D3DTFG_ANISOTROPIC
;
4930 case WINED3D_TEXF_FLAT_CUBIC
:
4931 *State
= D3DTFG_FLATCUBIC
;
4933 case WINED3D_TEXF_GAUSSIAN_CUBIC
:
4934 *State
= D3DTFG_GAUSSIANCUBIC
;
4937 ERR("Unexpected wined3d mag filter value %#x\n", *State
);
4938 *State
= D3DTFG_POINT
;
4950 hr
= wined3d_device_get_texture_stage_state(This
->wined3d_device
, Stage
, l
->state
, State
);
4953 wined3d_mutex_unlock();
4958 static HRESULT WINAPI
4959 IDirect3DDeviceImpl_7_GetTextureStageState_FPUSetup(IDirect3DDevice7
*iface
,
4961 D3DTEXTURESTAGESTATETYPE TexStageStateType
,
4964 return IDirect3DDeviceImpl_7_GetTextureStageState(iface
, Stage
, TexStageStateType
, State
);
4967 static HRESULT WINAPI
4968 IDirect3DDeviceImpl_7_GetTextureStageState_FPUPreserve(IDirect3DDevice7
*iface
,
4970 D3DTEXTURESTAGESTATETYPE TexStageStateType
,
4976 old_fpucw
= d3d_fpu_setup();
4977 hr
= IDirect3DDeviceImpl_7_GetTextureStageState(iface
, Stage
, TexStageStateType
, State
);
4978 set_fpu_control_word(old_fpucw
);
4983 static HRESULT WINAPI
IDirect3DDeviceImpl_3_GetTextureStageState(IDirect3DDevice3
*iface
,
4984 DWORD Stage
, D3DTEXTURESTAGESTATETYPE TexStageStateType
, DWORD
*State
)
4986 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
4988 TRACE("iface %p, stage %u, state %#x, value %p.\n",
4989 iface
, Stage
, TexStageStateType
, State
);
4991 return IDirect3DDevice7_GetTextureStageState(&This
->IDirect3DDevice7_iface
,
4992 Stage
, TexStageStateType
, State
);
4995 /*****************************************************************************
4996 * IDirect3DDevice7::SetTextureStageState
4998 * Sets a texture stage state. Some stage types need to be handled specially,
4999 * because they do not exist in WineD3D and were moved to another place
5004 * Stage: The stage to modify
5005 * TexStageStateType: The state to change
5006 * State: The new value for the state
5010 * For details, see IWineD3DDevice::SetTextureStageState
5012 *****************************************************************************/
5014 IDirect3DDeviceImpl_7_SetTextureStageState(IDirect3DDevice7
*iface
,
5016 D3DTEXTURESTAGESTATETYPE TexStageStateType
,
5019 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
5020 const struct tss_lookup
*l
;
5023 TRACE("iface %p, stage %u, state %#x, value %#x.\n",
5024 iface
, Stage
, TexStageStateType
, State
);
5026 if (TexStageStateType
> D3DTSS_TEXTURETRANSFORMFLAGS
)
5028 WARN("Invalid TexStageStateType %#x passed.\n", TexStageStateType
);
5032 l
= &tss_lookup
[TexStageStateType
];
5034 wined3d_mutex_lock();
5036 if (l
->sampler_state
)
5038 switch(TexStageStateType
)
5040 /* Mipfilter is a sampler state with different values */
5041 case D3DTSS_MIPFILTER
:
5046 State
= WINED3D_TEXF_NONE
;
5049 State
= WINED3D_TEXF_POINT
;
5051 case 0: /* Unchecked */
5053 State
= WINED3D_TEXF_LINEAR
;
5056 ERR("Unexpected mipfilter value %d\n", State
);
5057 State
= WINED3D_TEXF_NONE
;
5063 /* Magfilter has slightly different values */
5064 case D3DTSS_MAGFILTER
:
5069 State
= WINED3D_TEXF_POINT
;
5072 State
= WINED3D_TEXF_LINEAR
;
5074 case D3DTFG_FLATCUBIC
:
5075 State
= WINED3D_TEXF_FLAT_CUBIC
;
5077 case D3DTFG_GAUSSIANCUBIC
:
5078 State
= WINED3D_TEXF_GAUSSIAN_CUBIC
;
5080 case D3DTFG_ANISOTROPIC
:
5081 State
= WINED3D_TEXF_ANISOTROPIC
;
5084 ERR("Unexpected d3d7 mag filter type %d\n", State
);
5085 State
= WINED3D_TEXF_POINT
;
5091 case D3DTSS_ADDRESS
:
5092 wined3d_device_set_sampler_state(This
->wined3d_device
, Stage
, WINED3D_SAMP_ADDRESS_V
, State
);
5099 hr
= wined3d_device_set_sampler_state(This
->wined3d_device
, Stage
, l
->state
, State
);
5103 hr
= wined3d_device_set_texture_stage_state(This
->wined3d_device
, Stage
, l
->state
, State
);
5106 wined3d_mutex_unlock();
5111 static HRESULT WINAPI
5112 IDirect3DDeviceImpl_7_SetTextureStageState_FPUSetup(IDirect3DDevice7
*iface
,
5114 D3DTEXTURESTAGESTATETYPE TexStageStateType
,
5117 return IDirect3DDeviceImpl_7_SetTextureStageState(iface
, Stage
, TexStageStateType
, State
);
5120 static HRESULT WINAPI
5121 IDirect3DDeviceImpl_7_SetTextureStageState_FPUPreserve(IDirect3DDevice7
*iface
,
5123 D3DTEXTURESTAGESTATETYPE TexStageStateType
,
5129 old_fpucw
= d3d_fpu_setup();
5130 hr
= IDirect3DDeviceImpl_7_SetTextureStageState(iface
, Stage
, TexStageStateType
, State
);
5131 set_fpu_control_word(old_fpucw
);
5136 static HRESULT WINAPI
IDirect3DDeviceImpl_3_SetTextureStageState(IDirect3DDevice3
*iface
,
5137 DWORD Stage
, D3DTEXTURESTAGESTATETYPE TexStageStateType
, DWORD State
)
5139 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
5141 TRACE("iface %p, stage %u, state %#x, value %#x.\n",
5142 iface
, Stage
, TexStageStateType
, State
);
5144 return IDirect3DDevice7_SetTextureStageState(&This
->IDirect3DDevice7_iface
,
5145 Stage
, TexStageStateType
, State
);
5148 /*****************************************************************************
5149 * IDirect3DDevice7::ValidateDevice
5151 * SDK: "Reports the device's ability to render the currently set
5152 * texture-blending operations in a single pass". Whatever that means
5158 * NumPasses: Address to write the number of necessary passes for the
5159 * desired effect to.
5163 * See IWineD3DDevice::ValidateDevice for more details
5165 *****************************************************************************/
5167 IDirect3DDeviceImpl_7_ValidateDevice(IDirect3DDevice7
*iface
,
5170 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
5173 TRACE("iface %p, pass_count %p.\n", iface
, NumPasses
);
5175 wined3d_mutex_lock();
5176 hr
= wined3d_device_validate_device(This
->wined3d_device
, NumPasses
);
5177 wined3d_mutex_unlock();
5182 static HRESULT WINAPI
5183 IDirect3DDeviceImpl_7_ValidateDevice_FPUSetup(IDirect3DDevice7
*iface
,
5186 return IDirect3DDeviceImpl_7_ValidateDevice(iface
, NumPasses
);
5189 static HRESULT WINAPI
5190 IDirect3DDeviceImpl_7_ValidateDevice_FPUPreserve(IDirect3DDevice7
*iface
,
5196 old_fpucw
= d3d_fpu_setup();
5197 hr
= IDirect3DDeviceImpl_7_ValidateDevice(iface
, NumPasses
);
5198 set_fpu_control_word(old_fpucw
);
5203 static HRESULT WINAPI
IDirect3DDeviceImpl_3_ValidateDevice(IDirect3DDevice3
*iface
, DWORD
*Passes
)
5205 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
5207 TRACE("iface %p, pass_count %p.\n", iface
, Passes
);
5209 return IDirect3DDevice7_ValidateDevice(&This
->IDirect3DDevice7_iface
, Passes
);
5212 /*****************************************************************************
5213 * IDirect3DDevice7::Clear
5215 * Fills the render target, the z buffer and the stencil buffer with a
5216 * clear color / value
5221 * Count: Number of rectangles in Rects must be 0 if Rects is NULL
5222 * Rects: Rectangles to clear. If NULL, the whole surface is cleared
5223 * Flags: Some flags, as usual
5224 * Color: Clear color for the render target
5225 * Z: Clear value for the Z buffer
5226 * Stencil: Clear value to store in each stencil buffer entry
5230 * For details, see IWineD3DDevice::Clear
5232 *****************************************************************************/
5233 static HRESULT
IDirect3DDeviceImpl_7_Clear(IDirect3DDevice7
*iface
, DWORD count
,
5234 D3DRECT
*rects
, DWORD flags
, D3DCOLOR color
, D3DVALUE z
, DWORD stencil
)
5236 const struct wined3d_color c
=
5238 ((color
>> 16) & 0xff) / 255.0f
,
5239 ((color
>> 8) & 0xff) / 255.0f
,
5240 (color
& 0xff) / 255.0f
,
5241 ((color
>> 24) & 0xff) / 255.0f
,
5243 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
5246 TRACE("iface %p, count %u, rects %p, flags %#x, color 0x%08x, z %.8e, stencil %#x.\n",
5247 iface
, count
, rects
, flags
, color
, z
, stencil
);
5249 wined3d_mutex_lock();
5250 hr
= wined3d_device_clear(This
->wined3d_device
, count
, (RECT
*)rects
, flags
, &c
, z
, stencil
);
5251 wined3d_mutex_unlock();
5256 static HRESULT WINAPI
5257 IDirect3DDeviceImpl_7_Clear_FPUSetup(IDirect3DDevice7
*iface
,
5265 return IDirect3DDeviceImpl_7_Clear(iface
, Count
, Rects
, Flags
, Color
, Z
, Stencil
);
5268 static HRESULT WINAPI
5269 IDirect3DDeviceImpl_7_Clear_FPUPreserve(IDirect3DDevice7
*iface
,
5280 old_fpucw
= d3d_fpu_setup();
5281 hr
= IDirect3DDeviceImpl_7_Clear(iface
, Count
, Rects
, Flags
, Color
, Z
, Stencil
);
5282 set_fpu_control_word(old_fpucw
);
5287 /*****************************************************************************
5288 * IDirect3DDevice7::SetViewport
5290 * Sets the current viewport.
5292 * Version 7 only, but IDirect3DViewport uses this call for older
5296 * Data: The new viewport to set
5300 * DDERR_INVALIDPARAMS if Data is NULL
5301 * For more details, see IWineDDDevice::SetViewport
5303 *****************************************************************************/
5305 IDirect3DDeviceImpl_7_SetViewport(IDirect3DDevice7
*iface
,
5308 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
5311 TRACE("iface %p, viewport %p.\n", iface
, Data
);
5314 return DDERR_INVALIDPARAMS
;
5316 /* Note: D3DVIEWPORT7 is compatible with struct wined3d_viewport. */
5317 wined3d_mutex_lock();
5318 hr
= wined3d_device_set_viewport(This
->wined3d_device
, (struct wined3d_viewport
*)Data
);
5319 wined3d_mutex_unlock();
5324 static HRESULT WINAPI
5325 IDirect3DDeviceImpl_7_SetViewport_FPUSetup(IDirect3DDevice7
*iface
,
5328 return IDirect3DDeviceImpl_7_SetViewport(iface
, Data
);
5331 static HRESULT WINAPI
5332 IDirect3DDeviceImpl_7_SetViewport_FPUPreserve(IDirect3DDevice7
*iface
,
5338 old_fpucw
= d3d_fpu_setup();
5339 hr
= IDirect3DDeviceImpl_7_SetViewport(iface
, Data
);
5340 set_fpu_control_word(old_fpucw
);
5345 /*****************************************************************************
5346 * IDirect3DDevice::GetViewport
5348 * Returns the current viewport
5353 * Data: D3D7Viewport structure to write the viewport information to
5357 * DDERR_INVALIDPARAMS if Data is NULL
5358 * For more details, see IWineD3DDevice::GetViewport
5360 *****************************************************************************/
5362 IDirect3DDeviceImpl_7_GetViewport(IDirect3DDevice7
*iface
,
5365 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
5368 TRACE("iface %p, viewport %p.\n", iface
, Data
);
5371 return DDERR_INVALIDPARAMS
;
5373 /* Note: D3DVIEWPORT7 is compatible with struct wined3d_viewport. */
5374 wined3d_mutex_lock();
5375 hr
= wined3d_device_get_viewport(This
->wined3d_device
, (struct wined3d_viewport
*)Data
);
5376 wined3d_mutex_unlock();
5378 return hr_ddraw_from_wined3d(hr
);
5381 static HRESULT WINAPI
5382 IDirect3DDeviceImpl_7_GetViewport_FPUSetup(IDirect3DDevice7
*iface
,
5385 return IDirect3DDeviceImpl_7_GetViewport(iface
, Data
);
5388 static HRESULT WINAPI
5389 IDirect3DDeviceImpl_7_GetViewport_FPUPreserve(IDirect3DDevice7
*iface
,
5395 old_fpucw
= d3d_fpu_setup();
5396 hr
= IDirect3DDeviceImpl_7_GetViewport(iface
, Data
);
5397 set_fpu_control_word(old_fpucw
);
5402 /*****************************************************************************
5403 * IDirect3DDevice7::SetMaterial
5410 * Mat: The material to set
5414 * DDERR_INVALIDPARAMS if Mat is NULL.
5415 * For more details, see IWineD3DDevice::SetMaterial
5417 *****************************************************************************/
5419 IDirect3DDeviceImpl_7_SetMaterial(IDirect3DDevice7
*iface
,
5422 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
5425 TRACE("iface %p, material %p.\n", iface
, Mat
);
5427 if (!Mat
) return DDERR_INVALIDPARAMS
;
5429 wined3d_mutex_lock();
5430 /* Note: D3DMATERIAL7 is compatible with struct wined3d_material. */
5431 hr
= wined3d_device_set_material(This
->wined3d_device
, (struct wined3d_material
*)Mat
);
5432 wined3d_mutex_unlock();
5434 return hr_ddraw_from_wined3d(hr
);
5437 static HRESULT WINAPI
5438 IDirect3DDeviceImpl_7_SetMaterial_FPUSetup(IDirect3DDevice7
*iface
,
5441 return IDirect3DDeviceImpl_7_SetMaterial(iface
, Mat
);
5444 static HRESULT WINAPI
5445 IDirect3DDeviceImpl_7_SetMaterial_FPUPreserve(IDirect3DDevice7
*iface
,
5451 old_fpucw
= d3d_fpu_setup();
5452 hr
= IDirect3DDeviceImpl_7_SetMaterial(iface
, Mat
);
5453 set_fpu_control_word(old_fpucw
);
5458 /*****************************************************************************
5459 * IDirect3DDevice7::GetMaterial
5461 * Returns the current material
5466 * Mat: D3DMATERIAL7 structure to write the material parameters to
5470 * DDERR_INVALIDPARAMS if Mat is NULL
5471 * For more details, see IWineD3DDevice::GetMaterial
5473 *****************************************************************************/
5475 IDirect3DDeviceImpl_7_GetMaterial(IDirect3DDevice7
*iface
,
5478 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
5481 TRACE("iface %p, material %p.\n", iface
, Mat
);
5483 wined3d_mutex_lock();
5484 /* Note: D3DMATERIAL7 is compatible with struct wined3d_material. */
5485 hr
= wined3d_device_get_material(This
->wined3d_device
, (struct wined3d_material
*)Mat
);
5486 wined3d_mutex_unlock();
5488 return hr_ddraw_from_wined3d(hr
);
5491 static HRESULT WINAPI
5492 IDirect3DDeviceImpl_7_GetMaterial_FPUSetup(IDirect3DDevice7
*iface
,
5495 return IDirect3DDeviceImpl_7_GetMaterial(iface
, Mat
);
5498 static HRESULT WINAPI
5499 IDirect3DDeviceImpl_7_GetMaterial_FPUPreserve(IDirect3DDevice7
*iface
,
5505 old_fpucw
= d3d_fpu_setup();
5506 hr
= IDirect3DDeviceImpl_7_GetMaterial(iface
, Mat
);
5507 set_fpu_control_word(old_fpucw
);
5512 /*****************************************************************************
5513 * IDirect3DDevice7::SetLight
5515 * Assigns a light to a light index, but doesn't activate it yet.
5517 * Version 7, IDirect3DLight uses this method for older versions
5520 * LightIndex: The index of the new light
5521 * Light: A D3DLIGHT7 structure describing the light
5525 * For more details, see IWineD3DDevice::SetLight
5527 *****************************************************************************/
5529 IDirect3DDeviceImpl_7_SetLight(IDirect3DDevice7
*iface
,
5533 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
5536 TRACE("iface %p, light_idx %u, light %p.\n", iface
, LightIndex
, Light
);
5538 wined3d_mutex_lock();
5539 /* Note: D3DLIGHT7 is compatible with struct wined3d_light. */
5540 hr
= wined3d_device_set_light(This
->wined3d_device
, LightIndex
, (struct wined3d_light
*)Light
);
5541 wined3d_mutex_unlock();
5543 return hr_ddraw_from_wined3d(hr
);
5546 static HRESULT WINAPI
5547 IDirect3DDeviceImpl_7_SetLight_FPUSetup(IDirect3DDevice7
*iface
,
5551 return IDirect3DDeviceImpl_7_SetLight(iface
, LightIndex
, Light
);
5554 static HRESULT WINAPI
5555 IDirect3DDeviceImpl_7_SetLight_FPUPreserve(IDirect3DDevice7
*iface
,
5562 old_fpucw
= d3d_fpu_setup();
5563 hr
= IDirect3DDeviceImpl_7_SetLight(iface
, LightIndex
, Light
);
5564 set_fpu_control_word(old_fpucw
);
5569 /*****************************************************************************
5570 * IDirect3DDevice7::GetLight
5572 * Returns the light assigned to a light index
5575 * Light: Structure to write the light information to
5579 * DDERR_INVALIDPARAMS if Light is NULL
5580 * For details, see IWineD3DDevice::GetLight
5582 *****************************************************************************/
5584 IDirect3DDeviceImpl_7_GetLight(IDirect3DDevice7
*iface
,
5588 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
5591 TRACE("iface %p, light_idx %u, light %p.\n", iface
, LightIndex
, Light
);
5593 wined3d_mutex_lock();
5594 /* Note: D3DLIGHT7 is compatible with struct wined3d_light. */
5595 rc
= wined3d_device_get_light(This
->wined3d_device
, LightIndex
, (struct wined3d_light
*)Light
);
5596 wined3d_mutex_unlock();
5598 /* Translate the result. WineD3D returns other values than D3D7 */
5599 return hr_ddraw_from_wined3d(rc
);
5602 static HRESULT WINAPI
5603 IDirect3DDeviceImpl_7_GetLight_FPUSetup(IDirect3DDevice7
*iface
,
5607 return IDirect3DDeviceImpl_7_GetLight(iface
, LightIndex
, Light
);
5610 static HRESULT WINAPI
5611 IDirect3DDeviceImpl_7_GetLight_FPUPreserve(IDirect3DDevice7
*iface
,
5618 old_fpucw
= d3d_fpu_setup();
5619 hr
= IDirect3DDeviceImpl_7_GetLight(iface
, LightIndex
, Light
);
5620 set_fpu_control_word(old_fpucw
);
5625 /*****************************************************************************
5626 * IDirect3DDevice7::BeginStateBlock
5628 * Begins recording to a stateblock
5634 * For details see IWineD3DDevice::BeginStateBlock
5636 *****************************************************************************/
5638 IDirect3DDeviceImpl_7_BeginStateBlock(IDirect3DDevice7
*iface
)
5640 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
5643 TRACE("iface %p.\n", iface
);
5645 wined3d_mutex_lock();
5646 hr
= wined3d_device_begin_stateblock(This
->wined3d_device
);
5647 wined3d_mutex_unlock();
5649 return hr_ddraw_from_wined3d(hr
);
5652 static HRESULT WINAPI
5653 IDirect3DDeviceImpl_7_BeginStateBlock_FPUSetup(IDirect3DDevice7
*iface
)
5655 return IDirect3DDeviceImpl_7_BeginStateBlock(iface
);
5658 static HRESULT WINAPI
5659 IDirect3DDeviceImpl_7_BeginStateBlock_FPUPreserve(IDirect3DDevice7
*iface
)
5664 old_fpucw
= d3d_fpu_setup();
5665 hr
= IDirect3DDeviceImpl_7_BeginStateBlock(iface
);
5666 set_fpu_control_word(old_fpucw
);
5671 /*****************************************************************************
5672 * IDirect3DDevice7::EndStateBlock
5674 * Stops recording to a state block and returns the created stateblock
5680 * BlockHandle: Address to store the stateblock's handle to
5684 * DDERR_INVALIDPARAMS if BlockHandle is NULL
5685 * See IWineD3DDevice::EndStateBlock for more details
5687 *****************************************************************************/
5689 IDirect3DDeviceImpl_7_EndStateBlock(IDirect3DDevice7
*iface
,
5692 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
5693 struct wined3d_stateblock
*wined3d_sb
;
5697 TRACE("iface %p, stateblock %p.\n", iface
, BlockHandle
);
5701 WARN("BlockHandle == NULL, returning DDERR_INVALIDPARAMS\n");
5702 return DDERR_INVALIDPARAMS
;
5705 wined3d_mutex_lock();
5707 hr
= wined3d_device_end_stateblock(This
->wined3d_device
, &wined3d_sb
);
5710 WARN("Failed to end stateblock, hr %#x.\n", hr
);
5711 wined3d_mutex_unlock();
5713 return hr_ddraw_from_wined3d(hr
);
5716 h
= ddraw_allocate_handle(&This
->handle_table
, wined3d_sb
, DDRAW_HANDLE_STATEBLOCK
);
5717 if (h
== DDRAW_INVALID_HANDLE
)
5719 ERR("Failed to allocate a stateblock handle.\n");
5720 wined3d_stateblock_decref(wined3d_sb
);
5721 wined3d_mutex_unlock();
5723 return DDERR_OUTOFMEMORY
;
5726 wined3d_mutex_unlock();
5727 *BlockHandle
= h
+ 1;
5729 return hr_ddraw_from_wined3d(hr
);
5732 static HRESULT WINAPI
5733 IDirect3DDeviceImpl_7_EndStateBlock_FPUSetup(IDirect3DDevice7
*iface
,
5736 return IDirect3DDeviceImpl_7_EndStateBlock(iface
, BlockHandle
);
5739 static HRESULT WINAPI
5740 IDirect3DDeviceImpl_7_EndStateBlock_FPUPreserve(IDirect3DDevice7
*iface
,
5746 old_fpucw
= d3d_fpu_setup();
5747 hr
= IDirect3DDeviceImpl_7_EndStateBlock(iface
, BlockHandle
);
5748 set_fpu_control_word(old_fpucw
);
5753 /*****************************************************************************
5754 * IDirect3DDevice7::PreLoad
5756 * Allows the app to signal that a texture will be used soon, to allow
5757 * the Direct3DDevice to load it to the video card in the meantime.
5762 * Texture: The texture to preload
5766 * DDERR_INVALIDPARAMS if Texture is NULL
5767 * See IWineD3DSurface::PreLoad for details
5769 *****************************************************************************/
5771 IDirect3DDeviceImpl_7_PreLoad(IDirect3DDevice7
*iface
,
5772 IDirectDrawSurface7
*Texture
)
5774 IDirectDrawSurfaceImpl
*surf
= unsafe_impl_from_IDirectDrawSurface7(Texture
);
5776 TRACE("iface %p, texture %p.\n", iface
, Texture
);
5779 return DDERR_INVALIDPARAMS
;
5781 wined3d_mutex_lock();
5782 wined3d_surface_preload(surf
->wined3d_surface
);
5783 wined3d_mutex_unlock();
5788 static HRESULT WINAPI
5789 IDirect3DDeviceImpl_7_PreLoad_FPUSetup(IDirect3DDevice7
*iface
,
5790 IDirectDrawSurface7
*Texture
)
5792 return IDirect3DDeviceImpl_7_PreLoad(iface
, Texture
);
5795 static HRESULT WINAPI
5796 IDirect3DDeviceImpl_7_PreLoad_FPUPreserve(IDirect3DDevice7
*iface
,
5797 IDirectDrawSurface7
*Texture
)
5802 old_fpucw
= d3d_fpu_setup();
5803 hr
= IDirect3DDeviceImpl_7_PreLoad(iface
, Texture
);
5804 set_fpu_control_word(old_fpucw
);
5809 /*****************************************************************************
5810 * IDirect3DDevice7::ApplyStateBlock
5812 * Activates the state stored in a state block handle.
5815 * BlockHandle: The stateblock handle to activate
5819 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is NULL
5821 *****************************************************************************/
5823 IDirect3DDeviceImpl_7_ApplyStateBlock(IDirect3DDevice7
*iface
,
5826 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
5827 struct wined3d_stateblock
*wined3d_sb
;
5830 TRACE("iface %p, stateblock %#x.\n", iface
, BlockHandle
);
5832 wined3d_mutex_lock();
5833 wined3d_sb
= ddraw_get_object(&This
->handle_table
, BlockHandle
- 1, DDRAW_HANDLE_STATEBLOCK
);
5836 WARN("Invalid stateblock handle.\n");
5837 wined3d_mutex_unlock();
5838 return D3DERR_INVALIDSTATEBLOCK
;
5841 hr
= wined3d_stateblock_apply(wined3d_sb
);
5842 wined3d_mutex_unlock();
5844 return hr_ddraw_from_wined3d(hr
);
5847 static HRESULT WINAPI
5848 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUSetup(IDirect3DDevice7
*iface
,
5851 return IDirect3DDeviceImpl_7_ApplyStateBlock(iface
, BlockHandle
);
5854 static HRESULT WINAPI
5855 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUPreserve(IDirect3DDevice7
*iface
,
5861 old_fpucw
= d3d_fpu_setup();
5862 hr
= IDirect3DDeviceImpl_7_ApplyStateBlock(iface
, BlockHandle
);
5863 set_fpu_control_word(old_fpucw
);
5868 /*****************************************************************************
5869 * IDirect3DDevice7::CaptureStateBlock
5871 * Updates a stateblock's values to the values currently set for the device
5876 * BlockHandle: Stateblock to update
5880 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is NULL
5881 * See IWineD3DDevice::CaptureStateBlock for more details
5883 *****************************************************************************/
5885 IDirect3DDeviceImpl_7_CaptureStateBlock(IDirect3DDevice7
*iface
,
5888 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
5889 struct wined3d_stateblock
*wined3d_sb
;
5892 TRACE("iface %p, stateblock %#x.\n", iface
, BlockHandle
);
5894 wined3d_mutex_lock();
5895 wined3d_sb
= ddraw_get_object(&This
->handle_table
, BlockHandle
- 1, DDRAW_HANDLE_STATEBLOCK
);
5898 WARN("Invalid stateblock handle.\n");
5899 wined3d_mutex_unlock();
5900 return D3DERR_INVALIDSTATEBLOCK
;
5903 hr
= wined3d_stateblock_capture(wined3d_sb
);
5904 wined3d_mutex_unlock();
5906 return hr_ddraw_from_wined3d(hr
);
5909 static HRESULT WINAPI
5910 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUSetup(IDirect3DDevice7
*iface
,
5913 return IDirect3DDeviceImpl_7_CaptureStateBlock(iface
, BlockHandle
);
5916 static HRESULT WINAPI
5917 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUPreserve(IDirect3DDevice7
*iface
,
5923 old_fpucw
= d3d_fpu_setup();
5924 hr
= IDirect3DDeviceImpl_7_CaptureStateBlock(iface
, BlockHandle
);
5925 set_fpu_control_word(old_fpucw
);
5930 /*****************************************************************************
5931 * IDirect3DDevice7::DeleteStateBlock
5933 * Deletes a stateblock handle. This means releasing the WineD3DStateBlock
5938 * BlockHandle: Stateblock handle to delete
5942 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is 0
5944 *****************************************************************************/
5946 IDirect3DDeviceImpl_7_DeleteStateBlock(IDirect3DDevice7
*iface
,
5949 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
5950 struct wined3d_stateblock
*wined3d_sb
;
5953 TRACE("iface %p, stateblock %#x.\n", iface
, BlockHandle
);
5955 wined3d_mutex_lock();
5957 wined3d_sb
= ddraw_free_handle(&This
->handle_table
, BlockHandle
- 1, DDRAW_HANDLE_STATEBLOCK
);
5960 WARN("Invalid stateblock handle.\n");
5961 wined3d_mutex_unlock();
5962 return D3DERR_INVALIDSTATEBLOCK
;
5965 if ((ref
= wined3d_stateblock_decref(wined3d_sb
)))
5967 ERR("Something is still holding stateblock %p (refcount %u).\n", wined3d_sb
, ref
);
5970 wined3d_mutex_unlock();
5975 static HRESULT WINAPI
5976 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUSetup(IDirect3DDevice7
*iface
,
5979 return IDirect3DDeviceImpl_7_DeleteStateBlock(iface
, BlockHandle
);
5982 static HRESULT WINAPI
5983 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUPreserve(IDirect3DDevice7
*iface
,
5989 old_fpucw
= d3d_fpu_setup();
5990 hr
= IDirect3DDeviceImpl_7_DeleteStateBlock(iface
, BlockHandle
);
5991 set_fpu_control_word(old_fpucw
);
5996 /*****************************************************************************
5997 * IDirect3DDevice7::CreateStateBlock
5999 * Creates a new state block handle.
6004 * Type: The state block type
6005 * BlockHandle: Address to write the created handle to
6009 * DDERR_INVALIDPARAMS if BlockHandle is NULL
6011 *****************************************************************************/
6013 IDirect3DDeviceImpl_7_CreateStateBlock(IDirect3DDevice7
*iface
,
6014 D3DSTATEBLOCKTYPE Type
,
6017 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
6018 struct wined3d_stateblock
*wined3d_sb
;
6022 TRACE("iface %p, type %#x, stateblock %p.\n", iface
, Type
, BlockHandle
);
6026 WARN("BlockHandle == NULL, returning DDERR_INVALIDPARAMS\n");
6027 return DDERR_INVALIDPARAMS
;
6029 if(Type
!= D3DSBT_ALL
&& Type
!= D3DSBT_PIXELSTATE
&&
6030 Type
!= D3DSBT_VERTEXSTATE
) {
6031 WARN("Unexpected stateblock type, returning DDERR_INVALIDPARAMS\n");
6032 return DDERR_INVALIDPARAMS
;
6035 wined3d_mutex_lock();
6037 /* The D3DSTATEBLOCKTYPE enum is fine here. */
6038 hr
= wined3d_stateblock_create(This
->wined3d_device
, Type
, &wined3d_sb
);
6041 WARN("Failed to create stateblock, hr %#x.\n", hr
);
6042 wined3d_mutex_unlock();
6043 return hr_ddraw_from_wined3d(hr
);
6046 h
= ddraw_allocate_handle(&This
->handle_table
, wined3d_sb
, DDRAW_HANDLE_STATEBLOCK
);
6047 if (h
== DDRAW_INVALID_HANDLE
)
6049 ERR("Failed to allocate stateblock handle.\n");
6050 wined3d_stateblock_decref(wined3d_sb
);
6051 wined3d_mutex_unlock();
6052 return DDERR_OUTOFMEMORY
;
6055 *BlockHandle
= h
+ 1;
6056 wined3d_mutex_unlock();
6058 return hr_ddraw_from_wined3d(hr
);
6061 static HRESULT WINAPI
6062 IDirect3DDeviceImpl_7_CreateStateBlock_FPUSetup(IDirect3DDevice7
*iface
,
6063 D3DSTATEBLOCKTYPE Type
,
6066 return IDirect3DDeviceImpl_7_CreateStateBlock(iface
, Type
, BlockHandle
);
6069 static HRESULT WINAPI
6070 IDirect3DDeviceImpl_7_CreateStateBlock_FPUPreserve(IDirect3DDevice7
*iface
,
6071 D3DSTATEBLOCKTYPE Type
,
6077 old_fpucw
= d3d_fpu_setup();
6078 hr
=IDirect3DDeviceImpl_7_CreateStateBlock(iface
, Type
, BlockHandle
);
6079 set_fpu_control_word(old_fpucw
);
6084 /* Helper function for IDirect3DDeviceImpl_7_Load. */
6085 static BOOL
is_mip_level_subset(IDirectDrawSurfaceImpl
*dest
,
6086 IDirectDrawSurfaceImpl
*src
)
6088 IDirectDrawSurfaceImpl
*src_level
, *dest_level
;
6089 IDirectDrawSurface7
*temp
;
6090 DDSURFACEDESC2 ddsd
;
6091 BOOL levelFound
; /* at least one suitable sublevel in dest found */
6093 /* To satisfy "destination is mip level subset of source" criteria (regular texture counts as 1 level),
6094 * 1) there must be at least one mip level in destination that matched dimensions of some mip level in source and
6095 * 2) there must be no destination levels that don't match any levels in source. Otherwise it's INVALIDPARAMS.
6102 for (;src_level
&& dest_level
;)
6104 if (src_level
->surface_desc
.dwWidth
== dest_level
->surface_desc
.dwWidth
&&
6105 src_level
->surface_desc
.dwHeight
== dest_level
->surface_desc
.dwHeight
)
6109 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
6110 ddsd
.ddsCaps
.dwCaps2
= DDSCAPS2_MIPMAPSUBLEVEL
;
6111 IDirectDrawSurface7_GetAttachedSurface(&dest_level
->IDirectDrawSurface7_iface
, &ddsd
.ddsCaps
, &temp
);
6113 if (dest_level
!= dest
) IDirectDrawSurface7_Release(&dest_level
->IDirectDrawSurface7_iface
);
6115 dest_level
= unsafe_impl_from_IDirectDrawSurface7(temp
);
6118 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
6119 ddsd
.ddsCaps
.dwCaps2
= DDSCAPS2_MIPMAPSUBLEVEL
;
6120 IDirectDrawSurface7_GetAttachedSurface(&src_level
->IDirectDrawSurface7_iface
, &ddsd
.ddsCaps
, &temp
);
6122 if (src_level
!= src
) IDirectDrawSurface7_Release(&src_level
->IDirectDrawSurface7_iface
);
6124 src_level
= unsafe_impl_from_IDirectDrawSurface7(temp
);
6127 if (src_level
&& src_level
!= src
) IDirectDrawSurface7_Release(&src_level
->IDirectDrawSurface7_iface
);
6128 if (dest_level
&& dest_level
!= dest
) IDirectDrawSurface7_Release(&dest_level
->IDirectDrawSurface7_iface
);
6130 return !dest_level
&& levelFound
;
6133 /* Helper function for IDirect3DDeviceImpl_7_Load. */
6134 static void copy_mipmap_chain(IDirect3DDeviceImpl
*device
,
6135 IDirectDrawSurfaceImpl
*dest
,
6136 IDirectDrawSurfaceImpl
*src
,
6137 const POINT
*DestPoint
,
6138 const RECT
*SrcRect
)
6140 IDirectDrawSurfaceImpl
*src_level
, *dest_level
;
6141 IDirectDrawSurface7
*temp
;
6142 DDSURFACEDESC2 ddsd
;
6146 IDirectDrawPalette
*pal
= NULL
, *pal_src
= NULL
;
6150 /* Copy palette, if possible. */
6151 IDirectDrawSurface7_GetPalette(&src
->IDirectDrawSurface7_iface
, &pal_src
);
6152 IDirectDrawSurface7_GetPalette(&dest
->IDirectDrawSurface7_iface
, &pal
);
6154 if (pal_src
!= NULL
&& pal
!= NULL
)
6156 PALETTEENTRY palent
[256];
6158 IDirectDrawPalette_GetEntries(pal_src
, 0, 0, 256, palent
);
6159 IDirectDrawPalette_SetEntries(pal
, 0, 0, 256, palent
);
6162 if (pal
) IDirectDrawPalette_Release(pal
);
6163 if (pal_src
) IDirectDrawPalette_Release(pal_src
);
6165 /* Copy colorkeys, if present. */
6166 for (ckeyflag
= DDCKEY_DESTBLT
; ckeyflag
<= DDCKEY_SRCOVERLAY
; ckeyflag
<<= 1)
6168 hr
= IDirectDrawSurface7_GetColorKey(&src
->IDirectDrawSurface7_iface
, ckeyflag
, &ddckey
);
6172 IDirectDrawSurface7_SetColorKey(&dest
->IDirectDrawSurface7_iface
, ckeyflag
, &ddckey
);
6180 src_rect
= *SrcRect
;
6182 for (;src_level
&& dest_level
;)
6184 if (src_level
->surface_desc
.dwWidth
== dest_level
->surface_desc
.dwWidth
&&
6185 src_level
->surface_desc
.dwHeight
== dest_level
->surface_desc
.dwHeight
)
6187 UINT src_w
= src_rect
.right
- src_rect
.left
;
6188 UINT src_h
= src_rect
.bottom
- src_rect
.top
;
6189 RECT dst_rect
= {point
.x
, point
.y
, point
.x
+ src_w
, point
.y
+ src_h
};
6191 if (FAILED(hr
= wined3d_surface_blt(dest_level
->wined3d_surface
, &dst_rect
,
6192 src_level
->wined3d_surface
, &src_rect
, 0, NULL
, WINED3D_TEXF_POINT
)))
6193 ERR("Blit failed, hr %#x.\n", hr
);
6195 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
6196 ddsd
.ddsCaps
.dwCaps2
= DDSCAPS2_MIPMAPSUBLEVEL
;
6197 IDirectDrawSurface7_GetAttachedSurface(&dest_level
->IDirectDrawSurface7_iface
, &ddsd
.ddsCaps
, &temp
);
6199 if (dest_level
!= dest
) IDirectDrawSurface7_Release(&dest_level
->IDirectDrawSurface7_iface
);
6201 dest_level
= unsafe_impl_from_IDirectDrawSurface7(temp
);
6204 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
6205 ddsd
.ddsCaps
.dwCaps2
= DDSCAPS2_MIPMAPSUBLEVEL
;
6206 IDirectDrawSurface7_GetAttachedSurface(&src_level
->IDirectDrawSurface7_iface
, &ddsd
.ddsCaps
, &temp
);
6208 if (src_level
!= src
) IDirectDrawSurface7_Release(&src_level
->IDirectDrawSurface7_iface
);
6210 src_level
= unsafe_impl_from_IDirectDrawSurface7(temp
);
6217 src_rect
.right
= (src_rect
.right
+ 1) / 2;
6218 src_rect
.bottom
= (src_rect
.bottom
+ 1) / 2;
6221 if (src_level
&& src_level
!= src
) IDirectDrawSurface7_Release(&src_level
->IDirectDrawSurface7_iface
);
6222 if (dest_level
&& dest_level
!= dest
) IDirectDrawSurface7_Release(&dest_level
->IDirectDrawSurface7_iface
);
6225 /*****************************************************************************
6226 * IDirect3DDevice7::Load
6228 * Loads a rectangular area from the source into the destination texture.
6229 * It can also copy the source to the faces of a cubic environment map
6234 * DestTex: Destination texture
6235 * DestPoint: Point in the destination where the source image should be
6237 * SrcTex: Source texture
6238 * SrcRect: Source rectangle
6239 * Flags: Cubemap faces to load (DDSCAPS2_CUBEMAP_ALLFACES, DDSCAPS2_CUBEMAP_POSITIVEX,
6240 * DDSCAPS2_CUBEMAP_NEGATIVEX, DDSCAPS2_CUBEMAP_POSITIVEY, DDSCAPS2_CUBEMAP_NEGATIVEY,
6241 * DDSCAPS2_CUBEMAP_POSITIVEZ, DDSCAPS2_CUBEMAP_NEGATIVEZ)
6245 * DDERR_INVALIDPARAMS if DestTex or SrcTex are NULL, broken coordinates or anything unexpected.
6248 *****************************************************************************/
6251 IDirect3DDeviceImpl_7_Load(IDirect3DDevice7
*iface
,
6252 IDirectDrawSurface7
*DestTex
,
6254 IDirectDrawSurface7
*SrcTex
,
6258 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
6259 IDirectDrawSurfaceImpl
*dest
= unsafe_impl_from_IDirectDrawSurface7(DestTex
);
6260 IDirectDrawSurfaceImpl
*src
= unsafe_impl_from_IDirectDrawSurface7(SrcTex
);
6264 TRACE("iface %p, dst_texture %p, dst_pos %s, src_texture %p, src_rect %s, flags %#x.\n",
6265 iface
, DestTex
, wine_dbgstr_point(DestPoint
), SrcTex
, wine_dbgstr_rect(SrcRect
), Flags
);
6267 if( (!src
) || (!dest
) )
6268 return DDERR_INVALIDPARAMS
;
6270 wined3d_mutex_lock();
6272 if (SrcRect
) srcrect
= *SrcRect
;
6275 srcrect
.left
= srcrect
.top
= 0;
6276 srcrect
.right
= src
->surface_desc
.dwWidth
;
6277 srcrect
.bottom
= src
->surface_desc
.dwHeight
;
6280 if (DestPoint
) destpoint
= *DestPoint
;
6283 destpoint
.x
= destpoint
.y
= 0;
6285 /* Check bad dimensions. DestPoint is validated against src, not dest, because
6286 * destination can be a subset of mip levels, in which case actual coordinates used
6287 * for it may be divided. If any dimension of dest is larger than source, it can't be
6288 * mip level subset, so an error can be returned early.
6290 if (srcrect
.left
>= srcrect
.right
|| srcrect
.top
>= srcrect
.bottom
||
6291 srcrect
.right
> src
->surface_desc
.dwWidth
||
6292 srcrect
.bottom
> src
->surface_desc
.dwHeight
||
6293 destpoint
.x
+ srcrect
.right
- srcrect
.left
> src
->surface_desc
.dwWidth
||
6294 destpoint
.y
+ srcrect
.bottom
- srcrect
.top
> src
->surface_desc
.dwHeight
||
6295 dest
->surface_desc
.dwWidth
> src
->surface_desc
.dwWidth
||
6296 dest
->surface_desc
.dwHeight
> src
->surface_desc
.dwHeight
)
6298 wined3d_mutex_unlock();
6299 return DDERR_INVALIDPARAMS
;
6302 /* Must be top level surfaces. */
6303 if (src
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_MIPMAPSUBLEVEL
||
6304 dest
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_MIPMAPSUBLEVEL
)
6306 wined3d_mutex_unlock();
6307 return DDERR_INVALIDPARAMS
;
6310 if (src
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_CUBEMAP
)
6312 DWORD src_face_flag
, dest_face_flag
;
6313 IDirectDrawSurfaceImpl
*src_face
, *dest_face
;
6314 IDirectDrawSurface7
*temp
;
6315 DDSURFACEDESC2 ddsd
;
6318 if (!(dest
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_CUBEMAP
))
6320 wined3d_mutex_unlock();
6321 return DDERR_INVALIDPARAMS
;
6324 /* Iterate through cube faces 2 times. First time is just to check INVALIDPARAMS conditions, second
6325 * time it's actual surface loading. */
6326 for (i
= 0; i
< 2; i
++)
6331 for (;dest_face
&& src_face
;)
6333 src_face_flag
= src_face
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_CUBEMAP_ALLFACES
;
6334 dest_face_flag
= dest_face
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_CUBEMAP_ALLFACES
;
6336 if (src_face_flag
== dest_face_flag
)
6340 /* Destination mip levels must be subset of source mip levels. */
6341 if (!is_mip_level_subset(dest_face
, src_face
))
6343 wined3d_mutex_unlock();
6344 return DDERR_INVALIDPARAMS
;
6347 else if (Flags
& dest_face_flag
)
6349 copy_mipmap_chain(This
, dest_face
, src_face
, &destpoint
, &srcrect
);
6352 if (src_face_flag
< DDSCAPS2_CUBEMAP_NEGATIVEZ
)
6354 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
6355 ddsd
.ddsCaps
.dwCaps2
= DDSCAPS2_CUBEMAP
| (src_face_flag
<< 1);
6356 IDirectDrawSurface7_GetAttachedSurface(&src
->IDirectDrawSurface7_iface
, &ddsd
.ddsCaps
, &temp
);
6358 if (src_face
!= src
) IDirectDrawSurface7_Release(&src_face
->IDirectDrawSurface7_iface
);
6360 src_face
= unsafe_impl_from_IDirectDrawSurface7(temp
);
6364 if (src_face
!= src
) IDirectDrawSurface7_Release(&src_face
->IDirectDrawSurface7_iface
);
6370 if (dest_face_flag
< DDSCAPS2_CUBEMAP_NEGATIVEZ
)
6372 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
6373 ddsd
.ddsCaps
.dwCaps2
= DDSCAPS2_CUBEMAP
| (dest_face_flag
<< 1);
6374 IDirectDrawSurface7_GetAttachedSurface(&dest
->IDirectDrawSurface7_iface
, &ddsd
.ddsCaps
, &temp
);
6376 if (dest_face
!= dest
) IDirectDrawSurface7_Release(&dest_face
->IDirectDrawSurface7_iface
);
6378 dest_face
= unsafe_impl_from_IDirectDrawSurface7(temp
);
6382 if (dest_face
!= dest
) IDirectDrawSurface7_Release(&dest_face
->IDirectDrawSurface7_iface
);
6390 /* Native returns error if src faces are not subset of dest faces. */
6393 wined3d_mutex_unlock();
6394 return DDERR_INVALIDPARAMS
;
6399 wined3d_mutex_unlock();
6402 else if (dest
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_CUBEMAP
)
6404 wined3d_mutex_unlock();
6405 return DDERR_INVALIDPARAMS
;
6408 /* Handle non cube map textures. */
6410 /* Destination mip levels must be subset of source mip levels. */
6411 if (!is_mip_level_subset(dest
, src
))
6413 wined3d_mutex_unlock();
6414 return DDERR_INVALIDPARAMS
;
6417 copy_mipmap_chain(This
, dest
, src
, &destpoint
, &srcrect
);
6419 wined3d_mutex_unlock();
6424 static HRESULT WINAPI
6425 IDirect3DDeviceImpl_7_Load_FPUSetup(IDirect3DDevice7
*iface
,
6426 IDirectDrawSurface7
*DestTex
,
6428 IDirectDrawSurface7
*SrcTex
,
6432 return IDirect3DDeviceImpl_7_Load(iface
, DestTex
, DestPoint
, SrcTex
, SrcRect
, Flags
);
6435 static HRESULT WINAPI
6436 IDirect3DDeviceImpl_7_Load_FPUPreserve(IDirect3DDevice7
*iface
,
6437 IDirectDrawSurface7
*DestTex
,
6439 IDirectDrawSurface7
*SrcTex
,
6446 old_fpucw
= d3d_fpu_setup();
6447 hr
= IDirect3DDeviceImpl_7_Load(iface
, DestTex
, DestPoint
, SrcTex
, SrcRect
, Flags
);
6448 set_fpu_control_word(old_fpucw
);
6453 /*****************************************************************************
6454 * IDirect3DDevice7::LightEnable
6456 * Enables or disables a light
6458 * Version 7, IDirect3DLight uses this method too.
6461 * LightIndex: The index of the light to enable / disable
6462 * Enable: Enable or disable the light
6466 * For more details, see IWineD3DDevice::SetLightEnable
6468 *****************************************************************************/
6470 IDirect3DDeviceImpl_7_LightEnable(IDirect3DDevice7
*iface
,
6474 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
6477 TRACE("iface %p, light_idx %u, enabled %#x.\n", iface
, LightIndex
, Enable
);
6479 wined3d_mutex_lock();
6480 hr
= wined3d_device_set_light_enable(This
->wined3d_device
, LightIndex
, Enable
);
6481 wined3d_mutex_unlock();
6483 return hr_ddraw_from_wined3d(hr
);
6486 static HRESULT WINAPI
6487 IDirect3DDeviceImpl_7_LightEnable_FPUSetup(IDirect3DDevice7
*iface
,
6491 return IDirect3DDeviceImpl_7_LightEnable(iface
, LightIndex
, Enable
);
6494 static HRESULT WINAPI
6495 IDirect3DDeviceImpl_7_LightEnable_FPUPreserve(IDirect3DDevice7
*iface
,
6502 old_fpucw
= d3d_fpu_setup();
6503 hr
= IDirect3DDeviceImpl_7_LightEnable(iface
, LightIndex
, Enable
);
6504 set_fpu_control_word(old_fpucw
);
6509 /*****************************************************************************
6510 * IDirect3DDevice7::GetLightEnable
6512 * Retrieves if the light with the given index is enabled or not
6517 * LightIndex: Index of desired light
6518 * Enable: Pointer to a BOOL which contains the result
6522 * DDERR_INVALIDPARAMS if Enable is NULL
6523 * See IWineD3DDevice::GetLightEnable for more details
6525 *****************************************************************************/
6527 IDirect3DDeviceImpl_7_GetLightEnable(IDirect3DDevice7
*iface
,
6531 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
6534 TRACE("iface %p, light_idx %u, enabled %p.\n", iface
, LightIndex
, Enable
);
6537 return DDERR_INVALIDPARAMS
;
6539 wined3d_mutex_lock();
6540 hr
= wined3d_device_get_light_enable(This
->wined3d_device
, LightIndex
, Enable
);
6541 wined3d_mutex_unlock();
6543 return hr_ddraw_from_wined3d(hr
);
6546 static HRESULT WINAPI
6547 IDirect3DDeviceImpl_7_GetLightEnable_FPUSetup(IDirect3DDevice7
*iface
,
6551 return IDirect3DDeviceImpl_7_GetLightEnable(iface
, LightIndex
, Enable
);
6554 static HRESULT WINAPI
6555 IDirect3DDeviceImpl_7_GetLightEnable_FPUPreserve(IDirect3DDevice7
*iface
,
6562 old_fpucw
= d3d_fpu_setup();
6563 hr
= IDirect3DDeviceImpl_7_GetLightEnable(iface
, LightIndex
, Enable
);
6564 set_fpu_control_word(old_fpucw
);
6569 /*****************************************************************************
6570 * IDirect3DDevice7::SetClipPlane
6572 * Sets custom clipping plane
6577 * Index: The index of the clipping plane
6578 * PlaneEquation: An equation defining the clipping plane
6582 * DDERR_INVALIDPARAMS if PlaneEquation is NULL
6583 * See IWineD3DDevice::SetClipPlane for more details
6585 *****************************************************************************/
6587 IDirect3DDeviceImpl_7_SetClipPlane(IDirect3DDevice7
*iface
,
6589 D3DVALUE
* PlaneEquation
)
6591 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
6594 TRACE("iface %p, idx %u, plane %p.\n", iface
, Index
, PlaneEquation
);
6597 return DDERR_INVALIDPARAMS
;
6599 wined3d_mutex_lock();
6600 hr
= wined3d_device_set_clip_plane(This
->wined3d_device
, Index
, PlaneEquation
);
6601 wined3d_mutex_unlock();
6606 static HRESULT WINAPI
6607 IDirect3DDeviceImpl_7_SetClipPlane_FPUSetup(IDirect3DDevice7
*iface
,
6609 D3DVALUE
* PlaneEquation
)
6611 return IDirect3DDeviceImpl_7_SetClipPlane(iface
, Index
, PlaneEquation
);
6614 static HRESULT WINAPI
6615 IDirect3DDeviceImpl_7_SetClipPlane_FPUPreserve(IDirect3DDevice7
*iface
,
6617 D3DVALUE
* PlaneEquation
)
6622 old_fpucw
= d3d_fpu_setup();
6623 hr
= IDirect3DDeviceImpl_7_SetClipPlane(iface
, Index
, PlaneEquation
);
6624 set_fpu_control_word(old_fpucw
);
6629 /*****************************************************************************
6630 * IDirect3DDevice7::GetClipPlane
6632 * Returns the clipping plane with a specific index
6635 * Index: The index of the desired plane
6636 * PlaneEquation: Address to store the plane equation to
6640 * DDERR_INVALIDPARAMS if PlaneEquation is NULL
6641 * See IWineD3DDevice::GetClipPlane for more details
6643 *****************************************************************************/
6645 IDirect3DDeviceImpl_7_GetClipPlane(IDirect3DDevice7
*iface
,
6647 D3DVALUE
* PlaneEquation
)
6649 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
6652 TRACE("iface %p, idx %u, plane %p.\n", iface
, Index
, PlaneEquation
);
6655 return DDERR_INVALIDPARAMS
;
6657 wined3d_mutex_lock();
6658 hr
= wined3d_device_get_clip_plane(This
->wined3d_device
, Index
, PlaneEquation
);
6659 wined3d_mutex_unlock();
6664 static HRESULT WINAPI
6665 IDirect3DDeviceImpl_7_GetClipPlane_FPUSetup(IDirect3DDevice7
*iface
,
6667 D3DVALUE
* PlaneEquation
)
6669 return IDirect3DDeviceImpl_7_GetClipPlane(iface
, Index
, PlaneEquation
);
6672 static HRESULT WINAPI
6673 IDirect3DDeviceImpl_7_GetClipPlane_FPUPreserve(IDirect3DDevice7
*iface
,
6675 D3DVALUE
* PlaneEquation
)
6680 old_fpucw
= d3d_fpu_setup();
6681 hr
= IDirect3DDeviceImpl_7_GetClipPlane(iface
, Index
, PlaneEquation
);
6682 set_fpu_control_word(old_fpucw
);
6687 /*****************************************************************************
6688 * IDirect3DDevice7::GetInfo
6690 * Retrieves some information about the device. The DirectX sdk says that
6691 * this version returns S_FALSE for all retail builds of DirectX, that's what
6692 * this implementation does.
6695 * DevInfoID: Information type requested
6696 * DevInfoStruct: Pointer to a structure to store the info to
6697 * Size: Size of the structure
6700 * S_FALSE, because it's a non-debug driver
6702 *****************************************************************************/
6703 static HRESULT WINAPI
6704 IDirect3DDeviceImpl_7_GetInfo(IDirect3DDevice7
*iface
,
6706 void *DevInfoStruct
,
6709 TRACE("iface %p, info_id %#x, info %p, info_size %u.\n",
6710 iface
, DevInfoID
, DevInfoStruct
, Size
);
6712 if (TRACE_ON(ddraw
))
6714 TRACE(" info requested : ");
6717 case D3DDEVINFOID_TEXTUREMANAGER
: TRACE("D3DDEVINFOID_TEXTUREMANAGER\n"); break;
6718 case D3DDEVINFOID_D3DTEXTUREMANAGER
: TRACE("D3DDEVINFOID_D3DTEXTUREMANAGER\n"); break;
6719 case D3DDEVINFOID_TEXTURING
: TRACE("D3DDEVINFOID_TEXTURING\n"); break;
6720 default: ERR(" invalid flag !!!\n"); return DDERR_INVALIDPARAMS
;
6724 return S_FALSE
; /* According to MSDN, this is valid for a non-debug driver */
6727 /* For performance optimization, devices created in FPUSETUP and FPUPRESERVE modes
6728 * have separate vtables. Simple functions where this doesn't matter like GetDirect3D
6729 * are not duplicated.
6731 * Device created with DDSCL_FPUSETUP (d3d7 default) - device methods assume that FPU
6732 * has already been setup for optimal d3d operation.
6734 * Device created with DDSCL_FPUPRESERVE - resets and restores FPU mode when necessary in
6735 * d3d calls (FPU may be in a mode non-suitable for d3d when the app calls d3d). Required
6736 * by Sacrifice (game). */
6737 static const struct IDirect3DDevice7Vtbl d3d_device7_fpu_setup_vtbl
=
6739 /*** IUnknown Methods ***/
6740 IDirect3DDeviceImpl_7_QueryInterface
,
6741 IDirect3DDeviceImpl_7_AddRef
,
6742 IDirect3DDeviceImpl_7_Release
,
6743 /*** IDirect3DDevice7 ***/
6744 IDirect3DDeviceImpl_7_GetCaps_FPUSetup
,
6745 IDirect3DDeviceImpl_7_EnumTextureFormats_FPUSetup
,
6746 IDirect3DDeviceImpl_7_BeginScene_FPUSetup
,
6747 IDirect3DDeviceImpl_7_EndScene_FPUSetup
,
6748 IDirect3DDeviceImpl_7_GetDirect3D
,
6749 IDirect3DDeviceImpl_7_SetRenderTarget_FPUSetup
,
6750 IDirect3DDeviceImpl_7_GetRenderTarget
,
6751 IDirect3DDeviceImpl_7_Clear_FPUSetup
,
6752 IDirect3DDeviceImpl_7_SetTransform_FPUSetup
,
6753 IDirect3DDeviceImpl_7_GetTransform_FPUSetup
,
6754 IDirect3DDeviceImpl_7_SetViewport_FPUSetup
,
6755 IDirect3DDeviceImpl_7_MultiplyTransform_FPUSetup
,
6756 IDirect3DDeviceImpl_7_GetViewport_FPUSetup
,
6757 IDirect3DDeviceImpl_7_SetMaterial_FPUSetup
,
6758 IDirect3DDeviceImpl_7_GetMaterial_FPUSetup
,
6759 IDirect3DDeviceImpl_7_SetLight_FPUSetup
,
6760 IDirect3DDeviceImpl_7_GetLight_FPUSetup
,
6761 IDirect3DDeviceImpl_7_SetRenderState_FPUSetup
,
6762 IDirect3DDeviceImpl_7_GetRenderState_FPUSetup
,
6763 IDirect3DDeviceImpl_7_BeginStateBlock_FPUSetup
,
6764 IDirect3DDeviceImpl_7_EndStateBlock_FPUSetup
,
6765 IDirect3DDeviceImpl_7_PreLoad_FPUSetup
,
6766 IDirect3DDeviceImpl_7_DrawPrimitive_FPUSetup
,
6767 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUSetup
,
6768 IDirect3DDeviceImpl_7_SetClipStatus
,
6769 IDirect3DDeviceImpl_7_GetClipStatus
,
6770 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUSetup
,
6771 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUSetup
,
6772 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUSetup
,
6773 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUSetup
,
6774 IDirect3DDeviceImpl_7_ComputeSphereVisibility
,
6775 IDirect3DDeviceImpl_7_GetTexture_FPUSetup
,
6776 IDirect3DDeviceImpl_7_SetTexture_FPUSetup
,
6777 IDirect3DDeviceImpl_7_GetTextureStageState_FPUSetup
,
6778 IDirect3DDeviceImpl_7_SetTextureStageState_FPUSetup
,
6779 IDirect3DDeviceImpl_7_ValidateDevice_FPUSetup
,
6780 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUSetup
,
6781 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUSetup
,
6782 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUSetup
,
6783 IDirect3DDeviceImpl_7_CreateStateBlock_FPUSetup
,
6784 IDirect3DDeviceImpl_7_Load_FPUSetup
,
6785 IDirect3DDeviceImpl_7_LightEnable_FPUSetup
,
6786 IDirect3DDeviceImpl_7_GetLightEnable_FPUSetup
,
6787 IDirect3DDeviceImpl_7_SetClipPlane_FPUSetup
,
6788 IDirect3DDeviceImpl_7_GetClipPlane_FPUSetup
,
6789 IDirect3DDeviceImpl_7_GetInfo
6792 static const struct IDirect3DDevice7Vtbl d3d_device7_fpu_preserve_vtbl
=
6794 /*** IUnknown Methods ***/
6795 IDirect3DDeviceImpl_7_QueryInterface
,
6796 IDirect3DDeviceImpl_7_AddRef
,
6797 IDirect3DDeviceImpl_7_Release
,
6798 /*** IDirect3DDevice7 ***/
6799 IDirect3DDeviceImpl_7_GetCaps_FPUPreserve
,
6800 IDirect3DDeviceImpl_7_EnumTextureFormats_FPUPreserve
,
6801 IDirect3DDeviceImpl_7_BeginScene_FPUPreserve
,
6802 IDirect3DDeviceImpl_7_EndScene_FPUPreserve
,
6803 IDirect3DDeviceImpl_7_GetDirect3D
,
6804 IDirect3DDeviceImpl_7_SetRenderTarget_FPUPreserve
,
6805 IDirect3DDeviceImpl_7_GetRenderTarget
,
6806 IDirect3DDeviceImpl_7_Clear_FPUPreserve
,
6807 IDirect3DDeviceImpl_7_SetTransform_FPUPreserve
,
6808 IDirect3DDeviceImpl_7_GetTransform_FPUPreserve
,
6809 IDirect3DDeviceImpl_7_SetViewport_FPUPreserve
,
6810 IDirect3DDeviceImpl_7_MultiplyTransform_FPUPreserve
,
6811 IDirect3DDeviceImpl_7_GetViewport_FPUPreserve
,
6812 IDirect3DDeviceImpl_7_SetMaterial_FPUPreserve
,
6813 IDirect3DDeviceImpl_7_GetMaterial_FPUPreserve
,
6814 IDirect3DDeviceImpl_7_SetLight_FPUPreserve
,
6815 IDirect3DDeviceImpl_7_GetLight_FPUPreserve
,
6816 IDirect3DDeviceImpl_7_SetRenderState_FPUPreserve
,
6817 IDirect3DDeviceImpl_7_GetRenderState_FPUPreserve
,
6818 IDirect3DDeviceImpl_7_BeginStateBlock_FPUPreserve
,
6819 IDirect3DDeviceImpl_7_EndStateBlock_FPUPreserve
,
6820 IDirect3DDeviceImpl_7_PreLoad_FPUPreserve
,
6821 IDirect3DDeviceImpl_7_DrawPrimitive_FPUPreserve
,
6822 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUPreserve
,
6823 IDirect3DDeviceImpl_7_SetClipStatus
,
6824 IDirect3DDeviceImpl_7_GetClipStatus
,
6825 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUPreserve
,
6826 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUPreserve
,
6827 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUPreserve
,
6828 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUPreserve
,
6829 IDirect3DDeviceImpl_7_ComputeSphereVisibility
,
6830 IDirect3DDeviceImpl_7_GetTexture_FPUPreserve
,
6831 IDirect3DDeviceImpl_7_SetTexture_FPUPreserve
,
6832 IDirect3DDeviceImpl_7_GetTextureStageState_FPUPreserve
,
6833 IDirect3DDeviceImpl_7_SetTextureStageState_FPUPreserve
,
6834 IDirect3DDeviceImpl_7_ValidateDevice_FPUPreserve
,
6835 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUPreserve
,
6836 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUPreserve
,
6837 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUPreserve
,
6838 IDirect3DDeviceImpl_7_CreateStateBlock_FPUPreserve
,
6839 IDirect3DDeviceImpl_7_Load_FPUPreserve
,
6840 IDirect3DDeviceImpl_7_LightEnable_FPUPreserve
,
6841 IDirect3DDeviceImpl_7_GetLightEnable_FPUPreserve
,
6842 IDirect3DDeviceImpl_7_SetClipPlane_FPUPreserve
,
6843 IDirect3DDeviceImpl_7_GetClipPlane_FPUPreserve
,
6844 IDirect3DDeviceImpl_7_GetInfo
6847 static const struct IDirect3DDevice3Vtbl d3d_device3_vtbl
=
6849 /*** IUnknown Methods ***/
6850 IDirect3DDeviceImpl_3_QueryInterface
,
6851 IDirect3DDeviceImpl_3_AddRef
,
6852 IDirect3DDeviceImpl_3_Release
,
6853 /*** IDirect3DDevice3 ***/
6854 IDirect3DDeviceImpl_3_GetCaps
,
6855 IDirect3DDeviceImpl_3_GetStats
,
6856 IDirect3DDeviceImpl_3_AddViewport
,
6857 IDirect3DDeviceImpl_3_DeleteViewport
,
6858 IDirect3DDeviceImpl_3_NextViewport
,
6859 IDirect3DDeviceImpl_3_EnumTextureFormats
,
6860 IDirect3DDeviceImpl_3_BeginScene
,
6861 IDirect3DDeviceImpl_3_EndScene
,
6862 IDirect3DDeviceImpl_3_GetDirect3D
,
6863 IDirect3DDeviceImpl_3_SetCurrentViewport
,
6864 IDirect3DDeviceImpl_3_GetCurrentViewport
,
6865 IDirect3DDeviceImpl_3_SetRenderTarget
,
6866 IDirect3DDeviceImpl_3_GetRenderTarget
,
6867 IDirect3DDeviceImpl_3_Begin
,
6868 IDirect3DDeviceImpl_3_BeginIndexed
,
6869 IDirect3DDeviceImpl_3_Vertex
,
6870 IDirect3DDeviceImpl_3_Index
,
6871 IDirect3DDeviceImpl_3_End
,
6872 IDirect3DDeviceImpl_3_GetRenderState
,
6873 IDirect3DDeviceImpl_3_SetRenderState
,
6874 IDirect3DDeviceImpl_3_GetLightState
,
6875 IDirect3DDeviceImpl_3_SetLightState
,
6876 IDirect3DDeviceImpl_3_SetTransform
,
6877 IDirect3DDeviceImpl_3_GetTransform
,
6878 IDirect3DDeviceImpl_3_MultiplyTransform
,
6879 IDirect3DDeviceImpl_3_DrawPrimitive
,
6880 IDirect3DDeviceImpl_3_DrawIndexedPrimitive
,
6881 IDirect3DDeviceImpl_3_SetClipStatus
,
6882 IDirect3DDeviceImpl_3_GetClipStatus
,
6883 IDirect3DDeviceImpl_3_DrawPrimitiveStrided
,
6884 IDirect3DDeviceImpl_3_DrawIndexedPrimitiveStrided
,
6885 IDirect3DDeviceImpl_3_DrawPrimitiveVB
,
6886 IDirect3DDeviceImpl_3_DrawIndexedPrimitiveVB
,
6887 IDirect3DDeviceImpl_3_ComputeSphereVisibility
,
6888 IDirect3DDeviceImpl_3_GetTexture
,
6889 IDirect3DDeviceImpl_3_SetTexture
,
6890 IDirect3DDeviceImpl_3_GetTextureStageState
,
6891 IDirect3DDeviceImpl_3_SetTextureStageState
,
6892 IDirect3DDeviceImpl_3_ValidateDevice
6895 static const struct IDirect3DDevice2Vtbl d3d_device2_vtbl
=
6897 /*** IUnknown Methods ***/
6898 IDirect3DDeviceImpl_2_QueryInterface
,
6899 IDirect3DDeviceImpl_2_AddRef
,
6900 IDirect3DDeviceImpl_2_Release
,
6901 /*** IDirect3DDevice2 ***/
6902 IDirect3DDeviceImpl_2_GetCaps
,
6903 IDirect3DDeviceImpl_2_SwapTextureHandles
,
6904 IDirect3DDeviceImpl_2_GetStats
,
6905 IDirect3DDeviceImpl_2_AddViewport
,
6906 IDirect3DDeviceImpl_2_DeleteViewport
,
6907 IDirect3DDeviceImpl_2_NextViewport
,
6908 IDirect3DDeviceImpl_2_EnumTextureFormats
,
6909 IDirect3DDeviceImpl_2_BeginScene
,
6910 IDirect3DDeviceImpl_2_EndScene
,
6911 IDirect3DDeviceImpl_2_GetDirect3D
,
6912 IDirect3DDeviceImpl_2_SetCurrentViewport
,
6913 IDirect3DDeviceImpl_2_GetCurrentViewport
,
6914 IDirect3DDeviceImpl_2_SetRenderTarget
,
6915 IDirect3DDeviceImpl_2_GetRenderTarget
,
6916 IDirect3DDeviceImpl_2_Begin
,
6917 IDirect3DDeviceImpl_2_BeginIndexed
,
6918 IDirect3DDeviceImpl_2_Vertex
,
6919 IDirect3DDeviceImpl_2_Index
,
6920 IDirect3DDeviceImpl_2_End
,
6921 IDirect3DDeviceImpl_2_GetRenderState
,
6922 IDirect3DDeviceImpl_2_SetRenderState
,
6923 IDirect3DDeviceImpl_2_GetLightState
,
6924 IDirect3DDeviceImpl_2_SetLightState
,
6925 IDirect3DDeviceImpl_2_SetTransform
,
6926 IDirect3DDeviceImpl_2_GetTransform
,
6927 IDirect3DDeviceImpl_2_MultiplyTransform
,
6928 IDirect3DDeviceImpl_2_DrawPrimitive
,
6929 IDirect3DDeviceImpl_2_DrawIndexedPrimitive
,
6930 IDirect3DDeviceImpl_2_SetClipStatus
,
6931 IDirect3DDeviceImpl_2_GetClipStatus
6934 static const struct IDirect3DDeviceVtbl d3d_device1_vtbl
=
6936 /*** IUnknown Methods ***/
6937 IDirect3DDeviceImpl_1_QueryInterface
,
6938 IDirect3DDeviceImpl_1_AddRef
,
6939 IDirect3DDeviceImpl_1_Release
,
6940 /*** IDirect3DDevice1 ***/
6941 IDirect3DDeviceImpl_1_Initialize
,
6942 IDirect3DDeviceImpl_1_GetCaps
,
6943 IDirect3DDeviceImpl_1_SwapTextureHandles
,
6944 IDirect3DDeviceImpl_1_CreateExecuteBuffer
,
6945 IDirect3DDeviceImpl_1_GetStats
,
6946 IDirect3DDeviceImpl_1_Execute
,
6947 IDirect3DDeviceImpl_1_AddViewport
,
6948 IDirect3DDeviceImpl_1_DeleteViewport
,
6949 IDirect3DDeviceImpl_1_NextViewport
,
6950 IDirect3DDeviceImpl_1_Pick
,
6951 IDirect3DDeviceImpl_1_GetPickRecords
,
6952 IDirect3DDeviceImpl_1_EnumTextureFormats
,
6953 IDirect3DDeviceImpl_1_CreateMatrix
,
6954 IDirect3DDeviceImpl_1_SetMatrix
,
6955 IDirect3DDeviceImpl_1_GetMatrix
,
6956 IDirect3DDeviceImpl_1_DeleteMatrix
,
6957 IDirect3DDeviceImpl_1_BeginScene
,
6958 IDirect3DDeviceImpl_1_EndScene
,
6959 IDirect3DDeviceImpl_1_GetDirect3D
6962 IDirect3DDeviceImpl
*unsafe_impl_from_IDirect3DDevice7(IDirect3DDevice7
*iface
)
6964 if (!iface
) return NULL
;
6965 assert((iface
->lpVtbl
== &d3d_device7_fpu_preserve_vtbl
) || (iface
->lpVtbl
== &d3d_device7_fpu_setup_vtbl
));
6966 return CONTAINING_RECORD(iface
, IDirect3DDeviceImpl
, IDirect3DDevice7_iface
);
6969 IDirect3DDeviceImpl
*unsafe_impl_from_IDirect3DDevice3(IDirect3DDevice3
*iface
)
6971 if (!iface
) return NULL
;
6972 assert(iface
->lpVtbl
== &d3d_device3_vtbl
);
6973 return CONTAINING_RECORD(iface
, IDirect3DDeviceImpl
, IDirect3DDevice3_iface
);
6976 IDirect3DDeviceImpl
*unsafe_impl_from_IDirect3DDevice2(IDirect3DDevice2
*iface
)
6978 if (!iface
) return NULL
;
6979 assert(iface
->lpVtbl
== &d3d_device2_vtbl
);
6980 return CONTAINING_RECORD(iface
, IDirect3DDeviceImpl
, IDirect3DDevice2_iface
);
6983 IDirect3DDeviceImpl
*unsafe_impl_from_IDirect3DDevice(IDirect3DDevice
*iface
)
6985 if (!iface
) return NULL
;
6986 assert(iface
->lpVtbl
== &d3d_device1_vtbl
);
6987 return CONTAINING_RECORD(iface
, IDirect3DDeviceImpl
, IDirect3DDevice_iface
);
6990 /*****************************************************************************
6991 * IDirect3DDeviceImpl_UpdateDepthStencil
6993 * Checks the current render target for attached depth stencils and sets the
6994 * WineD3D depth stencil accordingly.
6997 * The depth stencil state to set if creating the device
6999 *****************************************************************************/
7000 enum wined3d_depth_buffer_type
IDirect3DDeviceImpl_UpdateDepthStencil(IDirect3DDeviceImpl
*This
)
7002 IDirectDrawSurface7
*depthStencil
= NULL
;
7003 IDirectDrawSurfaceImpl
*dsi
;
7004 static DDSCAPS2 depthcaps
= { DDSCAPS_ZBUFFER
, 0, 0, 0 };
7006 IDirectDrawSurface7_GetAttachedSurface(&This
->target
->IDirectDrawSurface7_iface
, &depthcaps
, &depthStencil
);
7009 TRACE("Setting wined3d depth stencil to NULL\n");
7010 wined3d_device_set_depth_stencil(This
->wined3d_device
, NULL
);
7011 return WINED3D_ZB_FALSE
;
7014 dsi
= impl_from_IDirectDrawSurface7(depthStencil
);
7015 TRACE("Setting wined3d depth stencil to %p (wined3d %p)\n", dsi
, dsi
->wined3d_surface
);
7016 wined3d_device_set_depth_stencil(This
->wined3d_device
, dsi
->wined3d_surface
);
7018 IDirectDrawSurface7_Release(depthStencil
);
7019 return WINED3D_ZB_TRUE
;
7022 HRESULT
d3d_device_init(IDirect3DDeviceImpl
*device
, IDirectDrawImpl
*ddraw
, IDirectDrawSurfaceImpl
*target
)
7024 static const D3DMATRIX ident
=
7026 1.0f
, 0.0f
, 0.0f
, 0.0f
,
7027 0.0f
, 1.0f
, 0.0f
, 0.0f
,
7028 0.0f
, 0.0f
, 1.0f
, 0.0f
,
7029 0.0f
, 0.0f
, 0.0f
, 1.0f
,
7033 if (ddraw
->cooperative_level
& DDSCL_FPUPRESERVE
)
7034 device
->IDirect3DDevice7_iface
.lpVtbl
= &d3d_device7_fpu_preserve_vtbl
;
7036 device
->IDirect3DDevice7_iface
.lpVtbl
= &d3d_device7_fpu_setup_vtbl
;
7038 device
->IDirect3DDevice3_iface
.lpVtbl
= &d3d_device3_vtbl
;
7039 device
->IDirect3DDevice2_iface
.lpVtbl
= &d3d_device2_vtbl
;
7040 device
->IDirect3DDevice_iface
.lpVtbl
= &d3d_device1_vtbl
;
7042 device
->ddraw
= ddraw
;
7043 device
->target
= target
;
7044 list_init(&device
->viewport_list
);
7046 if (!ddraw_handle_table_init(&device
->handle_table
, 64))
7048 ERR("Failed to initialize handle table.\n");
7049 return DDERR_OUTOFMEMORY
;
7052 device
->legacyTextureBlending
= FALSE
;
7053 device
->legacy_projection
= ident
;
7054 device
->legacy_clipspace
= ident
;
7056 /* Create an index buffer, it's needed for indexed drawing */
7057 hr
= wined3d_buffer_create_ib(ddraw
->wined3d_device
, 0x40000 /* Length. Don't know how long it should be */,
7058 WINED3DUSAGE_DYNAMIC
/* Usage */, WINED3D_POOL_DEFAULT
, NULL
,
7059 &ddraw_null_wined3d_parent_ops
, &device
->indexbuffer
);
7062 ERR("Failed to create an index buffer, hr %#x.\n", hr
);
7063 ddraw_handle_table_destroy(&device
->handle_table
);
7067 /* This is for convenience. */
7068 device
->wined3d_device
= ddraw
->wined3d_device
;
7069 wined3d_device_incref(ddraw
->wined3d_device
);
7071 /* Render to the back buffer */
7072 hr
= wined3d_device_set_render_target(ddraw
->wined3d_device
, 0, target
->wined3d_surface
, TRUE
);
7075 ERR("Failed to set render target, hr %#x.\n", hr
);
7076 wined3d_buffer_decref(device
->indexbuffer
);
7077 ddraw_handle_table_destroy(&device
->handle_table
);
7081 /* FIXME: This is broken. The target AddRef() makes some sense, because
7082 * we store a pointer during initialization, but then that's also where
7083 * the AddRef() should be. We don't store ddraw->d3d_target anywhere. */
7084 /* AddRef the render target. Also AddRef the render target from ddraw,
7085 * because if it is released before the app releases the D3D device, the
7086 * D3D capabilities of wined3d will be uninitialized, which has bad effects.
7088 * In most cases, those surfaces are the same anyway, but this will simply
7089 * add another ref which is released when the device is destroyed. */
7090 IDirectDrawSurface7_AddRef(&target
->IDirectDrawSurface7_iface
);
7092 ddraw
->d3ddevice
= device
;
7094 wined3d_device_set_render_state(ddraw
->wined3d_device
, WINED3D_RS_ZENABLE
,
7095 IDirect3DDeviceImpl_UpdateDepthStencil(device
));