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
);
36 WINE_DECLARE_DEBUG_CHANNEL(winediag
);
39 const GUID IID_D3DDEVICE_WineD3D
= {
43 { 0xb7,0x98,0xc6,0x8a,0x77,0x2d,0x72,0x2a }
46 static inline void set_fpu_control_word(WORD fpucw
)
48 #if defined(__i386__) && defined(__GNUC__)
49 __asm__
volatile ("fldcw %0" : : "m" (fpucw
));
50 #elif defined(__i386__) && defined(_MSC_VER)
55 static inline WORD
d3d_fpu_setup(void)
59 #if defined(__i386__) && defined(__GNUC__)
60 __asm__
volatile ("fnstcw %0" : "=m" (oldcw
));
61 #elif defined(__i386__) && defined(_MSC_VER)
64 static BOOL warned
= FALSE
;
67 FIXME("FPUPRESERVE not implemented for this platform / compiler\n");
73 set_fpu_control_word(0x37f);
78 /*****************************************************************************
79 * IUnknown Methods. Common for Version 1, 2, 3 and 7
80 *****************************************************************************/
82 /*****************************************************************************
83 * IDirect3DDevice7::QueryInterface
85 * Used to query other interfaces from a Direct3DDevice interface.
86 * It can return interface pointers to all Direct3DDevice versions as well
87 * as IDirectDraw and IDirect3D. For a link to QueryInterface
88 * rules see ddraw.c, IDirectDraw7::QueryInterface
90 * Exists in Version 1, 2, 3 and 7
93 * refiid: Interface ID queried for
94 * obj: Used to return the interface pointer
97 * D3D_OK or E_NOINTERFACE
99 *****************************************************************************/
100 static HRESULT WINAPI
101 IDirect3DDeviceImpl_7_QueryInterface(IDirect3DDevice7
*iface
,
105 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
107 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(refiid
), obj
);
109 /* According to COM docs, if the QueryInterface fails, obj should be set to NULL */
113 return DDERR_INVALIDPARAMS
;
115 if ( IsEqualGUID( &IID_IUnknown
, refiid
) )
120 /* Check DirectDraw Interfaces. */
121 else if( IsEqualGUID( &IID_IDirectDraw7
, refiid
) )
123 *obj
= &This
->ddraw
->IDirectDraw7_iface
;
124 TRACE("(%p) Returning IDirectDraw7 interface at %p\n", This
, *obj
);
126 else if ( IsEqualGUID( &IID_IDirectDraw4
, refiid
) )
128 *obj
= &This
->ddraw
->IDirectDraw4_iface
;
129 TRACE("(%p) Returning IDirectDraw4 interface at %p\n", This
, *obj
);
131 else if ( IsEqualGUID( &IID_IDirectDraw2
, refiid
) )
133 *obj
= &This
->ddraw
->IDirectDraw2_iface
;
134 TRACE("(%p) Returning IDirectDraw2 interface at %p\n", This
, *obj
);
136 else if( IsEqualGUID( &IID_IDirectDraw
, refiid
) )
138 *obj
= &This
->ddraw
->IDirectDraw_iface
;
139 TRACE("(%p) Returning IDirectDraw interface at %p\n", This
, *obj
);
143 else if ( IsEqualGUID( &IID_IDirect3D
, refiid
) )
145 *obj
= &This
->ddraw
->IDirect3D_iface
;
146 TRACE("(%p) Returning IDirect3D interface at %p\n", This
, *obj
);
148 else if ( IsEqualGUID( &IID_IDirect3D2
, refiid
) )
150 *obj
= &This
->ddraw
->IDirect3D2_iface
;
151 TRACE("(%p) Returning IDirect3D2 interface at %p\n", This
, *obj
);
153 else if ( IsEqualGUID( &IID_IDirect3D3
, refiid
) )
155 *obj
= &This
->ddraw
->IDirect3D3_iface
;
156 TRACE("(%p) Returning IDirect3D3 interface at %p\n", This
, *obj
);
158 else if ( IsEqualGUID( &IID_IDirect3D7
, refiid
) )
160 *obj
= &This
->ddraw
->IDirect3D7_iface
;
161 TRACE("(%p) Returning IDirect3D7 interface at %p\n", This
, *obj
);
165 else if ( IsEqualGUID( &IID_IDirect3DDevice
, refiid
) )
167 *obj
= &This
->IDirect3DDevice_iface
;
168 TRACE("(%p) Returning IDirect3DDevice interface at %p\n", This
, *obj
);
170 else if ( IsEqualGUID( &IID_IDirect3DDevice2
, refiid
) ) {
171 *obj
= &This
->IDirect3DDevice2_iface
;
172 TRACE("(%p) Returning IDirect3DDevice2 interface at %p\n", This
, *obj
);
174 else if ( IsEqualGUID( &IID_IDirect3DDevice3
, refiid
) ) {
175 *obj
= &This
->IDirect3DDevice3_iface
;
176 TRACE("(%p) Returning IDirect3DDevice3 interface at %p\n", This
, *obj
);
178 else if ( IsEqualGUID( &IID_IDirect3DDevice7
, refiid
) ) {
179 *obj
= &This
->IDirect3DDevice7_iface
;
180 TRACE("(%p) Returning IDirect3DDevice7 interface at %p\n", This
, *obj
);
183 /* DirectDrawSurface */
184 else if (IsEqualGUID(&IID_IDirectDrawSurface
, refiid
) && This
->version
== 1)
186 *obj
= &This
->target
->IDirectDrawSurface_iface
;
187 TRACE("Returning IDirectDrawSurface interface %p.\n", *obj
);
190 /* Unknown interface */
193 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(refiid
));
194 return E_NOINTERFACE
;
197 /* AddRef the returned interface */
198 IUnknown_AddRef( (IUnknown
*) *obj
);
202 static HRESULT WINAPI
IDirect3DDeviceImpl_3_QueryInterface(IDirect3DDevice3
*iface
, REFIID riid
,
205 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
206 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), obj
);
208 return IDirect3DDevice7_QueryInterface(&This
->IDirect3DDevice7_iface
, riid
, obj
);
211 static HRESULT WINAPI
IDirect3DDeviceImpl_2_QueryInterface(IDirect3DDevice2
*iface
, REFIID riid
,
214 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
215 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), obj
);
217 return IDirect3DDevice7_QueryInterface(&This
->IDirect3DDevice7_iface
, riid
, obj
);
220 static HRESULT WINAPI
IDirect3DDeviceImpl_1_QueryInterface(IDirect3DDevice
*iface
, REFIID riid
,
223 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
224 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), obp
);
226 return IDirect3DDevice7_QueryInterface(&This
->IDirect3DDevice7_iface
, riid
, obp
);
229 /*****************************************************************************
230 * IDirect3DDevice7::AddRef
232 * Increases the refcount....
233 * The most exciting Method, definitely
235 * Exists in Version 1, 2, 3 and 7
240 *****************************************************************************/
242 IDirect3DDeviceImpl_7_AddRef(IDirect3DDevice7
*iface
)
244 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
245 ULONG ref
= InterlockedIncrement(&This
->ref
);
247 TRACE("%p increasing refcount to %u.\n", This
, ref
);
252 static ULONG WINAPI
IDirect3DDeviceImpl_3_AddRef(IDirect3DDevice3
*iface
)
254 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
255 TRACE("iface %p.\n", iface
);
257 return IDirect3DDevice7_AddRef(&This
->IDirect3DDevice7_iface
);
260 static ULONG WINAPI
IDirect3DDeviceImpl_2_AddRef(IDirect3DDevice2
*iface
)
262 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
263 TRACE("iface %p.\n", iface
);
265 return IDirect3DDevice7_AddRef(&This
->IDirect3DDevice7_iface
);
268 static ULONG WINAPI
IDirect3DDeviceImpl_1_AddRef(IDirect3DDevice
*iface
)
270 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
271 TRACE("iface %p.\n", iface
);
273 return IDirect3DDevice7_AddRef(&This
->IDirect3DDevice7_iface
);
276 /*****************************************************************************
277 * IDirect3DDevice7::Release
279 * Decreases the refcount of the interface
280 * When the refcount is reduced to 0, the object is destroyed.
282 * Exists in Version 1, 2, 3 and 7
287 *****************************************************************************/
289 IDirect3DDeviceImpl_7_Release(IDirect3DDevice7
*iface
)
291 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
292 ULONG ref
= InterlockedDecrement(&This
->ref
);
294 TRACE("%p decreasing refcount to %u.\n", This
, ref
);
296 /* This method doesn't destroy the WineD3DDevice, because it's still in use for
297 * 2D rendering. IDirectDrawSurface7::Release will destroy the WineD3DDevice
298 * when the render target is released
304 wined3d_mutex_lock();
306 /* There is no need to unset any resources here, wined3d will take
307 * care of that on Uninit3D(). */
309 /* Free the index buffer. */
310 wined3d_buffer_decref(This
->indexbuffer
);
312 /* Set the device up to render to the front buffer since the back
313 * buffer will vanish soon. */
314 wined3d_device_set_render_target(This
->wined3d_device
, 0,
315 This
->ddraw
->wined3d_frontbuffer
, TRUE
);
317 /* Release the WineD3DDevice. This won't destroy it. */
318 if (!wined3d_device_decref(This
->wined3d_device
))
319 ERR("The wined3d device (%p) was destroyed unexpectedly.\n", This
->wined3d_device
);
321 /* The texture handles should be unset by now, but there might be some bits
322 * missing in our reference counting(needs test). Do a sanity check. */
323 for (i
= 0; i
< This
->handle_table
.entry_count
; ++i
)
325 struct ddraw_handle_entry
*entry
= &This
->handle_table
.entries
[i
];
329 case DDRAW_HANDLE_FREE
:
332 case DDRAW_HANDLE_MATERIAL
:
334 struct d3d_material
*m
= entry
->object
;
335 FIXME("Material handle %#x (%p) not unset properly.\n", i
+ 1, m
);
340 case DDRAW_HANDLE_MATRIX
:
342 /* No FIXME here because this might happen because of sloppy applications. */
343 WARN("Leftover matrix handle %#x (%p), deleting.\n", i
+ 1, entry
->object
);
344 IDirect3DDevice_DeleteMatrix(&This
->IDirect3DDevice_iface
, i
+ 1);
348 case DDRAW_HANDLE_STATEBLOCK
:
350 /* No FIXME here because this might happen because of sloppy applications. */
351 WARN("Leftover stateblock handle %#x (%p), deleting.\n", i
+ 1, entry
->object
);
352 IDirect3DDevice7_DeleteStateBlock(iface
, i
+ 1);
356 case DDRAW_HANDLE_SURFACE
:
358 struct ddraw_surface
*surf
= entry
->object
;
359 FIXME("Texture handle %#x (%p) not unset properly.\n", i
+ 1, surf
);
365 FIXME("Handle %#x (%p) has unknown type %#x.\n", i
+ 1, entry
->object
, entry
->type
);
370 ddraw_handle_table_destroy(&This
->handle_table
);
372 TRACE("Releasing target %p.\n", This
->target
);
373 /* Release the render target and the WineD3D render target
374 * (See IDirect3D7::CreateDevice for more comments on this)
376 IDirectDrawSurface7_Release(&This
->target
->IDirectDrawSurface7_iface
);
377 TRACE("Target release done\n");
379 This
->ddraw
->d3ddevice
= NULL
;
381 /* Now free the structure */
382 HeapFree(GetProcessHeap(), 0, This
);
383 wined3d_mutex_unlock();
390 static ULONG WINAPI
IDirect3DDeviceImpl_3_Release(IDirect3DDevice3
*iface
)
392 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
393 TRACE("iface %p.\n", iface
);
395 return IDirect3DDevice7_Release(&This
->IDirect3DDevice7_iface
);
398 static ULONG WINAPI
IDirect3DDeviceImpl_2_Release(IDirect3DDevice2
*iface
)
400 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
401 TRACE("iface %p.\n", iface
);
403 return IDirect3DDevice7_Release(&This
->IDirect3DDevice7_iface
);
406 static ULONG WINAPI
IDirect3DDeviceImpl_1_Release(IDirect3DDevice
*iface
)
408 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
409 TRACE("iface %p.\n", iface
);
411 return IDirect3DDevice7_Release(&This
->IDirect3DDevice7_iface
);
414 /*****************************************************************************
415 * IDirect3DDevice Methods
416 *****************************************************************************/
418 /*****************************************************************************
419 * IDirect3DDevice::Initialize
421 * Initializes a Direct3DDevice. This implementation is a no-op, as all
422 * initialization is done at create time.
424 * Exists in Version 1
427 * No idea what they mean, as the MSDN page is gone
431 *****************************************************************************/
432 static HRESULT WINAPI
433 IDirect3DDeviceImpl_1_Initialize(IDirect3DDevice
*iface
,
434 IDirect3D
*Direct3D
, GUID
*guid
,
437 /* It shouldn't be crucial, but print a FIXME, I'm interested if
438 * any game calls it and when. */
439 FIXME("iface %p, d3d %p, guid %s, device_desc %p nop!\n",
440 iface
, Direct3D
, debugstr_guid(guid
), Desc
);
445 /*****************************************************************************
446 * IDirect3DDevice7::GetCaps
448 * Retrieves the device's capabilities
450 * This implementation is used for Version 7 only, the older versions have
451 * their own implementation.
454 * Desc: Pointer to a D3DDEVICEDESC7 structure to fill
458 * D3DERR_* if a problem occurs. See WineD3D
460 *****************************************************************************/
462 IDirect3DDeviceImpl_7_GetCaps(IDirect3DDevice7
*iface
,
463 D3DDEVICEDESC7
*Desc
)
465 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
466 D3DDEVICEDESC OldDesc
;
468 TRACE("iface %p, device_desc %p.\n", iface
, Desc
);
472 WARN("Desc is NULL, returning DDERR_INVALIDPARAMS.\n");
473 return DDERR_INVALIDPARAMS
;
476 /* Call the same function used by IDirect3D, this saves code */
477 return IDirect3DImpl_GetCaps(This
->ddraw
->wined3d
, &OldDesc
, Desc
);
480 static HRESULT WINAPI
481 IDirect3DDeviceImpl_7_GetCaps_FPUSetup(IDirect3DDevice7
*iface
,
482 D3DDEVICEDESC7
*Desc
)
484 return IDirect3DDeviceImpl_7_GetCaps(iface
, Desc
);
487 static HRESULT WINAPI
488 IDirect3DDeviceImpl_7_GetCaps_FPUPreserve(IDirect3DDevice7
*iface
,
489 D3DDEVICEDESC7
*Desc
)
494 old_fpucw
= d3d_fpu_setup();
495 hr
= IDirect3DDeviceImpl_7_GetCaps(iface
, Desc
);
496 set_fpu_control_word(old_fpucw
);
500 /*****************************************************************************
501 * IDirect3DDevice3::GetCaps
503 * Retrieves the capabilities of the hardware device and the emulation
504 * device. For Wine, hardware and emulation are the same (it's all HW).
506 * This implementation is used for Version 1, 2, and 3. Version 7 has its own
509 * HWDesc: Structure to fill with the HW caps
510 * HelDesc: Structure to fill with the hardware emulation caps
514 * D3DERR_* if a problem occurs. See WineD3D
516 *****************************************************************************/
518 /* There are 3 versions of D3DDEVICEDESC. All 3 share the same name because
519 * Microsoft just expanded the existing structure without naming them
520 * D3DDEVICEDESC2 and D3DDEVICEDESC3. Which version is used have depends
521 * on the version of the DirectX SDK. DirectX 6+ and Wine use the latest
522 * one with 252 bytes.
524 * All 3 versions are allowed as parameters and only the specified amount of
527 * Note that Direct3D7 and earlier are not available in native Win64
528 * ddraw.dll builds, so possible size differences between 32 bit and
529 * 64 bit are a non-issue.
531 static inline BOOL
check_d3ddevicedesc_size(DWORD size
)
533 if (size
== FIELD_OFFSET(D3DDEVICEDESC
, dwMinTextureWidth
) /* 172 */
534 || size
== FIELD_OFFSET(D3DDEVICEDESC
, dwMaxTextureRepeat
) /* 204 */
535 || size
== sizeof(D3DDEVICEDESC
) /* 252 */) return TRUE
;
539 static HRESULT WINAPI
540 IDirect3DDeviceImpl_3_GetCaps(IDirect3DDevice3
*iface
,
541 D3DDEVICEDESC
*HWDesc
,
542 D3DDEVICEDESC
*HelDesc
)
544 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
545 D3DDEVICEDESC oldDesc
;
546 D3DDEVICEDESC7 newDesc
;
549 TRACE("iface %p, hw_desc %p, hel_desc %p.\n", iface
, HWDesc
, HelDesc
);
553 WARN("HWDesc is NULL, returning DDERR_INVALIDPARAMS.\n");
554 return DDERR_INVALIDPARAMS
;
556 if (!check_d3ddevicedesc_size(HWDesc
->dwSize
))
558 WARN("HWDesc->dwSize is %u, returning DDERR_INVALIDPARAMS.\n", HWDesc
->dwSize
);
559 return DDERR_INVALIDPARAMS
;
563 WARN("HelDesc is NULL, returning DDERR_INVALIDPARAMS.\n");
564 return DDERR_INVALIDPARAMS
;
566 if (!check_d3ddevicedesc_size(HelDesc
->dwSize
))
568 WARN("HelDesc->dwSize is %u, returning DDERR_INVALIDPARAMS.\n", HelDesc
->dwSize
);
569 return DDERR_INVALIDPARAMS
;
572 hr
= IDirect3DImpl_GetCaps(This
->ddraw
->wined3d
, &oldDesc
, &newDesc
);
573 if(hr
!= D3D_OK
) return hr
;
575 DD_STRUCT_COPY_BYSIZE(HWDesc
, &oldDesc
);
576 DD_STRUCT_COPY_BYSIZE(HelDesc
, &oldDesc
);
580 static HRESULT WINAPI
IDirect3DDeviceImpl_2_GetCaps(IDirect3DDevice2
*iface
,
581 D3DDEVICEDESC
*D3DHWDevDesc
, D3DDEVICEDESC
*D3DHELDevDesc
)
583 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
584 TRACE("iface %p, hw_desc %p, hel_desc %p.\n", iface
, D3DHWDevDesc
, D3DHELDevDesc
);
585 return IDirect3DDevice3_GetCaps(&This
->IDirect3DDevice3_iface
, D3DHWDevDesc
, D3DHELDevDesc
);
588 static HRESULT WINAPI
IDirect3DDeviceImpl_1_GetCaps(IDirect3DDevice
*iface
,
589 D3DDEVICEDESC
*D3DHWDevDesc
, D3DDEVICEDESC
*D3DHELDevDesc
)
591 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
592 TRACE("iface %p, hw_desc %p, hel_desc %p.\n", iface
, D3DHWDevDesc
, D3DHELDevDesc
);
593 return IDirect3DDevice3_GetCaps(&This
->IDirect3DDevice3_iface
, D3DHWDevDesc
, D3DHELDevDesc
);
596 /*****************************************************************************
597 * IDirect3DDevice2::SwapTextureHandles
599 * Swaps the texture handles of 2 Texture interfaces. Version 1 and 2
602 * Tex1, Tex2: The 2 Textures to swap
607 *****************************************************************************/
608 static HRESULT WINAPI
609 IDirect3DDeviceImpl_2_SwapTextureHandles(IDirect3DDevice2
*iface
,
610 IDirect3DTexture2
*Tex1
,
611 IDirect3DTexture2
*Tex2
)
613 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
614 struct ddraw_surface
*surf1
= unsafe_impl_from_IDirect3DTexture2(Tex1
);
615 struct ddraw_surface
*surf2
= unsafe_impl_from_IDirect3DTexture2(Tex2
);
618 TRACE("iface %p, tex1 %p, tex2 %p.\n", iface
, Tex1
, Tex2
);
620 wined3d_mutex_lock();
622 h1
= surf1
->Handle
- 1;
623 h2
= surf2
->Handle
- 1;
624 This
->handle_table
.entries
[h1
].object
= surf2
;
625 This
->handle_table
.entries
[h2
].object
= surf1
;
626 surf2
->Handle
= h1
+ 1;
627 surf1
->Handle
= h2
+ 1;
629 wined3d_mutex_unlock();
634 static HRESULT WINAPI
IDirect3DDeviceImpl_1_SwapTextureHandles(IDirect3DDevice
*iface
,
635 IDirect3DTexture
*D3DTex1
, IDirect3DTexture
*D3DTex2
)
637 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
638 struct ddraw_surface
*surf1
= unsafe_impl_from_IDirect3DTexture(D3DTex1
);
639 struct ddraw_surface
*surf2
= unsafe_impl_from_IDirect3DTexture(D3DTex2
);
640 IDirect3DTexture2
*t1
= surf1
? &surf1
->IDirect3DTexture2_iface
: NULL
;
641 IDirect3DTexture2
*t2
= surf2
? &surf2
->IDirect3DTexture2_iface
: NULL
;
643 TRACE("iface %p, tex1 %p, tex2 %p.\n", iface
, D3DTex1
, D3DTex2
);
645 return IDirect3DDevice2_SwapTextureHandles(&This
->IDirect3DDevice2_iface
, t1
, t2
);
648 /*****************************************************************************
649 * IDirect3DDevice3::GetStats
651 * This method seems to retrieve some stats from the device.
652 * The MSDN documentation doesn't exist any more, but the D3DSTATS
653 * structure suggests that the amount of drawn primitives and processed
654 * vertices is returned.
656 * Exists in Version 1, 2 and 3
659 * Stats: Pointer to a D3DSTATS structure to be filled
663 * DDERR_INVALIDPARAMS if Stats == NULL
665 *****************************************************************************/
666 static HRESULT WINAPI
667 IDirect3DDeviceImpl_3_GetStats(IDirect3DDevice3
*iface
,
670 FIXME("iface %p, stats %p stub!\n", iface
, Stats
);
673 return DDERR_INVALIDPARAMS
;
675 /* Fill the Stats with 0 */
676 Stats
->dwTrianglesDrawn
= 0;
677 Stats
->dwLinesDrawn
= 0;
678 Stats
->dwPointsDrawn
= 0;
679 Stats
->dwSpansDrawn
= 0;
680 Stats
->dwVerticesProcessed
= 0;
685 static HRESULT WINAPI
IDirect3DDeviceImpl_2_GetStats(IDirect3DDevice2
*iface
, D3DSTATS
*Stats
)
687 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
689 TRACE("iface %p, stats %p.\n", iface
, Stats
);
691 return IDirect3DDevice3_GetStats(&This
->IDirect3DDevice3_iface
, Stats
);
694 static HRESULT WINAPI
IDirect3DDeviceImpl_1_GetStats(IDirect3DDevice
*iface
, D3DSTATS
*Stats
)
696 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
698 TRACE("iface %p, stats %p.\n", iface
, Stats
);
700 return IDirect3DDevice3_GetStats(&This
->IDirect3DDevice3_iface
, Stats
);
703 /*****************************************************************************
704 * IDirect3DDevice::CreateExecuteBuffer
706 * Creates an IDirect3DExecuteBuffer, used for rendering with a
712 * Desc: Buffer description
713 * ExecuteBuffer: Address to return the Interface pointer at
714 * UnkOuter: Must be NULL. Basically for aggregation, which ddraw doesn't
718 * CLASS_E_NOAGGREGATION if UnkOuter != NULL
719 * DDERR_OUTOFMEMORY if we ran out of memory
722 *****************************************************************************/
723 static HRESULT WINAPI
724 IDirect3DDeviceImpl_1_CreateExecuteBuffer(IDirect3DDevice
*iface
,
725 D3DEXECUTEBUFFERDESC
*Desc
,
726 IDirect3DExecuteBuffer
**ExecuteBuffer
,
729 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
730 IDirect3DExecuteBufferImpl
* object
;
733 TRACE("iface %p, buffer_desc %p, buffer %p, outer_unknown %p.\n",
734 iface
, Desc
, ExecuteBuffer
, UnkOuter
);
737 return CLASS_E_NOAGGREGATION
;
739 /* Allocate the new Execute Buffer */
740 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirect3DExecuteBufferImpl
));
743 ERR("Out of memory when allocating a IDirect3DExecuteBufferImpl structure\n");
744 return DDERR_OUTOFMEMORY
;
747 hr
= d3d_execute_buffer_init(object
, This
, Desc
);
750 WARN("Failed to initialize execute buffer, hr %#x.\n", hr
);
751 HeapFree(GetProcessHeap(), 0, object
);
755 *ExecuteBuffer
= &object
->IDirect3DExecuteBuffer_iface
;
757 TRACE(" Returning IDirect3DExecuteBuffer at %p, implementation is at %p\n", *ExecuteBuffer
, object
);
762 /*****************************************************************************
763 * IDirect3DDevice::Execute
765 * Executes all the stuff in an execute buffer.
768 * ExecuteBuffer: The buffer to execute
769 * Viewport: The viewport used for rendering
773 * DDERR_INVALIDPARAMS if ExecuteBuffer == NULL
776 *****************************************************************************/
777 static HRESULT WINAPI
IDirect3DDeviceImpl_1_Execute(IDirect3DDevice
*iface
,
778 IDirect3DExecuteBuffer
*ExecuteBuffer
, IDirect3DViewport
*Viewport
, DWORD Flags
)
780 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
781 IDirect3DExecuteBufferImpl
*buffer
= unsafe_impl_from_IDirect3DExecuteBuffer(ExecuteBuffer
);
782 struct d3d_viewport
*viewport_impl
= unsafe_impl_from_IDirect3DViewport(Viewport
);
785 TRACE("iface %p, buffer %p, viewport %p, flags %#x.\n", iface
, ExecuteBuffer
, Viewport
, Flags
);
788 return DDERR_INVALIDPARAMS
;
791 wined3d_mutex_lock();
792 hr
= d3d_execute_buffer_execute(buffer
, This
, viewport_impl
);
793 wined3d_mutex_unlock();
798 /*****************************************************************************
799 * IDirect3DDevice3::AddViewport
801 * Add a Direct3DViewport to the device's viewport list. These viewports
802 * are wrapped to IDirect3DDevice7 viewports in viewport.c
804 * Exists in Version 1, 2 and 3. Note that IDirect3DViewport 1, 2 and 3
805 * are the same interfaces.
808 * Viewport: The viewport to add
811 * DDERR_INVALIDPARAMS if Viewport == NULL
814 *****************************************************************************/
815 static HRESULT WINAPI
816 IDirect3DDeviceImpl_3_AddViewport(IDirect3DDevice3
*iface
,
817 IDirect3DViewport3
*Viewport
)
819 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
820 struct d3d_viewport
*vp
= unsafe_impl_from_IDirect3DViewport3(Viewport
);
822 TRACE("iface %p, viewport %p.\n", iface
, Viewport
);
826 return DDERR_INVALIDPARAMS
;
828 wined3d_mutex_lock();
829 list_add_head(&This
->viewport_list
, &vp
->entry
);
830 vp
->active_device
= This
; /* Viewport must be usable for Clear() after AddViewport,
831 so set active_device here. */
832 wined3d_mutex_unlock();
837 static HRESULT WINAPI
IDirect3DDeviceImpl_2_AddViewport(IDirect3DDevice2
*iface
,
838 IDirect3DViewport2
*Direct3DViewport2
)
840 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
841 struct d3d_viewport
*vp
= unsafe_impl_from_IDirect3DViewport2(Direct3DViewport2
);
843 TRACE("iface %p, viewport %p.\n", iface
, Direct3DViewport2
);
845 return IDirect3DDevice3_AddViewport(&This
->IDirect3DDevice3_iface
, &vp
->IDirect3DViewport3_iface
);
848 static HRESULT WINAPI
IDirect3DDeviceImpl_1_AddViewport(IDirect3DDevice
*iface
,
849 IDirect3DViewport
*Direct3DViewport
)
851 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
852 struct d3d_viewport
*vp
= unsafe_impl_from_IDirect3DViewport(Direct3DViewport
);
854 TRACE("iface %p, viewport %p.\n", iface
, Direct3DViewport
);
856 return IDirect3DDevice3_AddViewport(&This
->IDirect3DDevice3_iface
, &vp
->IDirect3DViewport3_iface
);
859 /*****************************************************************************
860 * IDirect3DDevice3::DeleteViewport
862 * Deletes a Direct3DViewport from the device's viewport list.
864 * Exists in Version 1, 2 and 3. Note that all Viewport interface versions
868 * Viewport: The viewport to delete
872 * DDERR_INVALIDPARAMS if the viewport wasn't found in the list
874 *****************************************************************************/
875 static HRESULT WINAPI
IDirect3DDeviceImpl_3_DeleteViewport(IDirect3DDevice3
*iface
, IDirect3DViewport3
*viewport
)
877 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
878 struct d3d_viewport
*vp
= unsafe_impl_from_IDirect3DViewport3(viewport
);
880 TRACE("iface %p, viewport %p.\n", iface
, viewport
);
882 wined3d_mutex_lock();
884 if (vp
->active_device
!= This
)
886 WARN("Viewport %p active device is %p.\n", vp
, vp
->active_device
);
887 wined3d_mutex_unlock();
888 return DDERR_INVALIDPARAMS
;
891 vp
->active_device
= NULL
;
892 list_remove(&vp
->entry
);
894 wined3d_mutex_unlock();
899 static HRESULT WINAPI
IDirect3DDeviceImpl_2_DeleteViewport(IDirect3DDevice2
*iface
,
900 IDirect3DViewport2
*Direct3DViewport2
)
902 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
903 struct d3d_viewport
*vp
= unsafe_impl_from_IDirect3DViewport2(Direct3DViewport2
);
905 TRACE("iface %p, viewport %p.\n", iface
, Direct3DViewport2
);
907 return IDirect3DDevice3_DeleteViewport(&This
->IDirect3DDevice3_iface
, &vp
->IDirect3DViewport3_iface
);
910 static HRESULT WINAPI
IDirect3DDeviceImpl_1_DeleteViewport(IDirect3DDevice
*iface
,
911 IDirect3DViewport
*Direct3DViewport
)
913 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
914 struct d3d_viewport
*vp
= unsafe_impl_from_IDirect3DViewport(Direct3DViewport
);
916 TRACE("iface %p, viewport %p.\n", iface
, Direct3DViewport
);
918 return IDirect3DDevice3_DeleteViewport(&This
->IDirect3DDevice3_iface
, &vp
->IDirect3DViewport3_iface
);
921 /*****************************************************************************
922 * IDirect3DDevice3::NextViewport
924 * Returns a viewport from the viewport list, depending on the
925 * passed viewport and the flags.
927 * Exists in Version 1, 2 and 3. Note that all Viewport interface versions
931 * Viewport: Viewport to use for beginning the search
932 * Flags: D3DNEXT_NEXT, D3DNEXT_HEAD or D3DNEXT_TAIL
936 * DDERR_INVALIDPARAMS if the flags were wrong, or Viewport was NULL
938 *****************************************************************************/
939 static HRESULT WINAPI
940 IDirect3DDeviceImpl_3_NextViewport(IDirect3DDevice3
*iface
,
941 IDirect3DViewport3
*Viewport3
,
942 IDirect3DViewport3
**lplpDirect3DViewport3
,
945 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
946 struct d3d_viewport
*vp
= unsafe_impl_from_IDirect3DViewport3(Viewport3
);
947 struct d3d_viewport
*next
;
950 TRACE("iface %p, viewport %p, next %p, flags %#x.\n",
951 iface
, Viewport3
, lplpDirect3DViewport3
, Flags
);
955 *lplpDirect3DViewport3
= NULL
;
956 return DDERR_INVALIDPARAMS
;
960 wined3d_mutex_lock();
964 entry
= list_next(&This
->viewport_list
, &vp
->entry
);
968 entry
= list_head(&This
->viewport_list
);
972 entry
= list_tail(&This
->viewport_list
);
976 WARN("Invalid flags %#x.\n", Flags
);
977 *lplpDirect3DViewport3
= NULL
;
978 wined3d_mutex_unlock();
979 return DDERR_INVALIDPARAMS
;
984 next
= LIST_ENTRY(entry
, struct d3d_viewport
, entry
);
985 *lplpDirect3DViewport3
= &next
->IDirect3DViewport3_iface
;
988 *lplpDirect3DViewport3
= NULL
;
990 wined3d_mutex_unlock();
995 static HRESULT WINAPI
IDirect3DDeviceImpl_2_NextViewport(IDirect3DDevice2
*iface
,
996 IDirect3DViewport2
*Viewport2
, IDirect3DViewport2
**lplpDirect3DViewport2
, DWORD Flags
)
998 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
999 struct d3d_viewport
*vp
= unsafe_impl_from_IDirect3DViewport2(Viewport2
);
1000 IDirect3DViewport3
*res
;
1003 TRACE("iface %p, viewport %p, next %p, flags %#x.\n",
1004 iface
, Viewport2
, lplpDirect3DViewport2
, Flags
);
1006 hr
= IDirect3DDevice3_NextViewport(&This
->IDirect3DDevice3_iface
,
1007 &vp
->IDirect3DViewport3_iface
, &res
, Flags
);
1008 *lplpDirect3DViewport2
= (IDirect3DViewport2
*)res
;
1012 static HRESULT WINAPI
IDirect3DDeviceImpl_1_NextViewport(IDirect3DDevice
*iface
,
1013 IDirect3DViewport
*Viewport
, IDirect3DViewport
**lplpDirect3DViewport
, DWORD Flags
)
1015 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
1016 struct d3d_viewport
*vp
= unsafe_impl_from_IDirect3DViewport(Viewport
);
1017 IDirect3DViewport3
*res
;
1020 TRACE("iface %p, viewport %p, next %p, flags %#x.\n",
1021 iface
, Viewport
, lplpDirect3DViewport
, Flags
);
1023 hr
= IDirect3DDevice3_NextViewport(&This
->IDirect3DDevice3_iface
,
1024 &vp
->IDirect3DViewport3_iface
, &res
, Flags
);
1025 *lplpDirect3DViewport
= (IDirect3DViewport
*)res
;
1029 /*****************************************************************************
1030 * IDirect3DDevice::Pick
1032 * Executes an execute buffer without performing rendering. Instead, a
1033 * list of primitives that intersect with (x1,y1) of the passed rectangle
1034 * is created. IDirect3DDevice::GetPickRecords can be used to retrieve
1040 * ExecuteBuffer: Buffer to execute
1041 * Viewport: Viewport to use for execution
1042 * Flags: None are defined, according to the SDK
1043 * Rect: Specifies the coordinates to be picked. Only x1 and y2 are used,
1044 * x2 and y2 are ignored.
1047 * D3D_OK because it's a stub
1049 *****************************************************************************/
1050 static HRESULT WINAPI
1051 IDirect3DDeviceImpl_1_Pick(IDirect3DDevice
*iface
,
1052 IDirect3DExecuteBuffer
*ExecuteBuffer
,
1053 IDirect3DViewport
*Viewport
,
1057 FIXME("iface %p, buffer %p, viewport %p, flags %#x, rect %s stub!\n",
1058 iface
, ExecuteBuffer
, Viewport
, Flags
, wine_dbgstr_rect((RECT
*)Rect
));
1063 /*****************************************************************************
1064 * IDirect3DDevice::GetPickRecords
1066 * Retrieves the pick records generated by IDirect3DDevice::GetPickRecords
1071 * Count: Pointer to a DWORD containing the numbers of pick records to
1073 * D3DPickRec: Address to store the resulting D3DPICKRECORD array.
1076 * D3D_OK, because it's a stub
1078 *****************************************************************************/
1079 static HRESULT WINAPI
1080 IDirect3DDeviceImpl_1_GetPickRecords(IDirect3DDevice
*iface
,
1082 D3DPICKRECORD
*D3DPickRec
)
1084 FIXME("iface %p, count %p, records %p stub!\n", iface
, Count
, D3DPickRec
);
1089 /*****************************************************************************
1090 * IDirect3DDevice7::EnumTextureformats
1092 * Enumerates the supported texture formats. It has a list of all possible
1093 * formats and calls IWineD3D::CheckDeviceFormat for each format to see if
1094 * WineD3D supports it. If so, then it is passed to the app.
1096 * This is for Version 7 and 3, older versions have a different
1097 * callback function and their own implementation
1100 * Callback: Callback to call for each enumerated format
1101 * Arg: Argument to pass to the callback
1105 * DDERR_INVALIDPARAMS if Callback == NULL
1107 *****************************************************************************/
1109 IDirect3DDeviceImpl_7_EnumTextureFormats(IDirect3DDevice7
*iface
,
1110 LPD3DENUMPIXELFORMATSCALLBACK Callback
,
1113 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
1114 struct wined3d_display_mode mode
;
1118 static const enum wined3d_format_id FormatList
[] =
1121 WINED3DFMT_B5G5R5X1_UNORM
,
1122 WINED3DFMT_B5G5R5A1_UNORM
,
1123 WINED3DFMT_B4G4R4A4_UNORM
,
1124 WINED3DFMT_B5G6R5_UNORM
,
1126 WINED3DFMT_B8G8R8X8_UNORM
,
1127 WINED3DFMT_B8G8R8A8_UNORM
,
1129 WINED3DFMT_B2G3R3_UNORM
,
1137 static const enum wined3d_format_id BumpFormatList
[] =
1139 WINED3DFMT_R8G8_SNORM
,
1140 WINED3DFMT_R5G5_SNORM_L6_UNORM
,
1141 WINED3DFMT_R8G8_SNORM_L8X8_UNORM
,
1142 WINED3DFMT_R16G16_SNORM
,
1143 WINED3DFMT_R10G11B11_SNORM
,
1144 WINED3DFMT_R10G10B10_SNORM_A2_UNORM
1147 TRACE("iface %p, callback %p, context %p.\n", iface
, Callback
, Arg
);
1150 return DDERR_INVALIDPARAMS
;
1152 wined3d_mutex_lock();
1154 memset(&mode
, 0, sizeof(mode
));
1155 hr
= wined3d_device_get_display_mode(This
->ddraw
->wined3d_device
, 0, &mode
);
1158 wined3d_mutex_unlock();
1159 WARN("Cannot get the current adapter format\n");
1163 for (i
= 0; i
< sizeof(FormatList
) / sizeof(*FormatList
); ++i
)
1165 hr
= wined3d_check_device_format(This
->ddraw
->wined3d
, WINED3DADAPTER_DEFAULT
, WINED3D_DEVICE_TYPE_HAL
,
1166 mode
.format_id
, 0, WINED3D_RTYPE_TEXTURE
, FormatList
[i
], WINED3D_SURFACE_TYPE_OPENGL
);
1169 DDPIXELFORMAT pformat
;
1171 memset(&pformat
, 0, sizeof(pformat
));
1172 pformat
.dwSize
= sizeof(pformat
);
1173 PixelFormat_WineD3DtoDD(&pformat
, FormatList
[i
]);
1175 TRACE("Enumerating WineD3DFormat %d\n", FormatList
[i
]);
1176 hr
= Callback(&pformat
, Arg
);
1177 if(hr
!= DDENUMRET_OK
)
1179 TRACE("Format enumeration cancelled by application\n");
1180 wined3d_mutex_unlock();
1186 for (i
= 0; i
< sizeof(BumpFormatList
) / sizeof(*BumpFormatList
); ++i
)
1188 hr
= wined3d_check_device_format(This
->ddraw
->wined3d
, WINED3DADAPTER_DEFAULT
,
1189 WINED3D_DEVICE_TYPE_HAL
, mode
.format_id
, WINED3DUSAGE_QUERY_LEGACYBUMPMAP
,
1190 WINED3D_RTYPE_TEXTURE
, BumpFormatList
[i
], WINED3D_SURFACE_TYPE_OPENGL
);
1193 DDPIXELFORMAT pformat
;
1195 memset(&pformat
, 0, sizeof(pformat
));
1196 pformat
.dwSize
= sizeof(pformat
);
1197 PixelFormat_WineD3DtoDD(&pformat
, BumpFormatList
[i
]);
1199 TRACE("Enumerating WineD3DFormat %d\n", BumpFormatList
[i
]);
1200 hr
= Callback(&pformat
, Arg
);
1201 if(hr
!= DDENUMRET_OK
)
1203 TRACE("Format enumeration cancelled by application\n");
1204 wined3d_mutex_unlock();
1209 TRACE("End of enumeration\n");
1210 wined3d_mutex_unlock();
1215 static HRESULT WINAPI
1216 IDirect3DDeviceImpl_7_EnumTextureFormats_FPUSetup(IDirect3DDevice7
*iface
,
1217 LPD3DENUMPIXELFORMATSCALLBACK Callback
,
1220 return IDirect3DDeviceImpl_7_EnumTextureFormats(iface
, Callback
, Arg
);
1223 static HRESULT WINAPI
1224 IDirect3DDeviceImpl_7_EnumTextureFormats_FPUPreserve(IDirect3DDevice7
*iface
,
1225 LPD3DENUMPIXELFORMATSCALLBACK Callback
,
1231 old_fpucw
= d3d_fpu_setup();
1232 hr
= IDirect3DDeviceImpl_7_EnumTextureFormats(iface
, Callback
, Arg
);
1233 set_fpu_control_word(old_fpucw
);
1238 static HRESULT WINAPI
IDirect3DDeviceImpl_3_EnumTextureFormats(IDirect3DDevice3
*iface
,
1239 LPD3DENUMPIXELFORMATSCALLBACK Callback
, void *Arg
)
1241 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
1243 TRACE("iface %p, callback %p, context %p.\n", iface
, Callback
, Arg
);
1245 return IDirect3DDevice7_EnumTextureFormats(&This
->IDirect3DDevice7_iface
, Callback
, Arg
);
1248 /*****************************************************************************
1249 * IDirect3DDevice2::EnumTextureformats
1251 * EnumTextureFormats for Version 1 and 2, see
1252 * IDirect3DDevice7::EnumTexureFormats for a more detailed description.
1254 * This version has a different callback and does not enumerate FourCC
1257 *****************************************************************************/
1258 static HRESULT WINAPI
1259 IDirect3DDeviceImpl_2_EnumTextureFormats(IDirect3DDevice2
*iface
,
1260 LPD3DENUMTEXTUREFORMATSCALLBACK Callback
,
1263 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
1264 struct wined3d_display_mode mode
;
1268 static const enum wined3d_format_id FormatList
[] =
1271 WINED3DFMT_B5G5R5X1_UNORM
,
1272 WINED3DFMT_B5G5R5A1_UNORM
,
1273 WINED3DFMT_B4G4R4A4_UNORM
,
1274 WINED3DFMT_B5G6R5_UNORM
,
1276 WINED3DFMT_B8G8R8X8_UNORM
,
1277 WINED3DFMT_B8G8R8A8_UNORM
,
1279 WINED3DFMT_B2G3R3_UNORM
,
1281 /* FOURCC codes - Not in this version*/
1284 TRACE("iface %p, callback %p, context %p.\n", iface
, Callback
, Arg
);
1287 return DDERR_INVALIDPARAMS
;
1289 wined3d_mutex_lock();
1291 memset(&mode
, 0, sizeof(mode
));
1292 hr
= wined3d_device_get_display_mode(This
->ddraw
->wined3d_device
, 0, &mode
);
1295 wined3d_mutex_unlock();
1296 WARN("Cannot get the current adapter format\n");
1300 for (i
= 0; i
< sizeof(FormatList
) / sizeof(*FormatList
); ++i
)
1302 hr
= wined3d_check_device_format(This
->ddraw
->wined3d
, 0, WINED3D_DEVICE_TYPE_HAL
,
1303 mode
.format_id
, 0, WINED3D_RTYPE_TEXTURE
, FormatList
[i
], WINED3D_SURFACE_TYPE_OPENGL
);
1306 DDSURFACEDESC sdesc
;
1308 memset(&sdesc
, 0, sizeof(sdesc
));
1309 sdesc
.dwSize
= sizeof(sdesc
);
1310 sdesc
.dwFlags
= DDSD_PIXELFORMAT
| DDSD_CAPS
;
1311 sdesc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
1312 sdesc
.ddpfPixelFormat
.dwSize
= sizeof(sdesc
.ddpfPixelFormat
);
1313 PixelFormat_WineD3DtoDD(&sdesc
.ddpfPixelFormat
, FormatList
[i
]);
1315 TRACE("Enumerating WineD3DFormat %d\n", FormatList
[i
]);
1316 hr
= Callback(&sdesc
, Arg
);
1317 if(hr
!= DDENUMRET_OK
)
1319 TRACE("Format enumeration cancelled by application\n");
1320 wined3d_mutex_unlock();
1325 TRACE("End of enumeration\n");
1326 wined3d_mutex_unlock();
1331 static HRESULT WINAPI
IDirect3DDeviceImpl_1_EnumTextureFormats(IDirect3DDevice
*iface
,
1332 LPD3DENUMTEXTUREFORMATSCALLBACK Callback
, void *Arg
)
1334 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
1336 TRACE("iface %p, callback %p, context %p.\n", iface
, Callback
, Arg
);
1338 return IDirect3DDevice2_EnumTextureFormats(&This
->IDirect3DDevice2_iface
, Callback
, Arg
);
1341 /*****************************************************************************
1342 * IDirect3DDevice::CreateMatrix
1344 * Creates a matrix handle. A handle is created and memory for a D3DMATRIX is
1345 * allocated for the handle.
1350 * D3DMatHandle: Address to return the handle at
1354 * DDERR_INVALIDPARAMS if D3DMatHandle = NULL
1356 *****************************************************************************/
1357 static HRESULT WINAPI
1358 IDirect3DDeviceImpl_1_CreateMatrix(IDirect3DDevice
*iface
, D3DMATRIXHANDLE
*D3DMatHandle
)
1360 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
1364 TRACE("iface %p, matrix_handle %p.\n", iface
, D3DMatHandle
);
1367 return DDERR_INVALIDPARAMS
;
1369 Matrix
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(D3DMATRIX
));
1372 ERR("Out of memory when allocating a D3DMATRIX\n");
1373 return DDERR_OUTOFMEMORY
;
1376 wined3d_mutex_lock();
1378 h
= ddraw_allocate_handle(&This
->handle_table
, Matrix
, DDRAW_HANDLE_MATRIX
);
1379 if (h
== DDRAW_INVALID_HANDLE
)
1381 ERR("Failed to allocate a matrix handle.\n");
1382 HeapFree(GetProcessHeap(), 0, Matrix
);
1383 wined3d_mutex_unlock();
1384 return DDERR_OUTOFMEMORY
;
1387 *D3DMatHandle
= h
+ 1;
1389 TRACE(" returning matrix handle %d\n", *D3DMatHandle
);
1391 wined3d_mutex_unlock();
1396 /*****************************************************************************
1397 * IDirect3DDevice::SetMatrix
1399 * Sets a matrix for a matrix handle. The matrix is copied into the memory
1400 * allocated for the handle
1405 * D3DMatHandle: Handle to set the matrix to
1406 * D3DMatrix: Matrix to set
1410 * DDERR_INVALIDPARAMS if the handle of the matrix is invalid or the matrix
1413 *****************************************************************************/
1414 static HRESULT WINAPI
1415 IDirect3DDeviceImpl_1_SetMatrix(IDirect3DDevice
*iface
,
1416 D3DMATRIXHANDLE D3DMatHandle
,
1417 D3DMATRIX
*D3DMatrix
)
1419 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
1422 TRACE("iface %p, matrix_handle %#x, matrix %p.\n", iface
, D3DMatHandle
, D3DMatrix
);
1424 if (!D3DMatrix
) return DDERR_INVALIDPARAMS
;
1426 wined3d_mutex_lock();
1428 m
= ddraw_get_object(&This
->handle_table
, D3DMatHandle
- 1, DDRAW_HANDLE_MATRIX
);
1431 WARN("Invalid matrix handle.\n");
1432 wined3d_mutex_unlock();
1433 return DDERR_INVALIDPARAMS
;
1436 if (TRACE_ON(ddraw
))
1437 dump_D3DMATRIX(D3DMatrix
);
1441 if (D3DMatHandle
== This
->world
)
1442 wined3d_device_set_transform(This
->wined3d_device
,
1443 WINED3D_TS_WORLD_MATRIX(0), (struct wined3d_matrix
*)D3DMatrix
);
1445 if (D3DMatHandle
== This
->view
)
1446 wined3d_device_set_transform(This
->wined3d_device
,
1447 WINED3D_TS_VIEW
, (struct wined3d_matrix
*)D3DMatrix
);
1449 if (D3DMatHandle
== This
->proj
)
1450 wined3d_device_set_transform(This
->wined3d_device
,
1451 WINED3D_TS_PROJECTION
, (struct wined3d_matrix
*)D3DMatrix
);
1453 wined3d_mutex_unlock();
1458 /*****************************************************************************
1459 * IDirect3DDevice::GetMatrix
1461 * Returns the content of a D3DMATRIX handle
1466 * D3DMatHandle: Matrix handle to read the content from
1467 * D3DMatrix: Address to store the content at
1471 * DDERR_INVALIDPARAMS if D3DMatHandle is invalid or D3DMatrix is NULL
1473 *****************************************************************************/
1474 static HRESULT WINAPI
1475 IDirect3DDeviceImpl_1_GetMatrix(IDirect3DDevice
*iface
,
1476 D3DMATRIXHANDLE D3DMatHandle
,
1477 D3DMATRIX
*D3DMatrix
)
1479 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
1482 TRACE("iface %p, matrix_handle %#x, matrix %p.\n", iface
, D3DMatHandle
, D3DMatrix
);
1484 if (!D3DMatrix
) return DDERR_INVALIDPARAMS
;
1486 wined3d_mutex_lock();
1488 m
= ddraw_get_object(&This
->handle_table
, D3DMatHandle
- 1, DDRAW_HANDLE_MATRIX
);
1491 WARN("Invalid matrix handle.\n");
1492 wined3d_mutex_unlock();
1493 return DDERR_INVALIDPARAMS
;
1498 wined3d_mutex_unlock();
1503 /*****************************************************************************
1504 * IDirect3DDevice::DeleteMatrix
1506 * Destroys a Matrix handle. Frees the memory and unsets the handle data
1511 * D3DMatHandle: Handle to destroy
1515 * DDERR_INVALIDPARAMS if D3DMatHandle is invalid
1517 *****************************************************************************/
1518 static HRESULT WINAPI
1519 IDirect3DDeviceImpl_1_DeleteMatrix(IDirect3DDevice
*iface
,
1520 D3DMATRIXHANDLE D3DMatHandle
)
1522 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
1525 TRACE("iface %p, matrix_handle %#x.\n", iface
, D3DMatHandle
);
1527 wined3d_mutex_lock();
1529 m
= ddraw_free_handle(&This
->handle_table
, D3DMatHandle
- 1, DDRAW_HANDLE_MATRIX
);
1532 WARN("Invalid matrix handle.\n");
1533 wined3d_mutex_unlock();
1534 return DDERR_INVALIDPARAMS
;
1537 wined3d_mutex_unlock();
1539 HeapFree(GetProcessHeap(), 0, m
);
1544 /*****************************************************************************
1545 * IDirect3DDevice7::BeginScene
1547 * This method must be called before any rendering is performed.
1548 * IDirect3DDevice::EndScene has to be called after the scene is complete
1550 * Version 1, 2, 3 and 7
1553 * D3D_OK on success, for details see IWineD3DDevice::BeginScene
1554 * D3DERR_SCENE_IN_SCENE if WineD3D returns an error(Only in case of an already
1557 *****************************************************************************/
1559 IDirect3DDeviceImpl_7_BeginScene(IDirect3DDevice7
*iface
)
1561 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
1564 TRACE("iface %p.\n", iface
);
1566 wined3d_mutex_lock();
1567 hr
= wined3d_device_begin_scene(This
->wined3d_device
);
1568 wined3d_mutex_unlock();
1570 if(hr
== WINED3D_OK
) return D3D_OK
;
1571 else return D3DERR_SCENE_IN_SCENE
; /* TODO: Other possible causes of failure */
1574 static HRESULT WINAPI
1575 IDirect3DDeviceImpl_7_BeginScene_FPUSetup(IDirect3DDevice7
*iface
)
1577 return IDirect3DDeviceImpl_7_BeginScene(iface
);
1580 static HRESULT WINAPI
1581 IDirect3DDeviceImpl_7_BeginScene_FPUPreserve(IDirect3DDevice7
*iface
)
1586 old_fpucw
= d3d_fpu_setup();
1587 hr
= IDirect3DDeviceImpl_7_BeginScene(iface
);
1588 set_fpu_control_word(old_fpucw
);
1593 static HRESULT WINAPI
IDirect3DDeviceImpl_3_BeginScene(IDirect3DDevice3
*iface
)
1595 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
1596 TRACE("iface %p.\n", iface
);
1598 return IDirect3DDevice7_BeginScene(&This
->IDirect3DDevice7_iface
);
1601 static HRESULT WINAPI
IDirect3DDeviceImpl_2_BeginScene(IDirect3DDevice2
*iface
)
1603 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
1604 TRACE("iface %p.\n", iface
);
1606 return IDirect3DDevice7_BeginScene(&This
->IDirect3DDevice7_iface
);
1609 static HRESULT WINAPI
IDirect3DDeviceImpl_1_BeginScene(IDirect3DDevice
*iface
)
1611 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
1612 TRACE("iface %p.\n", iface
);
1614 return IDirect3DDevice7_BeginScene(&This
->IDirect3DDevice7_iface
);
1617 /*****************************************************************************
1618 * IDirect3DDevice7::EndScene
1620 * Ends a scene that has been begun with IDirect3DDevice7::BeginScene.
1621 * This method must be called after rendering is finished.
1623 * Version 1, 2, 3 and 7
1626 * D3D_OK on success, for details see IWineD3DDevice::EndScene
1627 * D3DERR_SCENE_NOT_IN_SCENE is returned if WineD3D returns an error. It does
1628 * that only if the scene was already ended.
1630 *****************************************************************************/
1632 IDirect3DDeviceImpl_7_EndScene(IDirect3DDevice7
*iface
)
1634 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
1637 TRACE("iface %p.\n", iface
);
1639 wined3d_mutex_lock();
1640 hr
= wined3d_device_end_scene(This
->wined3d_device
);
1641 wined3d_mutex_unlock();
1643 if(hr
== WINED3D_OK
) return D3D_OK
;
1644 else return D3DERR_SCENE_NOT_IN_SCENE
;
1647 static HRESULT WINAPI DECLSPEC_HOTPATCH
1648 IDirect3DDeviceImpl_7_EndScene_FPUSetup(IDirect3DDevice7
*iface
)
1650 return IDirect3DDeviceImpl_7_EndScene(iface
);
1653 static HRESULT WINAPI DECLSPEC_HOTPATCH
1654 IDirect3DDeviceImpl_7_EndScene_FPUPreserve(IDirect3DDevice7
*iface
)
1659 old_fpucw
= d3d_fpu_setup();
1660 hr
= IDirect3DDeviceImpl_7_EndScene(iface
);
1661 set_fpu_control_word(old_fpucw
);
1666 static HRESULT WINAPI DECLSPEC_HOTPATCH
IDirect3DDeviceImpl_3_EndScene(IDirect3DDevice3
*iface
)
1668 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
1669 TRACE("iface %p.\n", iface
);
1671 return IDirect3DDevice7_EndScene(&This
->IDirect3DDevice7_iface
);
1674 static HRESULT WINAPI DECLSPEC_HOTPATCH
IDirect3DDeviceImpl_2_EndScene(IDirect3DDevice2
*iface
)
1676 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
1677 TRACE("iface %p.\n", iface
);
1679 return IDirect3DDevice7_EndScene(&This
->IDirect3DDevice7_iface
);
1682 static HRESULT WINAPI DECLSPEC_HOTPATCH
IDirect3DDeviceImpl_1_EndScene(IDirect3DDevice
*iface
)
1684 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
1685 TRACE("iface %p.\n", iface
);
1687 return IDirect3DDevice7_EndScene(&This
->IDirect3DDevice7_iface
);
1690 /*****************************************************************************
1691 * IDirect3DDevice7::GetDirect3D
1693 * Returns the IDirect3D(= interface to the DirectDraw object) used to create
1697 * Direct3D7: Address to store the interface pointer at
1701 * DDERR_INVALIDPARAMS if Direct3D7 == NULL
1703 *****************************************************************************/
1704 static HRESULT WINAPI
1705 IDirect3DDeviceImpl_7_GetDirect3D(IDirect3DDevice7
*iface
,
1706 IDirect3D7
**Direct3D7
)
1708 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
1710 TRACE("iface %p, d3d %p.\n", iface
, Direct3D7
);
1713 return DDERR_INVALIDPARAMS
;
1715 *Direct3D7
= &This
->ddraw
->IDirect3D7_iface
;
1716 IDirect3D7_AddRef(*Direct3D7
);
1718 TRACE(" returning interface %p\n", *Direct3D7
);
1722 static HRESULT WINAPI
IDirect3DDeviceImpl_3_GetDirect3D(IDirect3DDevice3
*iface
,
1723 IDirect3D3
**Direct3D3
)
1725 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
1727 TRACE("iface %p, d3d %p.\n", iface
, Direct3D3
);
1730 return DDERR_INVALIDPARAMS
;
1732 IDirect3D3_AddRef(&This
->ddraw
->IDirect3D3_iface
);
1733 *Direct3D3
= &This
->ddraw
->IDirect3D3_iface
;
1734 TRACE(" returning interface %p\n", *Direct3D3
);
1738 static HRESULT WINAPI
IDirect3DDeviceImpl_2_GetDirect3D(IDirect3DDevice2
*iface
,
1739 IDirect3D2
**Direct3D2
)
1741 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
1743 TRACE("iface %p, d3d %p.\n", iface
, Direct3D2
);
1746 return DDERR_INVALIDPARAMS
;
1748 IDirect3D2_AddRef(&This
->ddraw
->IDirect3D2_iface
);
1749 *Direct3D2
= &This
->ddraw
->IDirect3D2_iface
;
1750 TRACE(" returning interface %p\n", *Direct3D2
);
1754 static HRESULT WINAPI
IDirect3DDeviceImpl_1_GetDirect3D(IDirect3DDevice
*iface
,
1755 IDirect3D
**Direct3D
)
1757 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
1759 TRACE("iface %p, d3d %p.\n", iface
, Direct3D
);
1762 return DDERR_INVALIDPARAMS
;
1764 IDirect3D_AddRef(&This
->ddraw
->IDirect3D_iface
);
1765 *Direct3D
= &This
->ddraw
->IDirect3D_iface
;
1766 TRACE(" returning interface %p\n", *Direct3D
);
1770 /*****************************************************************************
1771 * IDirect3DDevice3::SetCurrentViewport
1773 * Sets a Direct3DViewport as the current viewport.
1774 * For the thunks note that all viewport interface versions are equal
1777 * Direct3DViewport3: The viewport to set
1783 * (Is a NULL viewport valid?)
1785 *****************************************************************************/
1786 static HRESULT WINAPI
1787 IDirect3DDeviceImpl_3_SetCurrentViewport(IDirect3DDevice3
*iface
,
1788 IDirect3DViewport3
*Direct3DViewport3
)
1790 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
1791 struct d3d_viewport
*vp
= unsafe_impl_from_IDirect3DViewport3(Direct3DViewport3
);
1793 TRACE("iface %p, viewport %p.\n", iface
, Direct3DViewport3
);
1795 wined3d_mutex_lock();
1796 /* Do nothing if the specified viewport is the same as the current one */
1797 if (This
->current_viewport
== vp
)
1799 wined3d_mutex_unlock();
1803 if (vp
->active_device
!= This
)
1805 WARN("Viewport %p active device is %p.\n", vp
, vp
->active_device
);
1806 wined3d_mutex_unlock();
1807 return DDERR_INVALIDPARAMS
;
1810 /* Release previous viewport and AddRef the new one */
1811 if (This
->current_viewport
)
1813 TRACE("ViewportImpl is at %p, interface is at %p\n", This
->current_viewport
,
1814 &This
->current_viewport
->IDirect3DViewport3_iface
);
1815 IDirect3DViewport3_Release(&This
->current_viewport
->IDirect3DViewport3_iface
);
1817 IDirect3DViewport3_AddRef(Direct3DViewport3
);
1819 /* Set this viewport as the current viewport */
1820 This
->current_viewport
= vp
;
1822 /* Activate this viewport */
1823 viewport_activate(This
->current_viewport
, FALSE
);
1825 wined3d_mutex_unlock();
1830 static HRESULT WINAPI
IDirect3DDeviceImpl_2_SetCurrentViewport(IDirect3DDevice2
*iface
,
1831 IDirect3DViewport2
*Direct3DViewport2
)
1833 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
1834 struct d3d_viewport
*vp
= unsafe_impl_from_IDirect3DViewport2(Direct3DViewport2
);
1836 TRACE("iface %p, viewport %p.\n", iface
, Direct3DViewport2
);
1838 return IDirect3DDevice3_SetCurrentViewport(&This
->IDirect3DDevice3_iface
,
1839 &vp
->IDirect3DViewport3_iface
);
1842 /*****************************************************************************
1843 * IDirect3DDevice3::GetCurrentViewport
1845 * Returns the currently active viewport.
1850 * Direct3DViewport3: Address to return the interface pointer at
1854 * DDERR_INVALIDPARAMS if Direct3DViewport == NULL
1856 *****************************************************************************/
1857 static HRESULT WINAPI
1858 IDirect3DDeviceImpl_3_GetCurrentViewport(IDirect3DDevice3
*iface
,
1859 IDirect3DViewport3
**Direct3DViewport3
)
1861 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
1863 TRACE("iface %p, viewport %p.\n", iface
, Direct3DViewport3
);
1865 if(!Direct3DViewport3
)
1866 return DDERR_INVALIDPARAMS
;
1868 wined3d_mutex_lock();
1869 *Direct3DViewport3
= &This
->current_viewport
->IDirect3DViewport3_iface
;
1871 /* AddRef the returned viewport */
1872 if(*Direct3DViewport3
) IDirect3DViewport3_AddRef(*Direct3DViewport3
);
1874 TRACE(" returning interface %p\n", *Direct3DViewport3
);
1876 wined3d_mutex_unlock();
1881 static HRESULT WINAPI
IDirect3DDeviceImpl_2_GetCurrentViewport(IDirect3DDevice2
*iface
,
1882 IDirect3DViewport2
**Direct3DViewport2
)
1884 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
1887 TRACE("iface %p, viewport %p.\n", iface
, Direct3DViewport2
);
1889 hr
= IDirect3DDevice3_GetCurrentViewport(&This
->IDirect3DDevice3_iface
,
1890 (IDirect3DViewport3
**)Direct3DViewport2
);
1891 if(hr
!= D3D_OK
) return hr
;
1895 /*****************************************************************************
1896 * IDirect3DDevice7::SetRenderTarget
1898 * Sets the render target for the Direct3DDevice.
1899 * For the thunks note that IDirectDrawSurface7 == IDirectDrawSurface4 and
1900 * IDirectDrawSurface3 == IDirectDrawSurface
1902 * Version 2, 3 and 7
1905 * NewTarget: Pointer to an IDirectDrawSurface7 interface to set as the new
1910 * D3D_OK on success, for details see IWineD3DDevice::SetRenderTarget
1912 *****************************************************************************/
1913 static HRESULT
d3d_device_set_render_target(IDirect3DDeviceImpl
*This
, struct ddraw_surface
*target
)
1917 wined3d_mutex_lock();
1919 if (This
->target
== target
)
1921 TRACE("No-op SetRenderTarget operation, not doing anything\n");
1922 wined3d_mutex_unlock();
1925 This
->target
= target
;
1926 hr
= wined3d_device_set_render_target(This
->wined3d_device
, 0,
1927 target
? target
->wined3d_surface
: NULL
, FALSE
);
1930 wined3d_mutex_unlock();
1933 IDirect3DDeviceImpl_UpdateDepthStencil(This
);
1935 wined3d_mutex_unlock();
1941 IDirect3DDeviceImpl_7_SetRenderTarget(IDirect3DDevice7
*iface
,
1942 IDirectDrawSurface7
*NewTarget
,
1945 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
1946 struct ddraw_surface
*target
= unsafe_impl_from_IDirectDrawSurface7(NewTarget
);
1948 TRACE("iface %p, target %p, flags %#x.\n", iface
, NewTarget
, Flags
);
1949 /* Flags: Not used */
1951 IDirectDrawSurface7_AddRef(NewTarget
);
1952 IDirectDrawSurface7_Release(&This
->target
->IDirectDrawSurface7_iface
);
1953 return d3d_device_set_render_target(This
, target
);
1956 static HRESULT WINAPI
1957 IDirect3DDeviceImpl_7_SetRenderTarget_FPUSetup(IDirect3DDevice7
*iface
,
1958 IDirectDrawSurface7
*NewTarget
,
1961 return IDirect3DDeviceImpl_7_SetRenderTarget(iface
, NewTarget
, Flags
);
1964 static HRESULT WINAPI
1965 IDirect3DDeviceImpl_7_SetRenderTarget_FPUPreserve(IDirect3DDevice7
*iface
,
1966 IDirectDrawSurface7
*NewTarget
,
1972 old_fpucw
= d3d_fpu_setup();
1973 hr
= IDirect3DDeviceImpl_7_SetRenderTarget(iface
, NewTarget
, Flags
);
1974 set_fpu_control_word(old_fpucw
);
1979 static HRESULT WINAPI
IDirect3DDeviceImpl_3_SetRenderTarget(IDirect3DDevice3
*iface
,
1980 IDirectDrawSurface4
*NewRenderTarget
, DWORD Flags
)
1982 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
1983 struct ddraw_surface
*target
= unsafe_impl_from_IDirectDrawSurface4(NewRenderTarget
);
1985 TRACE("iface %p, target %p, flags %#x.\n", iface
, NewRenderTarget
, Flags
);
1987 IDirectDrawSurface4_AddRef(NewRenderTarget
);
1988 IDirectDrawSurface4_Release(&This
->target
->IDirectDrawSurface4_iface
);
1989 return d3d_device_set_render_target(This
, target
);
1992 static HRESULT WINAPI
IDirect3DDeviceImpl_2_SetRenderTarget(IDirect3DDevice2
*iface
,
1993 IDirectDrawSurface
*NewRenderTarget
, DWORD Flags
)
1995 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
1996 struct ddraw_surface
*target
= unsafe_impl_from_IDirectDrawSurface(NewRenderTarget
);
1998 TRACE("iface %p, target %p, flags %#x.\n", iface
, NewRenderTarget
, Flags
);
2000 IDirectDrawSurface_AddRef(NewRenderTarget
);
2001 IDirectDrawSurface_Release(&This
->target
->IDirectDrawSurface_iface
);
2002 return d3d_device_set_render_target(This
, target
);
2005 /*****************************************************************************
2006 * IDirect3DDevice7::GetRenderTarget
2008 * Returns the current render target.
2009 * This is handled locally, because the WineD3D render target's parent
2012 * Version 2, 3 and 7
2015 * RenderTarget: Address to store the surface interface pointer
2019 * DDERR_INVALIDPARAMS if RenderTarget == NULL
2021 *****************************************************************************/
2022 static HRESULT WINAPI
2023 IDirect3DDeviceImpl_7_GetRenderTarget(IDirect3DDevice7
*iface
,
2024 IDirectDrawSurface7
**RenderTarget
)
2026 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
2028 TRACE("iface %p, target %p.\n", iface
, RenderTarget
);
2031 return DDERR_INVALIDPARAMS
;
2033 wined3d_mutex_lock();
2034 *RenderTarget
= &This
->target
->IDirectDrawSurface7_iface
;
2035 IDirectDrawSurface7_AddRef(*RenderTarget
);
2036 wined3d_mutex_unlock();
2041 static HRESULT WINAPI
IDirect3DDeviceImpl_3_GetRenderTarget(IDirect3DDevice3
*iface
,
2042 IDirectDrawSurface4
**RenderTarget
)
2044 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
2045 IDirectDrawSurface7
*RenderTarget7
;
2046 struct ddraw_surface
*RenderTargetImpl
;
2049 TRACE("iface %p, target %p.\n", iface
, RenderTarget
);
2052 return DDERR_INVALIDPARAMS
;
2054 hr
= IDirect3DDevice7_GetRenderTarget(&This
->IDirect3DDevice7_iface
, &RenderTarget7
);
2055 if(hr
!= D3D_OK
) return hr
;
2056 RenderTargetImpl
= impl_from_IDirectDrawSurface7(RenderTarget7
);
2057 *RenderTarget
= &RenderTargetImpl
->IDirectDrawSurface4_iface
;
2058 IDirectDrawSurface4_AddRef(*RenderTarget
);
2059 IDirectDrawSurface7_Release(RenderTarget7
);
2063 static HRESULT WINAPI
IDirect3DDeviceImpl_2_GetRenderTarget(IDirect3DDevice2
*iface
,
2064 IDirectDrawSurface
**RenderTarget
)
2066 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
2067 IDirectDrawSurface7
*RenderTarget7
;
2068 struct ddraw_surface
*RenderTargetImpl
;
2071 TRACE("iface %p, target %p.\n", iface
, RenderTarget
);
2074 return DDERR_INVALIDPARAMS
;
2076 hr
= IDirect3DDevice7_GetRenderTarget(&This
->IDirect3DDevice7_iface
, &RenderTarget7
);
2077 if(hr
!= D3D_OK
) return hr
;
2078 RenderTargetImpl
= impl_from_IDirectDrawSurface7(RenderTarget7
);
2079 *RenderTarget
= &RenderTargetImpl
->IDirectDrawSurface_iface
;
2080 IDirectDrawSurface_AddRef(*RenderTarget
);
2081 IDirectDrawSurface7_Release(RenderTarget7
);
2085 /*****************************************************************************
2086 * IDirect3DDevice3::Begin
2088 * Begins a description block of vertices. This is similar to glBegin()
2089 * and glEnd(). After a call to IDirect3DDevice3::End, the vertices
2090 * described with IDirect3DDevice::Vertex are drawn.
2095 * PrimitiveType: The type of primitives to draw
2096 * VertexTypeDesc: A flexible vertex format description of the vertices
2097 * Flags: Some flags..
2102 *****************************************************************************/
2103 static HRESULT WINAPI
2104 IDirect3DDeviceImpl_3_Begin(IDirect3DDevice3
*iface
,
2105 D3DPRIMITIVETYPE PrimitiveType
,
2106 DWORD VertexTypeDesc
,
2109 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
2111 TRACE("iface %p, primitive_type %#x, FVF %#x, flags %#x.\n",
2112 iface
, PrimitiveType
, VertexTypeDesc
, Flags
);
2114 wined3d_mutex_lock();
2115 This
->primitive_type
= PrimitiveType
;
2116 This
->vertex_type
= VertexTypeDesc
;
2117 This
->render_flags
= Flags
;
2118 This
->vertex_size
= get_flexible_vertex_size(This
->vertex_type
);
2119 This
->nb_vertices
= 0;
2120 wined3d_mutex_unlock();
2125 static HRESULT WINAPI
IDirect3DDeviceImpl_2_Begin(IDirect3DDevice2
*iface
, D3DPRIMITIVETYPE d3dpt
,
2126 D3DVERTEXTYPE dwVertexTypeDesc
, DWORD dwFlags
)
2129 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
2131 TRACE("iface %p, primitive_type %#x, vertex_type %#x, flags %#x.\n",
2132 iface
, d3dpt
, dwVertexTypeDesc
, dwFlags
);
2134 switch(dwVertexTypeDesc
)
2136 case D3DVT_VERTEX
: FVF
= D3DFVF_VERTEX
; break;
2137 case D3DVT_LVERTEX
: FVF
= D3DFVF_LVERTEX
; break;
2138 case D3DVT_TLVERTEX
: FVF
= D3DFVF_TLVERTEX
; break;
2140 ERR("Unexpected vertex type %d\n", dwVertexTypeDesc
);
2141 return DDERR_INVALIDPARAMS
; /* Should never happen */
2144 return IDirect3DDevice3_Begin(&This
->IDirect3DDevice3_iface
, d3dpt
, FVF
, dwFlags
);
2147 /*****************************************************************************
2148 * IDirect3DDevice3::BeginIndexed
2150 * Draws primitives based on vertices in a vertex array which are specified
2156 * PrimitiveType: Primitive type to draw
2157 * VertexType: A FVF description of the vertex format
2158 * Vertices: pointer to an array containing the vertices
2159 * NumVertices: The number of vertices in the vertex array
2160 * Flags: Some flags ...
2163 * D3D_OK, because it's a stub
2165 *****************************************************************************/
2166 static HRESULT WINAPI
2167 IDirect3DDeviceImpl_3_BeginIndexed(IDirect3DDevice3
*iface
,
2168 D3DPRIMITIVETYPE PrimitiveType
,
2174 FIXME("iface %p, primitive_type %#x, FVF %#x, vertices %p, vertex_count %u, flags %#x stub!\n",
2175 iface
, PrimitiveType
, VertexType
, Vertices
, NumVertices
, Flags
);
2181 static HRESULT WINAPI
IDirect3DDeviceImpl_2_BeginIndexed(IDirect3DDevice2
*iface
,
2182 D3DPRIMITIVETYPE d3dptPrimitiveType
, D3DVERTEXTYPE d3dvtVertexType
,
2183 void *lpvVertices
, DWORD dwNumVertices
, DWORD dwFlags
)
2186 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
2188 TRACE("iface %p, primitive_type %#x, vertex_type %#x, vertices %p, vertex_count %u, flags %#x stub!\n",
2189 iface
, d3dptPrimitiveType
, d3dvtVertexType
, lpvVertices
, dwNumVertices
, dwFlags
);
2191 switch(d3dvtVertexType
)
2193 case D3DVT_VERTEX
: FVF
= D3DFVF_VERTEX
; break;
2194 case D3DVT_LVERTEX
: FVF
= D3DFVF_LVERTEX
; break;
2195 case D3DVT_TLVERTEX
: FVF
= D3DFVF_TLVERTEX
; break;
2197 ERR("Unexpected vertex type %d\n", d3dvtVertexType
);
2198 return DDERR_INVALIDPARAMS
; /* Should never happen */
2201 return IDirect3DDevice3_BeginIndexed(&This
->IDirect3DDevice3_iface
,
2202 d3dptPrimitiveType
, FVF
, lpvVertices
, dwNumVertices
, dwFlags
);
2205 /*****************************************************************************
2206 * IDirect3DDevice3::Vertex
2208 * Draws a vertex as described by IDirect3DDevice3::Begin. It places all
2209 * drawn vertices in a vertex buffer. If the buffer is too small, its
2210 * size is increased.
2215 * Vertex: Pointer to the vertex
2218 * D3D_OK, on success
2219 * DDERR_INVALIDPARAMS if Vertex is NULL
2221 *****************************************************************************/
2222 static HRESULT WINAPI
2223 IDirect3DDeviceImpl_3_Vertex(IDirect3DDevice3
*iface
,
2226 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
2228 TRACE("iface %p, vertex %p.\n", iface
, Vertex
);
2231 return DDERR_INVALIDPARAMS
;
2233 wined3d_mutex_lock();
2234 if ((This
->nb_vertices
+1)*This
->vertex_size
> This
->buffer_size
)
2237 This
->buffer_size
= This
->buffer_size
? This
->buffer_size
* 2 : This
->vertex_size
* 3;
2238 old_buffer
= This
->vertex_buffer
;
2239 This
->vertex_buffer
= HeapAlloc(GetProcessHeap(), 0, This
->buffer_size
);
2242 CopyMemory(This
->vertex_buffer
, old_buffer
, This
->nb_vertices
* This
->vertex_size
);
2243 HeapFree(GetProcessHeap(), 0, old_buffer
);
2247 CopyMemory(This
->vertex_buffer
+ This
->nb_vertices
++ * This
->vertex_size
, Vertex
, This
->vertex_size
);
2248 wined3d_mutex_unlock();
2253 static HRESULT WINAPI
IDirect3DDeviceImpl_2_Vertex(IDirect3DDevice2
*iface
, void *lpVertexType
)
2255 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
2257 TRACE("iface %p, vertex %p.\n", iface
, lpVertexType
);
2259 return IDirect3DDevice3_Vertex(&This
->IDirect3DDevice3_iface
, lpVertexType
);
2262 /*****************************************************************************
2263 * IDirect3DDevice3::Index
2265 * Specifies an index to a vertex to be drawn. The vertex array has to
2266 * be specified with BeginIndexed first.
2269 * VertexIndex: The index of the vertex to draw
2272 * D3D_OK because it's a stub
2274 *****************************************************************************/
2275 static HRESULT WINAPI
2276 IDirect3DDeviceImpl_3_Index(IDirect3DDevice3
*iface
,
2279 FIXME("iface %p, index %#x stub!\n", iface
, VertexIndex
);
2284 static HRESULT WINAPI
IDirect3DDeviceImpl_2_Index(IDirect3DDevice2
*iface
, WORD wVertexIndex
)
2286 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
2288 TRACE("iface %p, index %#x.\n", iface
, wVertexIndex
);
2290 return IDirect3DDevice3_Index(&This
->IDirect3DDevice3_iface
, wVertexIndex
);
2293 /*****************************************************************************
2294 * IDirect3DDevice3::End
2296 * Ends a draw begun with IDirect3DDevice3::Begin or
2297 * IDirect3DDevice::BeginIndexed. The vertices specified with
2298 * IDirect3DDevice::Vertex or IDirect3DDevice::Index are drawn using
2299 * the IDirect3DDevice7::DrawPrimitive method. So far only
2300 * non-indexed mode is supported
2305 * Flags: Some flags, as usual. Don't know which are defined
2308 * The return value of IDirect3DDevice7::DrawPrimitive
2310 *****************************************************************************/
2311 static HRESULT WINAPI
2312 IDirect3DDeviceImpl_3_End(IDirect3DDevice3
*iface
,
2315 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
2317 TRACE("iface %p, flags %#x.\n", iface
, Flags
);
2319 return IDirect3DDevice7_DrawPrimitive(&This
->IDirect3DDevice7_iface
, This
->primitive_type
,
2320 This
->vertex_type
, This
->vertex_buffer
, This
->nb_vertices
, This
->render_flags
);
2323 static HRESULT WINAPI
IDirect3DDeviceImpl_2_End(IDirect3DDevice2
*iface
, DWORD dwFlags
)
2325 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
2327 TRACE("iface %p, flags %#x.\n", iface
, dwFlags
);
2329 return IDirect3DDevice3_End(&This
->IDirect3DDevice3_iface
, dwFlags
);
2332 /*****************************************************************************
2333 * IDirect3DDevice7::GetRenderState
2335 * Returns the value of a render state. The possible render states are
2336 * defined in include/d3dtypes.h
2338 * Version 2, 3 and 7
2341 * RenderStateType: Render state to return the current setting of
2342 * Value: Address to store the value at
2345 * D3D_OK on success, for details see IWineD3DDevice::GetRenderState
2346 * DDERR_INVALIDPARAMS if Value == NULL
2348 *****************************************************************************/
2349 static HRESULT
IDirect3DDeviceImpl_7_GetRenderState(IDirect3DDevice7
*iface
,
2350 D3DRENDERSTATETYPE RenderStateType
, DWORD
*Value
)
2352 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
2355 TRACE("iface %p, state %#x, value %p.\n", iface
, RenderStateType
, Value
);
2358 return DDERR_INVALIDPARAMS
;
2360 wined3d_mutex_lock();
2361 switch(RenderStateType
)
2363 case D3DRENDERSTATE_TEXTUREMAG
:
2365 enum wined3d_texture_filter_type tex_mag
;
2367 hr
= wined3d_device_get_sampler_state(This
->wined3d_device
, 0, WINED3D_SAMP_MAG_FILTER
, &tex_mag
);
2371 case WINED3D_TEXF_POINT
:
2372 *Value
= D3DFILTER_NEAREST
;
2374 case WINED3D_TEXF_LINEAR
:
2375 *Value
= D3DFILTER_LINEAR
;
2378 ERR("Unhandled texture mag %d !\n",tex_mag
);
2384 case D3DRENDERSTATE_TEXTUREMIN
:
2386 enum wined3d_texture_filter_type tex_min
;
2387 enum wined3d_texture_filter_type tex_mip
;
2389 hr
= wined3d_device_get_sampler_state(This
->wined3d_device
,
2390 0, WINED3D_SAMP_MIN_FILTER
, &tex_min
);
2393 wined3d_mutex_unlock();
2396 hr
= wined3d_device_get_sampler_state(This
->wined3d_device
,
2397 0, WINED3D_SAMP_MIP_FILTER
, &tex_mip
);
2401 case WINED3D_TEXF_POINT
:
2404 case WINED3D_TEXF_NONE
:
2405 *Value
= D3DFILTER_NEAREST
;
2407 case WINED3D_TEXF_POINT
:
2408 *Value
= D3DFILTER_MIPNEAREST
;
2410 case WINED3D_TEXF_LINEAR
:
2411 *Value
= D3DFILTER_LINEARMIPNEAREST
;
2414 ERR("Unhandled mip filter %#x.\n", tex_mip
);
2415 *Value
= D3DFILTER_NEAREST
;
2419 case WINED3D_TEXF_LINEAR
:
2422 case WINED3D_TEXF_NONE
:
2423 *Value
= D3DFILTER_LINEAR
;
2425 case WINED3D_TEXF_POINT
:
2426 *Value
= D3DFILTER_MIPLINEAR
;
2428 case WINED3D_TEXF_LINEAR
:
2429 *Value
= D3DFILTER_LINEARMIPLINEAR
;
2432 ERR("Unhandled mip filter %#x.\n", tex_mip
);
2433 *Value
= D3DFILTER_LINEAR
;
2438 ERR("Unhandled texture min filter %#x.\n",tex_min
);
2439 *Value
= D3DFILTER_NEAREST
;
2445 case D3DRENDERSTATE_TEXTUREADDRESS
:
2446 case D3DRENDERSTATE_TEXTUREADDRESSU
:
2447 hr
= wined3d_device_get_sampler_state(This
->wined3d_device
,
2448 0, WINED3D_SAMP_ADDRESS_U
, Value
);
2450 case D3DRENDERSTATE_TEXTUREADDRESSV
:
2451 hr
= wined3d_device_get_sampler_state(This
->wined3d_device
,
2452 0, WINED3D_SAMP_ADDRESS_V
, Value
);
2455 case D3DRENDERSTATE_BORDERCOLOR
:
2456 FIXME("Unhandled render state D3DRENDERSTATE_BORDERCOLOR.\n");
2460 case D3DRENDERSTATE_TEXTUREHANDLE
:
2461 case D3DRENDERSTATE_TEXTUREMAPBLEND
:
2462 WARN("Render state %#x is invalid in d3d7.\n", RenderStateType
);
2463 hr
= DDERR_INVALIDPARAMS
;
2466 case D3DRENDERSTATE_ZBIAS
:
2467 hr
= wined3d_device_get_render_state(This
->wined3d_device
, WINED3D_RS_DEPTHBIAS
, Value
);
2471 if (RenderStateType
>= D3DRENDERSTATE_STIPPLEPATTERN00
2472 && RenderStateType
<= D3DRENDERSTATE_STIPPLEPATTERN31
)
2474 FIXME("Unhandled stipple pattern render state (%#x).\n",
2479 hr
= wined3d_device_get_render_state(This
->wined3d_device
, RenderStateType
, Value
);
2481 wined3d_mutex_unlock();
2486 static HRESULT WINAPI
2487 IDirect3DDeviceImpl_7_GetRenderState_FPUSetup(IDirect3DDevice7
*iface
,
2488 D3DRENDERSTATETYPE RenderStateType
,
2491 return IDirect3DDeviceImpl_7_GetRenderState(iface
, RenderStateType
, Value
);
2494 static HRESULT WINAPI
2495 IDirect3DDeviceImpl_7_GetRenderState_FPUPreserve(IDirect3DDevice7
*iface
,
2496 D3DRENDERSTATETYPE RenderStateType
,
2502 old_fpucw
= d3d_fpu_setup();
2503 hr
= IDirect3DDeviceImpl_7_GetRenderState(iface
, RenderStateType
, Value
);
2504 set_fpu_control_word(old_fpucw
);
2509 static HRESULT WINAPI
2510 IDirect3DDeviceImpl_3_GetRenderState(IDirect3DDevice3
*iface
,
2511 D3DRENDERSTATETYPE dwRenderStateType
,
2512 DWORD
*lpdwRenderState
)
2514 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
2517 TRACE("iface %p, state %#x, value %p.\n", iface
, dwRenderStateType
, lpdwRenderState
);
2519 switch(dwRenderStateType
)
2521 case D3DRENDERSTATE_TEXTUREHANDLE
:
2523 /* This state is wrapped to SetTexture in SetRenderState, so
2524 * it has to be wrapped to GetTexture here. */
2525 struct wined3d_texture
*tex
= NULL
;
2526 *lpdwRenderState
= 0;
2528 wined3d_mutex_lock();
2529 hr
= wined3d_device_get_texture(This
->wined3d_device
, 0, &tex
);
2530 if (SUCCEEDED(hr
) && tex
)
2532 /* The parent of the texture is the IDirectDrawSurface7
2533 * interface of the ddraw surface. */
2534 struct ddraw_surface
*parent
= wined3d_texture_get_parent(tex
);
2535 if (parent
) *lpdwRenderState
= parent
->Handle
;
2536 wined3d_texture_decref(tex
);
2538 wined3d_mutex_unlock();
2543 case D3DRENDERSTATE_TEXTUREMAPBLEND
:
2545 /* D3DRENDERSTATE_TEXTUREMAPBLEND is mapped to texture state stages in SetRenderState; reverse
2546 the mapping to get the value. */
2547 DWORD colorop
, colorarg1
, colorarg2
;
2548 DWORD alphaop
, alphaarg1
, alphaarg2
;
2550 wined3d_mutex_lock();
2552 This
->legacyTextureBlending
= TRUE
;
2554 wined3d_device_get_texture_stage_state(This
->wined3d_device
, 0, WINED3D_TSS_COLOR_OP
, &colorop
);
2555 wined3d_device_get_texture_stage_state(This
->wined3d_device
, 0, WINED3D_TSS_COLOR_ARG1
, &colorarg1
);
2556 wined3d_device_get_texture_stage_state(This
->wined3d_device
, 0, WINED3D_TSS_COLOR_ARG2
, &colorarg2
);
2557 wined3d_device_get_texture_stage_state(This
->wined3d_device
, 0, WINED3D_TSS_ALPHA_OP
, &alphaop
);
2558 wined3d_device_get_texture_stage_state(This
->wined3d_device
, 0, WINED3D_TSS_ALPHA_ARG1
, &alphaarg1
);
2559 wined3d_device_get_texture_stage_state(This
->wined3d_device
, 0, WINED3D_TSS_ALPHA_ARG2
, &alphaarg2
);
2561 if (colorop
== WINED3D_TOP_SELECT_ARG1
&& colorarg1
== WINED3DTA_TEXTURE
2562 && alphaop
== WINED3D_TOP_SELECT_ARG1
&& alphaarg1
== WINED3DTA_TEXTURE
)
2563 *lpdwRenderState
= D3DTBLEND_DECAL
;
2564 else if (colorop
== WINED3D_TOP_SELECT_ARG1
&& colorarg1
== WINED3DTA_TEXTURE
2565 && alphaop
== WINED3D_TOP_MODULATE
2566 && alphaarg1
== WINED3DTA_TEXTURE
&& alphaarg2
== WINED3DTA_CURRENT
)
2567 *lpdwRenderState
= D3DTBLEND_DECALALPHA
;
2568 else if (colorop
== WINED3D_TOP_MODULATE
2569 && colorarg1
== WINED3DTA_TEXTURE
&& colorarg2
== WINED3DTA_CURRENT
2570 && alphaop
== WINED3D_TOP_MODULATE
2571 && alphaarg1
== WINED3DTA_TEXTURE
&& alphaarg2
== WINED3DTA_CURRENT
)
2572 *lpdwRenderState
= D3DTBLEND_MODULATEALPHA
;
2575 struct wined3d_texture
*tex
= NULL
;
2577 BOOL tex_alpha
= FALSE
;
2578 DDPIXELFORMAT ddfmt
;
2580 hr
= wined3d_device_get_texture(This
->wined3d_device
, 0, &tex
);
2582 if(hr
== WINED3D_OK
&& tex
)
2584 struct wined3d_resource
*sub_resource
;
2586 if ((sub_resource
= wined3d_texture_get_sub_resource(tex
, 0)))
2588 struct wined3d_resource_desc desc
;
2590 wined3d_resource_get_desc(sub_resource
, &desc
);
2591 ddfmt
.dwSize
= sizeof(ddfmt
);
2592 PixelFormat_WineD3DtoDD(&ddfmt
, desc
.format
);
2593 if (ddfmt
.u5
.dwRGBAlphaBitMask
) tex_alpha
= TRUE
;
2596 wined3d_texture_decref(tex
);
2599 if (!(colorop
== WINED3D_TOP_MODULATE
2600 && colorarg1
== WINED3DTA_TEXTURE
&& colorarg2
== WINED3DTA_CURRENT
2601 && alphaop
== (tex_alpha
? WINED3D_TOP_SELECT_ARG1
: WINED3D_TOP_SELECT_ARG2
)
2602 && alphaarg1
== WINED3DTA_TEXTURE
&& alphaarg2
== WINED3DTA_CURRENT
))
2603 ERR("Unexpected texture stage state setup, returning D3DTBLEND_MODULATE - likely erroneous.\n");
2605 *lpdwRenderState
= D3DTBLEND_MODULATE
;
2608 wined3d_mutex_unlock();
2614 return IDirect3DDevice7_GetRenderState(&This
->IDirect3DDevice7_iface
, dwRenderStateType
, lpdwRenderState
);
2618 static HRESULT WINAPI
IDirect3DDeviceImpl_2_GetRenderState(IDirect3DDevice2
*iface
,
2619 D3DRENDERSTATETYPE dwRenderStateType
, DWORD
*lpdwRenderState
)
2621 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
2623 TRACE("iface %p, state %#x, value %p.\n", iface
, dwRenderStateType
, lpdwRenderState
);
2625 return IDirect3DDevice3_GetRenderState(&This
->IDirect3DDevice3_iface
,
2626 dwRenderStateType
, lpdwRenderState
);
2629 /*****************************************************************************
2630 * IDirect3DDevice7::SetRenderState
2632 * Sets a render state. The possible render states are defined in
2633 * include/d3dtypes.h
2635 * Version 2, 3 and 7
2638 * RenderStateType: State to set
2639 * Value: Value to assign to that state
2642 * D3D_OK on success,
2643 * for details see IWineD3DDevice::SetRenderState
2645 *****************************************************************************/
2647 IDirect3DDeviceImpl_7_SetRenderState(IDirect3DDevice7
*iface
,
2648 D3DRENDERSTATETYPE RenderStateType
,
2651 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
2654 TRACE("iface %p, state %#x, value %#x.\n", iface
, RenderStateType
, Value
);
2656 wined3d_mutex_lock();
2657 /* Some render states need special care */
2658 switch(RenderStateType
)
2661 * The ddraw texture filter mapping works like this:
2662 * D3DFILTER_NEAREST Point min/mag, no mip
2663 * D3DFILTER_MIPNEAREST Point min/mag, point mip
2664 * D3DFILTER_LINEARMIPNEAREST: Point min/mag, linear mip
2666 * D3DFILTER_LINEAR Linear min/mag, no mip
2667 * D3DFILTER_MIPLINEAR Linear min/mag, point mip
2668 * D3DFILTER_LINEARMIPLINEAR Linear min/mag, linear mip
2670 * This is the opposite of the GL naming convention,
2671 * D3DFILTER_LINEARMIPNEAREST corresponds to GL_NEAREST_MIPMAP_LINEAR.
2673 case D3DRENDERSTATE_TEXTUREMAG
:
2675 enum wined3d_texture_filter_type tex_mag
;
2679 case D3DFILTER_NEAREST
:
2680 case D3DFILTER_MIPNEAREST
:
2681 case D3DFILTER_LINEARMIPNEAREST
:
2682 tex_mag
= WINED3D_TEXF_POINT
;
2684 case D3DFILTER_LINEAR
:
2685 case D3DFILTER_MIPLINEAR
:
2686 case D3DFILTER_LINEARMIPLINEAR
:
2687 tex_mag
= WINED3D_TEXF_LINEAR
;
2690 tex_mag
= WINED3D_TEXF_POINT
;
2691 ERR("Unhandled texture mag %d !\n",Value
);
2695 hr
= wined3d_device_set_sampler_state(This
->wined3d_device
, 0, WINED3D_SAMP_MAG_FILTER
, tex_mag
);
2699 case D3DRENDERSTATE_TEXTUREMIN
:
2701 enum wined3d_texture_filter_type tex_min
;
2702 enum wined3d_texture_filter_type tex_mip
;
2704 switch ((D3DTEXTUREFILTER
)Value
)
2706 case D3DFILTER_NEAREST
:
2707 tex_min
= WINED3D_TEXF_POINT
;
2708 tex_mip
= WINED3D_TEXF_NONE
;
2710 case D3DFILTER_LINEAR
:
2711 tex_min
= WINED3D_TEXF_LINEAR
;
2712 tex_mip
= WINED3D_TEXF_NONE
;
2714 case D3DFILTER_MIPNEAREST
:
2715 tex_min
= WINED3D_TEXF_POINT
;
2716 tex_mip
= WINED3D_TEXF_POINT
;
2718 case D3DFILTER_MIPLINEAR
:
2719 tex_min
= WINED3D_TEXF_LINEAR
;
2720 tex_mip
= WINED3D_TEXF_POINT
;
2722 case D3DFILTER_LINEARMIPNEAREST
:
2723 tex_min
= WINED3D_TEXF_POINT
;
2724 tex_mip
= WINED3D_TEXF_LINEAR
;
2726 case D3DFILTER_LINEARMIPLINEAR
:
2727 tex_min
= WINED3D_TEXF_LINEAR
;
2728 tex_mip
= WINED3D_TEXF_LINEAR
;
2732 ERR("Unhandled texture min %d !\n",Value
);
2733 tex_min
= WINED3D_TEXF_POINT
;
2734 tex_mip
= WINED3D_TEXF_NONE
;
2738 wined3d_device_set_sampler_state(This
->wined3d_device
,
2739 0, WINED3D_SAMP_MIP_FILTER
, tex_mip
);
2740 hr
= wined3d_device_set_sampler_state(This
->wined3d_device
,
2741 0, WINED3D_SAMP_MIN_FILTER
, tex_min
);
2745 case D3DRENDERSTATE_TEXTUREADDRESS
:
2746 wined3d_device_set_sampler_state(This
->wined3d_device
,
2747 0, WINED3D_SAMP_ADDRESS_V
, Value
);
2749 case D3DRENDERSTATE_TEXTUREADDRESSU
:
2750 hr
= wined3d_device_set_sampler_state(This
->wined3d_device
,
2751 0, WINED3D_SAMP_ADDRESS_U
, Value
);
2753 case D3DRENDERSTATE_TEXTUREADDRESSV
:
2754 hr
= wined3d_device_set_sampler_state(This
->wined3d_device
,
2755 0, WINED3D_SAMP_ADDRESS_V
, Value
);
2758 case D3DRENDERSTATE_BORDERCOLOR
:
2759 /* This should probably just forward to the corresponding sampler
2760 * state. Needs tests. */
2761 FIXME("Unhandled render state D3DRENDERSTATE_BORDERCOLOR.\n");
2765 case D3DRENDERSTATE_TEXTUREHANDLE
:
2766 case D3DRENDERSTATE_TEXTUREMAPBLEND
:
2767 WARN("Render state %#x is invalid in d3d7.\n", RenderStateType
);
2768 hr
= DDERR_INVALIDPARAMS
;
2771 case D3DRENDERSTATE_ZBIAS
:
2772 hr
= wined3d_device_set_render_state(This
->wined3d_device
, WINED3D_RS_DEPTHBIAS
, Value
);
2776 if (RenderStateType
>= D3DRENDERSTATE_STIPPLEPATTERN00
2777 && RenderStateType
<= D3DRENDERSTATE_STIPPLEPATTERN31
)
2779 FIXME("Unhandled stipple pattern render state (%#x).\n",
2785 hr
= wined3d_device_set_render_state(This
->wined3d_device
, RenderStateType
, Value
);
2788 wined3d_mutex_unlock();
2793 static HRESULT WINAPI
2794 IDirect3DDeviceImpl_7_SetRenderState_FPUSetup(IDirect3DDevice7
*iface
,
2795 D3DRENDERSTATETYPE RenderStateType
,
2798 return IDirect3DDeviceImpl_7_SetRenderState(iface
, RenderStateType
, Value
);
2801 static HRESULT WINAPI
2802 IDirect3DDeviceImpl_7_SetRenderState_FPUPreserve(IDirect3DDevice7
*iface
,
2803 D3DRENDERSTATETYPE RenderStateType
,
2809 old_fpucw
= d3d_fpu_setup();
2810 hr
= IDirect3DDeviceImpl_7_SetRenderState(iface
, RenderStateType
, Value
);
2811 set_fpu_control_word(old_fpucw
);
2816 static HRESULT WINAPI
2817 IDirect3DDeviceImpl_3_SetRenderState(IDirect3DDevice3
*iface
,
2818 D3DRENDERSTATETYPE RenderStateType
,
2821 /* Note about D3DRENDERSTATE_TEXTUREMAPBLEND implementation: most of values
2822 for this state can be directly mapped to texture stage colorop and alphaop, but
2823 D3DTBLEND_MODULATE is tricky: it uses alpha from texture when available and alpha
2824 from diffuse otherwise. So changing the texture must be monitored in SetTexture to modify
2825 alphaarg when needed.
2827 Aliens vs Predator 1 depends on accurate D3DTBLEND_MODULATE emulation
2829 Legacy texture blending (TEXTUREMAPBLEND) and texture stage states: directx6 docs state that
2830 TEXTUREMAPBLEND is deprecated, yet can still be used. Games must not use both or results
2831 are undefined. D3DTBLEND_MODULATE mode in particular is dependent on texture pixel format and
2832 requires fixup of stage 0 texture states when texture changes, but this fixup can interfere
2833 with games not using this deprecated state. So a flag 'legacyTextureBlending' has to be kept
2834 in device - TRUE if the app is using TEXTUREMAPBLEND.
2836 Tests show that setting TEXTUREMAPBLEND on native doesn't seem to change values returned by
2837 GetTextureStageState and vice versa. Not so on Wine, but it is 'undefined' anyway so, probably, ok,
2838 unless some broken game will be found that cares. */
2841 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
2843 TRACE("iface %p, state %#x, value %#x.\n", iface
, RenderStateType
, Value
);
2845 wined3d_mutex_lock();
2847 switch(RenderStateType
)
2849 case D3DRENDERSTATE_TEXTUREHANDLE
:
2851 struct ddraw_surface
*surf
;
2855 hr
= wined3d_device_set_texture(This
->wined3d_device
, 0, NULL
);
2859 surf
= ddraw_get_object(&This
->handle_table
, Value
- 1, DDRAW_HANDLE_SURFACE
);
2862 WARN("Invalid texture handle.\n");
2863 hr
= DDERR_INVALIDPARAMS
;
2867 hr
= IDirect3DDevice3_SetTexture(iface
, 0, &surf
->IDirect3DTexture2_iface
);
2871 case D3DRENDERSTATE_TEXTUREMAPBLEND
:
2873 This
->legacyTextureBlending
= TRUE
;
2875 switch ( (D3DTEXTUREBLEND
) Value
)
2877 case D3DTBLEND_MODULATE
:
2879 struct wined3d_texture
*tex
= NULL
;
2880 BOOL tex_alpha
= FALSE
;
2881 DDPIXELFORMAT ddfmt
;
2883 hr
= wined3d_device_get_texture(This
->wined3d_device
, 0, &tex
);
2885 if(hr
== WINED3D_OK
&& tex
)
2887 struct wined3d_resource
*sub_resource
;
2889 if ((sub_resource
= wined3d_texture_get_sub_resource(tex
, 0)))
2891 struct wined3d_resource_desc desc
;
2893 wined3d_resource_get_desc(sub_resource
, &desc
);
2894 ddfmt
.dwSize
= sizeof(ddfmt
);
2895 PixelFormat_WineD3DtoDD(&ddfmt
, desc
.format
);
2896 if (ddfmt
.u5
.dwRGBAlphaBitMask
) tex_alpha
= TRUE
;
2899 wined3d_texture_decref(tex
);
2903 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2904 0, WINED3D_TSS_ALPHA_OP
, WINED3D_TOP_SELECT_ARG1
);
2906 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2907 0, WINED3D_TSS_ALPHA_OP
, WINED3D_TOP_SELECT_ARG2
);
2908 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2909 0, WINED3D_TSS_ALPHA_ARG1
, WINED3DTA_TEXTURE
);
2910 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2911 0, WINED3D_TSS_ALPHA_ARG2
, WINED3DTA_CURRENT
);
2912 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2913 0, WINED3D_TSS_COLOR_ARG1
, WINED3DTA_TEXTURE
);
2914 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2915 0, WINED3D_TSS_COLOR_ARG2
, WINED3DTA_CURRENT
);
2916 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2917 0, WINED3D_TSS_COLOR_OP
, WINED3D_TOP_MODULATE
);
2922 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2923 0, WINED3D_TSS_COLOR_OP
, WINED3D_TOP_ADD
);
2924 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2925 0, WINED3D_TSS_COLOR_ARG1
, WINED3DTA_TEXTURE
);
2926 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2927 0, WINED3D_TSS_COLOR_ARG2
, WINED3DTA_CURRENT
);
2928 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2929 0, WINED3D_TSS_ALPHA_OP
, WINED3D_TOP_SELECT_ARG2
);
2930 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2931 0, WINED3D_TSS_ALPHA_ARG2
, WINED3DTA_CURRENT
);
2934 case D3DTBLEND_MODULATEALPHA
:
2935 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2936 0, WINED3D_TSS_COLOR_ARG1
, WINED3DTA_TEXTURE
);
2937 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2938 0, WINED3D_TSS_ALPHA_ARG1
, WINED3DTA_TEXTURE
);
2939 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2940 0, WINED3D_TSS_COLOR_ARG2
, WINED3DTA_CURRENT
);
2941 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2942 0, WINED3D_TSS_ALPHA_ARG2
, WINED3DTA_CURRENT
);
2943 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2944 0, WINED3D_TSS_COLOR_OP
, WINED3D_TOP_MODULATE
);
2945 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2946 0, WINED3D_TSS_ALPHA_OP
, WINED3D_TOP_MODULATE
);
2949 case D3DTBLEND_COPY
:
2950 case D3DTBLEND_DECAL
:
2951 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2952 0, WINED3D_TSS_COLOR_ARG1
, WINED3DTA_TEXTURE
);
2953 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2954 0, WINED3D_TSS_ALPHA_ARG1
, WINED3DTA_TEXTURE
);
2955 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2956 0, WINED3D_TSS_COLOR_OP
, WINED3D_TOP_SELECT_ARG1
);
2957 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2958 0, WINED3D_TSS_ALPHA_OP
, WINED3D_TOP_SELECT_ARG1
);
2961 case D3DTBLEND_DECALALPHA
:
2962 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2963 0, WINED3D_TSS_COLOR_OP
, WINED3D_TOP_BLEND_TEXTURE_ALPHA
);
2964 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2965 0, WINED3D_TSS_COLOR_ARG1
, WINED3DTA_TEXTURE
);
2966 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2967 0, WINED3D_TSS_COLOR_ARG2
, WINED3DTA_CURRENT
);
2968 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2969 0, WINED3D_TSS_ALPHA_OP
, WINED3D_TOP_SELECT_ARG2
);
2970 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2971 0, WINED3D_TSS_ALPHA_ARG2
, WINED3DTA_CURRENT
);
2975 ERR("Unhandled texture environment %d !\n",Value
);
2983 hr
= IDirect3DDevice7_SetRenderState(&This
->IDirect3DDevice7_iface
, RenderStateType
, Value
);
2986 wined3d_mutex_unlock();
2991 static HRESULT WINAPI
IDirect3DDeviceImpl_2_SetRenderState(IDirect3DDevice2
*iface
,
2992 D3DRENDERSTATETYPE RenderStateType
, DWORD Value
)
2994 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
2996 TRACE("iface %p, state %#x, value %#x.\n", iface
, RenderStateType
, Value
);
2998 return IDirect3DDevice3_SetRenderState(&This
->IDirect3DDevice3_iface
, RenderStateType
, Value
);
3001 /*****************************************************************************
3002 * Direct3DDevice3::SetLightState
3004 * Sets a light state for Direct3DDevice3 and Direct3DDevice2. The
3005 * light states are forwarded to Direct3DDevice7 render states
3010 * LightStateType: The light state to change
3011 * Value: The value to assign to that light state
3015 * DDERR_INVALIDPARAMS if the parameters were incorrect
3016 * Also check IDirect3DDevice7::SetRenderState
3018 *****************************************************************************/
3019 static HRESULT WINAPI
3020 IDirect3DDeviceImpl_3_SetLightState(IDirect3DDevice3
*iface
,
3021 D3DLIGHTSTATETYPE LightStateType
,
3024 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
3027 TRACE("iface %p, state %#x, value %#x.\n", iface
, LightStateType
, Value
);
3029 if (!LightStateType
|| (LightStateType
> D3DLIGHTSTATE_COLORVERTEX
))
3031 TRACE("Unexpected Light State Type\n");
3032 return DDERR_INVALIDPARAMS
;
3035 wined3d_mutex_lock();
3036 if (LightStateType
== D3DLIGHTSTATE_MATERIAL
/* 1 */)
3038 struct d3d_material
*m
= ddraw_get_object(&This
->handle_table
, Value
- 1, DDRAW_HANDLE_MATERIAL
);
3041 WARN("Invalid material handle.\n");
3042 wined3d_mutex_unlock();
3043 return DDERR_INVALIDPARAMS
;
3046 TRACE(" activating material %p.\n", m
);
3047 material_activate(m
);
3049 This
->material
= Value
;
3051 else if (LightStateType
== D3DLIGHTSTATE_COLORMODEL
/* 3 */)
3056 ERR("DDCOLOR_MONO should not happen!\n");
3059 /* We are already in this mode */
3060 TRACE("Setting color model to RGB (no-op).\n");
3063 ERR("Unknown color model!\n");
3064 wined3d_mutex_unlock();
3065 return DDERR_INVALIDPARAMS
;
3070 D3DRENDERSTATETYPE rs
;
3071 switch (LightStateType
)
3073 case D3DLIGHTSTATE_AMBIENT
: /* 2 */
3074 rs
= D3DRENDERSTATE_AMBIENT
;
3076 case D3DLIGHTSTATE_FOGMODE
: /* 4 */
3077 rs
= D3DRENDERSTATE_FOGVERTEXMODE
;
3079 case D3DLIGHTSTATE_FOGSTART
: /* 5 */
3080 rs
= D3DRENDERSTATE_FOGSTART
;
3082 case D3DLIGHTSTATE_FOGEND
: /* 6 */
3083 rs
= D3DRENDERSTATE_FOGEND
;
3085 case D3DLIGHTSTATE_FOGDENSITY
: /* 7 */
3086 rs
= D3DRENDERSTATE_FOGDENSITY
;
3088 case D3DLIGHTSTATE_COLORVERTEX
: /* 8 */
3089 rs
= D3DRENDERSTATE_COLORVERTEX
;
3092 ERR("Unknown D3DLIGHTSTATETYPE %d.\n", LightStateType
);
3093 wined3d_mutex_unlock();
3094 return DDERR_INVALIDPARAMS
;
3097 hr
= IDirect3DDevice7_SetRenderState(&This
->IDirect3DDevice7_iface
, rs
, Value
);
3098 wined3d_mutex_unlock();
3101 wined3d_mutex_unlock();
3106 static HRESULT WINAPI
IDirect3DDeviceImpl_2_SetLightState(IDirect3DDevice2
*iface
,
3107 D3DLIGHTSTATETYPE LightStateType
, DWORD Value
)
3109 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
3111 TRACE("iface %p, state %#x, value %#x.\n", iface
, LightStateType
, Value
);
3113 return IDirect3DDevice3_SetLightState(&This
->IDirect3DDevice3_iface
, LightStateType
, Value
);
3116 /*****************************************************************************
3117 * IDirect3DDevice3::GetLightState
3119 * Returns the current setting of a light state. The state is read from
3120 * the Direct3DDevice7 render state.
3125 * LightStateType: The light state to return
3126 * Value: The address to store the light state setting at
3130 * DDDERR_INVALIDPARAMS if the parameters were incorrect
3131 * Also see IDirect3DDevice7::GetRenderState
3133 *****************************************************************************/
3134 static HRESULT WINAPI
3135 IDirect3DDeviceImpl_3_GetLightState(IDirect3DDevice3
*iface
,
3136 D3DLIGHTSTATETYPE LightStateType
,
3139 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
3142 TRACE("iface %p, state %#x, value %p.\n", iface
, LightStateType
, Value
);
3144 if (!LightStateType
|| (LightStateType
> D3DLIGHTSTATE_COLORVERTEX
))
3146 TRACE("Unexpected Light State Type\n");
3147 return DDERR_INVALIDPARAMS
;
3151 return DDERR_INVALIDPARAMS
;
3153 wined3d_mutex_lock();
3154 if (LightStateType
== D3DLIGHTSTATE_MATERIAL
/* 1 */)
3156 *Value
= This
->material
;
3158 else if (LightStateType
== D3DLIGHTSTATE_COLORMODEL
/* 3 */)
3160 *Value
= D3DCOLOR_RGB
;
3164 D3DRENDERSTATETYPE rs
;
3165 switch (LightStateType
)
3167 case D3DLIGHTSTATE_AMBIENT
: /* 2 */
3168 rs
= D3DRENDERSTATE_AMBIENT
;
3170 case D3DLIGHTSTATE_FOGMODE
: /* 4 */
3171 rs
= D3DRENDERSTATE_FOGVERTEXMODE
;
3173 case D3DLIGHTSTATE_FOGSTART
: /* 5 */
3174 rs
= D3DRENDERSTATE_FOGSTART
;
3176 case D3DLIGHTSTATE_FOGEND
: /* 6 */
3177 rs
= D3DRENDERSTATE_FOGEND
;
3179 case D3DLIGHTSTATE_FOGDENSITY
: /* 7 */
3180 rs
= D3DRENDERSTATE_FOGDENSITY
;
3182 case D3DLIGHTSTATE_COLORVERTEX
: /* 8 */
3183 rs
= D3DRENDERSTATE_COLORVERTEX
;
3186 ERR("Unknown D3DLIGHTSTATETYPE %d.\n", LightStateType
);
3187 wined3d_mutex_unlock();
3188 return DDERR_INVALIDPARAMS
;
3191 hr
= IDirect3DDevice7_GetRenderState(&This
->IDirect3DDevice7_iface
, rs
, Value
);
3192 wined3d_mutex_unlock();
3195 wined3d_mutex_unlock();
3200 static HRESULT WINAPI
IDirect3DDeviceImpl_2_GetLightState(IDirect3DDevice2
*iface
,
3201 D3DLIGHTSTATETYPE LightStateType
, DWORD
*Value
)
3203 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
3205 TRACE("iface %p, state %#x, value %p.\n", iface
, LightStateType
, Value
);
3207 return IDirect3DDevice3_GetLightState(&This
->IDirect3DDevice3_iface
, LightStateType
, Value
);
3210 /*****************************************************************************
3211 * IDirect3DDevice7::SetTransform
3213 * Assigns a D3DMATRIX to a transform type. The transform types are defined
3214 * in include/d3dtypes.h.
3215 * The D3DTRANSFORMSTATE_WORLD (=1) is translated to D3DTS_WORLDMATRIX(0)
3216 * (=255) for wined3d, because the 1 transform state was removed in d3d8
3217 * and WineD3D already understands the replacement D3DTS_WORLDMATRIX(0)
3219 * Version 2, 3 and 7
3222 * TransformStateType: transform state to set
3223 * Matrix: Matrix to assign to the state
3227 * DDERR_INVALIDPARAMS if Matrix == NULL
3228 * For details see IWineD3DDevice::SetTransform
3230 *****************************************************************************/
3232 IDirect3DDeviceImpl_7_SetTransform(IDirect3DDevice7
*iface
,
3233 D3DTRANSFORMSTATETYPE TransformStateType
,
3236 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
3237 D3DTRANSFORMSTATETYPE type
;
3240 TRACE("iface %p, state %#x, matrix %p.\n", iface
, TransformStateType
, Matrix
);
3242 switch (TransformStateType
)
3244 case D3DTRANSFORMSTATE_WORLD
:
3245 type
= WINED3D_TS_WORLD_MATRIX(0);
3247 case D3DTRANSFORMSTATE_WORLD1
:
3248 type
= WINED3D_TS_WORLD_MATRIX(1);
3250 case D3DTRANSFORMSTATE_WORLD2
:
3251 type
= WINED3D_TS_WORLD_MATRIX(2);
3253 case D3DTRANSFORMSTATE_WORLD3
:
3254 type
= WINED3D_TS_WORLD_MATRIX(3);
3257 type
= TransformStateType
;
3261 return DDERR_INVALIDPARAMS
;
3263 /* Note: D3DMATRIX is compatible with struct wined3d_matrix. */
3264 wined3d_mutex_lock();
3265 hr
= wined3d_device_set_transform(This
->wined3d_device
, type
, (struct wined3d_matrix
*)Matrix
);
3266 wined3d_mutex_unlock();
3271 static HRESULT WINAPI
3272 IDirect3DDeviceImpl_7_SetTransform_FPUSetup(IDirect3DDevice7
*iface
,
3273 D3DTRANSFORMSTATETYPE TransformStateType
,
3276 return IDirect3DDeviceImpl_7_SetTransform(iface
, TransformStateType
, Matrix
);
3279 static HRESULT WINAPI
3280 IDirect3DDeviceImpl_7_SetTransform_FPUPreserve(IDirect3DDevice7
*iface
,
3281 D3DTRANSFORMSTATETYPE TransformStateType
,
3287 old_fpucw
= d3d_fpu_setup();
3288 hr
= IDirect3DDeviceImpl_7_SetTransform(iface
, TransformStateType
, Matrix
);
3289 set_fpu_control_word(old_fpucw
);
3294 static HRESULT WINAPI
IDirect3DDeviceImpl_3_SetTransform(IDirect3DDevice3
*iface
,
3295 D3DTRANSFORMSTATETYPE state
, D3DMATRIX
*matrix
)
3297 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
3299 TRACE("iface %p, state %#x, matrix %p.\n", iface
, state
, matrix
);
3302 return DDERR_INVALIDPARAMS
;
3304 if (state
== D3DTRANSFORMSTATE_PROJECTION
)
3306 D3DMATRIX projection
;
3309 wined3d_mutex_lock();
3310 multiply_matrix(&projection
, &This
->legacy_clipspace
, matrix
);
3311 hr
= wined3d_device_set_transform(This
->wined3d_device
,
3312 WINED3D_TS_PROJECTION
, (struct wined3d_matrix
*)&projection
);
3314 This
->legacy_projection
= *matrix
;
3315 wined3d_mutex_unlock();
3320 return IDirect3DDevice7_SetTransform(&This
->IDirect3DDevice7_iface
, state
, matrix
);
3323 static HRESULT WINAPI
IDirect3DDeviceImpl_2_SetTransform(IDirect3DDevice2
*iface
,
3324 D3DTRANSFORMSTATETYPE TransformStateType
, D3DMATRIX
*D3DMatrix
)
3326 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
3328 TRACE("iface %p, state %#x, matrix %p.\n", iface
, TransformStateType
, D3DMatrix
);
3330 return IDirect3DDevice7_SetTransform(&This
->IDirect3DDevice7_iface
, TransformStateType
, D3DMatrix
);
3333 /*****************************************************************************
3334 * IDirect3DDevice7::GetTransform
3336 * Returns the matrix assigned to a transform state
3337 * D3DTRANSFORMSTATE_WORLD is translated to D3DTS_WORLDMATRIX(0), see
3341 * TransformStateType: State to read the matrix from
3342 * Matrix: Address to store the matrix at
3346 * DDERR_INVALIDPARAMS if Matrix == NULL
3347 * For details, see IWineD3DDevice::GetTransform
3349 *****************************************************************************/
3351 IDirect3DDeviceImpl_7_GetTransform(IDirect3DDevice7
*iface
,
3352 D3DTRANSFORMSTATETYPE TransformStateType
,
3355 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
3356 D3DTRANSFORMSTATETYPE type
;
3359 TRACE("iface %p, state %#x, matrix %p.\n", iface
, TransformStateType
, Matrix
);
3361 switch(TransformStateType
)
3363 case D3DTRANSFORMSTATE_WORLD
:
3364 type
= WINED3D_TS_WORLD_MATRIX(0);
3366 case D3DTRANSFORMSTATE_WORLD1
:
3367 type
= WINED3D_TS_WORLD_MATRIX(1);
3369 case D3DTRANSFORMSTATE_WORLD2
:
3370 type
= WINED3D_TS_WORLD_MATRIX(2);
3372 case D3DTRANSFORMSTATE_WORLD3
:
3373 type
= WINED3D_TS_WORLD_MATRIX(3);
3376 type
= TransformStateType
;
3380 return DDERR_INVALIDPARAMS
;
3382 /* Note: D3DMATRIX is compatible with struct wined3d_matrix. */
3383 wined3d_mutex_lock();
3384 hr
= wined3d_device_get_transform(This
->wined3d_device
, type
, (struct wined3d_matrix
*)Matrix
);
3385 wined3d_mutex_unlock();
3390 static HRESULT WINAPI
3391 IDirect3DDeviceImpl_7_GetTransform_FPUSetup(IDirect3DDevice7
*iface
,
3392 D3DTRANSFORMSTATETYPE TransformStateType
,
3395 return IDirect3DDeviceImpl_7_GetTransform(iface
, TransformStateType
, Matrix
);
3398 static HRESULT WINAPI
3399 IDirect3DDeviceImpl_7_GetTransform_FPUPreserve(IDirect3DDevice7
*iface
,
3400 D3DTRANSFORMSTATETYPE TransformStateType
,
3406 old_fpucw
= d3d_fpu_setup();
3407 hr
= IDirect3DDeviceImpl_7_GetTransform(iface
, TransformStateType
, Matrix
);
3408 set_fpu_control_word(old_fpucw
);
3413 static HRESULT WINAPI
IDirect3DDeviceImpl_3_GetTransform(IDirect3DDevice3
*iface
,
3414 D3DTRANSFORMSTATETYPE state
, D3DMATRIX
*matrix
)
3416 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
3418 TRACE("iface %p, state %#x, matrix %p.\n", iface
, state
, matrix
);
3421 return DDERR_INVALIDPARAMS
;
3423 if (state
== D3DTRANSFORMSTATE_PROJECTION
)
3425 wined3d_mutex_lock();
3426 *matrix
= This
->legacy_projection
;
3427 wined3d_mutex_unlock();
3431 return IDirect3DDevice7_GetTransform(&This
->IDirect3DDevice7_iface
, state
, matrix
);
3434 static HRESULT WINAPI
IDirect3DDeviceImpl_2_GetTransform(IDirect3DDevice2
*iface
,
3435 D3DTRANSFORMSTATETYPE TransformStateType
, D3DMATRIX
*D3DMatrix
)
3437 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
3439 TRACE("iface %p, state %#x, matrix %p.\n", iface
, TransformStateType
, D3DMatrix
);
3441 return IDirect3DDevice7_GetTransform(&This
->IDirect3DDevice7_iface
, TransformStateType
, D3DMatrix
);
3444 /*****************************************************************************
3445 * IDirect3DDevice7::MultiplyTransform
3447 * Multiplies the already-set transform matrix of a transform state
3448 * with another matrix. For the world matrix, see SetTransform
3450 * Version 2, 3 and 7
3453 * TransformStateType: Transform state to multiply
3454 * D3DMatrix Matrix to multiply with.
3458 * DDERR_INVALIDPARAMS if D3DMatrix is NULL
3459 * For details, see IWineD3DDevice::MultiplyTransform
3461 *****************************************************************************/
3463 IDirect3DDeviceImpl_7_MultiplyTransform(IDirect3DDevice7
*iface
,
3464 D3DTRANSFORMSTATETYPE TransformStateType
,
3465 D3DMATRIX
*D3DMatrix
)
3467 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
3469 D3DTRANSFORMSTATETYPE type
;
3471 TRACE("iface %p, state %#x, matrix %p.\n", iface
, TransformStateType
, D3DMatrix
);
3473 switch(TransformStateType
)
3475 case D3DTRANSFORMSTATE_WORLD
:
3476 type
= WINED3D_TS_WORLD_MATRIX(0);
3478 case D3DTRANSFORMSTATE_WORLD1
:
3479 type
= WINED3D_TS_WORLD_MATRIX(1);
3481 case D3DTRANSFORMSTATE_WORLD2
:
3482 type
= WINED3D_TS_WORLD_MATRIX(2);
3484 case D3DTRANSFORMSTATE_WORLD3
:
3485 type
= WINED3D_TS_WORLD_MATRIX(3);
3488 type
= TransformStateType
;
3491 /* Note: D3DMATRIX is compatible with struct wined3d_matrix. */
3492 wined3d_mutex_lock();
3493 hr
= wined3d_device_multiply_transform(This
->wined3d_device
,
3494 type
, (struct wined3d_matrix
*)D3DMatrix
);
3495 wined3d_mutex_unlock();
3500 static HRESULT WINAPI
3501 IDirect3DDeviceImpl_7_MultiplyTransform_FPUSetup(IDirect3DDevice7
*iface
,
3502 D3DTRANSFORMSTATETYPE TransformStateType
,
3503 D3DMATRIX
*D3DMatrix
)
3505 return IDirect3DDeviceImpl_7_MultiplyTransform(iface
, TransformStateType
, D3DMatrix
);
3508 static HRESULT WINAPI
3509 IDirect3DDeviceImpl_7_MultiplyTransform_FPUPreserve(IDirect3DDevice7
*iface
,
3510 D3DTRANSFORMSTATETYPE TransformStateType
,
3511 D3DMATRIX
*D3DMatrix
)
3516 old_fpucw
= d3d_fpu_setup();
3517 hr
= IDirect3DDeviceImpl_7_MultiplyTransform(iface
, TransformStateType
, D3DMatrix
);
3518 set_fpu_control_word(old_fpucw
);
3523 static HRESULT WINAPI
IDirect3DDeviceImpl_3_MultiplyTransform(IDirect3DDevice3
*iface
,
3524 D3DTRANSFORMSTATETYPE state
, D3DMATRIX
*matrix
)
3526 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
3528 TRACE("iface %p, state %#x, matrix %p.\n", iface
, state
, matrix
);
3530 if (state
== D3DTRANSFORMSTATE_PROJECTION
)
3532 D3DMATRIX projection
, tmp
;
3535 wined3d_mutex_lock();
3536 multiply_matrix(&tmp
, &This
->legacy_projection
, matrix
);
3537 multiply_matrix(&projection
, &This
->legacy_clipspace
, &tmp
);
3538 hr
= wined3d_device_set_transform(This
->wined3d_device
,
3539 WINED3D_TS_PROJECTION
, (struct wined3d_matrix
*)&projection
);
3541 This
->legacy_projection
= tmp
;
3542 wined3d_mutex_unlock();
3547 return IDirect3DDevice7_MultiplyTransform(&This
->IDirect3DDevice7_iface
, state
, matrix
);
3550 static HRESULT WINAPI
IDirect3DDeviceImpl_2_MultiplyTransform(IDirect3DDevice2
*iface
,
3551 D3DTRANSFORMSTATETYPE TransformStateType
, D3DMATRIX
*D3DMatrix
)
3553 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
3555 TRACE("iface %p, state %#x, matrix %p.\n", iface
, TransformStateType
, D3DMatrix
);
3557 return IDirect3DDevice7_MultiplyTransform(&This
->IDirect3DDevice7_iface
, TransformStateType
, D3DMatrix
);
3560 /*****************************************************************************
3561 * IDirect3DDevice7::DrawPrimitive
3563 * Draws primitives based on vertices in an application-provided pointer
3565 * Version 2, 3 and 7. The IDirect3DDevice2 thunk converts the fixed vertex type into
3566 * an FVF format for D3D7
3569 * PrimitiveType: The type of the primitives to draw
3570 * Vertex type: Flexible vertex format vertex description
3571 * Vertices: Pointer to the vertex array
3572 * VertexCount: The number of vertices to draw
3573 * Flags: As usual a few flags
3577 * DDERR_INVALIDPARAMS if Vertices is NULL
3578 * For details, see IWineD3DDevice::DrawPrimitiveUP
3580 *****************************************************************************/
3582 IDirect3DDeviceImpl_7_DrawPrimitive(IDirect3DDevice7
*iface
,
3583 D3DPRIMITIVETYPE PrimitiveType
,
3589 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
3593 TRACE("iface %p, primitive_type %#x, FVF %#x, vertices %p, vertex_count %u, flags %#x.\n",
3594 iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Flags
);
3597 return DDERR_INVALIDPARAMS
;
3599 /* Get the stride */
3600 stride
= get_flexible_vertex_size(VertexType
);
3603 wined3d_mutex_lock();
3604 hr
= wined3d_device_set_vertex_declaration(This
->wined3d_device
, ddraw_find_decl(This
->ddraw
, VertexType
));
3607 wined3d_mutex_unlock();
3611 /* This method translates to the user pointer draw of WineD3D */
3612 wined3d_device_set_primitive_type(This
->wined3d_device
, PrimitiveType
);
3613 hr
= wined3d_device_draw_primitive_up(This
->wined3d_device
, VertexCount
, Vertices
, stride
);
3614 wined3d_mutex_unlock();
3619 static HRESULT WINAPI
3620 IDirect3DDeviceImpl_7_DrawPrimitive_FPUSetup(IDirect3DDevice7
*iface
,
3621 D3DPRIMITIVETYPE PrimitiveType
,
3627 return IDirect3DDeviceImpl_7_DrawPrimitive(iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Flags
);
3630 static HRESULT WINAPI
3631 IDirect3DDeviceImpl_7_DrawPrimitive_FPUPreserve(IDirect3DDevice7
*iface
,
3632 D3DPRIMITIVETYPE PrimitiveType
,
3641 old_fpucw
= d3d_fpu_setup();
3642 hr
= IDirect3DDeviceImpl_7_DrawPrimitive(iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Flags
);
3643 set_fpu_control_word(old_fpucw
);
3648 static HRESULT WINAPI
IDirect3DDeviceImpl_3_DrawPrimitive(IDirect3DDevice3
*iface
,
3649 D3DPRIMITIVETYPE PrimitiveType
, DWORD VertexType
, void *Vertices
, DWORD VertexCount
,
3652 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
3653 TRACE("iface %p, primitive_type %#x, FVF %#x, vertices %p, vertex_count %u, flags %#x.\n",
3654 iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Flags
);
3656 return IDirect3DDevice7_DrawPrimitive(&This
->IDirect3DDevice7_iface
,
3657 PrimitiveType
, VertexType
, Vertices
, VertexCount
, Flags
);
3660 static HRESULT WINAPI
IDirect3DDeviceImpl_2_DrawPrimitive(IDirect3DDevice2
*iface
,
3661 D3DPRIMITIVETYPE PrimitiveType
, D3DVERTEXTYPE VertexType
, void *Vertices
,
3662 DWORD VertexCount
, DWORD Flags
)
3664 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
3667 TRACE("iface %p, primitive_type %#x, vertex_type %#x, vertices %p, vertex_count %u, flags %#x.\n",
3668 iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Flags
);
3672 case D3DVT_VERTEX
: FVF
= D3DFVF_VERTEX
; break;
3673 case D3DVT_LVERTEX
: FVF
= D3DFVF_LVERTEX
; break;
3674 case D3DVT_TLVERTEX
: FVF
= D3DFVF_TLVERTEX
; break;
3676 ERR("Unexpected vertex type %d\n", VertexType
);
3677 return DDERR_INVALIDPARAMS
; /* Should never happen */
3680 return IDirect3DDevice7_DrawPrimitive(&This
->IDirect3DDevice7_iface
,
3681 PrimitiveType
, FVF
, Vertices
, VertexCount
, Flags
);
3684 /*****************************************************************************
3685 * IDirect3DDevice7::DrawIndexedPrimitive
3687 * Draws vertices from an application-provided pointer, based on the index
3688 * numbers in a WORD array.
3690 * Version 2, 3 and 7. The version 7 thunk translates the vertex type into
3691 * an FVF format for D3D7
3694 * PrimitiveType: The primitive type to draw
3695 * VertexType: The FVF vertex description
3696 * Vertices: Pointer to the vertex array
3698 * Indices: Pointer to the index array
3699 * IndexCount: Number of indices = Number of vertices to draw
3700 * Flags: As usual, some flags
3704 * DDERR_INVALIDPARAMS if Vertices or Indices is NULL
3705 * For details, see IWineD3DDevice::DrawIndexedPrimitiveUP
3707 *****************************************************************************/
3709 IDirect3DDeviceImpl_7_DrawIndexedPrimitive(IDirect3DDevice7
*iface
,
3710 D3DPRIMITIVETYPE PrimitiveType
,
3718 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
3721 TRACE("iface %p, primitive_type %#x, FVF %#x, vertices %p, vertex_count %u, indices %p, index_count %u, flags %#x.\n",
3722 iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Indices
, IndexCount
, Flags
);
3724 /* Set the D3DDevice's FVF */
3725 wined3d_mutex_lock();
3726 hr
= wined3d_device_set_vertex_declaration(This
->wined3d_device
, ddraw_find_decl(This
->ddraw
, VertexType
));
3729 ERR(" (%p) Setting the FVF failed, hr = %x!\n", This
, hr
);
3730 wined3d_mutex_unlock();
3734 wined3d_device_set_primitive_type(This
->wined3d_device
, PrimitiveType
);
3735 hr
= wined3d_device_draw_indexed_primitive_up(This
->wined3d_device
, IndexCount
, Indices
,
3736 WINED3DFMT_R16_UINT
, Vertices
, get_flexible_vertex_size(VertexType
));
3737 wined3d_mutex_unlock();
3742 static HRESULT WINAPI
3743 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUSetup(IDirect3DDevice7
*iface
,
3744 D3DPRIMITIVETYPE PrimitiveType
,
3752 return IDirect3DDeviceImpl_7_DrawIndexedPrimitive(iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Indices
, IndexCount
, Flags
);
3755 static HRESULT WINAPI
3756 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUPreserve(IDirect3DDevice7
*iface
,
3757 D3DPRIMITIVETYPE PrimitiveType
,
3768 old_fpucw
= d3d_fpu_setup();
3769 hr
= IDirect3DDeviceImpl_7_DrawIndexedPrimitive(iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Indices
, IndexCount
, Flags
);
3770 set_fpu_control_word(old_fpucw
);
3775 static HRESULT WINAPI
IDirect3DDeviceImpl_3_DrawIndexedPrimitive(IDirect3DDevice3
*iface
,
3776 D3DPRIMITIVETYPE PrimitiveType
, DWORD VertexType
, void *Vertices
, DWORD VertexCount
,
3777 WORD
*Indices
, DWORD IndexCount
, DWORD Flags
)
3779 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
3780 TRACE("iface %p, primitive_type %#x, FVF %#x, vertices %p, vertex_count %u, indices %p, index_count %u, flags %#x.\n",
3781 iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Indices
, IndexCount
, Flags
);
3783 return IDirect3DDevice7_DrawIndexedPrimitive(&This
->IDirect3DDevice7_iface
,
3784 PrimitiveType
, VertexType
, Vertices
, VertexCount
, Indices
, IndexCount
, Flags
);
3787 static HRESULT WINAPI
IDirect3DDeviceImpl_2_DrawIndexedPrimitive(IDirect3DDevice2
*iface
,
3788 D3DPRIMITIVETYPE PrimitiveType
, D3DVERTEXTYPE VertexType
, void *Vertices
,
3789 DWORD VertexCount
, WORD
*Indices
, DWORD IndexCount
, DWORD Flags
)
3791 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
3794 TRACE("iface %p, primitive_type %#x, vertex_type %#x, vertices %p, vertex_count %u, indices %p, index_count %u, flags %#x.\n",
3795 iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Indices
, IndexCount
, Flags
);
3799 case D3DVT_VERTEX
: FVF
= D3DFVF_VERTEX
; break;
3800 case D3DVT_LVERTEX
: FVF
= D3DFVF_LVERTEX
; break;
3801 case D3DVT_TLVERTEX
: FVF
= D3DFVF_TLVERTEX
; break;
3803 ERR("Unexpected vertex type %d\n", VertexType
);
3804 return DDERR_INVALIDPARAMS
; /* Should never happen */
3807 return IDirect3DDevice7_DrawIndexedPrimitive(&This
->IDirect3DDevice7_iface
,
3808 PrimitiveType
, FVF
, Vertices
, VertexCount
, Indices
, IndexCount
, Flags
);
3811 /*****************************************************************************
3812 * IDirect3DDevice7::SetClipStatus
3814 * Sets the clip status. This defines things as clipping conditions and
3815 * the extents of the clipping region.
3817 * Version 2, 3 and 7
3823 * D3D_OK because it's a stub
3824 * (DDERR_INVALIDPARAMS if ClipStatus == NULL)
3826 *****************************************************************************/
3827 static HRESULT WINAPI
3828 IDirect3DDeviceImpl_7_SetClipStatus(IDirect3DDevice7
*iface
,
3829 D3DCLIPSTATUS
*ClipStatus
)
3831 FIXME("iface %p, clip_status %p stub!\n", iface
, ClipStatus
);
3833 /* D3DCLIPSTATUS and WINED3DCLIPSTATUS are different. I don't know how to convert them
3834 * Perhaps this needs a new data type and an additional IWineD3DDevice method
3836 /* return IWineD3DDevice_SetClipStatus(This->wineD3DDevice, ClipStatus);*/
3840 static HRESULT WINAPI
IDirect3DDeviceImpl_3_SetClipStatus(IDirect3DDevice3
*iface
,
3841 D3DCLIPSTATUS
*ClipStatus
)
3843 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
3844 TRACE("iface %p, clip_status %p.\n", iface
, ClipStatus
);
3846 return IDirect3DDevice7_SetClipStatus(&This
->IDirect3DDevice7_iface
, ClipStatus
);
3849 static HRESULT WINAPI
IDirect3DDeviceImpl_2_SetClipStatus(IDirect3DDevice2
*iface
,
3850 D3DCLIPSTATUS
*ClipStatus
)
3852 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
3853 TRACE("iface %p, clip_status %p.\n", iface
, ClipStatus
);
3855 return IDirect3DDevice7_SetClipStatus(&This
->IDirect3DDevice7_iface
, ClipStatus
);
3858 /*****************************************************************************
3859 * IDirect3DDevice7::GetClipStatus
3861 * Returns the clip status
3864 * ClipStatus: Address to write the clip status to
3867 * D3D_OK because it's a stub
3869 *****************************************************************************/
3870 static HRESULT WINAPI
3871 IDirect3DDeviceImpl_7_GetClipStatus(IDirect3DDevice7
*iface
,
3872 D3DCLIPSTATUS
*ClipStatus
)
3874 FIXME("iface %p, clip_status %p stub!\n", iface
, ClipStatus
);
3876 /* D3DCLIPSTATUS and WINED3DCLIPSTATUS are different. I don't know how to convert them */
3877 /* return IWineD3DDevice_GetClipStatus(This->wineD3DDevice, ClipStatus);*/
3881 static HRESULT WINAPI
IDirect3DDeviceImpl_3_GetClipStatus(IDirect3DDevice3
*iface
,
3882 D3DCLIPSTATUS
*ClipStatus
)
3884 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
3885 TRACE("iface %p, clip_status %p.\n", iface
, ClipStatus
);
3887 return IDirect3DDevice7_GetClipStatus(&This
->IDirect3DDevice7_iface
, ClipStatus
);
3890 static HRESULT WINAPI
IDirect3DDeviceImpl_2_GetClipStatus(IDirect3DDevice2
*iface
,
3891 D3DCLIPSTATUS
*ClipStatus
)
3893 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
3894 TRACE("iface %p, clip_status %p.\n", iface
, ClipStatus
);
3896 return IDirect3DDevice7_GetClipStatus(&This
->IDirect3DDevice7_iface
, ClipStatus
);
3899 /*****************************************************************************
3900 * IDirect3DDevice::DrawPrimitiveStrided
3902 * Draws vertices described by a D3DDRAWPRIMITIVESTRIDEDDATA structure.
3907 * PrimitiveType: The primitive type to draw
3908 * VertexType: The FVF description of the vertices to draw (for the stride??)
3909 * D3DDrawPrimStrideData: A D3DDRAWPRIMITIVESTRIDEDDATA structure describing
3910 * the vertex data locations
3911 * VertexCount: The number of vertices to draw
3915 * D3D_OK, because it's a stub
3916 * (DDERR_INVALIDPARAMS if D3DDrawPrimStrideData is NULL)
3917 * (For details, see IWineD3DDevice::DrawPrimitiveStrided)
3919 *****************************************************************************/
3921 IDirect3DDeviceImpl_7_DrawPrimitiveStrided(IDirect3DDevice7
*iface
,
3922 D3DPRIMITIVETYPE PrimitiveType
,
3924 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
,
3928 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
3929 struct wined3d_strided_data wined3d_strided
;
3933 TRACE("iface %p, primitive_type %#x, FVF %#x, strided_data %p, vertex_count %u, flags %#x.\n",
3934 iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Flags
);
3936 memset(&wined3d_strided
, 0, sizeof(wined3d_strided
));
3937 /* Get the strided data right. the wined3d structure is a bit bigger
3938 * Watch out: The contents of the strided data are determined by the fvf,
3939 * not by the members set in D3DDrawPrimStrideData. So it's valid
3940 * to have diffuse.lpvData set to 0xdeadbeef if the diffuse flag is
3941 * not set in the fvf.
3943 if(VertexType
& D3DFVF_POSITION_MASK
)
3945 wined3d_strided
.position
.format
= WINED3DFMT_R32G32B32_FLOAT
;
3946 wined3d_strided
.position
.data
= D3DDrawPrimStrideData
->position
.lpvData
;
3947 wined3d_strided
.position
.stride
= D3DDrawPrimStrideData
->position
.dwStride
;
3948 if (VertexType
& D3DFVF_XYZRHW
)
3950 wined3d_strided
.position
.format
= WINED3DFMT_R32G32B32A32_FLOAT
;
3951 wined3d_strided
.position_transformed
= TRUE
;
3955 wined3d_strided
.position_transformed
= FALSE
;
3959 if (VertexType
& D3DFVF_NORMAL
)
3961 wined3d_strided
.normal
.format
= WINED3DFMT_R32G32B32_FLOAT
;
3962 wined3d_strided
.normal
.data
= D3DDrawPrimStrideData
->normal
.lpvData
;
3963 wined3d_strided
.normal
.stride
= D3DDrawPrimStrideData
->normal
.dwStride
;
3966 if (VertexType
& D3DFVF_DIFFUSE
)
3968 wined3d_strided
.diffuse
.format
= WINED3DFMT_B8G8R8A8_UNORM
;
3969 wined3d_strided
.diffuse
.data
= D3DDrawPrimStrideData
->diffuse
.lpvData
;
3970 wined3d_strided
.diffuse
.stride
= D3DDrawPrimStrideData
->diffuse
.dwStride
;
3973 if (VertexType
& D3DFVF_SPECULAR
)
3975 wined3d_strided
.specular
.format
= WINED3DFMT_B8G8R8A8_UNORM
;
3976 wined3d_strided
.specular
.data
= D3DDrawPrimStrideData
->specular
.lpvData
;
3977 wined3d_strided
.specular
.stride
= D3DDrawPrimStrideData
->specular
.dwStride
;
3980 for (i
= 0; i
< GET_TEXCOUNT_FROM_FVF(VertexType
); ++i
)
3982 switch (GET_TEXCOORD_SIZE_FROM_FVF(VertexType
, i
))
3984 case 1: wined3d_strided
.tex_coords
[i
].format
= WINED3DFMT_R32_FLOAT
; break;
3985 case 2: wined3d_strided
.tex_coords
[i
].format
= WINED3DFMT_R32G32_FLOAT
; break;
3986 case 3: wined3d_strided
.tex_coords
[i
].format
= WINED3DFMT_R32G32B32_FLOAT
; break;
3987 case 4: wined3d_strided
.tex_coords
[i
].format
= WINED3DFMT_R32G32B32A32_FLOAT
; break;
3988 default: ERR("Unexpected texture coordinate size %d\n",
3989 GET_TEXCOORD_SIZE_FROM_FVF(VertexType
, i
));
3991 wined3d_strided
.tex_coords
[i
].data
= D3DDrawPrimStrideData
->textureCoords
[i
].lpvData
;
3992 wined3d_strided
.tex_coords
[i
].stride
= D3DDrawPrimStrideData
->textureCoords
[i
].dwStride
;
3995 /* WineD3D doesn't need the FVF here */
3996 wined3d_mutex_lock();
3997 wined3d_device_set_primitive_type(This
->wined3d_device
, PrimitiveType
);
3998 hr
= wined3d_device_draw_primitive_strided(This
->wined3d_device
, VertexCount
, &wined3d_strided
);
3999 wined3d_mutex_unlock();
4004 static HRESULT WINAPI
4005 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUSetup(IDirect3DDevice7
*iface
,
4006 D3DPRIMITIVETYPE PrimitiveType
,
4008 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
,
4012 return IDirect3DDeviceImpl_7_DrawPrimitiveStrided(iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Flags
);
4015 static HRESULT WINAPI
4016 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUPreserve(IDirect3DDevice7
*iface
,
4017 D3DPRIMITIVETYPE PrimitiveType
,
4019 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
,
4026 old_fpucw
= d3d_fpu_setup();
4027 hr
= IDirect3DDeviceImpl_7_DrawPrimitiveStrided(iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Flags
);
4028 set_fpu_control_word(old_fpucw
);
4033 static HRESULT WINAPI
IDirect3DDeviceImpl_3_DrawPrimitiveStrided(IDirect3DDevice3
*iface
,
4034 D3DPRIMITIVETYPE PrimitiveType
, DWORD VertexType
,
4035 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
, DWORD VertexCount
, DWORD Flags
)
4037 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
4039 TRACE("iface %p, primitive_type %#x, FVF %#x, strided_data %p, vertex_count %u, flags %#x.\n",
4040 iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Flags
);
4042 return IDirect3DDevice7_DrawPrimitiveStrided(&This
->IDirect3DDevice7_iface
,
4043 PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Flags
);
4046 /*****************************************************************************
4047 * IDirect3DDevice7::DrawIndexedPrimitiveStrided
4049 * Draws primitives specified by strided data locations based on indices
4057 * D3D_OK, because it's a stub
4058 * (DDERR_INVALIDPARAMS if D3DDrawPrimStrideData is NULL)
4059 * (DDERR_INVALIDPARAMS if Indices is NULL)
4060 * (For more details, see IWineD3DDevice::DrawIndexedPrimitiveStrided)
4062 *****************************************************************************/
4064 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided(IDirect3DDevice7
*iface
,
4065 D3DPRIMITIVETYPE PrimitiveType
,
4067 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
,
4073 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
4074 struct wined3d_strided_data wined3d_strided
;
4078 TRACE("iface %p, primitive_type %#x, FVF %#x, strided_data %p, vertex_count %u, indices %p, index_count %u, flags %#x.\n",
4079 iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Indices
, IndexCount
, Flags
);
4081 memset(&wined3d_strided
, 0, sizeof(wined3d_strided
));
4082 /* Get the strided data right. the wined3d structure is a bit bigger
4083 * Watch out: The contents of the strided data are determined by the fvf,
4084 * not by the members set in D3DDrawPrimStrideData. So it's valid
4085 * to have diffuse.lpvData set to 0xdeadbeef if the diffuse flag is
4086 * not set in the fvf. */
4087 if (VertexType
& D3DFVF_POSITION_MASK
)
4089 wined3d_strided
.position
.format
= WINED3DFMT_R32G32B32_FLOAT
;
4090 wined3d_strided
.position
.data
= D3DDrawPrimStrideData
->position
.lpvData
;
4091 wined3d_strided
.position
.stride
= D3DDrawPrimStrideData
->position
.dwStride
;
4092 if (VertexType
& D3DFVF_XYZRHW
)
4094 wined3d_strided
.position
.format
= WINED3DFMT_R32G32B32A32_FLOAT
;
4095 wined3d_strided
.position_transformed
= TRUE
;
4099 wined3d_strided
.position_transformed
= FALSE
;
4103 if (VertexType
& D3DFVF_NORMAL
)
4105 wined3d_strided
.normal
.format
= WINED3DFMT_R32G32B32_FLOAT
;
4106 wined3d_strided
.normal
.data
= D3DDrawPrimStrideData
->normal
.lpvData
;
4107 wined3d_strided
.normal
.stride
= D3DDrawPrimStrideData
->normal
.dwStride
;
4110 if (VertexType
& D3DFVF_DIFFUSE
)
4112 wined3d_strided
.diffuse
.format
= WINED3DFMT_B8G8R8A8_UNORM
;
4113 wined3d_strided
.diffuse
.data
= D3DDrawPrimStrideData
->diffuse
.lpvData
;
4114 wined3d_strided
.diffuse
.stride
= D3DDrawPrimStrideData
->diffuse
.dwStride
;
4117 if (VertexType
& D3DFVF_SPECULAR
)
4119 wined3d_strided
.specular
.format
= WINED3DFMT_B8G8R8A8_UNORM
;
4120 wined3d_strided
.specular
.data
= D3DDrawPrimStrideData
->specular
.lpvData
;
4121 wined3d_strided
.specular
.stride
= D3DDrawPrimStrideData
->specular
.dwStride
;
4124 for (i
= 0; i
< GET_TEXCOUNT_FROM_FVF(VertexType
); ++i
)
4126 switch (GET_TEXCOORD_SIZE_FROM_FVF(VertexType
, i
))
4128 case 1: wined3d_strided
.tex_coords
[i
].format
= WINED3DFMT_R32_FLOAT
; break;
4129 case 2: wined3d_strided
.tex_coords
[i
].format
= WINED3DFMT_R32G32_FLOAT
; break;
4130 case 3: wined3d_strided
.tex_coords
[i
].format
= WINED3DFMT_R32G32B32_FLOAT
; break;
4131 case 4: wined3d_strided
.tex_coords
[i
].format
= WINED3DFMT_R32G32B32A32_FLOAT
; break;
4132 default: ERR("Unexpected texture coordinate size %d\n",
4133 GET_TEXCOORD_SIZE_FROM_FVF(VertexType
, i
));
4135 wined3d_strided
.tex_coords
[i
].data
= D3DDrawPrimStrideData
->textureCoords
[i
].lpvData
;
4136 wined3d_strided
.tex_coords
[i
].stride
= D3DDrawPrimStrideData
->textureCoords
[i
].dwStride
;
4139 /* WineD3D doesn't need the FVF here */
4140 wined3d_mutex_lock();
4141 wined3d_device_set_primitive_type(This
->wined3d_device
, PrimitiveType
);
4142 hr
= wined3d_device_draw_indexed_primitive_strided(This
->wined3d_device
,
4143 IndexCount
, &wined3d_strided
, VertexCount
, Indices
, WINED3DFMT_R16_UINT
);
4144 wined3d_mutex_unlock();
4149 static HRESULT WINAPI
4150 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUSetup(IDirect3DDevice7
*iface
,
4151 D3DPRIMITIVETYPE PrimitiveType
,
4153 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
,
4159 return IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided(iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Indices
, IndexCount
, Flags
);
4162 static HRESULT WINAPI
4163 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUPreserve(IDirect3DDevice7
*iface
,
4164 D3DPRIMITIVETYPE PrimitiveType
,
4166 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
,
4175 old_fpucw
= d3d_fpu_setup();
4176 hr
= IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided(iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Indices
, IndexCount
, Flags
);
4177 set_fpu_control_word(old_fpucw
);
4182 static HRESULT WINAPI
IDirect3DDeviceImpl_3_DrawIndexedPrimitiveStrided(IDirect3DDevice3
*iface
,
4183 D3DPRIMITIVETYPE PrimitiveType
, DWORD VertexType
,
4184 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
, DWORD VertexCount
, WORD
*Indices
,
4185 DWORD IndexCount
, DWORD Flags
)
4187 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
4189 TRACE("iface %p, primitive_type %#x, FVF %#x, strided_data %p, vertex_count %u, indices %p, index_count %u, flags %#x.\n",
4190 iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Indices
, IndexCount
, Flags
);
4192 return IDirect3DDevice7_DrawIndexedPrimitiveStrided(&This
->IDirect3DDevice7_iface
,
4193 PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Indices
, IndexCount
, Flags
);
4196 /*****************************************************************************
4197 * IDirect3DDevice7::DrawPrimitiveVB
4199 * Draws primitives from a vertex buffer to the screen.
4204 * PrimitiveType: Type of primitive to be rendered.
4205 * D3DVertexBuf: Source Vertex Buffer
4206 * StartVertex: Index of the first vertex from the buffer to be rendered
4207 * NumVertices: Number of vertices to be rendered
4208 * Flags: Can be D3DDP_WAIT to wait until rendering has finished
4212 * DDERR_INVALIDPARAMS if D3DVertexBuf is NULL
4214 *****************************************************************************/
4216 IDirect3DDeviceImpl_7_DrawPrimitiveVB(IDirect3DDevice7
*iface
,
4217 D3DPRIMITIVETYPE PrimitiveType
,
4218 IDirect3DVertexBuffer7
*D3DVertexBuf
,
4223 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
4224 IDirect3DVertexBufferImpl
*vb
= unsafe_impl_from_IDirect3DVertexBuffer7(D3DVertexBuf
);
4228 TRACE("iface %p, primitive_type %#x, vb %p, start_vertex %u, vertex_count %u, flags %#x.\n",
4229 iface
, PrimitiveType
, D3DVertexBuf
, StartVertex
, NumVertices
, Flags
);
4234 ERR("(%p) No Vertex buffer specified\n", This
);
4235 return DDERR_INVALIDPARAMS
;
4237 stride
= get_flexible_vertex_size(vb
->fvf
);
4239 wined3d_mutex_lock();
4240 hr
= wined3d_device_set_vertex_declaration(This
->wined3d_device
, vb
->wineD3DVertexDeclaration
);
4243 ERR(" (%p) Setting the FVF failed, hr = %x!\n", This
, hr
);
4244 wined3d_mutex_unlock();
4248 /* Set the vertex stream source */
4249 hr
= wined3d_device_set_stream_source(This
->wined3d_device
, 0, vb
->wineD3DVertexBuffer
, 0, stride
);
4252 ERR("(%p) IDirect3DDevice::SetStreamSource failed with hr = %08x\n", This
, hr
);
4253 wined3d_mutex_unlock();
4257 /* Now draw the primitives */
4258 wined3d_device_set_primitive_type(This
->wined3d_device
, PrimitiveType
);
4259 hr
= wined3d_device_draw_primitive(This
->wined3d_device
, StartVertex
, NumVertices
);
4260 wined3d_mutex_unlock();
4265 static HRESULT WINAPI
4266 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUSetup(IDirect3DDevice7
*iface
,
4267 D3DPRIMITIVETYPE PrimitiveType
,
4268 IDirect3DVertexBuffer7
*D3DVertexBuf
,
4273 return IDirect3DDeviceImpl_7_DrawPrimitiveVB(iface
, PrimitiveType
, D3DVertexBuf
, StartVertex
, NumVertices
, Flags
);
4276 static HRESULT WINAPI
4277 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUPreserve(IDirect3DDevice7
*iface
,
4278 D3DPRIMITIVETYPE PrimitiveType
,
4279 IDirect3DVertexBuffer7
*D3DVertexBuf
,
4287 old_fpucw
= d3d_fpu_setup();
4288 hr
= IDirect3DDeviceImpl_7_DrawPrimitiveVB(iface
, PrimitiveType
, D3DVertexBuf
, StartVertex
, NumVertices
, Flags
);
4289 set_fpu_control_word(old_fpucw
);
4294 static HRESULT WINAPI
IDirect3DDeviceImpl_3_DrawPrimitiveVB(IDirect3DDevice3
*iface
,
4295 D3DPRIMITIVETYPE PrimitiveType
, IDirect3DVertexBuffer
*D3DVertexBuf
, DWORD StartVertex
,
4296 DWORD NumVertices
, DWORD Flags
)
4298 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
4299 IDirect3DVertexBufferImpl
*vb
= unsafe_impl_from_IDirect3DVertexBuffer(D3DVertexBuf
);
4301 TRACE("iface %p, primitive_type %#x, vb %p, start_vertex %u, vertex_count %u, flags %#x.\n",
4302 iface
, PrimitiveType
, D3DVertexBuf
, StartVertex
, NumVertices
, Flags
);
4304 return IDirect3DDevice7_DrawPrimitiveVB(&This
->IDirect3DDevice7_iface
,
4305 PrimitiveType
, &vb
->IDirect3DVertexBuffer7_iface
, StartVertex
, NumVertices
, Flags
);
4309 /*****************************************************************************
4310 * IDirect3DDevice7::DrawIndexedPrimitiveVB
4312 * Draws primitives from a vertex buffer to the screen
4315 * PrimitiveType: Type of primitive to be rendered.
4316 * D3DVertexBuf: Source Vertex Buffer
4317 * StartVertex: Index of the first vertex from the buffer to be rendered
4318 * NumVertices: Number of vertices to be rendered
4319 * Indices: Array of DWORDs used to index into the Vertices
4320 * IndexCount: Number of indices in Indices
4321 * Flags: Can be D3DDP_WAIT to wait until rendering has finished
4325 *****************************************************************************/
4327 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB(IDirect3DDevice7
*iface
,
4328 D3DPRIMITIVETYPE PrimitiveType
,
4329 IDirect3DVertexBuffer7
*D3DVertexBuf
,
4336 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
4337 IDirect3DVertexBufferImpl
*vb
= unsafe_impl_from_IDirect3DVertexBuffer7(D3DVertexBuf
);
4338 DWORD stride
= get_flexible_vertex_size(vb
->fvf
);
4339 struct wined3d_resource
*wined3d_resource
;
4340 struct wined3d_resource_desc desc
;
4341 WORD
*LockedIndices
;
4344 TRACE("iface %p, primitive_type %#x, vb %p, start_vertex %u, vertex_count %u, indices %p, index_count %u, flags %#x.\n",
4345 iface
, PrimitiveType
, D3DVertexBuf
, StartVertex
, NumVertices
, Indices
, IndexCount
, Flags
);
4348 * 1) Upload the Indices to the index buffer
4349 * 2) Set the index source
4350 * 3) Set the Vertex Buffer as the Stream source
4351 * 4) Call IWineD3DDevice::DrawIndexedPrimitive
4354 wined3d_mutex_lock();
4356 hr
= wined3d_device_set_vertex_declaration(This
->wined3d_device
, vb
->wineD3DVertexDeclaration
);
4359 ERR(" (%p) Setting the FVF failed, hr = %x!\n", This
, hr
);
4360 wined3d_mutex_unlock();
4364 /* check that the buffer is large enough to hold the indices,
4365 * reallocate if necessary. */
4366 wined3d_resource
= wined3d_buffer_get_resource(This
->indexbuffer
);
4367 wined3d_resource_get_desc(wined3d_resource
, &desc
);
4368 if (desc
.size
< IndexCount
* sizeof(WORD
))
4370 UINT size
= max(desc
.size
* 2, IndexCount
* sizeof(WORD
));
4371 struct wined3d_buffer
*buffer
;
4373 TRACE("Growing index buffer to %u bytes\n", size
);
4375 hr
= wined3d_buffer_create_ib(This
->wined3d_device
, size
, WINED3DUSAGE_DYNAMIC
/* Usage */,
4376 WINED3D_POOL_DEFAULT
, NULL
, &ddraw_null_wined3d_parent_ops
, &buffer
);
4379 ERR("(%p) IWineD3DDevice::CreateIndexBuffer failed with hr = %08x\n", This
, hr
);
4380 wined3d_mutex_unlock();
4384 wined3d_buffer_decref(This
->indexbuffer
);
4385 This
->indexbuffer
= buffer
;
4388 /* Copy the index stream into the index buffer. A new IWineD3DDevice
4389 * method could be created which takes an user pointer containing the
4390 * indices or a SetData-Method for the index buffer, which overrides the
4391 * index buffer data with our pointer. */
4392 hr
= wined3d_buffer_map(This
->indexbuffer
, 0, IndexCount
* sizeof(WORD
),
4393 (BYTE
**)&LockedIndices
, 0);
4396 ERR("Failed to map buffer, hr %#x.\n", hr
);
4397 wined3d_mutex_unlock();
4400 memcpy(LockedIndices
, Indices
, IndexCount
* sizeof(WORD
));
4401 wined3d_buffer_unmap(This
->indexbuffer
);
4403 /* Set the index stream */
4404 wined3d_device_set_base_vertex_index(This
->wined3d_device
, StartVertex
);
4405 hr
= wined3d_device_set_index_buffer(This
->wined3d_device
, This
->indexbuffer
, WINED3DFMT_R16_UINT
);
4407 /* Set the vertex stream source */
4408 hr
= wined3d_device_set_stream_source(This
->wined3d_device
, 0, vb
->wineD3DVertexBuffer
, 0, stride
);
4411 ERR("(%p) IDirect3DDevice::SetStreamSource failed with hr = %08x\n", This
, hr
);
4412 wined3d_mutex_unlock();
4417 wined3d_device_set_primitive_type(This
->wined3d_device
, PrimitiveType
);
4418 hr
= wined3d_device_draw_indexed_primitive(This
->wined3d_device
, 0, IndexCount
);
4420 wined3d_mutex_unlock();
4425 static HRESULT WINAPI
4426 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUSetup(IDirect3DDevice7
*iface
,
4427 D3DPRIMITIVETYPE PrimitiveType
,
4428 IDirect3DVertexBuffer7
*D3DVertexBuf
,
4435 return IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB(iface
, PrimitiveType
, D3DVertexBuf
, StartVertex
, NumVertices
, Indices
, IndexCount
, Flags
);
4438 static HRESULT WINAPI
4439 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUPreserve(IDirect3DDevice7
*iface
,
4440 D3DPRIMITIVETYPE PrimitiveType
,
4441 IDirect3DVertexBuffer7
*D3DVertexBuf
,
4451 old_fpucw
= d3d_fpu_setup();
4452 hr
= IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB(iface
, PrimitiveType
, D3DVertexBuf
, StartVertex
, NumVertices
, Indices
, IndexCount
, Flags
);
4453 set_fpu_control_word(old_fpucw
);
4458 static HRESULT WINAPI
IDirect3DDeviceImpl_3_DrawIndexedPrimitiveVB(IDirect3DDevice3
*iface
,
4459 D3DPRIMITIVETYPE PrimitiveType
, IDirect3DVertexBuffer
*D3DVertexBuf
, WORD
*Indices
,
4460 DWORD IndexCount
, DWORD Flags
)
4462 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
4463 IDirect3DVertexBufferImpl
*vb
= unsafe_impl_from_IDirect3DVertexBuffer(D3DVertexBuf
);
4465 TRACE("iface %p, primitive_type %#x, vb %p, indices %p, index_count %u, flags %#x.\n",
4466 iface
, PrimitiveType
, D3DVertexBuf
, Indices
, IndexCount
, Flags
);
4468 return IDirect3DDevice7_DrawIndexedPrimitiveVB(&This
->IDirect3DDevice7_iface
,
4469 PrimitiveType
, &vb
->IDirect3DVertexBuffer7_iface
, 0, IndexCount
, Indices
, IndexCount
,
4473 /*****************************************************************************
4474 * IDirect3DDevice7::ComputeSphereVisibility
4476 * Calculates the visibility of spheres in the current viewport. The spheres
4477 * are passed in the Centers and Radii arrays, the results are passed back
4478 * in the ReturnValues array. Return values are either completely visible,
4479 * partially visible or completely invisible.
4480 * The return value consist of a combination of D3DCLIP_* flags, or it's
4481 * 0 if the sphere is completely visible(according to the SDK, not checked)
4486 * Centers: Array containing the sphere centers
4487 * Radii: Array containing the sphere radii
4488 * NumSpheres: The number of centers and radii in the arrays
4490 * ReturnValues: Array to write the results to
4494 * (DDERR_INVALIDPARAMS if Centers, Radii or ReturnValues are NULL)
4495 * (D3DERR_INVALIDMATRIX if the combined world, view and proj matrix
4498 *****************************************************************************/
4500 static DWORD
in_plane(UINT plane
, D3DVECTOR normal
, D3DVALUE origin_plane
, D3DVECTOR center
, D3DVALUE radius
)
4502 float distance
, norm
;
4504 norm
= sqrt( normal
.u1
.x
* normal
.u1
.x
+ normal
.u2
.y
* normal
.u2
.y
+ normal
.u3
.z
* normal
.u3
.z
);
4505 distance
= ( origin_plane
+ normal
.u1
.x
* center
.u1
.x
+ normal
.u2
.y
* center
.u2
.y
+ normal
.u3
.z
* center
.u3
.z
) / norm
;
4507 if ( fabs( distance
) < radius
) return D3DSTATUS_CLIPUNIONLEFT
<< plane
;
4508 if ( distance
< -radius
) return (D3DSTATUS_CLIPUNIONLEFT
| D3DSTATUS_CLIPINTERSECTIONLEFT
) << plane
;
4512 static HRESULT WINAPI
4513 IDirect3DDeviceImpl_7_ComputeSphereVisibility(IDirect3DDevice7
*iface
,
4518 DWORD
*ReturnValues
)
4521 D3DVALUE origin_plane
[6];
4526 TRACE("iface %p, centers %p, radii %p, sphere_count %u, flags %#x, return_values %p.\n",
4527 iface
, Centers
, Radii
, NumSpheres
, Flags
, ReturnValues
);
4529 hr
= IDirect3DDeviceImpl_7_GetTransform(iface
, D3DTRANSFORMSTATE_WORLD
, &m
);
4530 if ( hr
!= DD_OK
) return DDERR_INVALIDPARAMS
;
4531 hr
= IDirect3DDeviceImpl_7_GetTransform(iface
, D3DTRANSFORMSTATE_VIEW
, &temp
);
4532 if ( hr
!= DD_OK
) return DDERR_INVALIDPARAMS
;
4533 multiply_matrix(&m
, &temp
, &m
);
4535 hr
= IDirect3DDeviceImpl_7_GetTransform(iface
, D3DTRANSFORMSTATE_PROJECTION
, &temp
);
4536 if ( hr
!= DD_OK
) return DDERR_INVALIDPARAMS
;
4537 multiply_matrix(&m
, &temp
, &m
);
4540 vec
[0].u1
.x
= m
._14
+ m
._11
;
4541 vec
[0].u2
.y
= m
._24
+ m
._21
;
4542 vec
[0].u3
.z
= m
._34
+ m
._31
;
4543 origin_plane
[0] = m
._44
+ m
._41
;
4546 vec
[1].u1
.x
= m
._14
- m
._11
;
4547 vec
[1].u2
.y
= m
._24
- m
._21
;
4548 vec
[1].u3
.z
= m
._34
- m
._31
;
4549 origin_plane
[1] = m
._44
- m
._41
;
4552 vec
[2].u1
.x
= m
._14
- m
._12
;
4553 vec
[2].u2
.y
= m
._24
- m
._22
;
4554 vec
[2].u3
.z
= m
._34
- m
._32
;
4555 origin_plane
[2] = m
._44
- m
._42
;
4558 vec
[3].u1
.x
= m
._14
+ m
._12
;
4559 vec
[3].u2
.y
= m
._24
+ m
._22
;
4560 vec
[3].u3
.z
= m
._34
+ m
._32
;
4561 origin_plane
[3] = m
._44
+ m
._42
;
4564 vec
[4].u1
.x
= m
._13
;
4565 vec
[4].u2
.y
= m
._23
;
4566 vec
[4].u3
.z
= m
._33
;
4567 origin_plane
[4] = m
._43
;
4570 vec
[5].u1
.x
= m
._14
- m
._13
;
4571 vec
[5].u2
.y
= m
._24
- m
._23
;
4572 vec
[5].u3
.z
= m
._34
- m
._33
;
4573 origin_plane
[5] = m
._44
- m
._43
;
4575 for(i
=0; i
<NumSpheres
; i
++)
4577 ReturnValues
[i
] = 0;
4578 for(j
=0; j
<6; j
++) ReturnValues
[i
] |= in_plane(j
, vec
[j
], origin_plane
[j
], Centers
[i
], Radii
[i
]);
4584 static HRESULT WINAPI
IDirect3DDeviceImpl_3_ComputeSphereVisibility(IDirect3DDevice3
*iface
,
4585 D3DVECTOR
*Centers
, D3DVALUE
*Radii
, DWORD NumSpheres
, DWORD Flags
, DWORD
*ReturnValues
)
4587 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
4589 TRACE("iface %p, centers %p, radii %p, sphere_count %u, flags %#x, return_values %p.\n",
4590 iface
, Centers
, Radii
, NumSpheres
, Flags
, ReturnValues
);
4592 return IDirect3DDevice7_ComputeSphereVisibility(&This
->IDirect3DDevice7_iface
,
4593 Centers
, Radii
, NumSpheres
, Flags
, ReturnValues
);
4596 /*****************************************************************************
4597 * IDirect3DDevice7::GetTexture
4599 * Returns the texture interface handle assigned to a texture stage.
4600 * The returned texture is AddRefed. This is taken from old ddraw,
4601 * not checked in Windows.
4606 * Stage: Texture stage to read the texture from
4607 * Texture: Address to store the interface pointer at
4611 * DDERR_INVALIDPARAMS if Texture is NULL
4612 * For details, see IWineD3DDevice::GetTexture
4614 *****************************************************************************/
4616 IDirect3DDeviceImpl_7_GetTexture(IDirect3DDevice7
*iface
,
4618 IDirectDrawSurface7
**Texture
)
4620 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
4621 struct wined3d_texture
*wined3d_texture
;
4624 TRACE("iface %p, stage %u, texture %p.\n", iface
, Stage
, Texture
);
4628 TRACE("Texture == NULL, failing with DDERR_INVALIDPARAMS\n");
4629 return DDERR_INVALIDPARAMS
;
4632 wined3d_mutex_lock();
4633 hr
= wined3d_device_get_texture(This
->wined3d_device
, Stage
, &wined3d_texture
);
4634 if (FAILED(hr
) || !wined3d_texture
)
4637 wined3d_mutex_unlock();
4641 *Texture
= wined3d_texture_get_parent(wined3d_texture
);
4642 IDirectDrawSurface7_AddRef(*Texture
);
4643 wined3d_texture_decref(wined3d_texture
);
4644 wined3d_mutex_unlock();
4649 static HRESULT WINAPI
4650 IDirect3DDeviceImpl_7_GetTexture_FPUSetup(IDirect3DDevice7
*iface
,
4652 IDirectDrawSurface7
**Texture
)
4654 return IDirect3DDeviceImpl_7_GetTexture(iface
, Stage
, Texture
);
4657 static HRESULT WINAPI
4658 IDirect3DDeviceImpl_7_GetTexture_FPUPreserve(IDirect3DDevice7
*iface
,
4660 IDirectDrawSurface7
**Texture
)
4665 old_fpucw
= d3d_fpu_setup();
4666 hr
= IDirect3DDeviceImpl_7_GetTexture(iface
, Stage
, Texture
);
4667 set_fpu_control_word(old_fpucw
);
4672 static HRESULT WINAPI
IDirect3DDeviceImpl_3_GetTexture(IDirect3DDevice3
*iface
, DWORD Stage
,
4673 IDirect3DTexture2
**Texture2
)
4675 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
4676 struct ddraw_surface
*ret_val_impl
;
4678 IDirectDrawSurface7
*ret_val
;
4680 TRACE("iface %p, stage %u, texture %p.\n", iface
, Stage
, Texture2
);
4682 ret
= IDirect3DDevice7_GetTexture(&This
->IDirect3DDevice7_iface
, Stage
, &ret_val
);
4684 ret_val_impl
= unsafe_impl_from_IDirectDrawSurface7(ret_val
);
4685 *Texture2
= ret_val_impl
? &ret_val_impl
->IDirect3DTexture2_iface
: NULL
;
4687 TRACE("Returning texture %p.\n", *Texture2
);
4692 /*****************************************************************************
4693 * IDirect3DDevice7::SetTexture
4695 * Assigns a texture to a texture stage. Is the texture AddRef-ed?
4700 * Stage: The stage to assign the texture to
4701 * Texture: Interface pointer to the texture surface
4705 * For details, see IWineD3DDevice::SetTexture
4707 *****************************************************************************/
4709 IDirect3DDeviceImpl_7_SetTexture(IDirect3DDevice7
*iface
,
4711 IDirectDrawSurface7
*Texture
)
4713 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
4714 struct ddraw_surface
*surf
= unsafe_impl_from_IDirectDrawSurface7(Texture
);
4717 TRACE("iface %p, stage %u, texture %p.\n", iface
, Stage
, Texture
);
4719 /* Texture may be NULL here */
4720 wined3d_mutex_lock();
4721 hr
= wined3d_device_set_texture(This
->wined3d_device
,
4722 Stage
, surf
? surf
->wined3d_texture
: NULL
);
4723 wined3d_mutex_unlock();
4728 static HRESULT WINAPI
4729 IDirect3DDeviceImpl_7_SetTexture_FPUSetup(IDirect3DDevice7
*iface
,
4731 IDirectDrawSurface7
*Texture
)
4733 return IDirect3DDeviceImpl_7_SetTexture(iface
, Stage
, Texture
);
4736 static HRESULT WINAPI
4737 IDirect3DDeviceImpl_7_SetTexture_FPUPreserve(IDirect3DDevice7
*iface
,
4739 IDirectDrawSurface7
*Texture
)
4744 old_fpucw
= d3d_fpu_setup();
4745 hr
= IDirect3DDeviceImpl_7_SetTexture(iface
, Stage
, Texture
);
4746 set_fpu_control_word(old_fpucw
);
4751 static HRESULT WINAPI
4752 IDirect3DDeviceImpl_3_SetTexture(IDirect3DDevice3
*iface
,
4754 IDirect3DTexture2
*Texture2
)
4756 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
4757 struct ddraw_surface
*tex
= unsafe_impl_from_IDirect3DTexture2(Texture2
);
4761 TRACE("iface %p, stage %u, texture %p.\n", iface
, Stage
, Texture2
);
4763 wined3d_mutex_lock();
4765 if (This
->legacyTextureBlending
)
4766 IDirect3DDevice3_GetRenderState(iface
, D3DRENDERSTATE_TEXTUREMAPBLEND
, &texmapblend
);
4768 hr
= IDirect3DDevice7_SetTexture(&This
->IDirect3DDevice7_iface
, Stage
, &tex
->IDirectDrawSurface7_iface
);
4770 if (This
->legacyTextureBlending
&& texmapblend
== D3DTBLEND_MODULATE
)
4772 /* This fixup is required by the way D3DTBLEND_MODULATE maps to texture stage states.
4773 See IDirect3DDeviceImpl_3_SetRenderState for details. */
4774 struct wined3d_texture
*tex
= NULL
;
4775 BOOL tex_alpha
= FALSE
;
4776 DDPIXELFORMAT ddfmt
;
4779 result
= wined3d_device_get_texture(This
->wined3d_device
, 0, &tex
);
4780 if (result
== WINED3D_OK
&& tex
)
4782 struct wined3d_resource
*sub_resource
;
4784 if ((sub_resource
= wined3d_texture_get_sub_resource(tex
, 0)))
4786 struct wined3d_resource_desc desc
;
4788 wined3d_resource_get_desc(sub_resource
, &desc
);
4789 ddfmt
.dwSize
= sizeof(ddfmt
);
4790 PixelFormat_WineD3DtoDD(&ddfmt
, desc
.format
);
4791 if (ddfmt
.u5
.dwRGBAlphaBitMask
) tex_alpha
= TRUE
;
4794 wined3d_texture_decref(tex
);
4797 /* Arg 1/2 are already set to WINED3DTA_TEXTURE/WINED3DTA_CURRENT in case of D3DTBLEND_MODULATE */
4799 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
4800 0, WINED3D_TSS_ALPHA_OP
, WINED3D_TOP_SELECT_ARG1
);
4802 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
4803 0, WINED3D_TSS_ALPHA_OP
, WINED3D_TOP_SELECT_ARG2
);
4806 wined3d_mutex_unlock();
4811 static const struct tss_lookup
4814 enum wined3d_texture_stage_state state
;
4818 {FALSE
, WINED3D_TSS_INVALID
}, /* 0, unused */
4819 {FALSE
, WINED3D_TSS_COLOR_OP
}, /* 1, D3DTSS_COLOROP */
4820 {FALSE
, WINED3D_TSS_COLOR_ARG1
}, /* 2, D3DTSS_COLORARG1 */
4821 {FALSE
, WINED3D_TSS_COLOR_ARG2
}, /* 3, D3DTSS_COLORARG2 */
4822 {FALSE
, WINED3D_TSS_ALPHA_OP
}, /* 4, D3DTSS_ALPHAOP */
4823 {FALSE
, WINED3D_TSS_ALPHA_ARG1
}, /* 5, D3DTSS_ALPHAARG1 */
4824 {FALSE
, WINED3D_TSS_ALPHA_ARG2
}, /* 6, D3DTSS_ALPHAARG2 */
4825 {FALSE
, WINED3D_TSS_BUMPENV_MAT00
}, /* 7, D3DTSS_BUMPENVMAT00 */
4826 {FALSE
, WINED3D_TSS_BUMPENV_MAT01
}, /* 8, D3DTSS_BUMPENVMAT01 */
4827 {FALSE
, WINED3D_TSS_BUMPENV_MAT10
}, /* 9, D3DTSS_BUMPENVMAT10 */
4828 {FALSE
, WINED3D_TSS_BUMPENV_MAT11
}, /* 10, D3DTSS_BUMPENVMAT11 */
4829 {FALSE
, WINED3D_TSS_TEXCOORD_INDEX
}, /* 11, D3DTSS_TEXCOORDINDEX */
4830 {TRUE
, WINED3D_SAMP_ADDRESS_U
}, /* 12, D3DTSS_ADDRESS */
4831 {TRUE
, WINED3D_SAMP_ADDRESS_U
}, /* 13, D3DTSS_ADDRESSU */
4832 {TRUE
, WINED3D_SAMP_ADDRESS_V
}, /* 14, D3DTSS_ADDRESSV */
4833 {TRUE
, WINED3D_SAMP_BORDER_COLOR
}, /* 15, D3DTSS_BORDERCOLOR */
4834 {TRUE
, WINED3D_SAMP_MAG_FILTER
}, /* 16, D3DTSS_MAGFILTER */
4835 {TRUE
, WINED3D_SAMP_MIN_FILTER
}, /* 17, D3DTSS_MINFILTER */
4836 {TRUE
, WINED3D_SAMP_MIP_FILTER
}, /* 18, D3DTSS_MIPFILTER */
4837 {TRUE
, WINED3D_SAMP_MIPMAP_LOD_BIAS
}, /* 19, D3DTSS_MIPMAPLODBIAS */
4838 {TRUE
, WINED3D_SAMP_MAX_MIP_LEVEL
}, /* 20, D3DTSS_MAXMIPLEVEL */
4839 {TRUE
, WINED3D_SAMP_MAX_ANISOTROPY
}, /* 21, D3DTSS_MAXANISOTROPY */
4840 {FALSE
, WINED3D_TSS_BUMPENV_LSCALE
}, /* 22, D3DTSS_BUMPENVLSCALE */
4841 {FALSE
, WINED3D_TSS_BUMPENV_LOFFSET
}, /* 23, D3DTSS_BUMPENVLOFFSET */
4842 {FALSE
, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS
}, /* 24, D3DTSS_TEXTURETRANSFORMFLAGS */
4845 /*****************************************************************************
4846 * IDirect3DDevice7::GetTextureStageState
4848 * Retrieves a state from a texture stage.
4853 * Stage: The stage to retrieve the state from
4854 * TexStageStateType: The state type to retrieve
4855 * State: Address to store the state's value at
4859 * DDERR_INVALIDPARAMS if State is NULL
4860 * For details, see IWineD3DDevice::GetTextureStageState
4862 *****************************************************************************/
4864 IDirect3DDeviceImpl_7_GetTextureStageState(IDirect3DDevice7
*iface
,
4866 D3DTEXTURESTAGESTATETYPE TexStageStateType
,
4869 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
4871 const struct tss_lookup
*l
;
4873 TRACE("iface %p, stage %u, state %#x, value %p.\n",
4874 iface
, Stage
, TexStageStateType
, State
);
4877 return DDERR_INVALIDPARAMS
;
4879 if (TexStageStateType
> D3DTSS_TEXTURETRANSFORMFLAGS
)
4881 WARN("Invalid TexStageStateType %#x passed.\n", TexStageStateType
);
4885 l
= &tss_lookup
[TexStageStateType
];
4887 wined3d_mutex_lock();
4889 if (l
->sampler_state
)
4891 hr
= wined3d_device_get_sampler_state(This
->wined3d_device
, Stage
, l
->state
, State
);
4893 switch(TexStageStateType
)
4895 /* Mipfilter is a sampler state with different values */
4896 case D3DTSS_MIPFILTER
:
4900 case WINED3D_TEXF_NONE
:
4901 *State
= D3DTFP_NONE
;
4903 case WINED3D_TEXF_POINT
:
4904 *State
= D3DTFP_POINT
;
4906 case WINED3D_TEXF_LINEAR
:
4907 *State
= D3DTFP_LINEAR
;
4910 ERR("Unexpected mipfilter value %#x\n", *State
);
4911 *State
= D3DTFP_NONE
;
4917 /* Magfilter has slightly different values */
4918 case D3DTSS_MAGFILTER
:
4922 case WINED3D_TEXF_POINT
:
4923 *State
= D3DTFG_POINT
;
4925 case WINED3D_TEXF_LINEAR
:
4926 *State
= D3DTFG_LINEAR
;
4928 case WINED3D_TEXF_ANISOTROPIC
:
4929 *State
= D3DTFG_ANISOTROPIC
;
4931 case WINED3D_TEXF_FLAT_CUBIC
:
4932 *State
= D3DTFG_FLATCUBIC
;
4934 case WINED3D_TEXF_GAUSSIAN_CUBIC
:
4935 *State
= D3DTFG_GAUSSIANCUBIC
;
4938 ERR("Unexpected wined3d mag filter value %#x\n", *State
);
4939 *State
= D3DTFG_POINT
;
4951 hr
= wined3d_device_get_texture_stage_state(This
->wined3d_device
, Stage
, l
->state
, State
);
4954 wined3d_mutex_unlock();
4959 static HRESULT WINAPI
4960 IDirect3DDeviceImpl_7_GetTextureStageState_FPUSetup(IDirect3DDevice7
*iface
,
4962 D3DTEXTURESTAGESTATETYPE TexStageStateType
,
4965 return IDirect3DDeviceImpl_7_GetTextureStageState(iface
, Stage
, TexStageStateType
, State
);
4968 static HRESULT WINAPI
4969 IDirect3DDeviceImpl_7_GetTextureStageState_FPUPreserve(IDirect3DDevice7
*iface
,
4971 D3DTEXTURESTAGESTATETYPE TexStageStateType
,
4977 old_fpucw
= d3d_fpu_setup();
4978 hr
= IDirect3DDeviceImpl_7_GetTextureStageState(iface
, Stage
, TexStageStateType
, State
);
4979 set_fpu_control_word(old_fpucw
);
4984 static HRESULT WINAPI
IDirect3DDeviceImpl_3_GetTextureStageState(IDirect3DDevice3
*iface
,
4985 DWORD Stage
, D3DTEXTURESTAGESTATETYPE TexStageStateType
, DWORD
*State
)
4987 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
4989 TRACE("iface %p, stage %u, state %#x, value %p.\n",
4990 iface
, Stage
, TexStageStateType
, State
);
4992 return IDirect3DDevice7_GetTextureStageState(&This
->IDirect3DDevice7_iface
,
4993 Stage
, TexStageStateType
, State
);
4996 /*****************************************************************************
4997 * IDirect3DDevice7::SetTextureStageState
4999 * Sets a texture stage state. Some stage types need to be handled specially,
5000 * because they do not exist in WineD3D and were moved to another place
5005 * Stage: The stage to modify
5006 * TexStageStateType: The state to change
5007 * State: The new value for the state
5011 * For details, see IWineD3DDevice::SetTextureStageState
5013 *****************************************************************************/
5015 IDirect3DDeviceImpl_7_SetTextureStageState(IDirect3DDevice7
*iface
,
5017 D3DTEXTURESTAGESTATETYPE TexStageStateType
,
5020 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
5021 const struct tss_lookup
*l
;
5024 TRACE("iface %p, stage %u, state %#x, value %#x.\n",
5025 iface
, Stage
, TexStageStateType
, State
);
5027 if (TexStageStateType
> D3DTSS_TEXTURETRANSFORMFLAGS
)
5029 WARN("Invalid TexStageStateType %#x passed.\n", TexStageStateType
);
5033 l
= &tss_lookup
[TexStageStateType
];
5035 wined3d_mutex_lock();
5037 if (l
->sampler_state
)
5039 switch(TexStageStateType
)
5041 /* Mipfilter is a sampler state with different values */
5042 case D3DTSS_MIPFILTER
:
5047 State
= WINED3D_TEXF_NONE
;
5050 State
= WINED3D_TEXF_POINT
;
5052 case 0: /* Unchecked */
5054 State
= WINED3D_TEXF_LINEAR
;
5057 ERR("Unexpected mipfilter value %d\n", State
);
5058 State
= WINED3D_TEXF_NONE
;
5064 /* Magfilter has slightly different values */
5065 case D3DTSS_MAGFILTER
:
5070 State
= WINED3D_TEXF_POINT
;
5073 State
= WINED3D_TEXF_LINEAR
;
5075 case D3DTFG_FLATCUBIC
:
5076 State
= WINED3D_TEXF_FLAT_CUBIC
;
5078 case D3DTFG_GAUSSIANCUBIC
:
5079 State
= WINED3D_TEXF_GAUSSIAN_CUBIC
;
5081 case D3DTFG_ANISOTROPIC
:
5082 State
= WINED3D_TEXF_ANISOTROPIC
;
5085 ERR("Unexpected d3d7 mag filter type %d\n", State
);
5086 State
= WINED3D_TEXF_POINT
;
5092 case D3DTSS_ADDRESS
:
5093 wined3d_device_set_sampler_state(This
->wined3d_device
, Stage
, WINED3D_SAMP_ADDRESS_V
, State
);
5100 hr
= wined3d_device_set_sampler_state(This
->wined3d_device
, Stage
, l
->state
, State
);
5104 hr
= wined3d_device_set_texture_stage_state(This
->wined3d_device
, Stage
, l
->state
, State
);
5107 wined3d_mutex_unlock();
5112 static HRESULT WINAPI
5113 IDirect3DDeviceImpl_7_SetTextureStageState_FPUSetup(IDirect3DDevice7
*iface
,
5115 D3DTEXTURESTAGESTATETYPE TexStageStateType
,
5118 return IDirect3DDeviceImpl_7_SetTextureStageState(iface
, Stage
, TexStageStateType
, State
);
5121 static HRESULT WINAPI
5122 IDirect3DDeviceImpl_7_SetTextureStageState_FPUPreserve(IDirect3DDevice7
*iface
,
5124 D3DTEXTURESTAGESTATETYPE TexStageStateType
,
5130 old_fpucw
= d3d_fpu_setup();
5131 hr
= IDirect3DDeviceImpl_7_SetTextureStageState(iface
, Stage
, TexStageStateType
, State
);
5132 set_fpu_control_word(old_fpucw
);
5137 static HRESULT WINAPI
IDirect3DDeviceImpl_3_SetTextureStageState(IDirect3DDevice3
*iface
,
5138 DWORD Stage
, D3DTEXTURESTAGESTATETYPE TexStageStateType
, DWORD State
)
5140 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
5142 TRACE("iface %p, stage %u, state %#x, value %#x.\n",
5143 iface
, Stage
, TexStageStateType
, State
);
5145 return IDirect3DDevice7_SetTextureStageState(&This
->IDirect3DDevice7_iface
,
5146 Stage
, TexStageStateType
, State
);
5149 /*****************************************************************************
5150 * IDirect3DDevice7::ValidateDevice
5152 * SDK: "Reports the device's ability to render the currently set
5153 * texture-blending operations in a single pass". Whatever that means
5159 * NumPasses: Address to write the number of necessary passes for the
5160 * desired effect to.
5164 * See IWineD3DDevice::ValidateDevice for more details
5166 *****************************************************************************/
5168 IDirect3DDeviceImpl_7_ValidateDevice(IDirect3DDevice7
*iface
,
5171 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
5174 TRACE("iface %p, pass_count %p.\n", iface
, NumPasses
);
5176 wined3d_mutex_lock();
5177 hr
= wined3d_device_validate_device(This
->wined3d_device
, NumPasses
);
5178 wined3d_mutex_unlock();
5183 static HRESULT WINAPI
5184 IDirect3DDeviceImpl_7_ValidateDevice_FPUSetup(IDirect3DDevice7
*iface
,
5187 return IDirect3DDeviceImpl_7_ValidateDevice(iface
, NumPasses
);
5190 static HRESULT WINAPI
5191 IDirect3DDeviceImpl_7_ValidateDevice_FPUPreserve(IDirect3DDevice7
*iface
,
5197 old_fpucw
= d3d_fpu_setup();
5198 hr
= IDirect3DDeviceImpl_7_ValidateDevice(iface
, NumPasses
);
5199 set_fpu_control_word(old_fpucw
);
5204 static HRESULT WINAPI
IDirect3DDeviceImpl_3_ValidateDevice(IDirect3DDevice3
*iface
, DWORD
*Passes
)
5206 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
5208 TRACE("iface %p, pass_count %p.\n", iface
, Passes
);
5210 return IDirect3DDevice7_ValidateDevice(&This
->IDirect3DDevice7_iface
, Passes
);
5213 /*****************************************************************************
5214 * IDirect3DDevice7::Clear
5216 * Fills the render target, the z buffer and the stencil buffer with a
5217 * clear color / value
5222 * Count: Number of rectangles in Rects must be 0 if Rects is NULL
5223 * Rects: Rectangles to clear. If NULL, the whole surface is cleared
5224 * Flags: Some flags, as usual
5225 * Color: Clear color for the render target
5226 * Z: Clear value for the Z buffer
5227 * Stencil: Clear value to store in each stencil buffer entry
5231 * For details, see IWineD3DDevice::Clear
5233 *****************************************************************************/
5234 static HRESULT
IDirect3DDeviceImpl_7_Clear(IDirect3DDevice7
*iface
, DWORD count
,
5235 D3DRECT
*rects
, DWORD flags
, D3DCOLOR color
, D3DVALUE z
, DWORD stencil
)
5237 const struct wined3d_color c
=
5239 ((color
>> 16) & 0xff) / 255.0f
,
5240 ((color
>> 8) & 0xff) / 255.0f
,
5241 (color
& 0xff) / 255.0f
,
5242 ((color
>> 24) & 0xff) / 255.0f
,
5244 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
5247 TRACE("iface %p, count %u, rects %p, flags %#x, color 0x%08x, z %.8e, stencil %#x.\n",
5248 iface
, count
, rects
, flags
, color
, z
, stencil
);
5250 wined3d_mutex_lock();
5251 hr
= wined3d_device_clear(This
->wined3d_device
, count
, (RECT
*)rects
, flags
, &c
, z
, stencil
);
5252 wined3d_mutex_unlock();
5257 static HRESULT WINAPI
5258 IDirect3DDeviceImpl_7_Clear_FPUSetup(IDirect3DDevice7
*iface
,
5266 return IDirect3DDeviceImpl_7_Clear(iface
, Count
, Rects
, Flags
, Color
, Z
, Stencil
);
5269 static HRESULT WINAPI
5270 IDirect3DDeviceImpl_7_Clear_FPUPreserve(IDirect3DDevice7
*iface
,
5281 old_fpucw
= d3d_fpu_setup();
5282 hr
= IDirect3DDeviceImpl_7_Clear(iface
, Count
, Rects
, Flags
, Color
, Z
, Stencil
);
5283 set_fpu_control_word(old_fpucw
);
5288 /*****************************************************************************
5289 * IDirect3DDevice7::SetViewport
5291 * Sets the current viewport.
5293 * Version 7 only, but IDirect3DViewport uses this call for older
5297 * Data: The new viewport to set
5301 * DDERR_INVALIDPARAMS if Data is NULL
5302 * For more details, see IWineDDDevice::SetViewport
5304 *****************************************************************************/
5306 IDirect3DDeviceImpl_7_SetViewport(IDirect3DDevice7
*iface
,
5309 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
5312 TRACE("iface %p, viewport %p.\n", iface
, Data
);
5315 return DDERR_INVALIDPARAMS
;
5317 /* Note: D3DVIEWPORT7 is compatible with struct wined3d_viewport. */
5318 wined3d_mutex_lock();
5319 hr
= wined3d_device_set_viewport(This
->wined3d_device
, (struct wined3d_viewport
*)Data
);
5320 wined3d_mutex_unlock();
5325 static HRESULT WINAPI
5326 IDirect3DDeviceImpl_7_SetViewport_FPUSetup(IDirect3DDevice7
*iface
,
5329 return IDirect3DDeviceImpl_7_SetViewport(iface
, Data
);
5332 static HRESULT WINAPI
5333 IDirect3DDeviceImpl_7_SetViewport_FPUPreserve(IDirect3DDevice7
*iface
,
5339 old_fpucw
= d3d_fpu_setup();
5340 hr
= IDirect3DDeviceImpl_7_SetViewport(iface
, Data
);
5341 set_fpu_control_word(old_fpucw
);
5346 /*****************************************************************************
5347 * IDirect3DDevice::GetViewport
5349 * Returns the current viewport
5354 * Data: D3D7Viewport structure to write the viewport information to
5358 * DDERR_INVALIDPARAMS if Data is NULL
5359 * For more details, see IWineD3DDevice::GetViewport
5361 *****************************************************************************/
5363 IDirect3DDeviceImpl_7_GetViewport(IDirect3DDevice7
*iface
,
5366 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
5369 TRACE("iface %p, viewport %p.\n", iface
, Data
);
5372 return DDERR_INVALIDPARAMS
;
5374 /* Note: D3DVIEWPORT7 is compatible with struct wined3d_viewport. */
5375 wined3d_mutex_lock();
5376 hr
= wined3d_device_get_viewport(This
->wined3d_device
, (struct wined3d_viewport
*)Data
);
5377 wined3d_mutex_unlock();
5379 return hr_ddraw_from_wined3d(hr
);
5382 static HRESULT WINAPI
5383 IDirect3DDeviceImpl_7_GetViewport_FPUSetup(IDirect3DDevice7
*iface
,
5386 return IDirect3DDeviceImpl_7_GetViewport(iface
, Data
);
5389 static HRESULT WINAPI
5390 IDirect3DDeviceImpl_7_GetViewport_FPUPreserve(IDirect3DDevice7
*iface
,
5396 old_fpucw
= d3d_fpu_setup();
5397 hr
= IDirect3DDeviceImpl_7_GetViewport(iface
, Data
);
5398 set_fpu_control_word(old_fpucw
);
5403 /*****************************************************************************
5404 * IDirect3DDevice7::SetMaterial
5411 * Mat: The material to set
5415 * DDERR_INVALIDPARAMS if Mat is NULL.
5416 * For more details, see IWineD3DDevice::SetMaterial
5418 *****************************************************************************/
5420 IDirect3DDeviceImpl_7_SetMaterial(IDirect3DDevice7
*iface
,
5423 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
5426 TRACE("iface %p, material %p.\n", iface
, Mat
);
5428 if (!Mat
) return DDERR_INVALIDPARAMS
;
5430 wined3d_mutex_lock();
5431 /* Note: D3DMATERIAL7 is compatible with struct wined3d_material. */
5432 hr
= wined3d_device_set_material(This
->wined3d_device
, (struct wined3d_material
*)Mat
);
5433 wined3d_mutex_unlock();
5435 return hr_ddraw_from_wined3d(hr
);
5438 static HRESULT WINAPI
5439 IDirect3DDeviceImpl_7_SetMaterial_FPUSetup(IDirect3DDevice7
*iface
,
5442 return IDirect3DDeviceImpl_7_SetMaterial(iface
, Mat
);
5445 static HRESULT WINAPI
5446 IDirect3DDeviceImpl_7_SetMaterial_FPUPreserve(IDirect3DDevice7
*iface
,
5452 old_fpucw
= d3d_fpu_setup();
5453 hr
= IDirect3DDeviceImpl_7_SetMaterial(iface
, Mat
);
5454 set_fpu_control_word(old_fpucw
);
5459 /*****************************************************************************
5460 * IDirect3DDevice7::GetMaterial
5462 * Returns the current material
5467 * Mat: D3DMATERIAL7 structure to write the material parameters to
5471 * DDERR_INVALIDPARAMS if Mat is NULL
5472 * For more details, see IWineD3DDevice::GetMaterial
5474 *****************************************************************************/
5476 IDirect3DDeviceImpl_7_GetMaterial(IDirect3DDevice7
*iface
,
5479 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
5482 TRACE("iface %p, material %p.\n", iface
, Mat
);
5484 wined3d_mutex_lock();
5485 /* Note: D3DMATERIAL7 is compatible with struct wined3d_material. */
5486 hr
= wined3d_device_get_material(This
->wined3d_device
, (struct wined3d_material
*)Mat
);
5487 wined3d_mutex_unlock();
5489 return hr_ddraw_from_wined3d(hr
);
5492 static HRESULT WINAPI
5493 IDirect3DDeviceImpl_7_GetMaterial_FPUSetup(IDirect3DDevice7
*iface
,
5496 return IDirect3DDeviceImpl_7_GetMaterial(iface
, Mat
);
5499 static HRESULT WINAPI
5500 IDirect3DDeviceImpl_7_GetMaterial_FPUPreserve(IDirect3DDevice7
*iface
,
5506 old_fpucw
= d3d_fpu_setup();
5507 hr
= IDirect3DDeviceImpl_7_GetMaterial(iface
, Mat
);
5508 set_fpu_control_word(old_fpucw
);
5513 /*****************************************************************************
5514 * IDirect3DDevice7::SetLight
5516 * Assigns a light to a light index, but doesn't activate it yet.
5518 * Version 7, IDirect3DLight uses this method for older versions
5521 * LightIndex: The index of the new light
5522 * Light: A D3DLIGHT7 structure describing the light
5526 * For more details, see IWineD3DDevice::SetLight
5528 *****************************************************************************/
5530 IDirect3DDeviceImpl_7_SetLight(IDirect3DDevice7
*iface
,
5534 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
5537 TRACE("iface %p, light_idx %u, light %p.\n", iface
, LightIndex
, Light
);
5539 wined3d_mutex_lock();
5540 /* Note: D3DLIGHT7 is compatible with struct wined3d_light. */
5541 hr
= wined3d_device_set_light(This
->wined3d_device
, LightIndex
, (struct wined3d_light
*)Light
);
5542 wined3d_mutex_unlock();
5544 return hr_ddraw_from_wined3d(hr
);
5547 static HRESULT WINAPI
5548 IDirect3DDeviceImpl_7_SetLight_FPUSetup(IDirect3DDevice7
*iface
,
5552 return IDirect3DDeviceImpl_7_SetLight(iface
, LightIndex
, Light
);
5555 static HRESULT WINAPI
5556 IDirect3DDeviceImpl_7_SetLight_FPUPreserve(IDirect3DDevice7
*iface
,
5563 old_fpucw
= d3d_fpu_setup();
5564 hr
= IDirect3DDeviceImpl_7_SetLight(iface
, LightIndex
, Light
);
5565 set_fpu_control_word(old_fpucw
);
5570 /*****************************************************************************
5571 * IDirect3DDevice7::GetLight
5573 * Returns the light assigned to a light index
5576 * Light: Structure to write the light information to
5580 * DDERR_INVALIDPARAMS if Light is NULL
5581 * For details, see IWineD3DDevice::GetLight
5583 *****************************************************************************/
5585 IDirect3DDeviceImpl_7_GetLight(IDirect3DDevice7
*iface
,
5589 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
5592 TRACE("iface %p, light_idx %u, light %p.\n", iface
, LightIndex
, Light
);
5594 wined3d_mutex_lock();
5595 /* Note: D3DLIGHT7 is compatible with struct wined3d_light. */
5596 rc
= wined3d_device_get_light(This
->wined3d_device
, LightIndex
, (struct wined3d_light
*)Light
);
5597 wined3d_mutex_unlock();
5599 /* Translate the result. WineD3D returns other values than D3D7 */
5600 return hr_ddraw_from_wined3d(rc
);
5603 static HRESULT WINAPI
5604 IDirect3DDeviceImpl_7_GetLight_FPUSetup(IDirect3DDevice7
*iface
,
5608 return IDirect3DDeviceImpl_7_GetLight(iface
, LightIndex
, Light
);
5611 static HRESULT WINAPI
5612 IDirect3DDeviceImpl_7_GetLight_FPUPreserve(IDirect3DDevice7
*iface
,
5619 old_fpucw
= d3d_fpu_setup();
5620 hr
= IDirect3DDeviceImpl_7_GetLight(iface
, LightIndex
, Light
);
5621 set_fpu_control_word(old_fpucw
);
5626 /*****************************************************************************
5627 * IDirect3DDevice7::BeginStateBlock
5629 * Begins recording to a stateblock
5635 * For details see IWineD3DDevice::BeginStateBlock
5637 *****************************************************************************/
5639 IDirect3DDeviceImpl_7_BeginStateBlock(IDirect3DDevice7
*iface
)
5641 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
5644 TRACE("iface %p.\n", iface
);
5646 wined3d_mutex_lock();
5647 hr
= wined3d_device_begin_stateblock(This
->wined3d_device
);
5648 wined3d_mutex_unlock();
5650 return hr_ddraw_from_wined3d(hr
);
5653 static HRESULT WINAPI
5654 IDirect3DDeviceImpl_7_BeginStateBlock_FPUSetup(IDirect3DDevice7
*iface
)
5656 return IDirect3DDeviceImpl_7_BeginStateBlock(iface
);
5659 static HRESULT WINAPI
5660 IDirect3DDeviceImpl_7_BeginStateBlock_FPUPreserve(IDirect3DDevice7
*iface
)
5665 old_fpucw
= d3d_fpu_setup();
5666 hr
= IDirect3DDeviceImpl_7_BeginStateBlock(iface
);
5667 set_fpu_control_word(old_fpucw
);
5672 /*****************************************************************************
5673 * IDirect3DDevice7::EndStateBlock
5675 * Stops recording to a state block and returns the created stateblock
5681 * BlockHandle: Address to store the stateblock's handle to
5685 * DDERR_INVALIDPARAMS if BlockHandle is NULL
5686 * See IWineD3DDevice::EndStateBlock for more details
5688 *****************************************************************************/
5690 IDirect3DDeviceImpl_7_EndStateBlock(IDirect3DDevice7
*iface
,
5693 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
5694 struct wined3d_stateblock
*wined3d_sb
;
5698 TRACE("iface %p, stateblock %p.\n", iface
, BlockHandle
);
5702 WARN("BlockHandle == NULL, returning DDERR_INVALIDPARAMS\n");
5703 return DDERR_INVALIDPARAMS
;
5706 wined3d_mutex_lock();
5708 hr
= wined3d_device_end_stateblock(This
->wined3d_device
, &wined3d_sb
);
5711 WARN("Failed to end stateblock, hr %#x.\n", hr
);
5712 wined3d_mutex_unlock();
5714 return hr_ddraw_from_wined3d(hr
);
5717 h
= ddraw_allocate_handle(&This
->handle_table
, wined3d_sb
, DDRAW_HANDLE_STATEBLOCK
);
5718 if (h
== DDRAW_INVALID_HANDLE
)
5720 ERR("Failed to allocate a stateblock handle.\n");
5721 wined3d_stateblock_decref(wined3d_sb
);
5722 wined3d_mutex_unlock();
5724 return DDERR_OUTOFMEMORY
;
5727 wined3d_mutex_unlock();
5728 *BlockHandle
= h
+ 1;
5730 return hr_ddraw_from_wined3d(hr
);
5733 static HRESULT WINAPI
5734 IDirect3DDeviceImpl_7_EndStateBlock_FPUSetup(IDirect3DDevice7
*iface
,
5737 return IDirect3DDeviceImpl_7_EndStateBlock(iface
, BlockHandle
);
5740 static HRESULT WINAPI
5741 IDirect3DDeviceImpl_7_EndStateBlock_FPUPreserve(IDirect3DDevice7
*iface
,
5747 old_fpucw
= d3d_fpu_setup();
5748 hr
= IDirect3DDeviceImpl_7_EndStateBlock(iface
, BlockHandle
);
5749 set_fpu_control_word(old_fpucw
);
5754 /*****************************************************************************
5755 * IDirect3DDevice7::PreLoad
5757 * Allows the app to signal that a texture will be used soon, to allow
5758 * the Direct3DDevice to load it to the video card in the meantime.
5763 * Texture: The texture to preload
5767 * DDERR_INVALIDPARAMS if Texture is NULL
5768 * See IWineD3DSurface::PreLoad for details
5770 *****************************************************************************/
5772 IDirect3DDeviceImpl_7_PreLoad(IDirect3DDevice7
*iface
,
5773 IDirectDrawSurface7
*Texture
)
5775 struct ddraw_surface
*surface
= unsafe_impl_from_IDirectDrawSurface7(Texture
);
5777 TRACE("iface %p, texture %p.\n", iface
, Texture
);
5780 return DDERR_INVALIDPARAMS
;
5782 wined3d_mutex_lock();
5783 wined3d_surface_preload(surface
->wined3d_surface
);
5784 wined3d_mutex_unlock();
5789 static HRESULT WINAPI
5790 IDirect3DDeviceImpl_7_PreLoad_FPUSetup(IDirect3DDevice7
*iface
,
5791 IDirectDrawSurface7
*Texture
)
5793 return IDirect3DDeviceImpl_7_PreLoad(iface
, Texture
);
5796 static HRESULT WINAPI
5797 IDirect3DDeviceImpl_7_PreLoad_FPUPreserve(IDirect3DDevice7
*iface
,
5798 IDirectDrawSurface7
*Texture
)
5803 old_fpucw
= d3d_fpu_setup();
5804 hr
= IDirect3DDeviceImpl_7_PreLoad(iface
, Texture
);
5805 set_fpu_control_word(old_fpucw
);
5810 /*****************************************************************************
5811 * IDirect3DDevice7::ApplyStateBlock
5813 * Activates the state stored in a state block handle.
5816 * BlockHandle: The stateblock handle to activate
5820 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is NULL
5822 *****************************************************************************/
5824 IDirect3DDeviceImpl_7_ApplyStateBlock(IDirect3DDevice7
*iface
,
5827 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
5828 struct wined3d_stateblock
*wined3d_sb
;
5831 TRACE("iface %p, stateblock %#x.\n", iface
, BlockHandle
);
5833 wined3d_mutex_lock();
5834 wined3d_sb
= ddraw_get_object(&This
->handle_table
, BlockHandle
- 1, DDRAW_HANDLE_STATEBLOCK
);
5837 WARN("Invalid stateblock handle.\n");
5838 wined3d_mutex_unlock();
5839 return D3DERR_INVALIDSTATEBLOCK
;
5842 hr
= wined3d_stateblock_apply(wined3d_sb
);
5843 wined3d_mutex_unlock();
5845 return hr_ddraw_from_wined3d(hr
);
5848 static HRESULT WINAPI
5849 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUSetup(IDirect3DDevice7
*iface
,
5852 return IDirect3DDeviceImpl_7_ApplyStateBlock(iface
, BlockHandle
);
5855 static HRESULT WINAPI
5856 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUPreserve(IDirect3DDevice7
*iface
,
5862 old_fpucw
= d3d_fpu_setup();
5863 hr
= IDirect3DDeviceImpl_7_ApplyStateBlock(iface
, BlockHandle
);
5864 set_fpu_control_word(old_fpucw
);
5869 /*****************************************************************************
5870 * IDirect3DDevice7::CaptureStateBlock
5872 * Updates a stateblock's values to the values currently set for the device
5877 * BlockHandle: Stateblock to update
5881 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is NULL
5882 * See IWineD3DDevice::CaptureStateBlock for more details
5884 *****************************************************************************/
5886 IDirect3DDeviceImpl_7_CaptureStateBlock(IDirect3DDevice7
*iface
,
5889 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
5890 struct wined3d_stateblock
*wined3d_sb
;
5893 TRACE("iface %p, stateblock %#x.\n", iface
, BlockHandle
);
5895 wined3d_mutex_lock();
5896 wined3d_sb
= ddraw_get_object(&This
->handle_table
, BlockHandle
- 1, DDRAW_HANDLE_STATEBLOCK
);
5899 WARN("Invalid stateblock handle.\n");
5900 wined3d_mutex_unlock();
5901 return D3DERR_INVALIDSTATEBLOCK
;
5904 hr
= wined3d_stateblock_capture(wined3d_sb
);
5905 wined3d_mutex_unlock();
5907 return hr_ddraw_from_wined3d(hr
);
5910 static HRESULT WINAPI
5911 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUSetup(IDirect3DDevice7
*iface
,
5914 return IDirect3DDeviceImpl_7_CaptureStateBlock(iface
, BlockHandle
);
5917 static HRESULT WINAPI
5918 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUPreserve(IDirect3DDevice7
*iface
,
5924 old_fpucw
= d3d_fpu_setup();
5925 hr
= IDirect3DDeviceImpl_7_CaptureStateBlock(iface
, BlockHandle
);
5926 set_fpu_control_word(old_fpucw
);
5931 /*****************************************************************************
5932 * IDirect3DDevice7::DeleteStateBlock
5934 * Deletes a stateblock handle. This means releasing the WineD3DStateBlock
5939 * BlockHandle: Stateblock handle to delete
5943 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is 0
5945 *****************************************************************************/
5947 IDirect3DDeviceImpl_7_DeleteStateBlock(IDirect3DDevice7
*iface
,
5950 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
5951 struct wined3d_stateblock
*wined3d_sb
;
5954 TRACE("iface %p, stateblock %#x.\n", iface
, BlockHandle
);
5956 wined3d_mutex_lock();
5958 wined3d_sb
= ddraw_free_handle(&This
->handle_table
, BlockHandle
- 1, DDRAW_HANDLE_STATEBLOCK
);
5961 WARN("Invalid stateblock handle.\n");
5962 wined3d_mutex_unlock();
5963 return D3DERR_INVALIDSTATEBLOCK
;
5966 if ((ref
= wined3d_stateblock_decref(wined3d_sb
)))
5968 ERR("Something is still holding stateblock %p (refcount %u).\n", wined3d_sb
, ref
);
5971 wined3d_mutex_unlock();
5976 static HRESULT WINAPI
5977 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUSetup(IDirect3DDevice7
*iface
,
5980 return IDirect3DDeviceImpl_7_DeleteStateBlock(iface
, BlockHandle
);
5983 static HRESULT WINAPI
5984 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUPreserve(IDirect3DDevice7
*iface
,
5990 old_fpucw
= d3d_fpu_setup();
5991 hr
= IDirect3DDeviceImpl_7_DeleteStateBlock(iface
, BlockHandle
);
5992 set_fpu_control_word(old_fpucw
);
5997 /*****************************************************************************
5998 * IDirect3DDevice7::CreateStateBlock
6000 * Creates a new state block handle.
6005 * Type: The state block type
6006 * BlockHandle: Address to write the created handle to
6010 * DDERR_INVALIDPARAMS if BlockHandle is NULL
6012 *****************************************************************************/
6014 IDirect3DDeviceImpl_7_CreateStateBlock(IDirect3DDevice7
*iface
,
6015 D3DSTATEBLOCKTYPE Type
,
6018 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
6019 struct wined3d_stateblock
*wined3d_sb
;
6023 TRACE("iface %p, type %#x, stateblock %p.\n", iface
, Type
, BlockHandle
);
6027 WARN("BlockHandle == NULL, returning DDERR_INVALIDPARAMS\n");
6028 return DDERR_INVALIDPARAMS
;
6030 if(Type
!= D3DSBT_ALL
&& Type
!= D3DSBT_PIXELSTATE
&&
6031 Type
!= D3DSBT_VERTEXSTATE
) {
6032 WARN("Unexpected stateblock type, returning DDERR_INVALIDPARAMS\n");
6033 return DDERR_INVALIDPARAMS
;
6036 wined3d_mutex_lock();
6038 /* The D3DSTATEBLOCKTYPE enum is fine here. */
6039 hr
= wined3d_stateblock_create(This
->wined3d_device
, Type
, &wined3d_sb
);
6042 WARN("Failed to create stateblock, hr %#x.\n", hr
);
6043 wined3d_mutex_unlock();
6044 return hr_ddraw_from_wined3d(hr
);
6047 h
= ddraw_allocate_handle(&This
->handle_table
, wined3d_sb
, DDRAW_HANDLE_STATEBLOCK
);
6048 if (h
== DDRAW_INVALID_HANDLE
)
6050 ERR("Failed to allocate stateblock handle.\n");
6051 wined3d_stateblock_decref(wined3d_sb
);
6052 wined3d_mutex_unlock();
6053 return DDERR_OUTOFMEMORY
;
6056 *BlockHandle
= h
+ 1;
6057 wined3d_mutex_unlock();
6059 return hr_ddraw_from_wined3d(hr
);
6062 static HRESULT WINAPI
6063 IDirect3DDeviceImpl_7_CreateStateBlock_FPUSetup(IDirect3DDevice7
*iface
,
6064 D3DSTATEBLOCKTYPE Type
,
6067 return IDirect3DDeviceImpl_7_CreateStateBlock(iface
, Type
, BlockHandle
);
6070 static HRESULT WINAPI
6071 IDirect3DDeviceImpl_7_CreateStateBlock_FPUPreserve(IDirect3DDevice7
*iface
,
6072 D3DSTATEBLOCKTYPE Type
,
6078 old_fpucw
= d3d_fpu_setup();
6079 hr
=IDirect3DDeviceImpl_7_CreateStateBlock(iface
, Type
, BlockHandle
);
6080 set_fpu_control_word(old_fpucw
);
6085 /* Helper function for IDirect3DDeviceImpl_7_Load. */
6086 static BOOL
is_mip_level_subset(struct ddraw_surface
*dest
, struct ddraw_surface
*src
)
6088 struct ddraw_surface
*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
, struct ddraw_surface
*dest
,
6135 struct ddraw_surface
*src
, const POINT
*DestPoint
, const RECT
*SrcRect
)
6137 struct ddraw_surface
*src_level
, *dest_level
;
6138 IDirectDrawSurface7
*temp
;
6139 DDSURFACEDESC2 ddsd
;
6143 IDirectDrawPalette
*pal
= NULL
, *pal_src
= NULL
;
6147 /* Copy palette, if possible. */
6148 IDirectDrawSurface7_GetPalette(&src
->IDirectDrawSurface7_iface
, &pal_src
);
6149 IDirectDrawSurface7_GetPalette(&dest
->IDirectDrawSurface7_iface
, &pal
);
6151 if (pal_src
!= NULL
&& pal
!= NULL
)
6153 PALETTEENTRY palent
[256];
6155 IDirectDrawPalette_GetEntries(pal_src
, 0, 0, 256, palent
);
6156 IDirectDrawPalette_SetEntries(pal
, 0, 0, 256, palent
);
6159 if (pal
) IDirectDrawPalette_Release(pal
);
6160 if (pal_src
) IDirectDrawPalette_Release(pal_src
);
6162 /* Copy colorkeys, if present. */
6163 for (ckeyflag
= DDCKEY_DESTBLT
; ckeyflag
<= DDCKEY_SRCOVERLAY
; ckeyflag
<<= 1)
6165 hr
= IDirectDrawSurface7_GetColorKey(&src
->IDirectDrawSurface7_iface
, ckeyflag
, &ddckey
);
6169 IDirectDrawSurface7_SetColorKey(&dest
->IDirectDrawSurface7_iface
, ckeyflag
, &ddckey
);
6177 src_rect
= *SrcRect
;
6179 for (;src_level
&& dest_level
;)
6181 if (src_level
->surface_desc
.dwWidth
== dest_level
->surface_desc
.dwWidth
&&
6182 src_level
->surface_desc
.dwHeight
== dest_level
->surface_desc
.dwHeight
)
6184 UINT src_w
= src_rect
.right
- src_rect
.left
;
6185 UINT src_h
= src_rect
.bottom
- src_rect
.top
;
6186 RECT dst_rect
= {point
.x
, point
.y
, point
.x
+ src_w
, point
.y
+ src_h
};
6188 if (FAILED(hr
= wined3d_surface_blt(dest_level
->wined3d_surface
, &dst_rect
,
6189 src_level
->wined3d_surface
, &src_rect
, 0, NULL
, WINED3D_TEXF_POINT
)))
6190 ERR("Blit failed, hr %#x.\n", hr
);
6192 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
6193 ddsd
.ddsCaps
.dwCaps2
= DDSCAPS2_MIPMAPSUBLEVEL
;
6194 IDirectDrawSurface7_GetAttachedSurface(&dest_level
->IDirectDrawSurface7_iface
, &ddsd
.ddsCaps
, &temp
);
6196 if (dest_level
!= dest
) IDirectDrawSurface7_Release(&dest_level
->IDirectDrawSurface7_iface
);
6198 dest_level
= unsafe_impl_from_IDirectDrawSurface7(temp
);
6201 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
6202 ddsd
.ddsCaps
.dwCaps2
= DDSCAPS2_MIPMAPSUBLEVEL
;
6203 IDirectDrawSurface7_GetAttachedSurface(&src_level
->IDirectDrawSurface7_iface
, &ddsd
.ddsCaps
, &temp
);
6205 if (src_level
!= src
) IDirectDrawSurface7_Release(&src_level
->IDirectDrawSurface7_iface
);
6207 src_level
= unsafe_impl_from_IDirectDrawSurface7(temp
);
6214 src_rect
.right
= (src_rect
.right
+ 1) / 2;
6215 src_rect
.bottom
= (src_rect
.bottom
+ 1) / 2;
6218 if (src_level
&& src_level
!= src
) IDirectDrawSurface7_Release(&src_level
->IDirectDrawSurface7_iface
);
6219 if (dest_level
&& dest_level
!= dest
) IDirectDrawSurface7_Release(&dest_level
->IDirectDrawSurface7_iface
);
6222 /*****************************************************************************
6223 * IDirect3DDevice7::Load
6225 * Loads a rectangular area from the source into the destination texture.
6226 * It can also copy the source to the faces of a cubic environment map
6231 * DestTex: Destination texture
6232 * DestPoint: Point in the destination where the source image should be
6234 * SrcTex: Source texture
6235 * SrcRect: Source rectangle
6236 * Flags: Cubemap faces to load (DDSCAPS2_CUBEMAP_ALLFACES, DDSCAPS2_CUBEMAP_POSITIVEX,
6237 * DDSCAPS2_CUBEMAP_NEGATIVEX, DDSCAPS2_CUBEMAP_POSITIVEY, DDSCAPS2_CUBEMAP_NEGATIVEY,
6238 * DDSCAPS2_CUBEMAP_POSITIVEZ, DDSCAPS2_CUBEMAP_NEGATIVEZ)
6242 * DDERR_INVALIDPARAMS if DestTex or SrcTex are NULL, broken coordinates or anything unexpected.
6245 *****************************************************************************/
6248 IDirect3DDeviceImpl_7_Load(IDirect3DDevice7
*iface
,
6249 IDirectDrawSurface7
*DestTex
,
6251 IDirectDrawSurface7
*SrcTex
,
6255 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
6256 struct ddraw_surface
*dest
= unsafe_impl_from_IDirectDrawSurface7(DestTex
);
6257 struct ddraw_surface
*src
= unsafe_impl_from_IDirectDrawSurface7(SrcTex
);
6261 TRACE("iface %p, dst_texture %p, dst_pos %s, src_texture %p, src_rect %s, flags %#x.\n",
6262 iface
, DestTex
, wine_dbgstr_point(DestPoint
), SrcTex
, wine_dbgstr_rect(SrcRect
), Flags
);
6264 if( (!src
) || (!dest
) )
6265 return DDERR_INVALIDPARAMS
;
6267 wined3d_mutex_lock();
6269 if (SrcRect
) srcrect
= *SrcRect
;
6272 srcrect
.left
= srcrect
.top
= 0;
6273 srcrect
.right
= src
->surface_desc
.dwWidth
;
6274 srcrect
.bottom
= src
->surface_desc
.dwHeight
;
6277 if (DestPoint
) destpoint
= *DestPoint
;
6280 destpoint
.x
= destpoint
.y
= 0;
6282 /* Check bad dimensions. DestPoint is validated against src, not dest, because
6283 * destination can be a subset of mip levels, in which case actual coordinates used
6284 * for it may be divided. If any dimension of dest is larger than source, it can't be
6285 * mip level subset, so an error can be returned early.
6287 if (srcrect
.left
>= srcrect
.right
|| srcrect
.top
>= srcrect
.bottom
||
6288 srcrect
.right
> src
->surface_desc
.dwWidth
||
6289 srcrect
.bottom
> src
->surface_desc
.dwHeight
||
6290 destpoint
.x
+ srcrect
.right
- srcrect
.left
> src
->surface_desc
.dwWidth
||
6291 destpoint
.y
+ srcrect
.bottom
- srcrect
.top
> src
->surface_desc
.dwHeight
||
6292 dest
->surface_desc
.dwWidth
> src
->surface_desc
.dwWidth
||
6293 dest
->surface_desc
.dwHeight
> src
->surface_desc
.dwHeight
)
6295 wined3d_mutex_unlock();
6296 return DDERR_INVALIDPARAMS
;
6299 /* Must be top level surfaces. */
6300 if (src
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_MIPMAPSUBLEVEL
||
6301 dest
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_MIPMAPSUBLEVEL
)
6303 wined3d_mutex_unlock();
6304 return DDERR_INVALIDPARAMS
;
6307 if (src
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_CUBEMAP
)
6309 struct ddraw_surface
*src_face
, *dest_face
;
6310 DWORD src_face_flag
, dest_face_flag
;
6311 IDirectDrawSurface7
*temp
;
6312 DDSURFACEDESC2 ddsd
;
6315 if (!(dest
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_CUBEMAP
))
6317 wined3d_mutex_unlock();
6318 return DDERR_INVALIDPARAMS
;
6321 /* Iterate through cube faces 2 times. First time is just to check INVALIDPARAMS conditions, second
6322 * time it's actual surface loading. */
6323 for (i
= 0; i
< 2; i
++)
6328 for (;dest_face
&& src_face
;)
6330 src_face_flag
= src_face
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_CUBEMAP_ALLFACES
;
6331 dest_face_flag
= dest_face
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_CUBEMAP_ALLFACES
;
6333 if (src_face_flag
== dest_face_flag
)
6337 /* Destination mip levels must be subset of source mip levels. */
6338 if (!is_mip_level_subset(dest_face
, src_face
))
6340 wined3d_mutex_unlock();
6341 return DDERR_INVALIDPARAMS
;
6344 else if (Flags
& dest_face_flag
)
6346 copy_mipmap_chain(This
, dest_face
, src_face
, &destpoint
, &srcrect
);
6349 if (src_face_flag
< DDSCAPS2_CUBEMAP_NEGATIVEZ
)
6351 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
6352 ddsd
.ddsCaps
.dwCaps2
= DDSCAPS2_CUBEMAP
| (src_face_flag
<< 1);
6353 IDirectDrawSurface7_GetAttachedSurface(&src
->IDirectDrawSurface7_iface
, &ddsd
.ddsCaps
, &temp
);
6355 if (src_face
!= src
) IDirectDrawSurface7_Release(&src_face
->IDirectDrawSurface7_iface
);
6357 src_face
= unsafe_impl_from_IDirectDrawSurface7(temp
);
6361 if (src_face
!= src
) IDirectDrawSurface7_Release(&src_face
->IDirectDrawSurface7_iface
);
6367 if (dest_face_flag
< DDSCAPS2_CUBEMAP_NEGATIVEZ
)
6369 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
6370 ddsd
.ddsCaps
.dwCaps2
= DDSCAPS2_CUBEMAP
| (dest_face_flag
<< 1);
6371 IDirectDrawSurface7_GetAttachedSurface(&dest
->IDirectDrawSurface7_iface
, &ddsd
.ddsCaps
, &temp
);
6373 if (dest_face
!= dest
) IDirectDrawSurface7_Release(&dest_face
->IDirectDrawSurface7_iface
);
6375 dest_face
= unsafe_impl_from_IDirectDrawSurface7(temp
);
6379 if (dest_face
!= dest
) IDirectDrawSurface7_Release(&dest_face
->IDirectDrawSurface7_iface
);
6387 /* Native returns error if src faces are not subset of dest faces. */
6390 wined3d_mutex_unlock();
6391 return DDERR_INVALIDPARAMS
;
6396 wined3d_mutex_unlock();
6399 else if (dest
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_CUBEMAP
)
6401 wined3d_mutex_unlock();
6402 return DDERR_INVALIDPARAMS
;
6405 /* Handle non cube map textures. */
6407 /* Destination mip levels must be subset of source mip levels. */
6408 if (!is_mip_level_subset(dest
, src
))
6410 wined3d_mutex_unlock();
6411 return DDERR_INVALIDPARAMS
;
6414 copy_mipmap_chain(This
, dest
, src
, &destpoint
, &srcrect
);
6416 wined3d_mutex_unlock();
6421 static HRESULT WINAPI
6422 IDirect3DDeviceImpl_7_Load_FPUSetup(IDirect3DDevice7
*iface
,
6423 IDirectDrawSurface7
*DestTex
,
6425 IDirectDrawSurface7
*SrcTex
,
6429 return IDirect3DDeviceImpl_7_Load(iface
, DestTex
, DestPoint
, SrcTex
, SrcRect
, Flags
);
6432 static HRESULT WINAPI
6433 IDirect3DDeviceImpl_7_Load_FPUPreserve(IDirect3DDevice7
*iface
,
6434 IDirectDrawSurface7
*DestTex
,
6436 IDirectDrawSurface7
*SrcTex
,
6443 old_fpucw
= d3d_fpu_setup();
6444 hr
= IDirect3DDeviceImpl_7_Load(iface
, DestTex
, DestPoint
, SrcTex
, SrcRect
, Flags
);
6445 set_fpu_control_word(old_fpucw
);
6450 /*****************************************************************************
6451 * IDirect3DDevice7::LightEnable
6453 * Enables or disables a light
6455 * Version 7, IDirect3DLight uses this method too.
6458 * LightIndex: The index of the light to enable / disable
6459 * Enable: Enable or disable the light
6463 * For more details, see IWineD3DDevice::SetLightEnable
6465 *****************************************************************************/
6467 IDirect3DDeviceImpl_7_LightEnable(IDirect3DDevice7
*iface
,
6471 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
6474 TRACE("iface %p, light_idx %u, enabled %#x.\n", iface
, LightIndex
, Enable
);
6476 wined3d_mutex_lock();
6477 hr
= wined3d_device_set_light_enable(This
->wined3d_device
, LightIndex
, Enable
);
6478 wined3d_mutex_unlock();
6480 return hr_ddraw_from_wined3d(hr
);
6483 static HRESULT WINAPI
6484 IDirect3DDeviceImpl_7_LightEnable_FPUSetup(IDirect3DDevice7
*iface
,
6488 return IDirect3DDeviceImpl_7_LightEnable(iface
, LightIndex
, Enable
);
6491 static HRESULT WINAPI
6492 IDirect3DDeviceImpl_7_LightEnable_FPUPreserve(IDirect3DDevice7
*iface
,
6499 old_fpucw
= d3d_fpu_setup();
6500 hr
= IDirect3DDeviceImpl_7_LightEnable(iface
, LightIndex
, Enable
);
6501 set_fpu_control_word(old_fpucw
);
6506 /*****************************************************************************
6507 * IDirect3DDevice7::GetLightEnable
6509 * Retrieves if the light with the given index is enabled or not
6514 * LightIndex: Index of desired light
6515 * Enable: Pointer to a BOOL which contains the result
6519 * DDERR_INVALIDPARAMS if Enable is NULL
6520 * See IWineD3DDevice::GetLightEnable for more details
6522 *****************************************************************************/
6524 IDirect3DDeviceImpl_7_GetLightEnable(IDirect3DDevice7
*iface
,
6528 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
6531 TRACE("iface %p, light_idx %u, enabled %p.\n", iface
, LightIndex
, Enable
);
6534 return DDERR_INVALIDPARAMS
;
6536 wined3d_mutex_lock();
6537 hr
= wined3d_device_get_light_enable(This
->wined3d_device
, LightIndex
, Enable
);
6538 wined3d_mutex_unlock();
6540 return hr_ddraw_from_wined3d(hr
);
6543 static HRESULT WINAPI
6544 IDirect3DDeviceImpl_7_GetLightEnable_FPUSetup(IDirect3DDevice7
*iface
,
6548 return IDirect3DDeviceImpl_7_GetLightEnable(iface
, LightIndex
, Enable
);
6551 static HRESULT WINAPI
6552 IDirect3DDeviceImpl_7_GetLightEnable_FPUPreserve(IDirect3DDevice7
*iface
,
6559 old_fpucw
= d3d_fpu_setup();
6560 hr
= IDirect3DDeviceImpl_7_GetLightEnable(iface
, LightIndex
, Enable
);
6561 set_fpu_control_word(old_fpucw
);
6566 /*****************************************************************************
6567 * IDirect3DDevice7::SetClipPlane
6569 * Sets custom clipping plane
6574 * Index: The index of the clipping plane
6575 * PlaneEquation: An equation defining the clipping plane
6579 * DDERR_INVALIDPARAMS if PlaneEquation is NULL
6580 * See IWineD3DDevice::SetClipPlane for more details
6582 *****************************************************************************/
6584 IDirect3DDeviceImpl_7_SetClipPlane(IDirect3DDevice7
*iface
,
6586 D3DVALUE
* PlaneEquation
)
6588 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
6591 TRACE("iface %p, idx %u, plane %p.\n", iface
, Index
, PlaneEquation
);
6594 return DDERR_INVALIDPARAMS
;
6596 wined3d_mutex_lock();
6597 hr
= wined3d_device_set_clip_plane(This
->wined3d_device
, Index
, PlaneEquation
);
6598 wined3d_mutex_unlock();
6603 static HRESULT WINAPI
6604 IDirect3DDeviceImpl_7_SetClipPlane_FPUSetup(IDirect3DDevice7
*iface
,
6606 D3DVALUE
* PlaneEquation
)
6608 return IDirect3DDeviceImpl_7_SetClipPlane(iface
, Index
, PlaneEquation
);
6611 static HRESULT WINAPI
6612 IDirect3DDeviceImpl_7_SetClipPlane_FPUPreserve(IDirect3DDevice7
*iface
,
6614 D3DVALUE
* PlaneEquation
)
6619 old_fpucw
= d3d_fpu_setup();
6620 hr
= IDirect3DDeviceImpl_7_SetClipPlane(iface
, Index
, PlaneEquation
);
6621 set_fpu_control_word(old_fpucw
);
6626 /*****************************************************************************
6627 * IDirect3DDevice7::GetClipPlane
6629 * Returns the clipping plane with a specific index
6632 * Index: The index of the desired plane
6633 * PlaneEquation: Address to store the plane equation to
6637 * DDERR_INVALIDPARAMS if PlaneEquation is NULL
6638 * See IWineD3DDevice::GetClipPlane for more details
6640 *****************************************************************************/
6642 IDirect3DDeviceImpl_7_GetClipPlane(IDirect3DDevice7
*iface
,
6644 D3DVALUE
* PlaneEquation
)
6646 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
6649 TRACE("iface %p, idx %u, plane %p.\n", iface
, Index
, PlaneEquation
);
6652 return DDERR_INVALIDPARAMS
;
6654 wined3d_mutex_lock();
6655 hr
= wined3d_device_get_clip_plane(This
->wined3d_device
, Index
, PlaneEquation
);
6656 wined3d_mutex_unlock();
6661 static HRESULT WINAPI
6662 IDirect3DDeviceImpl_7_GetClipPlane_FPUSetup(IDirect3DDevice7
*iface
,
6664 D3DVALUE
* PlaneEquation
)
6666 return IDirect3DDeviceImpl_7_GetClipPlane(iface
, Index
, PlaneEquation
);
6669 static HRESULT WINAPI
6670 IDirect3DDeviceImpl_7_GetClipPlane_FPUPreserve(IDirect3DDevice7
*iface
,
6672 D3DVALUE
* PlaneEquation
)
6677 old_fpucw
= d3d_fpu_setup();
6678 hr
= IDirect3DDeviceImpl_7_GetClipPlane(iface
, Index
, PlaneEquation
);
6679 set_fpu_control_word(old_fpucw
);
6684 /*****************************************************************************
6685 * IDirect3DDevice7::GetInfo
6687 * Retrieves some information about the device. The DirectX sdk says that
6688 * this version returns S_FALSE for all retail builds of DirectX, that's what
6689 * this implementation does.
6692 * DevInfoID: Information type requested
6693 * DevInfoStruct: Pointer to a structure to store the info to
6694 * Size: Size of the structure
6697 * S_FALSE, because it's a non-debug driver
6699 *****************************************************************************/
6700 static HRESULT WINAPI
6701 IDirect3DDeviceImpl_7_GetInfo(IDirect3DDevice7
*iface
,
6703 void *DevInfoStruct
,
6706 TRACE("iface %p, info_id %#x, info %p, info_size %u.\n",
6707 iface
, DevInfoID
, DevInfoStruct
, Size
);
6709 if (TRACE_ON(ddraw
))
6711 TRACE(" info requested : ");
6714 case D3DDEVINFOID_TEXTUREMANAGER
: TRACE("D3DDEVINFOID_TEXTUREMANAGER\n"); break;
6715 case D3DDEVINFOID_D3DTEXTUREMANAGER
: TRACE("D3DDEVINFOID_D3DTEXTUREMANAGER\n"); break;
6716 case D3DDEVINFOID_TEXTURING
: TRACE("D3DDEVINFOID_TEXTURING\n"); break;
6717 default: ERR(" invalid flag !!!\n"); return DDERR_INVALIDPARAMS
;
6721 return S_FALSE
; /* According to MSDN, this is valid for a non-debug driver */
6724 /* For performance optimization, devices created in FPUSETUP and FPUPRESERVE modes
6725 * have separate vtables. Simple functions where this doesn't matter like GetDirect3D
6726 * are not duplicated.
6728 * Device created with DDSCL_FPUSETUP (d3d7 default) - device methods assume that FPU
6729 * has already been setup for optimal d3d operation.
6731 * Device created with DDSCL_FPUPRESERVE - resets and restores FPU mode when necessary in
6732 * d3d calls (FPU may be in a mode non-suitable for d3d when the app calls d3d). Required
6733 * by Sacrifice (game). */
6734 static const struct IDirect3DDevice7Vtbl d3d_device7_fpu_setup_vtbl
=
6736 /*** IUnknown Methods ***/
6737 IDirect3DDeviceImpl_7_QueryInterface
,
6738 IDirect3DDeviceImpl_7_AddRef
,
6739 IDirect3DDeviceImpl_7_Release
,
6740 /*** IDirect3DDevice7 ***/
6741 IDirect3DDeviceImpl_7_GetCaps_FPUSetup
,
6742 IDirect3DDeviceImpl_7_EnumTextureFormats_FPUSetup
,
6743 IDirect3DDeviceImpl_7_BeginScene_FPUSetup
,
6744 IDirect3DDeviceImpl_7_EndScene_FPUSetup
,
6745 IDirect3DDeviceImpl_7_GetDirect3D
,
6746 IDirect3DDeviceImpl_7_SetRenderTarget_FPUSetup
,
6747 IDirect3DDeviceImpl_7_GetRenderTarget
,
6748 IDirect3DDeviceImpl_7_Clear_FPUSetup
,
6749 IDirect3DDeviceImpl_7_SetTransform_FPUSetup
,
6750 IDirect3DDeviceImpl_7_GetTransform_FPUSetup
,
6751 IDirect3DDeviceImpl_7_SetViewport_FPUSetup
,
6752 IDirect3DDeviceImpl_7_MultiplyTransform_FPUSetup
,
6753 IDirect3DDeviceImpl_7_GetViewport_FPUSetup
,
6754 IDirect3DDeviceImpl_7_SetMaterial_FPUSetup
,
6755 IDirect3DDeviceImpl_7_GetMaterial_FPUSetup
,
6756 IDirect3DDeviceImpl_7_SetLight_FPUSetup
,
6757 IDirect3DDeviceImpl_7_GetLight_FPUSetup
,
6758 IDirect3DDeviceImpl_7_SetRenderState_FPUSetup
,
6759 IDirect3DDeviceImpl_7_GetRenderState_FPUSetup
,
6760 IDirect3DDeviceImpl_7_BeginStateBlock_FPUSetup
,
6761 IDirect3DDeviceImpl_7_EndStateBlock_FPUSetup
,
6762 IDirect3DDeviceImpl_7_PreLoad_FPUSetup
,
6763 IDirect3DDeviceImpl_7_DrawPrimitive_FPUSetup
,
6764 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUSetup
,
6765 IDirect3DDeviceImpl_7_SetClipStatus
,
6766 IDirect3DDeviceImpl_7_GetClipStatus
,
6767 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUSetup
,
6768 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUSetup
,
6769 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUSetup
,
6770 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUSetup
,
6771 IDirect3DDeviceImpl_7_ComputeSphereVisibility
,
6772 IDirect3DDeviceImpl_7_GetTexture_FPUSetup
,
6773 IDirect3DDeviceImpl_7_SetTexture_FPUSetup
,
6774 IDirect3DDeviceImpl_7_GetTextureStageState_FPUSetup
,
6775 IDirect3DDeviceImpl_7_SetTextureStageState_FPUSetup
,
6776 IDirect3DDeviceImpl_7_ValidateDevice_FPUSetup
,
6777 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUSetup
,
6778 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUSetup
,
6779 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUSetup
,
6780 IDirect3DDeviceImpl_7_CreateStateBlock_FPUSetup
,
6781 IDirect3DDeviceImpl_7_Load_FPUSetup
,
6782 IDirect3DDeviceImpl_7_LightEnable_FPUSetup
,
6783 IDirect3DDeviceImpl_7_GetLightEnable_FPUSetup
,
6784 IDirect3DDeviceImpl_7_SetClipPlane_FPUSetup
,
6785 IDirect3DDeviceImpl_7_GetClipPlane_FPUSetup
,
6786 IDirect3DDeviceImpl_7_GetInfo
6789 static const struct IDirect3DDevice7Vtbl d3d_device7_fpu_preserve_vtbl
=
6791 /*** IUnknown Methods ***/
6792 IDirect3DDeviceImpl_7_QueryInterface
,
6793 IDirect3DDeviceImpl_7_AddRef
,
6794 IDirect3DDeviceImpl_7_Release
,
6795 /*** IDirect3DDevice7 ***/
6796 IDirect3DDeviceImpl_7_GetCaps_FPUPreserve
,
6797 IDirect3DDeviceImpl_7_EnumTextureFormats_FPUPreserve
,
6798 IDirect3DDeviceImpl_7_BeginScene_FPUPreserve
,
6799 IDirect3DDeviceImpl_7_EndScene_FPUPreserve
,
6800 IDirect3DDeviceImpl_7_GetDirect3D
,
6801 IDirect3DDeviceImpl_7_SetRenderTarget_FPUPreserve
,
6802 IDirect3DDeviceImpl_7_GetRenderTarget
,
6803 IDirect3DDeviceImpl_7_Clear_FPUPreserve
,
6804 IDirect3DDeviceImpl_7_SetTransform_FPUPreserve
,
6805 IDirect3DDeviceImpl_7_GetTransform_FPUPreserve
,
6806 IDirect3DDeviceImpl_7_SetViewport_FPUPreserve
,
6807 IDirect3DDeviceImpl_7_MultiplyTransform_FPUPreserve
,
6808 IDirect3DDeviceImpl_7_GetViewport_FPUPreserve
,
6809 IDirect3DDeviceImpl_7_SetMaterial_FPUPreserve
,
6810 IDirect3DDeviceImpl_7_GetMaterial_FPUPreserve
,
6811 IDirect3DDeviceImpl_7_SetLight_FPUPreserve
,
6812 IDirect3DDeviceImpl_7_GetLight_FPUPreserve
,
6813 IDirect3DDeviceImpl_7_SetRenderState_FPUPreserve
,
6814 IDirect3DDeviceImpl_7_GetRenderState_FPUPreserve
,
6815 IDirect3DDeviceImpl_7_BeginStateBlock_FPUPreserve
,
6816 IDirect3DDeviceImpl_7_EndStateBlock_FPUPreserve
,
6817 IDirect3DDeviceImpl_7_PreLoad_FPUPreserve
,
6818 IDirect3DDeviceImpl_7_DrawPrimitive_FPUPreserve
,
6819 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUPreserve
,
6820 IDirect3DDeviceImpl_7_SetClipStatus
,
6821 IDirect3DDeviceImpl_7_GetClipStatus
,
6822 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUPreserve
,
6823 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUPreserve
,
6824 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUPreserve
,
6825 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUPreserve
,
6826 IDirect3DDeviceImpl_7_ComputeSphereVisibility
,
6827 IDirect3DDeviceImpl_7_GetTexture_FPUPreserve
,
6828 IDirect3DDeviceImpl_7_SetTexture_FPUPreserve
,
6829 IDirect3DDeviceImpl_7_GetTextureStageState_FPUPreserve
,
6830 IDirect3DDeviceImpl_7_SetTextureStageState_FPUPreserve
,
6831 IDirect3DDeviceImpl_7_ValidateDevice_FPUPreserve
,
6832 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUPreserve
,
6833 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUPreserve
,
6834 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUPreserve
,
6835 IDirect3DDeviceImpl_7_CreateStateBlock_FPUPreserve
,
6836 IDirect3DDeviceImpl_7_Load_FPUPreserve
,
6837 IDirect3DDeviceImpl_7_LightEnable_FPUPreserve
,
6838 IDirect3DDeviceImpl_7_GetLightEnable_FPUPreserve
,
6839 IDirect3DDeviceImpl_7_SetClipPlane_FPUPreserve
,
6840 IDirect3DDeviceImpl_7_GetClipPlane_FPUPreserve
,
6841 IDirect3DDeviceImpl_7_GetInfo
6844 static const struct IDirect3DDevice3Vtbl d3d_device3_vtbl
=
6846 /*** IUnknown Methods ***/
6847 IDirect3DDeviceImpl_3_QueryInterface
,
6848 IDirect3DDeviceImpl_3_AddRef
,
6849 IDirect3DDeviceImpl_3_Release
,
6850 /*** IDirect3DDevice3 ***/
6851 IDirect3DDeviceImpl_3_GetCaps
,
6852 IDirect3DDeviceImpl_3_GetStats
,
6853 IDirect3DDeviceImpl_3_AddViewport
,
6854 IDirect3DDeviceImpl_3_DeleteViewport
,
6855 IDirect3DDeviceImpl_3_NextViewport
,
6856 IDirect3DDeviceImpl_3_EnumTextureFormats
,
6857 IDirect3DDeviceImpl_3_BeginScene
,
6858 IDirect3DDeviceImpl_3_EndScene
,
6859 IDirect3DDeviceImpl_3_GetDirect3D
,
6860 IDirect3DDeviceImpl_3_SetCurrentViewport
,
6861 IDirect3DDeviceImpl_3_GetCurrentViewport
,
6862 IDirect3DDeviceImpl_3_SetRenderTarget
,
6863 IDirect3DDeviceImpl_3_GetRenderTarget
,
6864 IDirect3DDeviceImpl_3_Begin
,
6865 IDirect3DDeviceImpl_3_BeginIndexed
,
6866 IDirect3DDeviceImpl_3_Vertex
,
6867 IDirect3DDeviceImpl_3_Index
,
6868 IDirect3DDeviceImpl_3_End
,
6869 IDirect3DDeviceImpl_3_GetRenderState
,
6870 IDirect3DDeviceImpl_3_SetRenderState
,
6871 IDirect3DDeviceImpl_3_GetLightState
,
6872 IDirect3DDeviceImpl_3_SetLightState
,
6873 IDirect3DDeviceImpl_3_SetTransform
,
6874 IDirect3DDeviceImpl_3_GetTransform
,
6875 IDirect3DDeviceImpl_3_MultiplyTransform
,
6876 IDirect3DDeviceImpl_3_DrawPrimitive
,
6877 IDirect3DDeviceImpl_3_DrawIndexedPrimitive
,
6878 IDirect3DDeviceImpl_3_SetClipStatus
,
6879 IDirect3DDeviceImpl_3_GetClipStatus
,
6880 IDirect3DDeviceImpl_3_DrawPrimitiveStrided
,
6881 IDirect3DDeviceImpl_3_DrawIndexedPrimitiveStrided
,
6882 IDirect3DDeviceImpl_3_DrawPrimitiveVB
,
6883 IDirect3DDeviceImpl_3_DrawIndexedPrimitiveVB
,
6884 IDirect3DDeviceImpl_3_ComputeSphereVisibility
,
6885 IDirect3DDeviceImpl_3_GetTexture
,
6886 IDirect3DDeviceImpl_3_SetTexture
,
6887 IDirect3DDeviceImpl_3_GetTextureStageState
,
6888 IDirect3DDeviceImpl_3_SetTextureStageState
,
6889 IDirect3DDeviceImpl_3_ValidateDevice
6892 static const struct IDirect3DDevice2Vtbl d3d_device2_vtbl
=
6894 /*** IUnknown Methods ***/
6895 IDirect3DDeviceImpl_2_QueryInterface
,
6896 IDirect3DDeviceImpl_2_AddRef
,
6897 IDirect3DDeviceImpl_2_Release
,
6898 /*** IDirect3DDevice2 ***/
6899 IDirect3DDeviceImpl_2_GetCaps
,
6900 IDirect3DDeviceImpl_2_SwapTextureHandles
,
6901 IDirect3DDeviceImpl_2_GetStats
,
6902 IDirect3DDeviceImpl_2_AddViewport
,
6903 IDirect3DDeviceImpl_2_DeleteViewport
,
6904 IDirect3DDeviceImpl_2_NextViewport
,
6905 IDirect3DDeviceImpl_2_EnumTextureFormats
,
6906 IDirect3DDeviceImpl_2_BeginScene
,
6907 IDirect3DDeviceImpl_2_EndScene
,
6908 IDirect3DDeviceImpl_2_GetDirect3D
,
6909 IDirect3DDeviceImpl_2_SetCurrentViewport
,
6910 IDirect3DDeviceImpl_2_GetCurrentViewport
,
6911 IDirect3DDeviceImpl_2_SetRenderTarget
,
6912 IDirect3DDeviceImpl_2_GetRenderTarget
,
6913 IDirect3DDeviceImpl_2_Begin
,
6914 IDirect3DDeviceImpl_2_BeginIndexed
,
6915 IDirect3DDeviceImpl_2_Vertex
,
6916 IDirect3DDeviceImpl_2_Index
,
6917 IDirect3DDeviceImpl_2_End
,
6918 IDirect3DDeviceImpl_2_GetRenderState
,
6919 IDirect3DDeviceImpl_2_SetRenderState
,
6920 IDirect3DDeviceImpl_2_GetLightState
,
6921 IDirect3DDeviceImpl_2_SetLightState
,
6922 IDirect3DDeviceImpl_2_SetTransform
,
6923 IDirect3DDeviceImpl_2_GetTransform
,
6924 IDirect3DDeviceImpl_2_MultiplyTransform
,
6925 IDirect3DDeviceImpl_2_DrawPrimitive
,
6926 IDirect3DDeviceImpl_2_DrawIndexedPrimitive
,
6927 IDirect3DDeviceImpl_2_SetClipStatus
,
6928 IDirect3DDeviceImpl_2_GetClipStatus
6931 static const struct IDirect3DDeviceVtbl d3d_device1_vtbl
=
6933 /*** IUnknown Methods ***/
6934 IDirect3DDeviceImpl_1_QueryInterface
,
6935 IDirect3DDeviceImpl_1_AddRef
,
6936 IDirect3DDeviceImpl_1_Release
,
6937 /*** IDirect3DDevice1 ***/
6938 IDirect3DDeviceImpl_1_Initialize
,
6939 IDirect3DDeviceImpl_1_GetCaps
,
6940 IDirect3DDeviceImpl_1_SwapTextureHandles
,
6941 IDirect3DDeviceImpl_1_CreateExecuteBuffer
,
6942 IDirect3DDeviceImpl_1_GetStats
,
6943 IDirect3DDeviceImpl_1_Execute
,
6944 IDirect3DDeviceImpl_1_AddViewport
,
6945 IDirect3DDeviceImpl_1_DeleteViewport
,
6946 IDirect3DDeviceImpl_1_NextViewport
,
6947 IDirect3DDeviceImpl_1_Pick
,
6948 IDirect3DDeviceImpl_1_GetPickRecords
,
6949 IDirect3DDeviceImpl_1_EnumTextureFormats
,
6950 IDirect3DDeviceImpl_1_CreateMatrix
,
6951 IDirect3DDeviceImpl_1_SetMatrix
,
6952 IDirect3DDeviceImpl_1_GetMatrix
,
6953 IDirect3DDeviceImpl_1_DeleteMatrix
,
6954 IDirect3DDeviceImpl_1_BeginScene
,
6955 IDirect3DDeviceImpl_1_EndScene
,
6956 IDirect3DDeviceImpl_1_GetDirect3D
6959 IDirect3DDeviceImpl
*unsafe_impl_from_IDirect3DDevice7(IDirect3DDevice7
*iface
)
6961 if (!iface
) return NULL
;
6962 assert((iface
->lpVtbl
== &d3d_device7_fpu_preserve_vtbl
) || (iface
->lpVtbl
== &d3d_device7_fpu_setup_vtbl
));
6963 return CONTAINING_RECORD(iface
, IDirect3DDeviceImpl
, IDirect3DDevice7_iface
);
6966 IDirect3DDeviceImpl
*unsafe_impl_from_IDirect3DDevice3(IDirect3DDevice3
*iface
)
6968 if (!iface
) return NULL
;
6969 assert(iface
->lpVtbl
== &d3d_device3_vtbl
);
6970 return CONTAINING_RECORD(iface
, IDirect3DDeviceImpl
, IDirect3DDevice3_iface
);
6973 IDirect3DDeviceImpl
*unsafe_impl_from_IDirect3DDevice2(IDirect3DDevice2
*iface
)
6975 if (!iface
) return NULL
;
6976 assert(iface
->lpVtbl
== &d3d_device2_vtbl
);
6977 return CONTAINING_RECORD(iface
, IDirect3DDeviceImpl
, IDirect3DDevice2_iface
);
6980 IDirect3DDeviceImpl
*unsafe_impl_from_IDirect3DDevice(IDirect3DDevice
*iface
)
6982 if (!iface
) return NULL
;
6983 assert(iface
->lpVtbl
== &d3d_device1_vtbl
);
6984 return CONTAINING_RECORD(iface
, IDirect3DDeviceImpl
, IDirect3DDevice_iface
);
6987 /*****************************************************************************
6988 * IDirect3DDeviceImpl_UpdateDepthStencil
6990 * Checks the current render target for attached depth stencils and sets the
6991 * WineD3D depth stencil accordingly.
6994 * The depth stencil state to set if creating the device
6996 *****************************************************************************/
6997 enum wined3d_depth_buffer_type
IDirect3DDeviceImpl_UpdateDepthStencil(IDirect3DDeviceImpl
*This
)
6999 IDirectDrawSurface7
*depthStencil
= NULL
;
7000 static DDSCAPS2 depthcaps
= { DDSCAPS_ZBUFFER
, 0, 0, 0 };
7001 struct ddraw_surface
*dsi
;
7003 IDirectDrawSurface7_GetAttachedSurface(&This
->target
->IDirectDrawSurface7_iface
, &depthcaps
, &depthStencil
);
7006 TRACE("Setting wined3d depth stencil to NULL\n");
7007 wined3d_device_set_depth_stencil(This
->wined3d_device
, NULL
);
7008 return WINED3D_ZB_FALSE
;
7011 dsi
= impl_from_IDirectDrawSurface7(depthStencil
);
7012 TRACE("Setting wined3d depth stencil to %p (wined3d %p)\n", dsi
, dsi
->wined3d_surface
);
7013 wined3d_device_set_depth_stencil(This
->wined3d_device
, dsi
->wined3d_surface
);
7015 IDirectDrawSurface7_Release(depthStencil
);
7016 return WINED3D_ZB_TRUE
;
7019 static HRESULT
d3d_device_init(IDirect3DDeviceImpl
*device
, struct ddraw
*ddraw
,
7020 struct ddraw_surface
*target
, UINT version
)
7022 static const D3DMATRIX ident
=
7024 1.0f
, 0.0f
, 0.0f
, 0.0f
,
7025 0.0f
, 1.0f
, 0.0f
, 0.0f
,
7026 0.0f
, 0.0f
, 1.0f
, 0.0f
,
7027 0.0f
, 0.0f
, 0.0f
, 1.0f
,
7031 if (ddraw
->cooperative_level
& DDSCL_FPUPRESERVE
)
7032 device
->IDirect3DDevice7_iface
.lpVtbl
= &d3d_device7_fpu_preserve_vtbl
;
7034 device
->IDirect3DDevice7_iface
.lpVtbl
= &d3d_device7_fpu_setup_vtbl
;
7036 device
->IDirect3DDevice3_iface
.lpVtbl
= &d3d_device3_vtbl
;
7037 device
->IDirect3DDevice2_iface
.lpVtbl
= &d3d_device2_vtbl
;
7038 device
->IDirect3DDevice_iface
.lpVtbl
= &d3d_device1_vtbl
;
7040 device
->version
= version
;
7041 device
->ddraw
= ddraw
;
7042 device
->target
= target
;
7043 list_init(&device
->viewport_list
);
7045 if (!ddraw_handle_table_init(&device
->handle_table
, 64))
7047 ERR("Failed to initialize handle table.\n");
7048 return DDERR_OUTOFMEMORY
;
7051 device
->legacyTextureBlending
= FALSE
;
7052 device
->legacy_projection
= ident
;
7053 device
->legacy_clipspace
= ident
;
7055 /* Create an index buffer, it's needed for indexed drawing */
7056 hr
= wined3d_buffer_create_ib(ddraw
->wined3d_device
, 0x40000 /* Length. Don't know how long it should be */,
7057 WINED3DUSAGE_DYNAMIC
/* Usage */, WINED3D_POOL_DEFAULT
, NULL
,
7058 &ddraw_null_wined3d_parent_ops
, &device
->indexbuffer
);
7061 ERR("Failed to create an index buffer, hr %#x.\n", hr
);
7062 ddraw_handle_table_destroy(&device
->handle_table
);
7066 /* This is for convenience. */
7067 device
->wined3d_device
= ddraw
->wined3d_device
;
7068 wined3d_device_incref(ddraw
->wined3d_device
);
7070 /* Render to the back buffer */
7071 hr
= wined3d_device_set_render_target(ddraw
->wined3d_device
, 0, target
->wined3d_surface
, TRUE
);
7074 ERR("Failed to set render target, hr %#x.\n", hr
);
7075 wined3d_buffer_decref(device
->indexbuffer
);
7076 ddraw_handle_table_destroy(&device
->handle_table
);
7080 /* FIXME: This is broken. The target AddRef() makes some sense, because
7081 * we store a pointer during initialization, but then that's also where
7082 * the AddRef() should be. We don't store ddraw->d3d_target anywhere. */
7083 /* AddRef the render target. Also AddRef the render target from ddraw,
7084 * because if it is released before the app releases the D3D device, the
7085 * D3D capabilities of wined3d will be uninitialized, which has bad effects.
7087 * In most cases, those surfaces are the same anyway, but this will simply
7088 * add another ref which is released when the device is destroyed. */
7089 IDirectDrawSurface7_AddRef(&target
->IDirectDrawSurface7_iface
);
7091 ddraw
->d3ddevice
= device
;
7093 wined3d_device_set_render_state(ddraw
->wined3d_device
, WINED3D_RS_ZENABLE
,
7094 IDirect3DDeviceImpl_UpdateDepthStencil(device
));
7099 HRESULT
d3d_device_create(struct ddraw
*ddraw
, struct ddraw_surface
*target
,
7100 UINT version
, IDirect3DDeviceImpl
**device
)
7102 IDirect3DDeviceImpl
*object
;
7105 TRACE("ddraw %p, target %p, version %u, device %p.\n", ddraw
, target
, version
, device
);
7107 if (DefaultSurfaceType
!= WINED3D_SURFACE_TYPE_OPENGL
)
7109 ERR_(winediag
)("The application wants to create a Direct3D device, "
7110 "but the current DirectDrawRenderer does not support this.\n");
7115 if (ddraw
->d3ddevice
)
7117 FIXME("Only one Direct3D device per DirectDraw object supported.\n");
7118 return DDERR_INVALIDPARAMS
;
7121 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*object
));
7124 ERR("Failed to allocate device memory.\n");
7125 return DDERR_OUTOFMEMORY
;
7128 hr
= d3d_device_init(object
, ddraw
, target
, version
);
7131 WARN("Failed to initialize device, hr %#x.\n", hr
);
7132 HeapFree(GetProcessHeap(), 0, object
);
7136 TRACE("Created device %p.\n", object
);