2 * Copyright (c) 1998-2004 Lionel Ulmer
3 * Copyright (c) 2002-2005 Christian Costa
4 * Copyright (c) 2006 Stefan Dösinger
5 * Copyright (c) 2008 Alexander Dorofeyev
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 * IDirect3DDevice implementation, version 1, 2, 3 and 7. Rendering is relayed
22 * to WineD3D, some minimal DirectDraw specific management is handled here.
23 * The Direct3DDevice is NOT the parent of the WineD3DDevice, because d3d
24 * is initialized when DirectDraw creates the primary surface.
25 * Some type management is necessary, because some D3D types changed between
31 #include "wine/port.h"
33 #include "ddraw_private.h"
35 WINE_DEFAULT_DEBUG_CHANNEL(ddraw
);
38 const GUID IID_D3DDEVICE_WineD3D
= {
42 { 0xb7,0x98,0xc6,0x8a,0x77,0x2d,0x72,0x2a }
45 static inline void set_fpu_control_word(WORD fpucw
)
47 #if defined(__i386__) && defined(__GNUC__)
48 __asm__
volatile ("fldcw %0" : : "m" (fpucw
));
49 #elif defined(__i386__) && defined(_MSC_VER)
54 static inline WORD
d3d_fpu_setup(void)
58 #if defined(__i386__) && defined(__GNUC__)
59 __asm__
volatile ("fnstcw %0" : "=m" (oldcw
));
60 #elif defined(__i386__) && defined(_MSC_VER)
63 static BOOL warned
= FALSE
;
66 FIXME("FPUPRESERVE not implemented for this platform / compiler\n");
72 set_fpu_control_word(0x37f);
77 /*****************************************************************************
78 * IUnknown Methods. Common for Version 1, 2, 3 and 7
79 *****************************************************************************/
81 /*****************************************************************************
82 * IDirect3DDevice7::QueryInterface
84 * Used to query other interfaces from a Direct3DDevice interface.
85 * It can return interface pointers to all Direct3DDevice versions as well
86 * as IDirectDraw and IDirect3D. For a link to QueryInterface
87 * rules see ddraw.c, IDirectDraw7::QueryInterface
89 * Exists in Version 1, 2, 3 and 7
92 * refiid: Interface ID queried for
93 * obj: Used to return the interface pointer
96 * D3D_OK or E_NOINTERFACE
98 *****************************************************************************/
100 IDirect3DDeviceImpl_7_QueryInterface(IDirect3DDevice7
*iface
,
104 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
106 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(refiid
), obj
);
108 /* According to COM docs, if the QueryInterface fails, obj should be set to NULL */
112 return DDERR_INVALIDPARAMS
;
114 if ( IsEqualGUID( &IID_IUnknown
, refiid
) )
119 /* Check DirectDraw Interfaces. */
120 else if( IsEqualGUID( &IID_IDirectDraw7
, refiid
) )
122 *obj
= &This
->ddraw
->IDirectDraw7_iface
;
123 TRACE("(%p) Returning IDirectDraw7 interface at %p\n", This
, *obj
);
125 else if ( IsEqualGUID( &IID_IDirectDraw4
, refiid
) )
127 *obj
= &This
->ddraw
->IDirectDraw4_iface
;
128 TRACE("(%p) Returning IDirectDraw4 interface at %p\n", This
, *obj
);
130 else if ( IsEqualGUID( &IID_IDirectDraw2
, refiid
) )
132 *obj
= &This
->ddraw
->IDirectDraw2_iface
;
133 TRACE("(%p) Returning IDirectDraw2 interface at %p\n", This
, *obj
);
135 else if( IsEqualGUID( &IID_IDirectDraw
, refiid
) )
137 *obj
= &This
->ddraw
->IDirectDraw_iface
;
138 TRACE("(%p) Returning IDirectDraw interface at %p\n", This
, *obj
);
142 else if ( IsEqualGUID( &IID_IDirect3D
, refiid
) )
144 *obj
= &This
->ddraw
->IDirect3D_iface
;
145 TRACE("(%p) Returning IDirect3D interface at %p\n", This
, *obj
);
147 else if ( IsEqualGUID( &IID_IDirect3D2
, refiid
) )
149 *obj
= &This
->ddraw
->IDirect3D2_iface
;
150 TRACE("(%p) Returning IDirect3D2 interface at %p\n", This
, *obj
);
152 else if ( IsEqualGUID( &IID_IDirect3D3
, refiid
) )
154 *obj
= &This
->ddraw
->IDirect3D3_iface
;
155 TRACE("(%p) Returning IDirect3D3 interface at %p\n", This
, *obj
);
157 else if ( IsEqualGUID( &IID_IDirect3D7
, refiid
) )
159 *obj
= &This
->ddraw
->IDirect3D7_iface
;
160 TRACE("(%p) Returning IDirect3D7 interface at %p\n", This
, *obj
);
164 else if ( IsEqualGUID( &IID_IDirect3DDevice
, refiid
) )
166 *obj
= &This
->IDirect3DDevice_iface
;
167 TRACE("(%p) Returning IDirect3DDevice interface at %p\n", This
, *obj
);
169 else if ( IsEqualGUID( &IID_IDirect3DDevice2
, refiid
) ) {
170 *obj
= &This
->IDirect3DDevice2_iface
;
171 TRACE("(%p) Returning IDirect3DDevice2 interface at %p\n", This
, *obj
);
173 else if ( IsEqualGUID( &IID_IDirect3DDevice3
, refiid
) ) {
174 *obj
= &This
->IDirect3DDevice3_iface
;
175 TRACE("(%p) Returning IDirect3DDevice3 interface at %p\n", This
, *obj
);
177 else if ( IsEqualGUID( &IID_IDirect3DDevice7
, refiid
) ) {
179 TRACE("(%p) Returning IDirect3DDevice7 interface at %p\n", This
, *obj
);
182 /* Unknown interface */
185 ERR("(%p)->(%s, %p): No interface found\n", This
, debugstr_guid(refiid
), obj
);
186 return E_NOINTERFACE
;
189 /* AddRef the returned interface */
190 IUnknown_AddRef( (IUnknown
*) *obj
);
194 static HRESULT WINAPI
IDirect3DDeviceImpl_3_QueryInterface(IDirect3DDevice3
*iface
, REFIID riid
,
197 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
198 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), obj
);
200 return IDirect3DDevice7_QueryInterface(&This
->IDirect3DDevice7_iface
, riid
, obj
);
203 static HRESULT WINAPI
IDirect3DDeviceImpl_2_QueryInterface(IDirect3DDevice2
*iface
, REFIID riid
,
206 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
207 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), obj
);
209 return IDirect3DDevice7_QueryInterface(&This
->IDirect3DDevice7_iface
, riid
, obj
);
212 static HRESULT WINAPI
IDirect3DDeviceImpl_1_QueryInterface(IDirect3DDevice
*iface
, REFIID riid
,
215 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
216 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), obp
);
218 return IDirect3DDevice7_QueryInterface(&This
->IDirect3DDevice7_iface
, riid
, obp
);
221 /*****************************************************************************
222 * IDirect3DDevice7::AddRef
224 * Increases the refcount....
225 * The most exciting Method, definitely
227 * Exists in Version 1, 2, 3 and 7
232 *****************************************************************************/
234 IDirect3DDeviceImpl_7_AddRef(IDirect3DDevice7
*iface
)
236 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
237 ULONG ref
= InterlockedIncrement(&This
->ref
);
239 TRACE("%p increasing refcount to %u.\n", This
, ref
);
244 static ULONG WINAPI
IDirect3DDeviceImpl_3_AddRef(IDirect3DDevice3
*iface
)
246 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
247 TRACE("iface %p.\n", iface
);
249 return IDirect3DDevice7_AddRef(&This
->IDirect3DDevice7_iface
);
252 static ULONG WINAPI
IDirect3DDeviceImpl_2_AddRef(IDirect3DDevice2
*iface
)
254 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
255 TRACE("iface %p.\n", iface
);
257 return IDirect3DDevice7_AddRef(&This
->IDirect3DDevice7_iface
);
260 static ULONG WINAPI
IDirect3DDeviceImpl_1_AddRef(IDirect3DDevice
*iface
)
262 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
263 TRACE("iface %p.\n", iface
);
265 return IDirect3DDevice7_AddRef(&This
->IDirect3DDevice7_iface
);
268 /*****************************************************************************
269 * IDirect3DDevice7::Release
271 * Decreases the refcount of the interface
272 * When the refcount is reduced to 0, the object is destroyed.
274 * Exists in Version 1, 2, 3 and 7
279 *****************************************************************************/
281 IDirect3DDeviceImpl_7_Release(IDirect3DDevice7
*iface
)
283 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
284 ULONG ref
= InterlockedDecrement(&This
->ref
);
286 TRACE("%p decreasing refcount to %u.\n", This
, ref
);
288 /* This method doesn't destroy the WineD3DDevice, because it's still in use for
289 * 2D rendering. IDirectDrawSurface7::Release will destroy the WineD3DDevice
290 * when the render target is released
296 wined3d_mutex_lock();
298 /* There is no need to unset any resources here, wined3d will take
299 * care of that on Uninit3D(). */
301 /* Free the index buffer. */
302 wined3d_buffer_decref(This
->indexbuffer
);
304 /* Set the device up to render to the front buffer since the back
305 * buffer will vanish soon. */
306 wined3d_device_set_render_target(This
->wined3d_device
, 0,
307 This
->ddraw
->wined3d_frontbuffer
, TRUE
);
309 /* Release the WineD3DDevice. This won't destroy it. */
310 if (!wined3d_device_decref(This
->wined3d_device
))
311 ERR("The wined3d device (%p) was destroyed unexpectedly.\n", This
->wined3d_device
);
313 /* The texture handles should be unset by now, but there might be some bits
314 * missing in our reference counting(needs test). Do a sanity check. */
315 for (i
= 0; i
< This
->handle_table
.entry_count
; ++i
)
317 struct ddraw_handle_entry
*entry
= &This
->handle_table
.entries
[i
];
321 case DDRAW_HANDLE_FREE
:
324 case DDRAW_HANDLE_MATERIAL
:
326 IDirect3DMaterialImpl
*m
= entry
->object
;
327 FIXME("Material handle %#x (%p) not unset properly.\n", i
+ 1, m
);
332 case DDRAW_HANDLE_MATRIX
:
334 /* No FIXME here because this might happen because of sloppy applications. */
335 WARN("Leftover matrix handle %#x (%p), deleting.\n", i
+ 1, entry
->object
);
336 IDirect3DDevice_DeleteMatrix(&This
->IDirect3DDevice_iface
, i
+ 1);
340 case DDRAW_HANDLE_STATEBLOCK
:
342 /* No FIXME here because this might happen because of sloppy applications. */
343 WARN("Leftover stateblock handle %#x (%p), deleting.\n", i
+ 1, entry
->object
);
344 IDirect3DDevice7_DeleteStateBlock(iface
, i
+ 1);
348 case DDRAW_HANDLE_SURFACE
:
350 IDirectDrawSurfaceImpl
*surf
= entry
->object
;
351 FIXME("Texture handle %#x (%p) not unset properly.\n", i
+ 1, surf
);
357 FIXME("Handle %#x (%p) has unknown type %#x.\n", i
+ 1, entry
->object
, entry
->type
);
362 ddraw_handle_table_destroy(&This
->handle_table
);
364 TRACE("Releasing target %p.\n", This
->target
);
365 /* Release the render target and the WineD3D render target
366 * (See IDirect3D7::CreateDevice for more comments on this)
368 IDirectDrawSurface7_Release(&This
->target
->IDirectDrawSurface7_iface
);
369 TRACE("Target release done\n");
371 This
->ddraw
->d3ddevice
= NULL
;
373 /* Now free the structure */
374 HeapFree(GetProcessHeap(), 0, This
);
375 wined3d_mutex_unlock();
382 static ULONG WINAPI
IDirect3DDeviceImpl_3_Release(IDirect3DDevice3
*iface
)
384 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
385 TRACE("iface %p.\n", iface
);
387 return IDirect3DDevice7_Release(&This
->IDirect3DDevice7_iface
);
390 static ULONG WINAPI
IDirect3DDeviceImpl_2_Release(IDirect3DDevice2
*iface
)
392 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
393 TRACE("iface %p.\n", iface
);
395 return IDirect3DDevice7_Release(&This
->IDirect3DDevice7_iface
);
398 static ULONG WINAPI
IDirect3DDeviceImpl_1_Release(IDirect3DDevice
*iface
)
400 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
401 TRACE("iface %p.\n", iface
);
403 return IDirect3DDevice7_Release(&This
->IDirect3DDevice7_iface
);
406 /*****************************************************************************
407 * IDirect3DDevice Methods
408 *****************************************************************************/
410 /*****************************************************************************
411 * IDirect3DDevice::Initialize
413 * Initializes a Direct3DDevice. This implementation is a no-op, as all
414 * initialization is done at create time.
416 * Exists in Version 1
419 * No idea what they mean, as the MSDN page is gone
423 *****************************************************************************/
424 static HRESULT WINAPI
425 IDirect3DDeviceImpl_1_Initialize(IDirect3DDevice
*iface
,
426 IDirect3D
*Direct3D
, GUID
*guid
,
429 /* It shouldn't be crucial, but print a FIXME, I'm interested if
430 * any game calls it and when. */
431 FIXME("iface %p, d3d %p, guid %s, device_desc %p nop!\n",
432 iface
, Direct3D
, debugstr_guid(guid
), Desc
);
437 /*****************************************************************************
438 * IDirect3DDevice7::GetCaps
440 * Retrieves the device's capabilities
442 * This implementation is used for Version 7 only, the older versions have
443 * their own implementation.
446 * Desc: Pointer to a D3DDEVICEDESC7 structure to fill
450 * D3DERR_* if a problem occurs. See WineD3D
452 *****************************************************************************/
454 IDirect3DDeviceImpl_7_GetCaps(IDirect3DDevice7
*iface
,
455 D3DDEVICEDESC7
*Desc
)
457 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
458 D3DDEVICEDESC OldDesc
;
460 TRACE("iface %p, device_desc %p.\n", iface
, Desc
);
464 WARN("Desc is NULL, returning DDERR_INVALIDPARAMS.\n");
465 return DDERR_INVALIDPARAMS
;
468 /* Call the same function used by IDirect3D, this saves code */
469 return IDirect3DImpl_GetCaps(This
->ddraw
->wined3d
, &OldDesc
, Desc
);
472 static HRESULT WINAPI
473 IDirect3DDeviceImpl_7_GetCaps_FPUSetup(IDirect3DDevice7
*iface
,
474 D3DDEVICEDESC7
*Desc
)
476 return IDirect3DDeviceImpl_7_GetCaps(iface
, Desc
);
479 static HRESULT WINAPI
480 IDirect3DDeviceImpl_7_GetCaps_FPUPreserve(IDirect3DDevice7
*iface
,
481 D3DDEVICEDESC7
*Desc
)
486 old_fpucw
= d3d_fpu_setup();
487 hr
= IDirect3DDeviceImpl_7_GetCaps(iface
, Desc
);
488 set_fpu_control_word(old_fpucw
);
492 /*****************************************************************************
493 * IDirect3DDevice3::GetCaps
495 * Retrieves the capabilities of the hardware device and the emulation
496 * device. For Wine, hardware and emulation are the same (it's all HW).
498 * This implementation is used for Version 1, 2, and 3. Version 7 has its own
501 * HWDesc: Structure to fill with the HW caps
502 * HelDesc: Structure to fill with the hardware emulation caps
506 * D3DERR_* if a problem occurs. See WineD3D
508 *****************************************************************************/
510 /* There are 3 versions of D3DDEVICEDESC. All 3 share the same name because
511 * Microsoft just expanded the existing structure without naming them
512 * D3DDEVICEDESC2 and D3DDEVICEDESC3. Which version is used have depends
513 * on the version of the DirectX SDK. DirectX 6+ and Wine use the latest
514 * one with 252 bytes.
516 * All 3 versions are allowed as parameters and only the specified amount of
519 * Note that Direct3D7 and earlier are not available in native Win64
520 * ddraw.dll builds, so possible size differences between 32 bit and
521 * 64 bit are a non-issue.
523 static inline BOOL
check_d3ddevicedesc_size(DWORD size
)
525 if (size
== FIELD_OFFSET(D3DDEVICEDESC
, dwMinTextureWidth
) /* 172 */
526 || size
== FIELD_OFFSET(D3DDEVICEDESC
, dwMaxTextureRepeat
) /* 204 */
527 || size
== sizeof(D3DDEVICEDESC
) /* 252 */) return TRUE
;
531 static HRESULT WINAPI
532 IDirect3DDeviceImpl_3_GetCaps(IDirect3DDevice3
*iface
,
533 D3DDEVICEDESC
*HWDesc
,
534 D3DDEVICEDESC
*HelDesc
)
536 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
537 D3DDEVICEDESC oldDesc
;
538 D3DDEVICEDESC7 newDesc
;
541 TRACE("iface %p, hw_desc %p, hel_desc %p.\n", iface
, HWDesc
, HelDesc
);
545 WARN("HWDesc is NULL, returning DDERR_INVALIDPARAMS.\n");
546 return DDERR_INVALIDPARAMS
;
548 if (!check_d3ddevicedesc_size(HWDesc
->dwSize
))
550 WARN("HWDesc->dwSize is %u, returning DDERR_INVALIDPARAMS.\n", HWDesc
->dwSize
);
551 return DDERR_INVALIDPARAMS
;
555 WARN("HelDesc is NULL, returning DDERR_INVALIDPARAMS.\n");
556 return DDERR_INVALIDPARAMS
;
558 if (!check_d3ddevicedesc_size(HelDesc
->dwSize
))
560 WARN("HelDesc->dwSize is %u, returning DDERR_INVALIDPARAMS.\n", HelDesc
->dwSize
);
561 return DDERR_INVALIDPARAMS
;
564 hr
= IDirect3DImpl_GetCaps(This
->ddraw
->wined3d
, &oldDesc
, &newDesc
);
565 if(hr
!= D3D_OK
) return hr
;
567 DD_STRUCT_COPY_BYSIZE(HWDesc
, &oldDesc
);
568 DD_STRUCT_COPY_BYSIZE(HelDesc
, &oldDesc
);
572 static HRESULT WINAPI
IDirect3DDeviceImpl_2_GetCaps(IDirect3DDevice2
*iface
,
573 D3DDEVICEDESC
*D3DHWDevDesc
, D3DDEVICEDESC
*D3DHELDevDesc
)
575 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
576 TRACE("iface %p, hw_desc %p, hel_desc %p.\n", iface
, D3DHWDevDesc
, D3DHELDevDesc
);
577 return IDirect3DDevice3_GetCaps(&This
->IDirect3DDevice3_iface
, D3DHWDevDesc
, D3DHELDevDesc
);
580 static HRESULT WINAPI
IDirect3DDeviceImpl_1_GetCaps(IDirect3DDevice
*iface
,
581 D3DDEVICEDESC
*D3DHWDevDesc
, D3DDEVICEDESC
*D3DHELDevDesc
)
583 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(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 /*****************************************************************************
589 * IDirect3DDevice2::SwapTextureHandles
591 * Swaps the texture handles of 2 Texture interfaces. Version 1 and 2
594 * Tex1, Tex2: The 2 Textures to swap
599 *****************************************************************************/
600 static HRESULT WINAPI
601 IDirect3DDeviceImpl_2_SwapTextureHandles(IDirect3DDevice2
*iface
,
602 IDirect3DTexture2
*Tex1
,
603 IDirect3DTexture2
*Tex2
)
605 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
606 IDirectDrawSurfaceImpl
*surf1
= unsafe_impl_from_IDirect3DTexture2(Tex1
);
607 IDirectDrawSurfaceImpl
*surf2
= unsafe_impl_from_IDirect3DTexture2(Tex2
);
610 TRACE("iface %p, tex1 %p, tex2 %p.\n", iface
, Tex1
, Tex2
);
612 wined3d_mutex_lock();
614 h1
= surf1
->Handle
- 1;
615 h2
= surf2
->Handle
- 1;
616 This
->handle_table
.entries
[h1
].object
= surf2
;
617 This
->handle_table
.entries
[h2
].object
= surf1
;
618 surf2
->Handle
= h1
+ 1;
619 surf1
->Handle
= h2
+ 1;
621 wined3d_mutex_unlock();
626 static HRESULT WINAPI
IDirect3DDeviceImpl_1_SwapTextureHandles(IDirect3DDevice
*iface
,
627 IDirect3DTexture
*D3DTex1
, IDirect3DTexture
*D3DTex2
)
629 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
630 IDirectDrawSurfaceImpl
*surf1
= unsafe_impl_from_IDirect3DTexture(D3DTex1
);
631 IDirectDrawSurfaceImpl
*surf2
= unsafe_impl_from_IDirect3DTexture(D3DTex2
);
632 IDirect3DTexture2
*t1
= surf1
? &surf1
->IDirect3DTexture2_iface
: NULL
;
633 IDirect3DTexture2
*t2
= surf2
? &surf2
->IDirect3DTexture2_iface
: NULL
;
635 TRACE("iface %p, tex1 %p, tex2 %p.\n", iface
, D3DTex1
, D3DTex2
);
637 return IDirect3DDevice2_SwapTextureHandles(&This
->IDirect3DDevice2_iface
, t1
, t2
);
640 /*****************************************************************************
641 * IDirect3DDevice3::GetStats
643 * This method seems to retrieve some stats from the device.
644 * The MSDN documentation doesn't exist any more, but the D3DSTATS
645 * structure suggests that the amount of drawn primitives and processed
646 * vertices is returned.
648 * Exists in Version 1, 2 and 3
651 * Stats: Pointer to a D3DSTATS structure to be filled
655 * DDERR_INVALIDPARAMS if Stats == NULL
657 *****************************************************************************/
658 static HRESULT WINAPI
659 IDirect3DDeviceImpl_3_GetStats(IDirect3DDevice3
*iface
,
662 FIXME("iface %p, stats %p stub!\n", iface
, Stats
);
665 return DDERR_INVALIDPARAMS
;
667 /* Fill the Stats with 0 */
668 Stats
->dwTrianglesDrawn
= 0;
669 Stats
->dwLinesDrawn
= 0;
670 Stats
->dwPointsDrawn
= 0;
671 Stats
->dwSpansDrawn
= 0;
672 Stats
->dwVerticesProcessed
= 0;
677 static HRESULT WINAPI
IDirect3DDeviceImpl_2_GetStats(IDirect3DDevice2
*iface
, D3DSTATS
*Stats
)
679 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
681 TRACE("iface %p, stats %p.\n", iface
, Stats
);
683 return IDirect3DDevice3_GetStats(&This
->IDirect3DDevice3_iface
, Stats
);
686 static HRESULT WINAPI
IDirect3DDeviceImpl_1_GetStats(IDirect3DDevice
*iface
, D3DSTATS
*Stats
)
688 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
690 TRACE("iface %p, stats %p.\n", iface
, Stats
);
692 return IDirect3DDevice3_GetStats(&This
->IDirect3DDevice3_iface
, Stats
);
695 /*****************************************************************************
696 * IDirect3DDevice::CreateExecuteBuffer
698 * Creates an IDirect3DExecuteBuffer, used for rendering with a
704 * Desc: Buffer description
705 * ExecuteBuffer: Address to return the Interface pointer at
706 * UnkOuter: Must be NULL. Basically for aggregation, which ddraw doesn't
710 * CLASS_E_NOAGGREGATION if UnkOuter != NULL
711 * DDERR_OUTOFMEMORY if we ran out of memory
714 *****************************************************************************/
715 static HRESULT WINAPI
716 IDirect3DDeviceImpl_1_CreateExecuteBuffer(IDirect3DDevice
*iface
,
717 D3DEXECUTEBUFFERDESC
*Desc
,
718 IDirect3DExecuteBuffer
**ExecuteBuffer
,
721 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
722 IDirect3DExecuteBufferImpl
* object
;
725 TRACE("iface %p, buffer_desc %p, buffer %p, outer_unknown %p.\n",
726 iface
, Desc
, ExecuteBuffer
, UnkOuter
);
729 return CLASS_E_NOAGGREGATION
;
731 /* Allocate the new Execute Buffer */
732 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirect3DExecuteBufferImpl
));
735 ERR("Out of memory when allocating a IDirect3DExecuteBufferImpl structure\n");
736 return DDERR_OUTOFMEMORY
;
739 hr
= d3d_execute_buffer_init(object
, This
, Desc
);
742 WARN("Failed to initialize execute buffer, hr %#x.\n", hr
);
743 HeapFree(GetProcessHeap(), 0, object
);
747 *ExecuteBuffer
= &object
->IDirect3DExecuteBuffer_iface
;
749 TRACE(" Returning IDirect3DExecuteBuffer at %p, implementation is at %p\n", *ExecuteBuffer
, object
);
754 /*****************************************************************************
755 * IDirect3DDevice::Execute
757 * Executes all the stuff in an execute buffer.
760 * ExecuteBuffer: The buffer to execute
761 * Viewport: The viewport used for rendering
765 * DDERR_INVALIDPARAMS if ExecuteBuffer == NULL
768 *****************************************************************************/
769 static HRESULT WINAPI
IDirect3DDeviceImpl_1_Execute(IDirect3DDevice
*iface
,
770 IDirect3DExecuteBuffer
*ExecuteBuffer
, IDirect3DViewport
*Viewport
, DWORD Flags
)
772 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
773 IDirect3DExecuteBufferImpl
*buffer
= unsafe_impl_from_IDirect3DExecuteBuffer(ExecuteBuffer
);
774 IDirect3DViewportImpl
*Direct3DViewportImpl
= unsafe_impl_from_IDirect3DViewport(Viewport
);
777 TRACE("iface %p, buffer %p, viewport %p, flags %#x.\n", iface
, ExecuteBuffer
, Viewport
, Flags
);
780 return DDERR_INVALIDPARAMS
;
783 wined3d_mutex_lock();
784 hr
= d3d_execute_buffer_execute(buffer
, This
, Direct3DViewportImpl
);
785 wined3d_mutex_unlock();
790 /*****************************************************************************
791 * IDirect3DDevice3::AddViewport
793 * Add a Direct3DViewport to the device's viewport list. These viewports
794 * are wrapped to IDirect3DDevice7 viewports in viewport.c
796 * Exists in Version 1, 2 and 3. Note that IDirect3DViewport 1, 2 and 3
797 * are the same interfaces.
800 * Viewport: The viewport to add
803 * DDERR_INVALIDPARAMS if Viewport == NULL
806 *****************************************************************************/
807 static HRESULT WINAPI
808 IDirect3DDeviceImpl_3_AddViewport(IDirect3DDevice3
*iface
,
809 IDirect3DViewport3
*Viewport
)
811 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
812 IDirect3DViewportImpl
*vp
= unsafe_impl_from_IDirect3DViewport3(Viewport
);
814 TRACE("iface %p, viewport %p.\n", iface
, Viewport
);
818 return DDERR_INVALIDPARAMS
;
820 wined3d_mutex_lock();
821 list_add_head(&This
->viewport_list
, &vp
->entry
);
822 vp
->active_device
= This
; /* Viewport must be usable for Clear() after AddViewport,
823 so set active_device here. */
824 wined3d_mutex_unlock();
829 static HRESULT WINAPI
IDirect3DDeviceImpl_2_AddViewport(IDirect3DDevice2
*iface
,
830 IDirect3DViewport2
*Direct3DViewport2
)
832 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
833 IDirect3DViewportImpl
*vp
= unsafe_impl_from_IDirect3DViewport2(Direct3DViewport2
);
835 TRACE("iface %p, viewport %p.\n", iface
, Direct3DViewport2
);
837 return IDirect3DDevice3_AddViewport(&This
->IDirect3DDevice3_iface
, &vp
->IDirect3DViewport3_iface
);
840 static HRESULT WINAPI
IDirect3DDeviceImpl_1_AddViewport(IDirect3DDevice
*iface
,
841 IDirect3DViewport
*Direct3DViewport
)
843 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
844 IDirect3DViewportImpl
*vp
= unsafe_impl_from_IDirect3DViewport(Direct3DViewport
);
846 TRACE("iface %p, viewport %p.\n", iface
, Direct3DViewport
);
848 return IDirect3DDevice3_AddViewport(&This
->IDirect3DDevice3_iface
, &vp
->IDirect3DViewport3_iface
);
851 /*****************************************************************************
852 * IDirect3DDevice3::DeleteViewport
854 * Deletes a Direct3DViewport from the device's viewport list.
856 * Exists in Version 1, 2 and 3. Note that all Viewport interface versions
860 * Viewport: The viewport to delete
864 * DDERR_INVALIDPARAMS if the viewport wasn't found in the list
866 *****************************************************************************/
867 static HRESULT WINAPI
IDirect3DDeviceImpl_3_DeleteViewport(IDirect3DDevice3
*iface
, IDirect3DViewport3
*viewport
)
869 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
870 IDirect3DViewportImpl
*vp
= unsafe_impl_from_IDirect3DViewport3(viewport
);
872 TRACE("iface %p, viewport %p.\n", iface
, viewport
);
874 wined3d_mutex_lock();
876 if (vp
->active_device
!= This
)
878 WARN("Viewport %p active device is %p.\n", vp
, vp
->active_device
);
879 wined3d_mutex_unlock();
880 return DDERR_INVALIDPARAMS
;
883 vp
->active_device
= NULL
;
884 list_remove(&vp
->entry
);
886 wined3d_mutex_unlock();
891 static HRESULT WINAPI
IDirect3DDeviceImpl_2_DeleteViewport(IDirect3DDevice2
*iface
,
892 IDirect3DViewport2
*Direct3DViewport2
)
894 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
895 IDirect3DViewportImpl
*vp
= unsafe_impl_from_IDirect3DViewport2(Direct3DViewport2
);
897 TRACE("iface %p, viewport %p.\n", iface
, Direct3DViewport2
);
899 return IDirect3DDevice3_DeleteViewport(&This
->IDirect3DDevice3_iface
, &vp
->IDirect3DViewport3_iface
);
902 static HRESULT WINAPI
IDirect3DDeviceImpl_1_DeleteViewport(IDirect3DDevice
*iface
,
903 IDirect3DViewport
*Direct3DViewport
)
905 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
906 IDirect3DViewportImpl
*vp
= unsafe_impl_from_IDirect3DViewport(Direct3DViewport
);
908 TRACE("iface %p, viewport %p.\n", iface
, Direct3DViewport
);
910 return IDirect3DDevice3_DeleteViewport(&This
->IDirect3DDevice3_iface
, &vp
->IDirect3DViewport3_iface
);
913 /*****************************************************************************
914 * IDirect3DDevice3::NextViewport
916 * Returns a viewport from the viewport list, depending on the
917 * passed viewport and the flags.
919 * Exists in Version 1, 2 and 3. Note that all Viewport interface versions
923 * Viewport: Viewport to use for beginning the search
924 * Flags: D3DNEXT_NEXT, D3DNEXT_HEAD or D3DNEXT_TAIL
928 * DDERR_INVALIDPARAMS if the flags were wrong, or Viewport was NULL
930 *****************************************************************************/
931 static HRESULT WINAPI
932 IDirect3DDeviceImpl_3_NextViewport(IDirect3DDevice3
*iface
,
933 IDirect3DViewport3
*Viewport3
,
934 IDirect3DViewport3
**lplpDirect3DViewport3
,
937 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
938 IDirect3DViewportImpl
*vp
= unsafe_impl_from_IDirect3DViewport3(Viewport3
);
939 IDirect3DViewportImpl
*next
;
942 TRACE("iface %p, viewport %p, next %p, flags %#x.\n",
943 iface
, Viewport3
, lplpDirect3DViewport3
, Flags
);
947 *lplpDirect3DViewport3
= NULL
;
948 return DDERR_INVALIDPARAMS
;
952 wined3d_mutex_lock();
956 entry
= list_next(&This
->viewport_list
, &vp
->entry
);
960 entry
= list_head(&This
->viewport_list
);
964 entry
= list_tail(&This
->viewport_list
);
968 WARN("Invalid flags %#x.\n", Flags
);
969 *lplpDirect3DViewport3
= NULL
;
970 wined3d_mutex_unlock();
971 return DDERR_INVALIDPARAMS
;
976 next
= LIST_ENTRY(entry
, IDirect3DViewportImpl
, entry
);
977 *lplpDirect3DViewport3
= &next
->IDirect3DViewport3_iface
;
980 *lplpDirect3DViewport3
= NULL
;
982 wined3d_mutex_unlock();
987 static HRESULT WINAPI
IDirect3DDeviceImpl_2_NextViewport(IDirect3DDevice2
*iface
,
988 IDirect3DViewport2
*Viewport2
, IDirect3DViewport2
**lplpDirect3DViewport2
, DWORD Flags
)
990 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
991 IDirect3DViewportImpl
*vp
= unsafe_impl_from_IDirect3DViewport2(Viewport2
);
992 IDirect3DViewport3
*res
;
995 TRACE("iface %p, viewport %p, next %p, flags %#x.\n",
996 iface
, Viewport2
, lplpDirect3DViewport2
, Flags
);
998 hr
= IDirect3DDevice3_NextViewport(&This
->IDirect3DDevice3_iface
,
999 &vp
->IDirect3DViewport3_iface
, &res
, Flags
);
1000 *lplpDirect3DViewport2
= (IDirect3DViewport2
*)res
;
1004 static HRESULT WINAPI
IDirect3DDeviceImpl_1_NextViewport(IDirect3DDevice
*iface
,
1005 IDirect3DViewport
*Viewport
, IDirect3DViewport
**lplpDirect3DViewport
, DWORD Flags
)
1007 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
1008 IDirect3DViewportImpl
*vp
= unsafe_impl_from_IDirect3DViewport(Viewport
);
1009 IDirect3DViewport3
*res
;
1012 TRACE("iface %p, viewport %p, next %p, flags %#x.\n",
1013 iface
, Viewport
, lplpDirect3DViewport
, Flags
);
1015 hr
= IDirect3DDevice3_NextViewport(&This
->IDirect3DDevice3_iface
,
1016 &vp
->IDirect3DViewport3_iface
, &res
, Flags
);
1017 *lplpDirect3DViewport
= (IDirect3DViewport
*)res
;
1021 /*****************************************************************************
1022 * IDirect3DDevice::Pick
1024 * Executes an execute buffer without performing rendering. Instead, a
1025 * list of primitives that intersect with (x1,y1) of the passed rectangle
1026 * is created. IDirect3DDevice::GetPickRecords can be used to retrieve
1032 * ExecuteBuffer: Buffer to execute
1033 * Viewport: Viewport to use for execution
1034 * Flags: None are defined, according to the SDK
1035 * Rect: Specifies the coordinates to be picked. Only x1 and y2 are used,
1036 * x2 and y2 are ignored.
1039 * D3D_OK because it's a stub
1041 *****************************************************************************/
1042 static HRESULT WINAPI
1043 IDirect3DDeviceImpl_1_Pick(IDirect3DDevice
*iface
,
1044 IDirect3DExecuteBuffer
*ExecuteBuffer
,
1045 IDirect3DViewport
*Viewport
,
1049 FIXME("iface %p, buffer %p, viewport %p, flags %#x, rect %s stub!\n",
1050 iface
, ExecuteBuffer
, Viewport
, Flags
, wine_dbgstr_rect((RECT
*)Rect
));
1055 /*****************************************************************************
1056 * IDirect3DDevice::GetPickRecords
1058 * Retrieves the pick records generated by IDirect3DDevice::GetPickRecords
1063 * Count: Pointer to a DWORD containing the numbers of pick records to
1065 * D3DPickRec: Address to store the resulting D3DPICKRECORD array.
1068 * D3D_OK, because it's a stub
1070 *****************************************************************************/
1071 static HRESULT WINAPI
1072 IDirect3DDeviceImpl_1_GetPickRecords(IDirect3DDevice
*iface
,
1074 D3DPICKRECORD
*D3DPickRec
)
1076 FIXME("iface %p, count %p, records %p stub!\n", iface
, Count
, D3DPickRec
);
1081 /*****************************************************************************
1082 * IDirect3DDevice7::EnumTextureformats
1084 * Enumerates the supported texture formats. It has a list of all possible
1085 * formats and calls IWineD3D::CheckDeviceFormat for each format to see if
1086 * WineD3D supports it. If so, then it is passed to the app.
1088 * This is for Version 7 and 3, older versions have a different
1089 * callback function and their own implementation
1092 * Callback: Callback to call for each enumerated format
1093 * Arg: Argument to pass to the callback
1097 * DDERR_INVALIDPARAMS if Callback == NULL
1099 *****************************************************************************/
1101 IDirect3DDeviceImpl_7_EnumTextureFormats(IDirect3DDevice7
*iface
,
1102 LPD3DENUMPIXELFORMATSCALLBACK Callback
,
1105 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
1106 struct wined3d_display_mode mode
;
1110 static const enum wined3d_format_id FormatList
[] =
1113 WINED3DFMT_B5G5R5X1_UNORM
,
1114 WINED3DFMT_B5G5R5A1_UNORM
,
1115 WINED3DFMT_B4G4R4A4_UNORM
,
1116 WINED3DFMT_B5G6R5_UNORM
,
1118 WINED3DFMT_B8G8R8X8_UNORM
,
1119 WINED3DFMT_B8G8R8A8_UNORM
,
1121 WINED3DFMT_B2G3R3_UNORM
,
1129 static const enum wined3d_format_id BumpFormatList
[] =
1131 WINED3DFMT_R8G8_SNORM
,
1132 WINED3DFMT_R5G5_SNORM_L6_UNORM
,
1133 WINED3DFMT_R8G8_SNORM_L8X8_UNORM
,
1134 WINED3DFMT_R16G16_SNORM
,
1135 WINED3DFMT_R10G11B11_SNORM
,
1136 WINED3DFMT_R10G10B10_SNORM_A2_UNORM
1139 TRACE("iface %p, callback %p, context %p.\n", iface
, Callback
, Arg
);
1142 return DDERR_INVALIDPARAMS
;
1144 wined3d_mutex_lock();
1146 memset(&mode
, 0, sizeof(mode
));
1147 hr
= wined3d_device_get_display_mode(This
->ddraw
->wined3d_device
, 0, &mode
);
1150 wined3d_mutex_unlock();
1151 WARN("Cannot get the current adapter format\n");
1155 for (i
= 0; i
< sizeof(FormatList
) / sizeof(*FormatList
); ++i
)
1157 hr
= wined3d_check_device_format(This
->ddraw
->wined3d
, WINED3DADAPTER_DEFAULT
, WINED3D_DEVICE_TYPE_HAL
,
1158 mode
.format_id
, 0, WINED3DRTYPE_TEXTURE
, FormatList
[i
], SURFACE_OPENGL
);
1161 DDPIXELFORMAT pformat
;
1163 memset(&pformat
, 0, sizeof(pformat
));
1164 pformat
.dwSize
= sizeof(pformat
);
1165 PixelFormat_WineD3DtoDD(&pformat
, FormatList
[i
]);
1167 TRACE("Enumerating WineD3DFormat %d\n", FormatList
[i
]);
1168 hr
= Callback(&pformat
, Arg
);
1169 if(hr
!= DDENUMRET_OK
)
1171 TRACE("Format enumeration cancelled by application\n");
1172 wined3d_mutex_unlock();
1178 for (i
= 0; i
< sizeof(BumpFormatList
) / sizeof(*BumpFormatList
); ++i
)
1180 hr
= wined3d_check_device_format(This
->ddraw
->wined3d
, WINED3DADAPTER_DEFAULT
,
1181 WINED3D_DEVICE_TYPE_HAL
, mode
.format_id
, WINED3DUSAGE_QUERY_LEGACYBUMPMAP
,
1182 WINED3DRTYPE_TEXTURE
, BumpFormatList
[i
], SURFACE_OPENGL
);
1185 DDPIXELFORMAT pformat
;
1187 memset(&pformat
, 0, sizeof(pformat
));
1188 pformat
.dwSize
= sizeof(pformat
);
1189 PixelFormat_WineD3DtoDD(&pformat
, BumpFormatList
[i
]);
1191 TRACE("Enumerating WineD3DFormat %d\n", BumpFormatList
[i
]);
1192 hr
= Callback(&pformat
, Arg
);
1193 if(hr
!= DDENUMRET_OK
)
1195 TRACE("Format enumeration cancelled by application\n");
1196 wined3d_mutex_unlock();
1201 TRACE("End of enumeration\n");
1202 wined3d_mutex_unlock();
1207 static HRESULT WINAPI
1208 IDirect3DDeviceImpl_7_EnumTextureFormats_FPUSetup(IDirect3DDevice7
*iface
,
1209 LPD3DENUMPIXELFORMATSCALLBACK Callback
,
1212 return IDirect3DDeviceImpl_7_EnumTextureFormats(iface
, Callback
, Arg
);
1215 static HRESULT WINAPI
1216 IDirect3DDeviceImpl_7_EnumTextureFormats_FPUPreserve(IDirect3DDevice7
*iface
,
1217 LPD3DENUMPIXELFORMATSCALLBACK Callback
,
1223 old_fpucw
= d3d_fpu_setup();
1224 hr
= IDirect3DDeviceImpl_7_EnumTextureFormats(iface
, Callback
, Arg
);
1225 set_fpu_control_word(old_fpucw
);
1230 static HRESULT WINAPI
IDirect3DDeviceImpl_3_EnumTextureFormats(IDirect3DDevice3
*iface
,
1231 LPD3DENUMPIXELFORMATSCALLBACK Callback
, void *Arg
)
1233 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
1235 TRACE("iface %p, callback %p, context %p.\n", iface
, Callback
, Arg
);
1237 return IDirect3DDevice7_EnumTextureFormats(&This
->IDirect3DDevice7_iface
, Callback
, Arg
);
1240 /*****************************************************************************
1241 * IDirect3DDevice2::EnumTextureformats
1243 * EnumTextureFormats for Version 1 and 2, see
1244 * IDirect3DDevice7::EnumTexureFormats for a more detailed description.
1246 * This version has a different callback and does not enumerate FourCC
1249 *****************************************************************************/
1250 static HRESULT WINAPI
1251 IDirect3DDeviceImpl_2_EnumTextureFormats(IDirect3DDevice2
*iface
,
1252 LPD3DENUMTEXTUREFORMATSCALLBACK Callback
,
1255 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
1256 struct wined3d_display_mode mode
;
1260 static const enum wined3d_format_id FormatList
[] =
1263 WINED3DFMT_B5G5R5X1_UNORM
,
1264 WINED3DFMT_B5G5R5A1_UNORM
,
1265 WINED3DFMT_B4G4R4A4_UNORM
,
1266 WINED3DFMT_B5G6R5_UNORM
,
1268 WINED3DFMT_B8G8R8X8_UNORM
,
1269 WINED3DFMT_B8G8R8A8_UNORM
,
1271 WINED3DFMT_B2G3R3_UNORM
,
1273 /* FOURCC codes - Not in this version*/
1276 TRACE("iface %p, callback %p, context %p.\n", iface
, Callback
, Arg
);
1279 return DDERR_INVALIDPARAMS
;
1281 wined3d_mutex_lock();
1283 memset(&mode
, 0, sizeof(mode
));
1284 hr
= wined3d_device_get_display_mode(This
->ddraw
->wined3d_device
, 0, &mode
);
1287 wined3d_mutex_unlock();
1288 WARN("Cannot get the current adapter format\n");
1292 for (i
= 0; i
< sizeof(FormatList
) / sizeof(*FormatList
); ++i
)
1294 hr
= wined3d_check_device_format(This
->ddraw
->wined3d
, 0, WINED3D_DEVICE_TYPE_HAL
,
1295 mode
.format_id
, 0, WINED3DRTYPE_TEXTURE
, FormatList
[i
], SURFACE_OPENGL
);
1298 DDSURFACEDESC sdesc
;
1300 memset(&sdesc
, 0, sizeof(sdesc
));
1301 sdesc
.dwSize
= sizeof(sdesc
);
1302 sdesc
.dwFlags
= DDSD_PIXELFORMAT
| DDSD_CAPS
;
1303 sdesc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
1304 sdesc
.ddpfPixelFormat
.dwSize
= sizeof(sdesc
.ddpfPixelFormat
);
1305 PixelFormat_WineD3DtoDD(&sdesc
.ddpfPixelFormat
, FormatList
[i
]);
1307 TRACE("Enumerating WineD3DFormat %d\n", FormatList
[i
]);
1308 hr
= Callback(&sdesc
, Arg
);
1309 if(hr
!= DDENUMRET_OK
)
1311 TRACE("Format enumeration cancelled by application\n");
1312 wined3d_mutex_unlock();
1317 TRACE("End of enumeration\n");
1318 wined3d_mutex_unlock();
1323 static HRESULT WINAPI
IDirect3DDeviceImpl_1_EnumTextureFormats(IDirect3DDevice
*iface
,
1324 LPD3DENUMTEXTUREFORMATSCALLBACK Callback
, void *Arg
)
1326 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
1328 TRACE("iface %p, callback %p, context %p.\n", iface
, Callback
, Arg
);
1330 return IDirect3DDevice2_EnumTextureFormats(&This
->IDirect3DDevice2_iface
, Callback
, Arg
);
1333 /*****************************************************************************
1334 * IDirect3DDevice::CreateMatrix
1336 * Creates a matrix handle. A handle is created and memory for a D3DMATRIX is
1337 * allocated for the handle.
1342 * D3DMatHandle: Address to return the handle at
1346 * DDERR_INVALIDPARAMS if D3DMatHandle = NULL
1348 *****************************************************************************/
1349 static HRESULT WINAPI
1350 IDirect3DDeviceImpl_1_CreateMatrix(IDirect3DDevice
*iface
, D3DMATRIXHANDLE
*D3DMatHandle
)
1352 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
1356 TRACE("iface %p, matrix_handle %p.\n", iface
, D3DMatHandle
);
1359 return DDERR_INVALIDPARAMS
;
1361 Matrix
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(D3DMATRIX
));
1364 ERR("Out of memory when allocating a D3DMATRIX\n");
1365 return DDERR_OUTOFMEMORY
;
1368 wined3d_mutex_lock();
1370 h
= ddraw_allocate_handle(&This
->handle_table
, Matrix
, DDRAW_HANDLE_MATRIX
);
1371 if (h
== DDRAW_INVALID_HANDLE
)
1373 ERR("Failed to allocate a matrix handle.\n");
1374 HeapFree(GetProcessHeap(), 0, Matrix
);
1375 wined3d_mutex_unlock();
1376 return DDERR_OUTOFMEMORY
;
1379 *D3DMatHandle
= h
+ 1;
1381 TRACE(" returning matrix handle %d\n", *D3DMatHandle
);
1383 wined3d_mutex_unlock();
1388 /*****************************************************************************
1389 * IDirect3DDevice::SetMatrix
1391 * Sets a matrix for a matrix handle. The matrix is copied into the memory
1392 * allocated for the handle
1397 * D3DMatHandle: Handle to set the matrix to
1398 * D3DMatrix: Matrix to set
1402 * DDERR_INVALIDPARAMS if the handle of the matrix is invalid or the matrix
1405 *****************************************************************************/
1406 static HRESULT WINAPI
1407 IDirect3DDeviceImpl_1_SetMatrix(IDirect3DDevice
*iface
,
1408 D3DMATRIXHANDLE D3DMatHandle
,
1409 D3DMATRIX
*D3DMatrix
)
1411 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
1414 TRACE("iface %p, matrix_handle %#x, matrix %p.\n", iface
, D3DMatHandle
, D3DMatrix
);
1416 if (!D3DMatrix
) return DDERR_INVALIDPARAMS
;
1418 wined3d_mutex_lock();
1420 m
= ddraw_get_object(&This
->handle_table
, D3DMatHandle
- 1, DDRAW_HANDLE_MATRIX
);
1423 WARN("Invalid matrix handle.\n");
1424 wined3d_mutex_unlock();
1425 return DDERR_INVALIDPARAMS
;
1428 if (TRACE_ON(ddraw
))
1429 dump_D3DMATRIX(D3DMatrix
);
1433 if (D3DMatHandle
== This
->world
)
1434 wined3d_device_set_transform(This
->wined3d_device
,
1435 WINED3DTS_WORLDMATRIX(0), (struct wined3d_matrix
*)D3DMatrix
);
1437 if (D3DMatHandle
== This
->view
)
1438 wined3d_device_set_transform(This
->wined3d_device
,
1439 WINED3DTS_VIEW
, (struct wined3d_matrix
*)D3DMatrix
);
1441 if (D3DMatHandle
== This
->proj
)
1442 wined3d_device_set_transform(This
->wined3d_device
,
1443 WINED3DTS_PROJECTION
, (struct wined3d_matrix
*)D3DMatrix
);
1445 wined3d_mutex_unlock();
1450 /*****************************************************************************
1451 * IDirect3DDevice::GetMatrix
1453 * Returns the content of a D3DMATRIX handle
1458 * D3DMatHandle: Matrix handle to read the content from
1459 * D3DMatrix: Address to store the content at
1463 * DDERR_INVALIDPARAMS if D3DMatHandle is invalid or D3DMatrix is NULL
1465 *****************************************************************************/
1466 static HRESULT WINAPI
1467 IDirect3DDeviceImpl_1_GetMatrix(IDirect3DDevice
*iface
,
1468 D3DMATRIXHANDLE D3DMatHandle
,
1469 D3DMATRIX
*D3DMatrix
)
1471 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
1474 TRACE("iface %p, matrix_handle %#x, matrix %p.\n", iface
, D3DMatHandle
, D3DMatrix
);
1476 if (!D3DMatrix
) return DDERR_INVALIDPARAMS
;
1478 wined3d_mutex_lock();
1480 m
= ddraw_get_object(&This
->handle_table
, D3DMatHandle
- 1, DDRAW_HANDLE_MATRIX
);
1483 WARN("Invalid matrix handle.\n");
1484 wined3d_mutex_unlock();
1485 return DDERR_INVALIDPARAMS
;
1490 wined3d_mutex_unlock();
1495 /*****************************************************************************
1496 * IDirect3DDevice::DeleteMatrix
1498 * Destroys a Matrix handle. Frees the memory and unsets the handle data
1503 * D3DMatHandle: Handle to destroy
1507 * DDERR_INVALIDPARAMS if D3DMatHandle is invalid
1509 *****************************************************************************/
1510 static HRESULT WINAPI
1511 IDirect3DDeviceImpl_1_DeleteMatrix(IDirect3DDevice
*iface
,
1512 D3DMATRIXHANDLE D3DMatHandle
)
1514 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
1517 TRACE("iface %p, matrix_handle %#x.\n", iface
, D3DMatHandle
);
1519 wined3d_mutex_lock();
1521 m
= ddraw_free_handle(&This
->handle_table
, D3DMatHandle
- 1, DDRAW_HANDLE_MATRIX
);
1524 WARN("Invalid matrix handle.\n");
1525 wined3d_mutex_unlock();
1526 return DDERR_INVALIDPARAMS
;
1529 wined3d_mutex_unlock();
1531 HeapFree(GetProcessHeap(), 0, m
);
1536 /*****************************************************************************
1537 * IDirect3DDevice7::BeginScene
1539 * This method must be called before any rendering is performed.
1540 * IDirect3DDevice::EndScene has to be called after the scene is complete
1542 * Version 1, 2, 3 and 7
1545 * D3D_OK on success, for details see IWineD3DDevice::BeginScene
1546 * D3DERR_SCENE_IN_SCENE if WineD3D returns an error(Only in case of an already
1549 *****************************************************************************/
1551 IDirect3DDeviceImpl_7_BeginScene(IDirect3DDevice7
*iface
)
1553 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
1556 TRACE("iface %p.\n", iface
);
1558 wined3d_mutex_lock();
1559 hr
= wined3d_device_begin_scene(This
->wined3d_device
);
1560 wined3d_mutex_unlock();
1562 if(hr
== WINED3D_OK
) return D3D_OK
;
1563 else return D3DERR_SCENE_IN_SCENE
; /* TODO: Other possible causes of failure */
1566 static HRESULT WINAPI
1567 IDirect3DDeviceImpl_7_BeginScene_FPUSetup(IDirect3DDevice7
*iface
)
1569 return IDirect3DDeviceImpl_7_BeginScene(iface
);
1572 static HRESULT WINAPI
1573 IDirect3DDeviceImpl_7_BeginScene_FPUPreserve(IDirect3DDevice7
*iface
)
1578 old_fpucw
= d3d_fpu_setup();
1579 hr
= IDirect3DDeviceImpl_7_BeginScene(iface
);
1580 set_fpu_control_word(old_fpucw
);
1585 static HRESULT WINAPI
IDirect3DDeviceImpl_3_BeginScene(IDirect3DDevice3
*iface
)
1587 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
1588 TRACE("iface %p.\n", iface
);
1590 return IDirect3DDevice7_BeginScene(&This
->IDirect3DDevice7_iface
);
1593 static HRESULT WINAPI
IDirect3DDeviceImpl_2_BeginScene(IDirect3DDevice2
*iface
)
1595 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
1596 TRACE("iface %p.\n", iface
);
1598 return IDirect3DDevice7_BeginScene(&This
->IDirect3DDevice7_iface
);
1601 static HRESULT WINAPI
IDirect3DDeviceImpl_1_BeginScene(IDirect3DDevice
*iface
)
1603 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
1604 TRACE("iface %p.\n", iface
);
1606 return IDirect3DDevice7_BeginScene(&This
->IDirect3DDevice7_iface
);
1609 /*****************************************************************************
1610 * IDirect3DDevice7::EndScene
1612 * Ends a scene that has been begun with IDirect3DDevice7::BeginScene.
1613 * This method must be called after rendering is finished.
1615 * Version 1, 2, 3 and 7
1618 * D3D_OK on success, for details see IWineD3DDevice::EndScene
1619 * D3DERR_SCENE_NOT_IN_SCENE is returned if WineD3D returns an error. It does
1620 * that only if the scene was already ended.
1622 *****************************************************************************/
1624 IDirect3DDeviceImpl_7_EndScene(IDirect3DDevice7
*iface
)
1626 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
1629 TRACE("iface %p.\n", iface
);
1631 wined3d_mutex_lock();
1632 hr
= wined3d_device_end_scene(This
->wined3d_device
);
1633 wined3d_mutex_unlock();
1635 if(hr
== WINED3D_OK
) return D3D_OK
;
1636 else return D3DERR_SCENE_NOT_IN_SCENE
;
1639 static HRESULT WINAPI DECLSPEC_HOTPATCH
1640 IDirect3DDeviceImpl_7_EndScene_FPUSetup(IDirect3DDevice7
*iface
)
1642 return IDirect3DDeviceImpl_7_EndScene(iface
);
1645 static HRESULT WINAPI DECLSPEC_HOTPATCH
1646 IDirect3DDeviceImpl_7_EndScene_FPUPreserve(IDirect3DDevice7
*iface
)
1651 old_fpucw
= d3d_fpu_setup();
1652 hr
= IDirect3DDeviceImpl_7_EndScene(iface
);
1653 set_fpu_control_word(old_fpucw
);
1658 static HRESULT WINAPI DECLSPEC_HOTPATCH
IDirect3DDeviceImpl_3_EndScene(IDirect3DDevice3
*iface
)
1660 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
1661 TRACE("iface %p.\n", iface
);
1663 return IDirect3DDevice7_EndScene(&This
->IDirect3DDevice7_iface
);
1666 static HRESULT WINAPI DECLSPEC_HOTPATCH
IDirect3DDeviceImpl_2_EndScene(IDirect3DDevice2
*iface
)
1668 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
1669 TRACE("iface %p.\n", iface
);
1671 return IDirect3DDevice7_EndScene(&This
->IDirect3DDevice7_iface
);
1674 static HRESULT WINAPI DECLSPEC_HOTPATCH
IDirect3DDeviceImpl_1_EndScene(IDirect3DDevice
*iface
)
1676 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
1677 TRACE("iface %p.\n", iface
);
1679 return IDirect3DDevice7_EndScene(&This
->IDirect3DDevice7_iface
);
1682 /*****************************************************************************
1683 * IDirect3DDevice7::GetDirect3D
1685 * Returns the IDirect3D(= interface to the DirectDraw object) used to create
1689 * Direct3D7: Address to store the interface pointer at
1693 * DDERR_INVALIDPARAMS if Direct3D7 == NULL
1695 *****************************************************************************/
1696 static HRESULT WINAPI
1697 IDirect3DDeviceImpl_7_GetDirect3D(IDirect3DDevice7
*iface
,
1698 IDirect3D7
**Direct3D7
)
1700 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
1702 TRACE("iface %p, d3d %p.\n", iface
, Direct3D7
);
1705 return DDERR_INVALIDPARAMS
;
1707 *Direct3D7
= &This
->ddraw
->IDirect3D7_iface
;
1708 IDirect3D7_AddRef(*Direct3D7
);
1710 TRACE(" returning interface %p\n", *Direct3D7
);
1714 static HRESULT WINAPI
IDirect3DDeviceImpl_3_GetDirect3D(IDirect3DDevice3
*iface
,
1715 IDirect3D3
**Direct3D3
)
1717 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
1719 TRACE("iface %p, d3d %p.\n", iface
, Direct3D3
);
1722 return DDERR_INVALIDPARAMS
;
1724 IDirect3D3_AddRef(&This
->ddraw
->IDirect3D3_iface
);
1725 *Direct3D3
= &This
->ddraw
->IDirect3D3_iface
;
1726 TRACE(" returning interface %p\n", *Direct3D3
);
1730 static HRESULT WINAPI
IDirect3DDeviceImpl_2_GetDirect3D(IDirect3DDevice2
*iface
,
1731 IDirect3D2
**Direct3D2
)
1733 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
1735 TRACE("iface %p, d3d %p.\n", iface
, Direct3D2
);
1738 return DDERR_INVALIDPARAMS
;
1740 IDirect3D2_AddRef(&This
->ddraw
->IDirect3D2_iface
);
1741 *Direct3D2
= &This
->ddraw
->IDirect3D2_iface
;
1742 TRACE(" returning interface %p\n", *Direct3D2
);
1746 static HRESULT WINAPI
IDirect3DDeviceImpl_1_GetDirect3D(IDirect3DDevice
*iface
,
1747 IDirect3D
**Direct3D
)
1749 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
1751 TRACE("iface %p, d3d %p.\n", iface
, Direct3D
);
1754 return DDERR_INVALIDPARAMS
;
1756 IDirect3D_AddRef(&This
->ddraw
->IDirect3D_iface
);
1757 *Direct3D
= &This
->ddraw
->IDirect3D_iface
;
1758 TRACE(" returning interface %p\n", *Direct3D
);
1762 /*****************************************************************************
1763 * IDirect3DDevice3::SetCurrentViewport
1765 * Sets a Direct3DViewport as the current viewport.
1766 * For the thunks note that all viewport interface versions are equal
1769 * Direct3DViewport3: The viewport to set
1775 * (Is a NULL viewport valid?)
1777 *****************************************************************************/
1778 static HRESULT WINAPI
1779 IDirect3DDeviceImpl_3_SetCurrentViewport(IDirect3DDevice3
*iface
,
1780 IDirect3DViewport3
*Direct3DViewport3
)
1782 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
1783 IDirect3DViewportImpl
*vp
= unsafe_impl_from_IDirect3DViewport3(Direct3DViewport3
);
1785 TRACE("iface %p, viewport %p.\n", iface
, Direct3DViewport3
);
1787 wined3d_mutex_lock();
1788 /* Do nothing if the specified viewport is the same as the current one */
1789 if (This
->current_viewport
== vp
)
1791 wined3d_mutex_unlock();
1795 if (vp
->active_device
!= This
)
1797 WARN("Viewport %p active device is %p.\n", vp
, vp
->active_device
);
1798 wined3d_mutex_unlock();
1799 return DDERR_INVALIDPARAMS
;
1802 /* Release previous viewport and AddRef the new one */
1803 if (This
->current_viewport
)
1805 TRACE("ViewportImpl is at %p, interface is at %p\n", This
->current_viewport
,
1806 &This
->current_viewport
->IDirect3DViewport3_iface
);
1807 IDirect3DViewport3_Release(&This
->current_viewport
->IDirect3DViewport3_iface
);
1809 IDirect3DViewport3_AddRef(Direct3DViewport3
);
1811 /* Set this viewport as the current viewport */
1812 This
->current_viewport
= vp
;
1814 /* Activate this viewport */
1815 viewport_activate(This
->current_viewport
, FALSE
);
1817 wined3d_mutex_unlock();
1822 static HRESULT WINAPI
IDirect3DDeviceImpl_2_SetCurrentViewport(IDirect3DDevice2
*iface
,
1823 IDirect3DViewport2
*Direct3DViewport2
)
1825 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
1826 IDirect3DViewportImpl
*vp
= unsafe_impl_from_IDirect3DViewport2(Direct3DViewport2
);
1828 TRACE("iface %p, viewport %p.\n", iface
, Direct3DViewport2
);
1830 return IDirect3DDevice3_SetCurrentViewport(&This
->IDirect3DDevice3_iface
,
1831 &vp
->IDirect3DViewport3_iface
);
1834 /*****************************************************************************
1835 * IDirect3DDevice3::GetCurrentViewport
1837 * Returns the currently active viewport.
1842 * Direct3DViewport3: Address to return the interface pointer at
1846 * DDERR_INVALIDPARAMS if Direct3DViewport == NULL
1848 *****************************************************************************/
1849 static HRESULT WINAPI
1850 IDirect3DDeviceImpl_3_GetCurrentViewport(IDirect3DDevice3
*iface
,
1851 IDirect3DViewport3
**Direct3DViewport3
)
1853 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
1855 TRACE("iface %p, viewport %p.\n", iface
, Direct3DViewport3
);
1857 if(!Direct3DViewport3
)
1858 return DDERR_INVALIDPARAMS
;
1860 wined3d_mutex_lock();
1861 *Direct3DViewport3
= &This
->current_viewport
->IDirect3DViewport3_iface
;
1863 /* AddRef the returned viewport */
1864 if(*Direct3DViewport3
) IDirect3DViewport3_AddRef(*Direct3DViewport3
);
1866 TRACE(" returning interface %p\n", *Direct3DViewport3
);
1868 wined3d_mutex_unlock();
1873 static HRESULT WINAPI
IDirect3DDeviceImpl_2_GetCurrentViewport(IDirect3DDevice2
*iface
,
1874 IDirect3DViewport2
**Direct3DViewport2
)
1876 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
1879 TRACE("iface %p, viewport %p.\n", iface
, Direct3DViewport2
);
1881 hr
= IDirect3DDevice3_GetCurrentViewport(&This
->IDirect3DDevice3_iface
,
1882 (IDirect3DViewport3
**)Direct3DViewport2
);
1883 if(hr
!= D3D_OK
) return hr
;
1887 /*****************************************************************************
1888 * IDirect3DDevice7::SetRenderTarget
1890 * Sets the render target for the Direct3DDevice.
1891 * For the thunks note that IDirectDrawSurface7 == IDirectDrawSurface4 and
1892 * IDirectDrawSurface3 == IDirectDrawSurface
1894 * Version 2, 3 and 7
1897 * NewTarget: Pointer to an IDirectDrawSurface7 interface to set as the new
1902 * D3D_OK on success, for details see IWineD3DDevice::SetRenderTarget
1904 *****************************************************************************/
1905 static HRESULT
d3d_device_set_render_target(IDirect3DDeviceImpl
*This
, IDirectDrawSurfaceImpl
*Target
)
1909 wined3d_mutex_lock();
1911 if(This
->target
== Target
)
1913 TRACE("No-op SetRenderTarget operation, not doing anything\n");
1914 wined3d_mutex_unlock();
1917 This
->target
= Target
;
1918 hr
= wined3d_device_set_render_target(This
->wined3d_device
, 0,
1919 Target
? Target
->wined3d_surface
: NULL
, FALSE
);
1922 wined3d_mutex_unlock();
1925 IDirect3DDeviceImpl_UpdateDepthStencil(This
);
1927 wined3d_mutex_unlock();
1933 IDirect3DDeviceImpl_7_SetRenderTarget(IDirect3DDevice7
*iface
,
1934 IDirectDrawSurface7
*NewTarget
,
1937 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
1938 IDirectDrawSurfaceImpl
*Target
= unsafe_impl_from_IDirectDrawSurface7(NewTarget
);
1940 TRACE("iface %p, target %p, flags %#x.\n", iface
, NewTarget
, Flags
);
1941 /* Flags: Not used */
1943 IDirectDrawSurface7_AddRef(NewTarget
);
1944 IDirectDrawSurface7_Release(&This
->target
->IDirectDrawSurface7_iface
);
1945 return d3d_device_set_render_target(This
, Target
);
1948 static HRESULT WINAPI
1949 IDirect3DDeviceImpl_7_SetRenderTarget_FPUSetup(IDirect3DDevice7
*iface
,
1950 IDirectDrawSurface7
*NewTarget
,
1953 return IDirect3DDeviceImpl_7_SetRenderTarget(iface
, NewTarget
, Flags
);
1956 static HRESULT WINAPI
1957 IDirect3DDeviceImpl_7_SetRenderTarget_FPUPreserve(IDirect3DDevice7
*iface
,
1958 IDirectDrawSurface7
*NewTarget
,
1964 old_fpucw
= d3d_fpu_setup();
1965 hr
= IDirect3DDeviceImpl_7_SetRenderTarget(iface
, NewTarget
, Flags
);
1966 set_fpu_control_word(old_fpucw
);
1971 static HRESULT WINAPI
IDirect3DDeviceImpl_3_SetRenderTarget(IDirect3DDevice3
*iface
,
1972 IDirectDrawSurface4
*NewRenderTarget
, DWORD Flags
)
1974 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
1975 IDirectDrawSurfaceImpl
*Target
= unsafe_impl_from_IDirectDrawSurface4(NewRenderTarget
);
1977 TRACE("iface %p, target %p, flags %#x.\n", iface
, NewRenderTarget
, Flags
);
1979 IDirectDrawSurface4_AddRef(NewRenderTarget
);
1980 IDirectDrawSurface4_Release(&This
->target
->IDirectDrawSurface4_iface
);
1981 return d3d_device_set_render_target(This
, Target
);
1984 static HRESULT WINAPI
IDirect3DDeviceImpl_2_SetRenderTarget(IDirect3DDevice2
*iface
,
1985 IDirectDrawSurface
*NewRenderTarget
, DWORD Flags
)
1987 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
1988 IDirectDrawSurfaceImpl
*Target
= unsafe_impl_from_IDirectDrawSurface(NewRenderTarget
);
1990 TRACE("iface %p, target %p, flags %#x.\n", iface
, NewRenderTarget
, Flags
);
1992 IDirectDrawSurface_AddRef(NewRenderTarget
);
1993 IDirectDrawSurface_Release(&This
->target
->IDirectDrawSurface_iface
);
1994 return d3d_device_set_render_target(This
, Target
);
1997 /*****************************************************************************
1998 * IDirect3DDevice7::GetRenderTarget
2000 * Returns the current render target.
2001 * This is handled locally, because the WineD3D render target's parent
2004 * Version 2, 3 and 7
2007 * RenderTarget: Address to store the surface interface pointer
2011 * DDERR_INVALIDPARAMS if RenderTarget == NULL
2013 *****************************************************************************/
2014 static HRESULT WINAPI
2015 IDirect3DDeviceImpl_7_GetRenderTarget(IDirect3DDevice7
*iface
,
2016 IDirectDrawSurface7
**RenderTarget
)
2018 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
2020 TRACE("iface %p, target %p.\n", iface
, RenderTarget
);
2023 return DDERR_INVALIDPARAMS
;
2025 wined3d_mutex_lock();
2026 *RenderTarget
= &This
->target
->IDirectDrawSurface7_iface
;
2027 IDirectDrawSurface7_AddRef(*RenderTarget
);
2028 wined3d_mutex_unlock();
2033 static HRESULT WINAPI
IDirect3DDeviceImpl_3_GetRenderTarget(IDirect3DDevice3
*iface
,
2034 IDirectDrawSurface4
**RenderTarget
)
2036 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
2037 IDirectDrawSurface7
*RenderTarget7
;
2038 IDirectDrawSurfaceImpl
*RenderTargetImpl
;
2041 TRACE("iface %p, target %p.\n", iface
, RenderTarget
);
2044 return DDERR_INVALIDPARAMS
;
2046 hr
= IDirect3DDevice7_GetRenderTarget(&This
->IDirect3DDevice7_iface
, &RenderTarget7
);
2047 if(hr
!= D3D_OK
) return hr
;
2048 RenderTargetImpl
= impl_from_IDirectDrawSurface7(RenderTarget7
);
2049 *RenderTarget
= &RenderTargetImpl
->IDirectDrawSurface4_iface
;
2050 IDirectDrawSurface4_AddRef(*RenderTarget
);
2051 IDirectDrawSurface7_Release(RenderTarget7
);
2055 static HRESULT WINAPI
IDirect3DDeviceImpl_2_GetRenderTarget(IDirect3DDevice2
*iface
,
2056 IDirectDrawSurface
**RenderTarget
)
2058 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
2059 IDirectDrawSurface7
*RenderTarget7
;
2060 IDirectDrawSurfaceImpl
*RenderTargetImpl
;
2063 TRACE("iface %p, target %p.\n", iface
, RenderTarget
);
2066 return DDERR_INVALIDPARAMS
;
2068 hr
= IDirect3DDevice7_GetRenderTarget(&This
->IDirect3DDevice7_iface
, &RenderTarget7
);
2069 if(hr
!= D3D_OK
) return hr
;
2070 RenderTargetImpl
= impl_from_IDirectDrawSurface7(RenderTarget7
);
2071 *RenderTarget
= &RenderTargetImpl
->IDirectDrawSurface_iface
;
2072 IDirectDrawSurface_AddRef(*RenderTarget
);
2073 IDirectDrawSurface7_Release(RenderTarget7
);
2077 /*****************************************************************************
2078 * IDirect3DDevice3::Begin
2080 * Begins a description block of vertices. This is similar to glBegin()
2081 * and glEnd(). After a call to IDirect3DDevice3::End, the vertices
2082 * described with IDirect3DDevice::Vertex are drawn.
2087 * PrimitiveType: The type of primitives to draw
2088 * VertexTypeDesc: A flexible vertex format description of the vertices
2089 * Flags: Some flags..
2094 *****************************************************************************/
2095 static HRESULT WINAPI
2096 IDirect3DDeviceImpl_3_Begin(IDirect3DDevice3
*iface
,
2097 D3DPRIMITIVETYPE PrimitiveType
,
2098 DWORD VertexTypeDesc
,
2101 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
2103 TRACE("iface %p, primitive_type %#x, FVF %#x, flags %#x.\n",
2104 iface
, PrimitiveType
, VertexTypeDesc
, Flags
);
2106 wined3d_mutex_lock();
2107 This
->primitive_type
= PrimitiveType
;
2108 This
->vertex_type
= VertexTypeDesc
;
2109 This
->render_flags
= Flags
;
2110 This
->vertex_size
= get_flexible_vertex_size(This
->vertex_type
);
2111 This
->nb_vertices
= 0;
2112 wined3d_mutex_unlock();
2117 static HRESULT WINAPI
IDirect3DDeviceImpl_2_Begin(IDirect3DDevice2
*iface
, D3DPRIMITIVETYPE d3dpt
,
2118 D3DVERTEXTYPE dwVertexTypeDesc
, DWORD dwFlags
)
2121 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
2123 TRACE("iface %p, primitive_type %#x, vertex_type %#x, flags %#x.\n",
2124 iface
, d3dpt
, dwVertexTypeDesc
, dwFlags
);
2126 switch(dwVertexTypeDesc
)
2128 case D3DVT_VERTEX
: FVF
= D3DFVF_VERTEX
; break;
2129 case D3DVT_LVERTEX
: FVF
= D3DFVF_LVERTEX
; break;
2130 case D3DVT_TLVERTEX
: FVF
= D3DFVF_TLVERTEX
; break;
2132 ERR("Unexpected vertex type %d\n", dwVertexTypeDesc
);
2133 return DDERR_INVALIDPARAMS
; /* Should never happen */
2136 return IDirect3DDevice3_Begin(&This
->IDirect3DDevice3_iface
, d3dpt
, FVF
, dwFlags
);
2139 /*****************************************************************************
2140 * IDirect3DDevice3::BeginIndexed
2142 * Draws primitives based on vertices in a vertex array which are specified
2148 * PrimitiveType: Primitive type to draw
2149 * VertexType: A FVF description of the vertex format
2150 * Vertices: pointer to an array containing the vertices
2151 * NumVertices: The number of vertices in the vertex array
2152 * Flags: Some flags ...
2155 * D3D_OK, because it's a stub
2157 *****************************************************************************/
2158 static HRESULT WINAPI
2159 IDirect3DDeviceImpl_3_BeginIndexed(IDirect3DDevice3
*iface
,
2160 D3DPRIMITIVETYPE PrimitiveType
,
2166 FIXME("iface %p, primitive_type %#x, FVF %#x, vertices %p, vertex_count %u, flags %#x stub!\n",
2167 iface
, PrimitiveType
, VertexType
, Vertices
, NumVertices
, Flags
);
2173 static HRESULT WINAPI
IDirect3DDeviceImpl_2_BeginIndexed(IDirect3DDevice2
*iface
,
2174 D3DPRIMITIVETYPE d3dptPrimitiveType
, D3DVERTEXTYPE d3dvtVertexType
,
2175 void *lpvVertices
, DWORD dwNumVertices
, DWORD dwFlags
)
2178 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
2180 TRACE("iface %p, primitive_type %#x, vertex_type %#x, vertices %p, vertex_count %u, flags %#x stub!\n",
2181 iface
, d3dptPrimitiveType
, d3dvtVertexType
, lpvVertices
, dwNumVertices
, dwFlags
);
2183 switch(d3dvtVertexType
)
2185 case D3DVT_VERTEX
: FVF
= D3DFVF_VERTEX
; break;
2186 case D3DVT_LVERTEX
: FVF
= D3DFVF_LVERTEX
; break;
2187 case D3DVT_TLVERTEX
: FVF
= D3DFVF_TLVERTEX
; break;
2189 ERR("Unexpected vertex type %d\n", d3dvtVertexType
);
2190 return DDERR_INVALIDPARAMS
; /* Should never happen */
2193 return IDirect3DDevice3_BeginIndexed(&This
->IDirect3DDevice3_iface
,
2194 d3dptPrimitiveType
, FVF
, lpvVertices
, dwNumVertices
, dwFlags
);
2197 /*****************************************************************************
2198 * IDirect3DDevice3::Vertex
2200 * Draws a vertex as described by IDirect3DDevice3::Begin. It places all
2201 * drawn vertices in a vertex buffer. If the buffer is too small, its
2202 * size is increased.
2207 * Vertex: Pointer to the vertex
2210 * D3D_OK, on success
2211 * DDERR_INVALIDPARAMS if Vertex is NULL
2213 *****************************************************************************/
2214 static HRESULT WINAPI
2215 IDirect3DDeviceImpl_3_Vertex(IDirect3DDevice3
*iface
,
2218 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
2220 TRACE("iface %p, vertex %p.\n", iface
, Vertex
);
2223 return DDERR_INVALIDPARAMS
;
2225 wined3d_mutex_lock();
2226 if ((This
->nb_vertices
+1)*This
->vertex_size
> This
->buffer_size
)
2229 This
->buffer_size
= This
->buffer_size
? This
->buffer_size
* 2 : This
->vertex_size
* 3;
2230 old_buffer
= This
->vertex_buffer
;
2231 This
->vertex_buffer
= HeapAlloc(GetProcessHeap(), 0, This
->buffer_size
);
2234 CopyMemory(This
->vertex_buffer
, old_buffer
, This
->nb_vertices
* This
->vertex_size
);
2235 HeapFree(GetProcessHeap(), 0, old_buffer
);
2239 CopyMemory(This
->vertex_buffer
+ This
->nb_vertices
++ * This
->vertex_size
, Vertex
, This
->vertex_size
);
2240 wined3d_mutex_unlock();
2245 static HRESULT WINAPI
IDirect3DDeviceImpl_2_Vertex(IDirect3DDevice2
*iface
, void *lpVertexType
)
2247 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
2249 TRACE("iface %p, vertex %p.\n", iface
, lpVertexType
);
2251 return IDirect3DDevice3_Vertex(&This
->IDirect3DDevice3_iface
, lpVertexType
);
2254 /*****************************************************************************
2255 * IDirect3DDevice3::Index
2257 * Specifies an index to a vertex to be drawn. The vertex array has to
2258 * be specified with BeginIndexed first.
2261 * VertexIndex: The index of the vertex to draw
2264 * D3D_OK because it's a stub
2266 *****************************************************************************/
2267 static HRESULT WINAPI
2268 IDirect3DDeviceImpl_3_Index(IDirect3DDevice3
*iface
,
2271 FIXME("iface %p, index %#x stub!\n", iface
, VertexIndex
);
2276 static HRESULT WINAPI
IDirect3DDeviceImpl_2_Index(IDirect3DDevice2
*iface
, WORD wVertexIndex
)
2278 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
2280 TRACE("iface %p, index %#x.\n", iface
, wVertexIndex
);
2282 return IDirect3DDevice3_Index(&This
->IDirect3DDevice3_iface
, wVertexIndex
);
2285 /*****************************************************************************
2286 * IDirect3DDevice3::End
2288 * Ends a draw begun with IDirect3DDevice3::Begin or
2289 * IDirect3DDevice::BeginIndexed. The vertices specified with
2290 * IDirect3DDevice::Vertex or IDirect3DDevice::Index are drawn using
2291 * the IDirect3DDevice7::DrawPrimitive method. So far only
2292 * non-indexed mode is supported
2297 * Flags: Some flags, as usual. Don't know which are defined
2300 * The return value of IDirect3DDevice7::DrawPrimitive
2302 *****************************************************************************/
2303 static HRESULT WINAPI
2304 IDirect3DDeviceImpl_3_End(IDirect3DDevice3
*iface
,
2307 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
2309 TRACE("iface %p, flags %#x.\n", iface
, Flags
);
2311 return IDirect3DDevice7_DrawPrimitive(&This
->IDirect3DDevice7_iface
, This
->primitive_type
,
2312 This
->vertex_type
, This
->vertex_buffer
, This
->nb_vertices
, This
->render_flags
);
2315 static HRESULT WINAPI
IDirect3DDeviceImpl_2_End(IDirect3DDevice2
*iface
, DWORD dwFlags
)
2317 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
2319 TRACE("iface %p, flags %#x.\n", iface
, dwFlags
);
2321 return IDirect3DDevice3_End(&This
->IDirect3DDevice3_iface
, dwFlags
);
2324 /*****************************************************************************
2325 * IDirect3DDevice7::GetRenderState
2327 * Returns the value of a render state. The possible render states are
2328 * defined in include/d3dtypes.h
2330 * Version 2, 3 and 7
2333 * RenderStateType: Render state to return the current setting of
2334 * Value: Address to store the value at
2337 * D3D_OK on success, for details see IWineD3DDevice::GetRenderState
2338 * DDERR_INVALIDPARAMS if Value == NULL
2340 *****************************************************************************/
2341 static HRESULT
IDirect3DDeviceImpl_7_GetRenderState(IDirect3DDevice7
*iface
,
2342 D3DRENDERSTATETYPE RenderStateType
, DWORD
*Value
)
2344 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
2347 TRACE("iface %p, state %#x, value %p.\n", iface
, RenderStateType
, Value
);
2350 return DDERR_INVALIDPARAMS
;
2352 wined3d_mutex_lock();
2353 switch(RenderStateType
)
2355 case D3DRENDERSTATE_TEXTUREMAG
:
2357 WINED3DTEXTUREFILTERTYPE tex_mag
;
2359 hr
= wined3d_device_get_sampler_state(This
->wined3d_device
, 0, WINED3D_SAMP_MAG_FILTER
, &tex_mag
);
2363 case WINED3DTEXF_POINT
:
2364 *Value
= D3DFILTER_NEAREST
;
2366 case WINED3DTEXF_LINEAR
:
2367 *Value
= D3DFILTER_LINEAR
;
2370 ERR("Unhandled texture mag %d !\n",tex_mag
);
2376 case D3DRENDERSTATE_TEXTUREMIN
:
2378 WINED3DTEXTUREFILTERTYPE tex_min
;
2379 WINED3DTEXTUREFILTERTYPE tex_mip
;
2381 hr
= wined3d_device_get_sampler_state(This
->wined3d_device
,
2382 0, WINED3D_SAMP_MIN_FILTER
, &tex_min
);
2385 wined3d_mutex_unlock();
2388 hr
= wined3d_device_get_sampler_state(This
->wined3d_device
,
2389 0, WINED3D_SAMP_MIP_FILTER
, &tex_mip
);
2393 case WINED3DTEXF_POINT
:
2396 case WINED3DTEXF_NONE
:
2397 *Value
= D3DFILTER_NEAREST
;
2399 case WINED3DTEXF_POINT
:
2400 *Value
= D3DFILTER_MIPNEAREST
;
2402 case WINED3DTEXF_LINEAR
:
2403 *Value
= D3DFILTER_LINEARMIPNEAREST
;
2406 ERR("Unhandled mip filter %#x.\n", tex_mip
);
2407 *Value
= D3DFILTER_NEAREST
;
2411 case WINED3DTEXF_LINEAR
:
2414 case WINED3DTEXF_NONE
:
2415 *Value
= D3DFILTER_LINEAR
;
2417 case WINED3DTEXF_POINT
:
2418 *Value
= D3DFILTER_MIPLINEAR
;
2420 case WINED3DTEXF_LINEAR
:
2421 *Value
= D3DFILTER_LINEARMIPLINEAR
;
2424 ERR("Unhandled mip filter %#x.\n", tex_mip
);
2425 *Value
= D3DFILTER_LINEAR
;
2430 ERR("Unhandled texture min filter %#x.\n",tex_min
);
2431 *Value
= D3DFILTER_NEAREST
;
2437 case D3DRENDERSTATE_TEXTUREADDRESS
:
2438 case D3DRENDERSTATE_TEXTUREADDRESSU
:
2439 hr
= wined3d_device_get_sampler_state(This
->wined3d_device
,
2440 0, WINED3D_SAMP_ADDRESS_U
, Value
);
2442 case D3DRENDERSTATE_TEXTUREADDRESSV
:
2443 hr
= wined3d_device_get_sampler_state(This
->wined3d_device
,
2444 0, WINED3D_SAMP_ADDRESS_V
, Value
);
2447 case D3DRENDERSTATE_BORDERCOLOR
:
2448 FIXME("Unhandled render state D3DRENDERSTATE_BORDERCOLOR.\n");
2452 case D3DRENDERSTATE_TEXTUREHANDLE
:
2453 case D3DRENDERSTATE_TEXTUREMAPBLEND
:
2454 WARN("Render state %#x is invalid in d3d7.\n", RenderStateType
);
2455 hr
= DDERR_INVALIDPARAMS
;
2458 case D3DRENDERSTATE_ZBIAS
:
2459 hr
= wined3d_device_get_render_state(This
->wined3d_device
, WINED3D_RS_DEPTHBIAS
, Value
);
2463 if (RenderStateType
>= D3DRENDERSTATE_STIPPLEPATTERN00
2464 && RenderStateType
<= D3DRENDERSTATE_STIPPLEPATTERN31
)
2466 FIXME("Unhandled stipple pattern render state (%#x).\n",
2471 hr
= wined3d_device_get_render_state(This
->wined3d_device
, RenderStateType
, Value
);
2473 wined3d_mutex_unlock();
2478 static HRESULT WINAPI
2479 IDirect3DDeviceImpl_7_GetRenderState_FPUSetup(IDirect3DDevice7
*iface
,
2480 D3DRENDERSTATETYPE RenderStateType
,
2483 return IDirect3DDeviceImpl_7_GetRenderState(iface
, RenderStateType
, Value
);
2486 static HRESULT WINAPI
2487 IDirect3DDeviceImpl_7_GetRenderState_FPUPreserve(IDirect3DDevice7
*iface
,
2488 D3DRENDERSTATETYPE RenderStateType
,
2494 old_fpucw
= d3d_fpu_setup();
2495 hr
= IDirect3DDeviceImpl_7_GetRenderState(iface
, RenderStateType
, Value
);
2496 set_fpu_control_word(old_fpucw
);
2501 static HRESULT WINAPI
2502 IDirect3DDeviceImpl_3_GetRenderState(IDirect3DDevice3
*iface
,
2503 D3DRENDERSTATETYPE dwRenderStateType
,
2504 DWORD
*lpdwRenderState
)
2506 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
2509 TRACE("iface %p, state %#x, value %p.\n", iface
, dwRenderStateType
, lpdwRenderState
);
2511 switch(dwRenderStateType
)
2513 case D3DRENDERSTATE_TEXTUREHANDLE
:
2515 /* This state is wrapped to SetTexture in SetRenderState, so
2516 * it has to be wrapped to GetTexture here. */
2517 struct wined3d_texture
*tex
= NULL
;
2518 *lpdwRenderState
= 0;
2520 wined3d_mutex_lock();
2521 hr
= wined3d_device_get_texture(This
->wined3d_device
, 0, &tex
);
2522 if (SUCCEEDED(hr
) && tex
)
2524 /* The parent of the texture is the IDirectDrawSurface7
2525 * interface of the ddraw surface. */
2526 IDirectDrawSurfaceImpl
*parent
= wined3d_texture_get_parent(tex
);
2527 if (parent
) *lpdwRenderState
= parent
->Handle
;
2528 wined3d_texture_decref(tex
);
2530 wined3d_mutex_unlock();
2535 case D3DRENDERSTATE_TEXTUREMAPBLEND
:
2537 /* D3DRENDERSTATE_TEXTUREMAPBLEND is mapped to texture state stages in SetRenderState; reverse
2538 the mapping to get the value. */
2539 DWORD colorop
, colorarg1
, colorarg2
;
2540 DWORD alphaop
, alphaarg1
, alphaarg2
;
2542 wined3d_mutex_lock();
2544 This
->legacyTextureBlending
= TRUE
;
2546 wined3d_device_get_texture_stage_state(This
->wined3d_device
, 0, WINED3D_TSS_COLOR_OP
, &colorop
);
2547 wined3d_device_get_texture_stage_state(This
->wined3d_device
, 0, WINED3D_TSS_COLOR_ARG1
, &colorarg1
);
2548 wined3d_device_get_texture_stage_state(This
->wined3d_device
, 0, WINED3D_TSS_COLOR_ARG2
, &colorarg2
);
2549 wined3d_device_get_texture_stage_state(This
->wined3d_device
, 0, WINED3D_TSS_ALPHA_OP
, &alphaop
);
2550 wined3d_device_get_texture_stage_state(This
->wined3d_device
, 0, WINED3D_TSS_ALPHA_ARG1
, &alphaarg1
);
2551 wined3d_device_get_texture_stage_state(This
->wined3d_device
, 0, WINED3D_TSS_ALPHA_ARG2
, &alphaarg2
);
2553 if (colorop
== WINED3DTOP_SELECTARG1
&& colorarg1
== WINED3DTA_TEXTURE
&&
2554 alphaop
== WINED3DTOP_SELECTARG1
&& alphaarg1
== WINED3DTA_TEXTURE
)
2556 *lpdwRenderState
= D3DTBLEND_DECAL
;
2558 else if (colorop
== WINED3DTOP_SELECTARG1
&& colorarg1
== WINED3DTA_TEXTURE
&&
2559 alphaop
== WINED3DTOP_MODULATE
&& alphaarg1
== WINED3DTA_TEXTURE
&& alphaarg2
== WINED3DTA_CURRENT
)
2561 *lpdwRenderState
= D3DTBLEND_DECALALPHA
;
2563 else if (colorop
== WINED3DTOP_MODULATE
&& colorarg1
== WINED3DTA_TEXTURE
&& colorarg2
== WINED3DTA_CURRENT
&&
2564 alphaop
== WINED3DTOP_MODULATE
&& alphaarg1
== WINED3DTA_TEXTURE
&& alphaarg2
== WINED3DTA_CURRENT
)
2566 *lpdwRenderState
= D3DTBLEND_MODULATEALPHA
;
2570 struct wined3d_texture
*tex
= NULL
;
2572 BOOL tex_alpha
= FALSE
;
2573 DDPIXELFORMAT ddfmt
;
2575 hr
= wined3d_device_get_texture(This
->wined3d_device
, 0, &tex
);
2577 if(hr
== WINED3D_OK
&& tex
)
2579 struct wined3d_resource
*sub_resource
;
2581 if ((sub_resource
= wined3d_texture_get_sub_resource(tex
, 0)))
2583 struct wined3d_resource_desc desc
;
2585 wined3d_resource_get_desc(sub_resource
, &desc
);
2586 ddfmt
.dwSize
= sizeof(ddfmt
);
2587 PixelFormat_WineD3DtoDD(&ddfmt
, desc
.format
);
2588 if (ddfmt
.u5
.dwRGBAlphaBitMask
) tex_alpha
= TRUE
;
2591 wined3d_texture_decref(tex
);
2594 if (!(colorop
== WINED3DTOP_MODULATE
&& colorarg1
== WINED3DTA_TEXTURE
&& colorarg2
== WINED3DTA_CURRENT
&&
2595 alphaop
== (tex_alpha
? WINED3DTOP_SELECTARG1
: WINED3DTOP_SELECTARG2
) &&
2596 alphaarg1
== WINED3DTA_TEXTURE
&& alphaarg2
== WINED3DTA_CURRENT
))
2598 ERR("Unexpected texture stage state setup, returning D3DTBLEND_MODULATE - likely erroneous\n");
2601 *lpdwRenderState
= D3DTBLEND_MODULATE
;
2604 wined3d_mutex_unlock();
2610 return IDirect3DDevice7_GetRenderState(&This
->IDirect3DDevice7_iface
, dwRenderStateType
, lpdwRenderState
);
2614 static HRESULT WINAPI
IDirect3DDeviceImpl_2_GetRenderState(IDirect3DDevice2
*iface
,
2615 D3DRENDERSTATETYPE dwRenderStateType
, DWORD
*lpdwRenderState
)
2617 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
2619 TRACE("iface %p, state %#x, value %p.\n", iface
, dwRenderStateType
, lpdwRenderState
);
2621 return IDirect3DDevice3_GetRenderState(&This
->IDirect3DDevice3_iface
,
2622 dwRenderStateType
, lpdwRenderState
);
2625 /*****************************************************************************
2626 * IDirect3DDevice7::SetRenderState
2628 * Sets a render state. The possible render states are defined in
2629 * include/d3dtypes.h
2631 * Version 2, 3 and 7
2634 * RenderStateType: State to set
2635 * Value: Value to assign to that state
2638 * D3D_OK on success,
2639 * for details see IWineD3DDevice::SetRenderState
2641 *****************************************************************************/
2643 IDirect3DDeviceImpl_7_SetRenderState(IDirect3DDevice7
*iface
,
2644 D3DRENDERSTATETYPE RenderStateType
,
2647 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
2650 TRACE("iface %p, state %#x, value %#x.\n", iface
, RenderStateType
, Value
);
2652 wined3d_mutex_lock();
2653 /* Some render states need special care */
2654 switch(RenderStateType
)
2657 * The ddraw texture filter mapping works like this:
2658 * D3DFILTER_NEAREST Point min/mag, no mip
2659 * D3DFILTER_MIPNEAREST Point min/mag, point mip
2660 * D3DFILTER_LINEARMIPNEAREST: Point min/mag, linear mip
2662 * D3DFILTER_LINEAR Linear min/mag, no mip
2663 * D3DFILTER_MIPLINEAR Linear min/mag, point mip
2664 * D3DFILTER_LINEARMIPLINEAR Linear min/mag, linear mip
2666 * This is the opposite of the GL naming convention,
2667 * D3DFILTER_LINEARMIPNEAREST corresponds to GL_NEAREST_MIPMAP_LINEAR.
2669 case D3DRENDERSTATE_TEXTUREMAG
:
2671 WINED3DTEXTUREFILTERTYPE tex_mag
;
2675 case D3DFILTER_NEAREST
:
2676 case D3DFILTER_MIPNEAREST
:
2677 case D3DFILTER_LINEARMIPNEAREST
:
2678 tex_mag
= WINED3DTEXF_POINT
;
2680 case D3DFILTER_LINEAR
:
2681 case D3DFILTER_MIPLINEAR
:
2682 case D3DFILTER_LINEARMIPLINEAR
:
2683 tex_mag
= WINED3DTEXF_LINEAR
;
2686 tex_mag
= WINED3DTEXF_POINT
;
2687 ERR("Unhandled texture mag %d !\n",Value
);
2691 hr
= wined3d_device_set_sampler_state(This
->wined3d_device
, 0, WINED3D_SAMP_MAG_FILTER
, tex_mag
);
2695 case D3DRENDERSTATE_TEXTUREMIN
:
2697 WINED3DTEXTUREFILTERTYPE tex_min
;
2698 WINED3DTEXTUREFILTERTYPE tex_mip
;
2700 switch ((D3DTEXTUREFILTER
) Value
)
2702 case D3DFILTER_NEAREST
:
2703 tex_min
= WINED3DTEXF_POINT
;
2704 tex_mip
= WINED3DTEXF_NONE
;
2706 case D3DFILTER_LINEAR
:
2707 tex_min
= WINED3DTEXF_LINEAR
;
2708 tex_mip
= WINED3DTEXF_NONE
;
2710 case D3DFILTER_MIPNEAREST
:
2711 tex_min
= WINED3DTEXF_POINT
;
2712 tex_mip
= WINED3DTEXF_POINT
;
2714 case D3DFILTER_MIPLINEAR
:
2715 tex_min
= WINED3DTEXF_LINEAR
;
2716 tex_mip
= WINED3DTEXF_POINT
;
2718 case D3DFILTER_LINEARMIPNEAREST
:
2719 tex_min
= WINED3DTEXF_POINT
;
2720 tex_mip
= WINED3DTEXF_LINEAR
;
2722 case D3DFILTER_LINEARMIPLINEAR
:
2723 tex_min
= WINED3DTEXF_LINEAR
;
2724 tex_mip
= WINED3DTEXF_LINEAR
;
2728 ERR("Unhandled texture min %d !\n",Value
);
2729 tex_min
= WINED3DTEXF_POINT
;
2730 tex_mip
= WINED3DTEXF_NONE
;
2734 wined3d_device_set_sampler_state(This
->wined3d_device
,
2735 0, WINED3D_SAMP_MIP_FILTER
, tex_mip
);
2736 hr
= wined3d_device_set_sampler_state(This
->wined3d_device
,
2737 0, WINED3D_SAMP_MIN_FILTER
, tex_min
);
2741 case D3DRENDERSTATE_TEXTUREADDRESS
:
2742 wined3d_device_set_sampler_state(This
->wined3d_device
,
2743 0, WINED3D_SAMP_ADDRESS_V
, Value
);
2745 case D3DRENDERSTATE_TEXTUREADDRESSU
:
2746 hr
= wined3d_device_set_sampler_state(This
->wined3d_device
,
2747 0, WINED3D_SAMP_ADDRESS_U
, Value
);
2749 case D3DRENDERSTATE_TEXTUREADDRESSV
:
2750 hr
= wined3d_device_set_sampler_state(This
->wined3d_device
,
2751 0, WINED3D_SAMP_ADDRESS_V
, Value
);
2754 case D3DRENDERSTATE_BORDERCOLOR
:
2755 /* This should probably just forward to the corresponding sampler
2756 * state. Needs tests. */
2757 FIXME("Unhandled render state D3DRENDERSTATE_BORDERCOLOR.\n");
2761 case D3DRENDERSTATE_TEXTUREHANDLE
:
2762 case D3DRENDERSTATE_TEXTUREMAPBLEND
:
2763 WARN("Render state %#x is invalid in d3d7.\n", RenderStateType
);
2764 hr
= DDERR_INVALIDPARAMS
;
2767 case D3DRENDERSTATE_ZBIAS
:
2768 hr
= wined3d_device_set_render_state(This
->wined3d_device
, WINED3D_RS_DEPTHBIAS
, Value
);
2772 if (RenderStateType
>= D3DRENDERSTATE_STIPPLEPATTERN00
2773 && RenderStateType
<= D3DRENDERSTATE_STIPPLEPATTERN31
)
2775 FIXME("Unhandled stipple pattern render state (%#x).\n",
2781 hr
= wined3d_device_set_render_state(This
->wined3d_device
, RenderStateType
, Value
);
2784 wined3d_mutex_unlock();
2789 static HRESULT WINAPI
2790 IDirect3DDeviceImpl_7_SetRenderState_FPUSetup(IDirect3DDevice7
*iface
,
2791 D3DRENDERSTATETYPE RenderStateType
,
2794 return IDirect3DDeviceImpl_7_SetRenderState(iface
, RenderStateType
, Value
);
2797 static HRESULT WINAPI
2798 IDirect3DDeviceImpl_7_SetRenderState_FPUPreserve(IDirect3DDevice7
*iface
,
2799 D3DRENDERSTATETYPE RenderStateType
,
2805 old_fpucw
= d3d_fpu_setup();
2806 hr
= IDirect3DDeviceImpl_7_SetRenderState(iface
, RenderStateType
, Value
);
2807 set_fpu_control_word(old_fpucw
);
2812 static HRESULT WINAPI
2813 IDirect3DDeviceImpl_3_SetRenderState(IDirect3DDevice3
*iface
,
2814 D3DRENDERSTATETYPE RenderStateType
,
2817 /* Note about D3DRENDERSTATE_TEXTUREMAPBLEND implementation: most of values
2818 for this state can be directly mapped to texture stage colorop and alphaop, but
2819 D3DTBLEND_MODULATE is tricky: it uses alpha from texture when available and alpha
2820 from diffuse otherwise. So changing the texture must be monitored in SetTexture to modify
2821 alphaarg when needed.
2823 Aliens vs Predator 1 depends on accurate D3DTBLEND_MODULATE emulation
2825 Legacy texture blending (TEXTUREMAPBLEND) and texture stage states: directx6 docs state that
2826 TEXTUREMAPBLEND is deprecated, yet can still be used. Games must not use both or results
2827 are undefined. D3DTBLEND_MODULATE mode in particular is dependent on texture pixel format and
2828 requires fixup of stage 0 texture states when texture changes, but this fixup can interfere
2829 with games not using this deprecated state. So a flag 'legacyTextureBlending' has to be kept
2830 in device - TRUE if the app is using TEXTUREMAPBLEND.
2832 Tests show that setting TEXTUREMAPBLEND on native doesn't seem to change values returned by
2833 GetTextureStageState and vice versa. Not so on Wine, but it is 'undefined' anyway so, probably, ok,
2834 unless some broken game will be found that cares. */
2837 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
2839 TRACE("iface %p, state %#x, value %#x.\n", iface
, RenderStateType
, Value
);
2841 wined3d_mutex_lock();
2843 switch(RenderStateType
)
2845 case D3DRENDERSTATE_TEXTUREHANDLE
:
2847 IDirectDrawSurfaceImpl
*surf
;
2851 hr
= wined3d_device_set_texture(This
->wined3d_device
, 0, NULL
);
2855 surf
= ddraw_get_object(&This
->handle_table
, Value
- 1, DDRAW_HANDLE_SURFACE
);
2858 WARN("Invalid texture handle.\n");
2859 hr
= DDERR_INVALIDPARAMS
;
2863 hr
= IDirect3DDevice3_SetTexture(iface
, 0, &surf
->IDirect3DTexture2_iface
);
2867 case D3DRENDERSTATE_TEXTUREMAPBLEND
:
2869 This
->legacyTextureBlending
= TRUE
;
2871 switch ( (D3DTEXTUREBLEND
) Value
)
2873 case D3DTBLEND_MODULATE
:
2875 struct wined3d_texture
*tex
= NULL
;
2876 BOOL tex_alpha
= FALSE
;
2877 DDPIXELFORMAT ddfmt
;
2879 hr
= wined3d_device_get_texture(This
->wined3d_device
, 0, &tex
);
2881 if(hr
== WINED3D_OK
&& tex
)
2883 struct wined3d_resource
*sub_resource
;
2885 if ((sub_resource
= wined3d_texture_get_sub_resource(tex
, 0)))
2887 struct wined3d_resource_desc desc
;
2889 wined3d_resource_get_desc(sub_resource
, &desc
);
2890 ddfmt
.dwSize
= sizeof(ddfmt
);
2891 PixelFormat_WineD3DtoDD(&ddfmt
, desc
.format
);
2892 if (ddfmt
.u5
.dwRGBAlphaBitMask
) tex_alpha
= TRUE
;
2895 wined3d_texture_decref(tex
);
2899 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2900 0, WINED3D_TSS_ALPHA_OP
, WINED3DTOP_SELECTARG1
);
2902 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2903 0, WINED3D_TSS_ALPHA_OP
, WINED3DTOP_SELECTARG2
);
2904 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2905 0, WINED3D_TSS_ALPHA_ARG1
, WINED3DTA_TEXTURE
);
2906 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2907 0, WINED3D_TSS_ALPHA_ARG2
, WINED3DTA_CURRENT
);
2908 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2909 0, WINED3D_TSS_COLOR_ARG1
, WINED3DTA_TEXTURE
);
2910 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2911 0, WINED3D_TSS_COLOR_ARG2
, WINED3DTA_CURRENT
);
2912 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2913 0, WINED3D_TSS_COLOR_OP
, WINED3DTOP_MODULATE
);
2918 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2919 0, WINED3D_TSS_COLOR_OP
, WINED3DTOP_ADD
);
2920 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2921 0, WINED3D_TSS_COLOR_ARG1
, WINED3DTA_TEXTURE
);
2922 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2923 0, WINED3D_TSS_COLOR_ARG2
, WINED3DTA_CURRENT
);
2924 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2925 0, WINED3D_TSS_ALPHA_OP
, WINED3DTOP_SELECTARG2
);
2926 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2927 0, WINED3D_TSS_ALPHA_ARG2
, WINED3DTA_CURRENT
);
2930 case D3DTBLEND_MODULATEALPHA
:
2931 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2932 0, WINED3D_TSS_COLOR_ARG1
, WINED3DTA_TEXTURE
);
2933 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2934 0, WINED3D_TSS_ALPHA_ARG1
, WINED3DTA_TEXTURE
);
2935 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2936 0, WINED3D_TSS_COLOR_ARG2
, WINED3DTA_CURRENT
);
2937 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2938 0, WINED3D_TSS_ALPHA_ARG2
, WINED3DTA_CURRENT
);
2939 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2940 0, WINED3D_TSS_COLOR_OP
, WINED3DTOP_MODULATE
);
2941 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2942 0, WINED3D_TSS_ALPHA_OP
, WINED3DTOP_MODULATE
);
2945 case D3DTBLEND_COPY
:
2946 case D3DTBLEND_DECAL
:
2947 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2948 0, WINED3D_TSS_COLOR_ARG1
, WINED3DTA_TEXTURE
);
2949 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2950 0, WINED3D_TSS_ALPHA_ARG1
, WINED3DTA_TEXTURE
);
2951 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2952 0, WINED3D_TSS_COLOR_OP
, WINED3DTOP_SELECTARG1
);
2953 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2954 0, WINED3D_TSS_ALPHA_OP
, WINED3DTOP_SELECTARG1
);
2957 case D3DTBLEND_DECALALPHA
:
2958 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2959 0, WINED3D_TSS_COLOR_OP
, WINED3DTOP_BLENDTEXTUREALPHA
);
2960 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2961 0, WINED3D_TSS_COLOR_ARG1
, WINED3DTA_TEXTURE
);
2962 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2963 0, WINED3D_TSS_COLOR_ARG2
, WINED3DTA_CURRENT
);
2964 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2965 0, WINED3D_TSS_ALPHA_OP
, WINED3DTOP_SELECTARG2
);
2966 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2967 0, WINED3D_TSS_ALPHA_ARG2
, WINED3DTA_CURRENT
);
2971 ERR("Unhandled texture environment %d !\n",Value
);
2979 hr
= IDirect3DDevice7_SetRenderState(&This
->IDirect3DDevice7_iface
, RenderStateType
, Value
);
2982 wined3d_mutex_unlock();
2987 static HRESULT WINAPI
IDirect3DDeviceImpl_2_SetRenderState(IDirect3DDevice2
*iface
,
2988 D3DRENDERSTATETYPE RenderStateType
, DWORD Value
)
2990 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
2992 TRACE("iface %p, state %#x, value %#x.\n", iface
, RenderStateType
, Value
);
2994 return IDirect3DDevice3_SetRenderState(&This
->IDirect3DDevice3_iface
, RenderStateType
, Value
);
2997 /*****************************************************************************
2998 * Direct3DDevice3::SetLightState
3000 * Sets a light state for Direct3DDevice3 and Direct3DDevice2. The
3001 * light states are forwarded to Direct3DDevice7 render states
3006 * LightStateType: The light state to change
3007 * Value: The value to assign to that light state
3011 * DDERR_INVALIDPARAMS if the parameters were incorrect
3012 * Also check IDirect3DDevice7::SetRenderState
3014 *****************************************************************************/
3015 static HRESULT WINAPI
3016 IDirect3DDeviceImpl_3_SetLightState(IDirect3DDevice3
*iface
,
3017 D3DLIGHTSTATETYPE LightStateType
,
3020 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
3023 TRACE("iface %p, state %#x, value %#x.\n", iface
, LightStateType
, Value
);
3025 if (!LightStateType
|| (LightStateType
> D3DLIGHTSTATE_COLORVERTEX
))
3027 TRACE("Unexpected Light State Type\n");
3028 return DDERR_INVALIDPARAMS
;
3031 wined3d_mutex_lock();
3032 if (LightStateType
== D3DLIGHTSTATE_MATERIAL
/* 1 */)
3034 IDirect3DMaterialImpl
*m
= ddraw_get_object(&This
->handle_table
, Value
- 1, DDRAW_HANDLE_MATERIAL
);
3037 WARN("Invalid material handle.\n");
3038 wined3d_mutex_unlock();
3039 return DDERR_INVALIDPARAMS
;
3042 TRACE(" activating material %p.\n", m
);
3043 material_activate(m
);
3045 This
->material
= Value
;
3047 else if (LightStateType
== D3DLIGHTSTATE_COLORMODEL
/* 3 */)
3052 ERR("DDCOLOR_MONO should not happen!\n");
3055 /* We are already in this mode */
3056 TRACE("Setting color model to RGB (no-op).\n");
3059 ERR("Unknown color model!\n");
3060 wined3d_mutex_unlock();
3061 return DDERR_INVALIDPARAMS
;
3066 D3DRENDERSTATETYPE rs
;
3067 switch (LightStateType
)
3069 case D3DLIGHTSTATE_AMBIENT
: /* 2 */
3070 rs
= D3DRENDERSTATE_AMBIENT
;
3072 case D3DLIGHTSTATE_FOGMODE
: /* 4 */
3073 rs
= D3DRENDERSTATE_FOGVERTEXMODE
;
3075 case D3DLIGHTSTATE_FOGSTART
: /* 5 */
3076 rs
= D3DRENDERSTATE_FOGSTART
;
3078 case D3DLIGHTSTATE_FOGEND
: /* 6 */
3079 rs
= D3DRENDERSTATE_FOGEND
;
3081 case D3DLIGHTSTATE_FOGDENSITY
: /* 7 */
3082 rs
= D3DRENDERSTATE_FOGDENSITY
;
3084 case D3DLIGHTSTATE_COLORVERTEX
: /* 8 */
3085 rs
= D3DRENDERSTATE_COLORVERTEX
;
3088 ERR("Unknown D3DLIGHTSTATETYPE %d.\n", LightStateType
);
3089 wined3d_mutex_unlock();
3090 return DDERR_INVALIDPARAMS
;
3093 hr
= IDirect3DDevice7_SetRenderState(&This
->IDirect3DDevice7_iface
, rs
, Value
);
3094 wined3d_mutex_unlock();
3097 wined3d_mutex_unlock();
3102 static HRESULT WINAPI
IDirect3DDeviceImpl_2_SetLightState(IDirect3DDevice2
*iface
,
3103 D3DLIGHTSTATETYPE LightStateType
, DWORD Value
)
3105 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
3107 TRACE("iface %p, state %#x, value %#x.\n", iface
, LightStateType
, Value
);
3109 return IDirect3DDevice3_SetLightState(&This
->IDirect3DDevice3_iface
, LightStateType
, Value
);
3112 /*****************************************************************************
3113 * IDirect3DDevice3::GetLightState
3115 * Returns the current setting of a light state. The state is read from
3116 * the Direct3DDevice7 render state.
3121 * LightStateType: The light state to return
3122 * Value: The address to store the light state setting at
3126 * DDDERR_INVALIDPARAMS if the parameters were incorrect
3127 * Also see IDirect3DDevice7::GetRenderState
3129 *****************************************************************************/
3130 static HRESULT WINAPI
3131 IDirect3DDeviceImpl_3_GetLightState(IDirect3DDevice3
*iface
,
3132 D3DLIGHTSTATETYPE LightStateType
,
3135 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
3138 TRACE("iface %p, state %#x, value %p.\n", iface
, LightStateType
, Value
);
3140 if (!LightStateType
|| (LightStateType
> D3DLIGHTSTATE_COLORVERTEX
))
3142 TRACE("Unexpected Light State Type\n");
3143 return DDERR_INVALIDPARAMS
;
3147 return DDERR_INVALIDPARAMS
;
3149 wined3d_mutex_lock();
3150 if (LightStateType
== D3DLIGHTSTATE_MATERIAL
/* 1 */)
3152 *Value
= This
->material
;
3154 else if (LightStateType
== D3DLIGHTSTATE_COLORMODEL
/* 3 */)
3156 *Value
= D3DCOLOR_RGB
;
3160 D3DRENDERSTATETYPE rs
;
3161 switch (LightStateType
)
3163 case D3DLIGHTSTATE_AMBIENT
: /* 2 */
3164 rs
= D3DRENDERSTATE_AMBIENT
;
3166 case D3DLIGHTSTATE_FOGMODE
: /* 4 */
3167 rs
= D3DRENDERSTATE_FOGVERTEXMODE
;
3169 case D3DLIGHTSTATE_FOGSTART
: /* 5 */
3170 rs
= D3DRENDERSTATE_FOGSTART
;
3172 case D3DLIGHTSTATE_FOGEND
: /* 6 */
3173 rs
= D3DRENDERSTATE_FOGEND
;
3175 case D3DLIGHTSTATE_FOGDENSITY
: /* 7 */
3176 rs
= D3DRENDERSTATE_FOGDENSITY
;
3178 case D3DLIGHTSTATE_COLORVERTEX
: /* 8 */
3179 rs
= D3DRENDERSTATE_COLORVERTEX
;
3182 ERR("Unknown D3DLIGHTSTATETYPE %d.\n", LightStateType
);
3183 wined3d_mutex_unlock();
3184 return DDERR_INVALIDPARAMS
;
3187 hr
= IDirect3DDevice7_GetRenderState(&This
->IDirect3DDevice7_iface
, rs
, Value
);
3188 wined3d_mutex_unlock();
3191 wined3d_mutex_unlock();
3196 static HRESULT WINAPI
IDirect3DDeviceImpl_2_GetLightState(IDirect3DDevice2
*iface
,
3197 D3DLIGHTSTATETYPE LightStateType
, DWORD
*Value
)
3199 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
3201 TRACE("iface %p, state %#x, value %p.\n", iface
, LightStateType
, Value
);
3203 return IDirect3DDevice3_GetLightState(&This
->IDirect3DDevice3_iface
, LightStateType
, Value
);
3206 /*****************************************************************************
3207 * IDirect3DDevice7::SetTransform
3209 * Assigns a D3DMATRIX to a transform type. The transform types are defined
3210 * in include/d3dtypes.h.
3211 * The D3DTRANSFORMSTATE_WORLD (=1) is translated to D3DTS_WORLDMATRIX(0)
3212 * (=255) for wined3d, because the 1 transform state was removed in d3d8
3213 * and WineD3D already understands the replacement D3DTS_WORLDMATRIX(0)
3215 * Version 2, 3 and 7
3218 * TransformStateType: transform state to set
3219 * Matrix: Matrix to assign to the state
3223 * DDERR_INVALIDPARAMS if Matrix == NULL
3224 * For details see IWineD3DDevice::SetTransform
3226 *****************************************************************************/
3228 IDirect3DDeviceImpl_7_SetTransform(IDirect3DDevice7
*iface
,
3229 D3DTRANSFORMSTATETYPE TransformStateType
,
3232 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
3233 D3DTRANSFORMSTATETYPE type
;
3236 TRACE("iface %p, state %#x, matrix %p.\n", iface
, TransformStateType
, Matrix
);
3238 switch(TransformStateType
)
3240 case D3DTRANSFORMSTATE_WORLD
: type
= WINED3DTS_WORLDMATRIX(0); break;
3241 case D3DTRANSFORMSTATE_WORLD1
: type
= WINED3DTS_WORLDMATRIX(1); break;
3242 case D3DTRANSFORMSTATE_WORLD2
: type
= WINED3DTS_WORLDMATRIX(2); break;
3243 case D3DTRANSFORMSTATE_WORLD3
: type
= WINED3DTS_WORLDMATRIX(3); break;
3244 default: type
= TransformStateType
;
3248 return DDERR_INVALIDPARAMS
;
3250 /* Note: D3DMATRIX is compatible with struct wined3d_matrix. */
3251 wined3d_mutex_lock();
3252 hr
= wined3d_device_set_transform(This
->wined3d_device
, type
, (struct wined3d_matrix
*)Matrix
);
3253 wined3d_mutex_unlock();
3258 static HRESULT WINAPI
3259 IDirect3DDeviceImpl_7_SetTransform_FPUSetup(IDirect3DDevice7
*iface
,
3260 D3DTRANSFORMSTATETYPE TransformStateType
,
3263 return IDirect3DDeviceImpl_7_SetTransform(iface
, TransformStateType
, Matrix
);
3266 static HRESULT WINAPI
3267 IDirect3DDeviceImpl_7_SetTransform_FPUPreserve(IDirect3DDevice7
*iface
,
3268 D3DTRANSFORMSTATETYPE TransformStateType
,
3274 old_fpucw
= d3d_fpu_setup();
3275 hr
= IDirect3DDeviceImpl_7_SetTransform(iface
, TransformStateType
, Matrix
);
3276 set_fpu_control_word(old_fpucw
);
3281 static HRESULT WINAPI
IDirect3DDeviceImpl_3_SetTransform(IDirect3DDevice3
*iface
,
3282 D3DTRANSFORMSTATETYPE state
, D3DMATRIX
*matrix
)
3284 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
3286 TRACE("iface %p, state %#x, matrix %p.\n", iface
, state
, matrix
);
3289 return DDERR_INVALIDPARAMS
;
3291 if (state
== D3DTRANSFORMSTATE_PROJECTION
)
3293 D3DMATRIX projection
;
3296 wined3d_mutex_lock();
3297 multiply_matrix(&projection
, &This
->legacy_clipspace
, matrix
);
3298 hr
= wined3d_device_set_transform(This
->wined3d_device
,
3299 WINED3DTS_PROJECTION
, (struct wined3d_matrix
*)&projection
);
3301 This
->legacy_projection
= *matrix
;
3302 wined3d_mutex_unlock();
3307 return IDirect3DDevice7_SetTransform(&This
->IDirect3DDevice7_iface
, state
, matrix
);
3310 static HRESULT WINAPI
IDirect3DDeviceImpl_2_SetTransform(IDirect3DDevice2
*iface
,
3311 D3DTRANSFORMSTATETYPE TransformStateType
, D3DMATRIX
*D3DMatrix
)
3313 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
3315 TRACE("iface %p, state %#x, matrix %p.\n", iface
, TransformStateType
, D3DMatrix
);
3317 return IDirect3DDevice7_SetTransform(&This
->IDirect3DDevice7_iface
, TransformStateType
, D3DMatrix
);
3320 /*****************************************************************************
3321 * IDirect3DDevice7::GetTransform
3323 * Returns the matrix assigned to a transform state
3324 * D3DTRANSFORMSTATE_WORLD is translated to D3DTS_WORLDMATRIX(0), see
3328 * TransformStateType: State to read the matrix from
3329 * Matrix: Address to store the matrix at
3333 * DDERR_INVALIDPARAMS if Matrix == NULL
3334 * For details, see IWineD3DDevice::GetTransform
3336 *****************************************************************************/
3338 IDirect3DDeviceImpl_7_GetTransform(IDirect3DDevice7
*iface
,
3339 D3DTRANSFORMSTATETYPE TransformStateType
,
3342 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
3343 D3DTRANSFORMSTATETYPE type
;
3346 TRACE("iface %p, state %#x, matrix %p.\n", iface
, TransformStateType
, Matrix
);
3348 switch(TransformStateType
)
3350 case D3DTRANSFORMSTATE_WORLD
: type
= WINED3DTS_WORLDMATRIX(0); break;
3351 case D3DTRANSFORMSTATE_WORLD1
: type
= WINED3DTS_WORLDMATRIX(1); break;
3352 case D3DTRANSFORMSTATE_WORLD2
: type
= WINED3DTS_WORLDMATRIX(2); break;
3353 case D3DTRANSFORMSTATE_WORLD3
: type
= WINED3DTS_WORLDMATRIX(3); break;
3354 default: type
= TransformStateType
;
3358 return DDERR_INVALIDPARAMS
;
3360 /* Note: D3DMATRIX is compatible with struct wined3d_matrix. */
3361 wined3d_mutex_lock();
3362 hr
= wined3d_device_get_transform(This
->wined3d_device
, type
, (struct wined3d_matrix
*)Matrix
);
3363 wined3d_mutex_unlock();
3368 static HRESULT WINAPI
3369 IDirect3DDeviceImpl_7_GetTransform_FPUSetup(IDirect3DDevice7
*iface
,
3370 D3DTRANSFORMSTATETYPE TransformStateType
,
3373 return IDirect3DDeviceImpl_7_GetTransform(iface
, TransformStateType
, Matrix
);
3376 static HRESULT WINAPI
3377 IDirect3DDeviceImpl_7_GetTransform_FPUPreserve(IDirect3DDevice7
*iface
,
3378 D3DTRANSFORMSTATETYPE TransformStateType
,
3384 old_fpucw
= d3d_fpu_setup();
3385 hr
= IDirect3DDeviceImpl_7_GetTransform(iface
, TransformStateType
, Matrix
);
3386 set_fpu_control_word(old_fpucw
);
3391 static HRESULT WINAPI
IDirect3DDeviceImpl_3_GetTransform(IDirect3DDevice3
*iface
,
3392 D3DTRANSFORMSTATETYPE state
, D3DMATRIX
*matrix
)
3394 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
3396 TRACE("iface %p, state %#x, matrix %p.\n", iface
, state
, matrix
);
3399 return DDERR_INVALIDPARAMS
;
3401 if (state
== D3DTRANSFORMSTATE_PROJECTION
)
3403 wined3d_mutex_lock();
3404 *matrix
= This
->legacy_projection
;
3405 wined3d_mutex_unlock();
3409 return IDirect3DDevice7_GetTransform(&This
->IDirect3DDevice7_iface
, state
, matrix
);
3412 static HRESULT WINAPI
IDirect3DDeviceImpl_2_GetTransform(IDirect3DDevice2
*iface
,
3413 D3DTRANSFORMSTATETYPE TransformStateType
, D3DMATRIX
*D3DMatrix
)
3415 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
3417 TRACE("iface %p, state %#x, matrix %p.\n", iface
, TransformStateType
, D3DMatrix
);
3419 return IDirect3DDevice7_GetTransform(&This
->IDirect3DDevice7_iface
, TransformStateType
, D3DMatrix
);
3422 /*****************************************************************************
3423 * IDirect3DDevice7::MultiplyTransform
3425 * Multiplies the already-set transform matrix of a transform state
3426 * with another matrix. For the world matrix, see SetTransform
3428 * Version 2, 3 and 7
3431 * TransformStateType: Transform state to multiply
3432 * D3DMatrix Matrix to multiply with.
3436 * DDERR_INVALIDPARAMS if D3DMatrix is NULL
3437 * For details, see IWineD3DDevice::MultiplyTransform
3439 *****************************************************************************/
3441 IDirect3DDeviceImpl_7_MultiplyTransform(IDirect3DDevice7
*iface
,
3442 D3DTRANSFORMSTATETYPE TransformStateType
,
3443 D3DMATRIX
*D3DMatrix
)
3445 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
3447 D3DTRANSFORMSTATETYPE type
;
3449 TRACE("iface %p, state %#x, matrix %p.\n", iface
, TransformStateType
, D3DMatrix
);
3451 switch(TransformStateType
)
3453 case D3DTRANSFORMSTATE_WORLD
: type
= WINED3DTS_WORLDMATRIX(0); break;
3454 case D3DTRANSFORMSTATE_WORLD1
: type
= WINED3DTS_WORLDMATRIX(1); break;
3455 case D3DTRANSFORMSTATE_WORLD2
: type
= WINED3DTS_WORLDMATRIX(2); break;
3456 case D3DTRANSFORMSTATE_WORLD3
: type
= WINED3DTS_WORLDMATRIX(3); break;
3457 default: type
= TransformStateType
;
3460 /* Note: D3DMATRIX is compatible with struct wined3d_matrix. */
3461 wined3d_mutex_lock();
3462 hr
= wined3d_device_multiply_transform(This
->wined3d_device
,
3463 type
, (struct wined3d_matrix
*)D3DMatrix
);
3464 wined3d_mutex_unlock();
3469 static HRESULT WINAPI
3470 IDirect3DDeviceImpl_7_MultiplyTransform_FPUSetup(IDirect3DDevice7
*iface
,
3471 D3DTRANSFORMSTATETYPE TransformStateType
,
3472 D3DMATRIX
*D3DMatrix
)
3474 return IDirect3DDeviceImpl_7_MultiplyTransform(iface
, TransformStateType
, D3DMatrix
);
3477 static HRESULT WINAPI
3478 IDirect3DDeviceImpl_7_MultiplyTransform_FPUPreserve(IDirect3DDevice7
*iface
,
3479 D3DTRANSFORMSTATETYPE TransformStateType
,
3480 D3DMATRIX
*D3DMatrix
)
3485 old_fpucw
= d3d_fpu_setup();
3486 hr
= IDirect3DDeviceImpl_7_MultiplyTransform(iface
, TransformStateType
, D3DMatrix
);
3487 set_fpu_control_word(old_fpucw
);
3492 static HRESULT WINAPI
IDirect3DDeviceImpl_3_MultiplyTransform(IDirect3DDevice3
*iface
,
3493 D3DTRANSFORMSTATETYPE state
, D3DMATRIX
*matrix
)
3495 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
3497 TRACE("iface %p, state %#x, matrix %p.\n", iface
, state
, matrix
);
3499 if (state
== D3DTRANSFORMSTATE_PROJECTION
)
3501 D3DMATRIX projection
, tmp
;
3504 wined3d_mutex_lock();
3505 multiply_matrix(&tmp
, &This
->legacy_projection
, matrix
);
3506 multiply_matrix(&projection
, &This
->legacy_clipspace
, &tmp
);
3507 hr
= wined3d_device_set_transform(This
->wined3d_device
,
3508 WINED3DTS_PROJECTION
, (struct wined3d_matrix
*)&projection
);
3510 This
->legacy_projection
= tmp
;
3511 wined3d_mutex_unlock();
3516 return IDirect3DDevice7_MultiplyTransform(&This
->IDirect3DDevice7_iface
, state
, matrix
);
3519 static HRESULT WINAPI
IDirect3DDeviceImpl_2_MultiplyTransform(IDirect3DDevice2
*iface
,
3520 D3DTRANSFORMSTATETYPE TransformStateType
, D3DMATRIX
*D3DMatrix
)
3522 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
3524 TRACE("iface %p, state %#x, matrix %p.\n", iface
, TransformStateType
, D3DMatrix
);
3526 return IDirect3DDevice7_MultiplyTransform(&This
->IDirect3DDevice7_iface
, TransformStateType
, D3DMatrix
);
3529 /*****************************************************************************
3530 * IDirect3DDevice7::DrawPrimitive
3532 * Draws primitives based on vertices in an application-provided pointer
3534 * Version 2, 3 and 7. The IDirect3DDevice2 thunk converts the fixed vertex type into
3535 * an FVF format for D3D7
3538 * PrimitiveType: The type of the primitives to draw
3539 * Vertex type: Flexible vertex format vertex description
3540 * Vertices: Pointer to the vertex array
3541 * VertexCount: The number of vertices to draw
3542 * Flags: As usual a few flags
3546 * DDERR_INVALIDPARAMS if Vertices is NULL
3547 * For details, see IWineD3DDevice::DrawPrimitiveUP
3549 *****************************************************************************/
3551 IDirect3DDeviceImpl_7_DrawPrimitive(IDirect3DDevice7
*iface
,
3552 D3DPRIMITIVETYPE PrimitiveType
,
3558 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
3562 TRACE("iface %p, primitive_type %#x, FVF %#x, vertices %p, vertex_count %u, flags %#x.\n",
3563 iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Flags
);
3566 return DDERR_INVALIDPARAMS
;
3568 /* Get the stride */
3569 stride
= get_flexible_vertex_size(VertexType
);
3572 wined3d_mutex_lock();
3573 hr
= wined3d_device_set_vertex_declaration(This
->wined3d_device
, ddraw_find_decl(This
->ddraw
, VertexType
));
3576 wined3d_mutex_unlock();
3580 /* This method translates to the user pointer draw of WineD3D */
3581 wined3d_device_set_primitive_type(This
->wined3d_device
, PrimitiveType
);
3582 hr
= wined3d_device_draw_primitive_up(This
->wined3d_device
, VertexCount
, Vertices
, stride
);
3583 wined3d_mutex_unlock();
3588 static HRESULT WINAPI
3589 IDirect3DDeviceImpl_7_DrawPrimitive_FPUSetup(IDirect3DDevice7
*iface
,
3590 D3DPRIMITIVETYPE PrimitiveType
,
3596 return IDirect3DDeviceImpl_7_DrawPrimitive(iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Flags
);
3599 static HRESULT WINAPI
3600 IDirect3DDeviceImpl_7_DrawPrimitive_FPUPreserve(IDirect3DDevice7
*iface
,
3601 D3DPRIMITIVETYPE PrimitiveType
,
3610 old_fpucw
= d3d_fpu_setup();
3611 hr
= IDirect3DDeviceImpl_7_DrawPrimitive(iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Flags
);
3612 set_fpu_control_word(old_fpucw
);
3617 static HRESULT WINAPI
IDirect3DDeviceImpl_3_DrawPrimitive(IDirect3DDevice3
*iface
,
3618 D3DPRIMITIVETYPE PrimitiveType
, DWORD VertexType
, void *Vertices
, DWORD VertexCount
,
3621 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
3622 TRACE("iface %p, primitive_type %#x, FVF %#x, vertices %p, vertex_count %u, flags %#x.\n",
3623 iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Flags
);
3625 return IDirect3DDevice7_DrawPrimitive(&This
->IDirect3DDevice7_iface
,
3626 PrimitiveType
, VertexType
, Vertices
, VertexCount
, Flags
);
3629 static HRESULT WINAPI
IDirect3DDeviceImpl_2_DrawPrimitive(IDirect3DDevice2
*iface
,
3630 D3DPRIMITIVETYPE PrimitiveType
, D3DVERTEXTYPE VertexType
, void *Vertices
,
3631 DWORD VertexCount
, DWORD Flags
)
3633 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
3636 TRACE("iface %p, primitive_type %#x, vertex_type %#x, vertices %p, vertex_count %u, flags %#x.\n",
3637 iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Flags
);
3641 case D3DVT_VERTEX
: FVF
= D3DFVF_VERTEX
; break;
3642 case D3DVT_LVERTEX
: FVF
= D3DFVF_LVERTEX
; break;
3643 case D3DVT_TLVERTEX
: FVF
= D3DFVF_TLVERTEX
; break;
3645 ERR("Unexpected vertex type %d\n", VertexType
);
3646 return DDERR_INVALIDPARAMS
; /* Should never happen */
3649 return IDirect3DDevice7_DrawPrimitive(&This
->IDirect3DDevice7_iface
,
3650 PrimitiveType
, FVF
, Vertices
, VertexCount
, Flags
);
3653 /*****************************************************************************
3654 * IDirect3DDevice7::DrawIndexedPrimitive
3656 * Draws vertices from an application-provided pointer, based on the index
3657 * numbers in a WORD array.
3659 * Version 2, 3 and 7. The version 7 thunk translates the vertex type into
3660 * an FVF format for D3D7
3663 * PrimitiveType: The primitive type to draw
3664 * VertexType: The FVF vertex description
3665 * Vertices: Pointer to the vertex array
3667 * Indices: Pointer to the index array
3668 * IndexCount: Number of indices = Number of vertices to draw
3669 * Flags: As usual, some flags
3673 * DDERR_INVALIDPARAMS if Vertices or Indices is NULL
3674 * For details, see IWineD3DDevice::DrawIndexedPrimitiveUP
3676 *****************************************************************************/
3678 IDirect3DDeviceImpl_7_DrawIndexedPrimitive(IDirect3DDevice7
*iface
,
3679 D3DPRIMITIVETYPE PrimitiveType
,
3687 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
3690 TRACE("iface %p, primitive_type %#x, FVF %#x, vertices %p, vertex_count %u, indices %p, index_count %u, flags %#x.\n",
3691 iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Indices
, IndexCount
, Flags
);
3693 /* Set the D3DDevice's FVF */
3694 wined3d_mutex_lock();
3695 hr
= wined3d_device_set_vertex_declaration(This
->wined3d_device
, ddraw_find_decl(This
->ddraw
, VertexType
));
3698 ERR(" (%p) Setting the FVF failed, hr = %x!\n", This
, hr
);
3699 wined3d_mutex_unlock();
3703 wined3d_device_set_primitive_type(This
->wined3d_device
, PrimitiveType
);
3704 hr
= wined3d_device_draw_indexed_primitive_up(This
->wined3d_device
, IndexCount
, Indices
,
3705 WINED3DFMT_R16_UINT
, Vertices
, get_flexible_vertex_size(VertexType
));
3706 wined3d_mutex_unlock();
3711 static HRESULT WINAPI
3712 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUSetup(IDirect3DDevice7
*iface
,
3713 D3DPRIMITIVETYPE PrimitiveType
,
3721 return IDirect3DDeviceImpl_7_DrawIndexedPrimitive(iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Indices
, IndexCount
, Flags
);
3724 static HRESULT WINAPI
3725 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUPreserve(IDirect3DDevice7
*iface
,
3726 D3DPRIMITIVETYPE PrimitiveType
,
3737 old_fpucw
= d3d_fpu_setup();
3738 hr
= IDirect3DDeviceImpl_7_DrawIndexedPrimitive(iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Indices
, IndexCount
, Flags
);
3739 set_fpu_control_word(old_fpucw
);
3744 static HRESULT WINAPI
IDirect3DDeviceImpl_3_DrawIndexedPrimitive(IDirect3DDevice3
*iface
,
3745 D3DPRIMITIVETYPE PrimitiveType
, DWORD VertexType
, void *Vertices
, DWORD VertexCount
,
3746 WORD
*Indices
, DWORD IndexCount
, DWORD Flags
)
3748 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
3749 TRACE("iface %p, primitive_type %#x, FVF %#x, vertices %p, vertex_count %u, indices %p, index_count %u, flags %#x.\n",
3750 iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Indices
, IndexCount
, Flags
);
3752 return IDirect3DDevice7_DrawIndexedPrimitive(&This
->IDirect3DDevice7_iface
,
3753 PrimitiveType
, VertexType
, Vertices
, VertexCount
, Indices
, IndexCount
, Flags
);
3756 static HRESULT WINAPI
IDirect3DDeviceImpl_2_DrawIndexedPrimitive(IDirect3DDevice2
*iface
,
3757 D3DPRIMITIVETYPE PrimitiveType
, D3DVERTEXTYPE VertexType
, void *Vertices
,
3758 DWORD VertexCount
, WORD
*Indices
, DWORD IndexCount
, DWORD Flags
)
3760 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
3763 TRACE("iface %p, primitive_type %#x, vertex_type %#x, vertices %p, vertex_count %u, indices %p, index_count %u, flags %#x.\n",
3764 iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Indices
, IndexCount
, Flags
);
3768 case D3DVT_VERTEX
: FVF
= D3DFVF_VERTEX
; break;
3769 case D3DVT_LVERTEX
: FVF
= D3DFVF_LVERTEX
; break;
3770 case D3DVT_TLVERTEX
: FVF
= D3DFVF_TLVERTEX
; break;
3772 ERR("Unexpected vertex type %d\n", VertexType
);
3773 return DDERR_INVALIDPARAMS
; /* Should never happen */
3776 return IDirect3DDevice7_DrawIndexedPrimitive(&This
->IDirect3DDevice7_iface
,
3777 PrimitiveType
, FVF
, Vertices
, VertexCount
, Indices
, IndexCount
, Flags
);
3780 /*****************************************************************************
3781 * IDirect3DDevice7::SetClipStatus
3783 * Sets the clip status. This defines things as clipping conditions and
3784 * the extents of the clipping region.
3786 * Version 2, 3 and 7
3792 * D3D_OK because it's a stub
3793 * (DDERR_INVALIDPARAMS if ClipStatus == NULL)
3795 *****************************************************************************/
3796 static HRESULT WINAPI
3797 IDirect3DDeviceImpl_7_SetClipStatus(IDirect3DDevice7
*iface
,
3798 D3DCLIPSTATUS
*ClipStatus
)
3800 FIXME("iface %p, clip_status %p stub!\n", iface
, ClipStatus
);
3802 /* D3DCLIPSTATUS and WINED3DCLIPSTATUS are different. I don't know how to convert them
3803 * Perhaps this needs a new data type and an additional IWineD3DDevice method
3805 /* return IWineD3DDevice_SetClipStatus(This->wineD3DDevice, ClipStatus);*/
3809 static HRESULT WINAPI
IDirect3DDeviceImpl_3_SetClipStatus(IDirect3DDevice3
*iface
,
3810 D3DCLIPSTATUS
*ClipStatus
)
3812 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
3813 TRACE("iface %p, clip_status %p.\n", iface
, ClipStatus
);
3815 return IDirect3DDevice7_SetClipStatus(&This
->IDirect3DDevice7_iface
, ClipStatus
);
3818 static HRESULT WINAPI
IDirect3DDeviceImpl_2_SetClipStatus(IDirect3DDevice2
*iface
,
3819 D3DCLIPSTATUS
*ClipStatus
)
3821 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
3822 TRACE("iface %p, clip_status %p.\n", iface
, ClipStatus
);
3824 return IDirect3DDevice7_SetClipStatus(&This
->IDirect3DDevice7_iface
, ClipStatus
);
3827 /*****************************************************************************
3828 * IDirect3DDevice7::GetClipStatus
3830 * Returns the clip status
3833 * ClipStatus: Address to write the clip status to
3836 * D3D_OK because it's a stub
3838 *****************************************************************************/
3839 static HRESULT WINAPI
3840 IDirect3DDeviceImpl_7_GetClipStatus(IDirect3DDevice7
*iface
,
3841 D3DCLIPSTATUS
*ClipStatus
)
3843 FIXME("iface %p, clip_status %p stub!\n", iface
, ClipStatus
);
3845 /* D3DCLIPSTATUS and WINED3DCLIPSTATUS are different. I don't know how to convert them */
3846 /* return IWineD3DDevice_GetClipStatus(This->wineD3DDevice, ClipStatus);*/
3850 static HRESULT WINAPI
IDirect3DDeviceImpl_3_GetClipStatus(IDirect3DDevice3
*iface
,
3851 D3DCLIPSTATUS
*ClipStatus
)
3853 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
3854 TRACE("iface %p, clip_status %p.\n", iface
, ClipStatus
);
3856 return IDirect3DDevice7_GetClipStatus(&This
->IDirect3DDevice7_iface
, ClipStatus
);
3859 static HRESULT WINAPI
IDirect3DDeviceImpl_2_GetClipStatus(IDirect3DDevice2
*iface
,
3860 D3DCLIPSTATUS
*ClipStatus
)
3862 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
3863 TRACE("iface %p, clip_status %p.\n", iface
, ClipStatus
);
3865 return IDirect3DDevice7_GetClipStatus(&This
->IDirect3DDevice7_iface
, ClipStatus
);
3868 /*****************************************************************************
3869 * IDirect3DDevice::DrawPrimitiveStrided
3871 * Draws vertices described by a D3DDRAWPRIMITIVESTRIDEDDATA structure.
3876 * PrimitiveType: The primitive type to draw
3877 * VertexType: The FVF description of the vertices to draw (for the stride??)
3878 * D3DDrawPrimStrideData: A D3DDRAWPRIMITIVESTRIDEDDATA structure describing
3879 * the vertex data locations
3880 * VertexCount: The number of vertices to draw
3884 * D3D_OK, because it's a stub
3885 * (DDERR_INVALIDPARAMS if D3DDrawPrimStrideData is NULL)
3886 * (For details, see IWineD3DDevice::DrawPrimitiveStrided)
3888 *****************************************************************************/
3890 IDirect3DDeviceImpl_7_DrawPrimitiveStrided(IDirect3DDevice7
*iface
,
3891 D3DPRIMITIVETYPE PrimitiveType
,
3893 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
,
3897 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
3898 struct wined3d_strided_data wined3d_strided
;
3902 TRACE("iface %p, primitive_type %#x, FVF %#x, strided_data %p, vertex_count %u, flags %#x.\n",
3903 iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Flags
);
3905 memset(&wined3d_strided
, 0, sizeof(wined3d_strided
));
3906 /* Get the strided data right. the wined3d structure is a bit bigger
3907 * Watch out: The contents of the strided data are determined by the fvf,
3908 * not by the members set in D3DDrawPrimStrideData. So it's valid
3909 * to have diffuse.lpvData set to 0xdeadbeef if the diffuse flag is
3910 * not set in the fvf.
3912 if(VertexType
& D3DFVF_POSITION_MASK
)
3914 wined3d_strided
.position
.format
= WINED3DFMT_R32G32B32_FLOAT
;
3915 wined3d_strided
.position
.data
= D3DDrawPrimStrideData
->position
.lpvData
;
3916 wined3d_strided
.position
.stride
= D3DDrawPrimStrideData
->position
.dwStride
;
3917 if (VertexType
& D3DFVF_XYZRHW
)
3919 wined3d_strided
.position
.format
= WINED3DFMT_R32G32B32A32_FLOAT
;
3920 wined3d_strided
.position_transformed
= TRUE
;
3924 wined3d_strided
.position_transformed
= FALSE
;
3928 if (VertexType
& D3DFVF_NORMAL
)
3930 wined3d_strided
.normal
.format
= WINED3DFMT_R32G32B32_FLOAT
;
3931 wined3d_strided
.normal
.data
= D3DDrawPrimStrideData
->normal
.lpvData
;
3932 wined3d_strided
.normal
.stride
= D3DDrawPrimStrideData
->normal
.dwStride
;
3935 if (VertexType
& D3DFVF_DIFFUSE
)
3937 wined3d_strided
.diffuse
.format
= WINED3DFMT_B8G8R8A8_UNORM
;
3938 wined3d_strided
.diffuse
.data
= D3DDrawPrimStrideData
->diffuse
.lpvData
;
3939 wined3d_strided
.diffuse
.stride
= D3DDrawPrimStrideData
->diffuse
.dwStride
;
3942 if (VertexType
& D3DFVF_SPECULAR
)
3944 wined3d_strided
.specular
.format
= WINED3DFMT_B8G8R8A8_UNORM
;
3945 wined3d_strided
.specular
.data
= D3DDrawPrimStrideData
->specular
.lpvData
;
3946 wined3d_strided
.specular
.stride
= D3DDrawPrimStrideData
->specular
.dwStride
;
3949 for (i
= 0; i
< GET_TEXCOUNT_FROM_FVF(VertexType
); ++i
)
3951 switch (GET_TEXCOORD_SIZE_FROM_FVF(VertexType
, i
))
3953 case 1: wined3d_strided
.tex_coords
[i
].format
= WINED3DFMT_R32_FLOAT
; break;
3954 case 2: wined3d_strided
.tex_coords
[i
].format
= WINED3DFMT_R32G32_FLOAT
; break;
3955 case 3: wined3d_strided
.tex_coords
[i
].format
= WINED3DFMT_R32G32B32_FLOAT
; break;
3956 case 4: wined3d_strided
.tex_coords
[i
].format
= WINED3DFMT_R32G32B32A32_FLOAT
; break;
3957 default: ERR("Unexpected texture coordinate size %d\n",
3958 GET_TEXCOORD_SIZE_FROM_FVF(VertexType
, i
));
3960 wined3d_strided
.tex_coords
[i
].data
= D3DDrawPrimStrideData
->textureCoords
[i
].lpvData
;
3961 wined3d_strided
.tex_coords
[i
].stride
= D3DDrawPrimStrideData
->textureCoords
[i
].dwStride
;
3964 /* WineD3D doesn't need the FVF here */
3965 wined3d_mutex_lock();
3966 wined3d_device_set_primitive_type(This
->wined3d_device
, PrimitiveType
);
3967 hr
= wined3d_device_draw_primitive_strided(This
->wined3d_device
, VertexCount
, &wined3d_strided
);
3968 wined3d_mutex_unlock();
3973 static HRESULT WINAPI
3974 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUSetup(IDirect3DDevice7
*iface
,
3975 D3DPRIMITIVETYPE PrimitiveType
,
3977 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
,
3981 return IDirect3DDeviceImpl_7_DrawPrimitiveStrided(iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Flags
);
3984 static HRESULT WINAPI
3985 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUPreserve(IDirect3DDevice7
*iface
,
3986 D3DPRIMITIVETYPE PrimitiveType
,
3988 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
,
3995 old_fpucw
= d3d_fpu_setup();
3996 hr
= IDirect3DDeviceImpl_7_DrawPrimitiveStrided(iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Flags
);
3997 set_fpu_control_word(old_fpucw
);
4002 static HRESULT WINAPI
IDirect3DDeviceImpl_3_DrawPrimitiveStrided(IDirect3DDevice3
*iface
,
4003 D3DPRIMITIVETYPE PrimitiveType
, DWORD VertexType
,
4004 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
, DWORD VertexCount
, DWORD Flags
)
4006 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
4008 TRACE("iface %p, primitive_type %#x, FVF %#x, strided_data %p, vertex_count %u, flags %#x.\n",
4009 iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Flags
);
4011 return IDirect3DDevice7_DrawPrimitiveStrided(&This
->IDirect3DDevice7_iface
,
4012 PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Flags
);
4015 /*****************************************************************************
4016 * IDirect3DDevice7::DrawIndexedPrimitiveStrided
4018 * Draws primitives specified by strided data locations based on indices
4026 * D3D_OK, because it's a stub
4027 * (DDERR_INVALIDPARAMS if D3DDrawPrimStrideData is NULL)
4028 * (DDERR_INVALIDPARAMS if Indices is NULL)
4029 * (For more details, see IWineD3DDevice::DrawIndexedPrimitiveStrided)
4031 *****************************************************************************/
4033 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided(IDirect3DDevice7
*iface
,
4034 D3DPRIMITIVETYPE PrimitiveType
,
4036 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
,
4042 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
4043 struct wined3d_strided_data wined3d_strided
;
4047 TRACE("iface %p, primitive_type %#x, FVF %#x, strided_data %p, vertex_count %u, indices %p, index_count %u, flags %#x.\n",
4048 iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Indices
, IndexCount
, Flags
);
4050 memset(&wined3d_strided
, 0, sizeof(wined3d_strided
));
4051 /* Get the strided data right. the wined3d structure is a bit bigger
4052 * Watch out: The contents of the strided data are determined by the fvf,
4053 * not by the members set in D3DDrawPrimStrideData. So it's valid
4054 * to have diffuse.lpvData set to 0xdeadbeef if the diffuse flag is
4055 * not set in the fvf. */
4056 if (VertexType
& D3DFVF_POSITION_MASK
)
4058 wined3d_strided
.position
.format
= WINED3DFMT_R32G32B32_FLOAT
;
4059 wined3d_strided
.position
.data
= D3DDrawPrimStrideData
->position
.lpvData
;
4060 wined3d_strided
.position
.stride
= D3DDrawPrimStrideData
->position
.dwStride
;
4061 if (VertexType
& D3DFVF_XYZRHW
)
4063 wined3d_strided
.position
.format
= WINED3DFMT_R32G32B32A32_FLOAT
;
4064 wined3d_strided
.position_transformed
= TRUE
;
4068 wined3d_strided
.position_transformed
= FALSE
;
4072 if (VertexType
& D3DFVF_NORMAL
)
4074 wined3d_strided
.normal
.format
= WINED3DFMT_R32G32B32_FLOAT
;
4075 wined3d_strided
.normal
.data
= D3DDrawPrimStrideData
->normal
.lpvData
;
4076 wined3d_strided
.normal
.stride
= D3DDrawPrimStrideData
->normal
.dwStride
;
4079 if (VertexType
& D3DFVF_DIFFUSE
)
4081 wined3d_strided
.diffuse
.format
= WINED3DFMT_B8G8R8A8_UNORM
;
4082 wined3d_strided
.diffuse
.data
= D3DDrawPrimStrideData
->diffuse
.lpvData
;
4083 wined3d_strided
.diffuse
.stride
= D3DDrawPrimStrideData
->diffuse
.dwStride
;
4086 if (VertexType
& D3DFVF_SPECULAR
)
4088 wined3d_strided
.specular
.format
= WINED3DFMT_B8G8R8A8_UNORM
;
4089 wined3d_strided
.specular
.data
= D3DDrawPrimStrideData
->specular
.lpvData
;
4090 wined3d_strided
.specular
.stride
= D3DDrawPrimStrideData
->specular
.dwStride
;
4093 for (i
= 0; i
< GET_TEXCOUNT_FROM_FVF(VertexType
); ++i
)
4095 switch (GET_TEXCOORD_SIZE_FROM_FVF(VertexType
, i
))
4097 case 1: wined3d_strided
.tex_coords
[i
].format
= WINED3DFMT_R32_FLOAT
; break;
4098 case 2: wined3d_strided
.tex_coords
[i
].format
= WINED3DFMT_R32G32_FLOAT
; break;
4099 case 3: wined3d_strided
.tex_coords
[i
].format
= WINED3DFMT_R32G32B32_FLOAT
; break;
4100 case 4: wined3d_strided
.tex_coords
[i
].format
= WINED3DFMT_R32G32B32A32_FLOAT
; break;
4101 default: ERR("Unexpected texture coordinate size %d\n",
4102 GET_TEXCOORD_SIZE_FROM_FVF(VertexType
, i
));
4104 wined3d_strided
.tex_coords
[i
].data
= D3DDrawPrimStrideData
->textureCoords
[i
].lpvData
;
4105 wined3d_strided
.tex_coords
[i
].stride
= D3DDrawPrimStrideData
->textureCoords
[i
].dwStride
;
4108 /* WineD3D doesn't need the FVF here */
4109 wined3d_mutex_lock();
4110 wined3d_device_set_primitive_type(This
->wined3d_device
, PrimitiveType
);
4111 hr
= wined3d_device_draw_indexed_primitive_strided(This
->wined3d_device
,
4112 IndexCount
, &wined3d_strided
, VertexCount
, Indices
, WINED3DFMT_R16_UINT
);
4113 wined3d_mutex_unlock();
4118 static HRESULT WINAPI
4119 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUSetup(IDirect3DDevice7
*iface
,
4120 D3DPRIMITIVETYPE PrimitiveType
,
4122 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
,
4128 return IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided(iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Indices
, IndexCount
, Flags
);
4131 static HRESULT WINAPI
4132 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUPreserve(IDirect3DDevice7
*iface
,
4133 D3DPRIMITIVETYPE PrimitiveType
,
4135 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
,
4144 old_fpucw
= d3d_fpu_setup();
4145 hr
= IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided(iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Indices
, IndexCount
, Flags
);
4146 set_fpu_control_word(old_fpucw
);
4151 static HRESULT WINAPI
IDirect3DDeviceImpl_3_DrawIndexedPrimitiveStrided(IDirect3DDevice3
*iface
,
4152 D3DPRIMITIVETYPE PrimitiveType
, DWORD VertexType
,
4153 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
, DWORD VertexCount
, WORD
*Indices
,
4154 DWORD IndexCount
, DWORD Flags
)
4156 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
4158 TRACE("iface %p, primitive_type %#x, FVF %#x, strided_data %p, vertex_count %u, indices %p, index_count %u, flags %#x.\n",
4159 iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Indices
, IndexCount
, Flags
);
4161 return IDirect3DDevice7_DrawIndexedPrimitiveStrided(&This
->IDirect3DDevice7_iface
,
4162 PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Indices
, IndexCount
, Flags
);
4165 /*****************************************************************************
4166 * IDirect3DDevice7::DrawPrimitiveVB
4168 * Draws primitives from a vertex buffer to the screen.
4173 * PrimitiveType: Type of primitive to be rendered.
4174 * D3DVertexBuf: Source Vertex Buffer
4175 * StartVertex: Index of the first vertex from the buffer to be rendered
4176 * NumVertices: Number of vertices to be rendered
4177 * Flags: Can be D3DDP_WAIT to wait until rendering has finished
4181 * DDERR_INVALIDPARAMS if D3DVertexBuf is NULL
4183 *****************************************************************************/
4185 IDirect3DDeviceImpl_7_DrawPrimitiveVB(IDirect3DDevice7
*iface
,
4186 D3DPRIMITIVETYPE PrimitiveType
,
4187 IDirect3DVertexBuffer7
*D3DVertexBuf
,
4192 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
4193 IDirect3DVertexBufferImpl
*vb
= unsafe_impl_from_IDirect3DVertexBuffer7(D3DVertexBuf
);
4197 TRACE("iface %p, primitive_type %#x, vb %p, start_vertex %u, vertex_count %u, flags %#x.\n",
4198 iface
, PrimitiveType
, D3DVertexBuf
, StartVertex
, NumVertices
, Flags
);
4203 ERR("(%p) No Vertex buffer specified\n", This
);
4204 return DDERR_INVALIDPARAMS
;
4206 stride
= get_flexible_vertex_size(vb
->fvf
);
4208 wined3d_mutex_lock();
4209 hr
= wined3d_device_set_vertex_declaration(This
->wined3d_device
, vb
->wineD3DVertexDeclaration
);
4212 ERR(" (%p) Setting the FVF failed, hr = %x!\n", This
, hr
);
4213 wined3d_mutex_unlock();
4217 /* Set the vertex stream source */
4218 hr
= wined3d_device_set_stream_source(This
->wined3d_device
, 0, vb
->wineD3DVertexBuffer
, 0, stride
);
4221 ERR("(%p) IDirect3DDevice::SetStreamSource failed with hr = %08x\n", This
, hr
);
4222 wined3d_mutex_unlock();
4226 /* Now draw the primitives */
4227 wined3d_device_set_primitive_type(This
->wined3d_device
, PrimitiveType
);
4228 hr
= wined3d_device_draw_primitive(This
->wined3d_device
, StartVertex
, NumVertices
);
4229 wined3d_mutex_unlock();
4234 static HRESULT WINAPI
4235 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUSetup(IDirect3DDevice7
*iface
,
4236 D3DPRIMITIVETYPE PrimitiveType
,
4237 IDirect3DVertexBuffer7
*D3DVertexBuf
,
4242 return IDirect3DDeviceImpl_7_DrawPrimitiveVB(iface
, PrimitiveType
, D3DVertexBuf
, StartVertex
, NumVertices
, Flags
);
4245 static HRESULT WINAPI
4246 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUPreserve(IDirect3DDevice7
*iface
,
4247 D3DPRIMITIVETYPE PrimitiveType
,
4248 IDirect3DVertexBuffer7
*D3DVertexBuf
,
4256 old_fpucw
= d3d_fpu_setup();
4257 hr
= IDirect3DDeviceImpl_7_DrawPrimitiveVB(iface
, PrimitiveType
, D3DVertexBuf
, StartVertex
, NumVertices
, Flags
);
4258 set_fpu_control_word(old_fpucw
);
4263 static HRESULT WINAPI
IDirect3DDeviceImpl_3_DrawPrimitiveVB(IDirect3DDevice3
*iface
,
4264 D3DPRIMITIVETYPE PrimitiveType
, IDirect3DVertexBuffer
*D3DVertexBuf
, DWORD StartVertex
,
4265 DWORD NumVertices
, DWORD Flags
)
4267 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
4268 IDirect3DVertexBufferImpl
*vb
= unsafe_impl_from_IDirect3DVertexBuffer(D3DVertexBuf
);
4270 TRACE("iface %p, primitive_type %#x, vb %p, start_vertex %u, vertex_count %u, flags %#x.\n",
4271 iface
, PrimitiveType
, D3DVertexBuf
, StartVertex
, NumVertices
, Flags
);
4273 return IDirect3DDevice7_DrawPrimitiveVB(&This
->IDirect3DDevice7_iface
,
4274 PrimitiveType
, &vb
->IDirect3DVertexBuffer7_iface
, StartVertex
, NumVertices
, Flags
);
4278 /*****************************************************************************
4279 * IDirect3DDevice7::DrawIndexedPrimitiveVB
4281 * Draws primitives from a vertex buffer to the screen
4284 * PrimitiveType: Type of primitive to be rendered.
4285 * D3DVertexBuf: Source Vertex Buffer
4286 * StartVertex: Index of the first vertex from the buffer to be rendered
4287 * NumVertices: Number of vertices to be rendered
4288 * Indices: Array of DWORDs used to index into the Vertices
4289 * IndexCount: Number of indices in Indices
4290 * Flags: Can be D3DDP_WAIT to wait until rendering has finished
4294 *****************************************************************************/
4296 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB(IDirect3DDevice7
*iface
,
4297 D3DPRIMITIVETYPE PrimitiveType
,
4298 IDirect3DVertexBuffer7
*D3DVertexBuf
,
4305 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
4306 IDirect3DVertexBufferImpl
*vb
= unsafe_impl_from_IDirect3DVertexBuffer7(D3DVertexBuf
);
4307 DWORD stride
= get_flexible_vertex_size(vb
->fvf
);
4308 struct wined3d_resource
*wined3d_resource
;
4309 struct wined3d_resource_desc desc
;
4310 WORD
*LockedIndices
;
4313 TRACE("iface %p, primitive_type %#x, vb %p, start_vertex %u, vertex_count %u, indices %p, index_count %u, flags %#x.\n",
4314 iface
, PrimitiveType
, D3DVertexBuf
, StartVertex
, NumVertices
, Indices
, IndexCount
, Flags
);
4317 * 1) Upload the Indices to the index buffer
4318 * 2) Set the index source
4319 * 3) Set the Vertex Buffer as the Stream source
4320 * 4) Call IWineD3DDevice::DrawIndexedPrimitive
4323 wined3d_mutex_lock();
4325 hr
= wined3d_device_set_vertex_declaration(This
->wined3d_device
, vb
->wineD3DVertexDeclaration
);
4328 ERR(" (%p) Setting the FVF failed, hr = %x!\n", This
, hr
);
4329 wined3d_mutex_unlock();
4333 /* check that the buffer is large enough to hold the indices,
4334 * reallocate if necessary. */
4335 wined3d_resource
= wined3d_buffer_get_resource(This
->indexbuffer
);
4336 wined3d_resource_get_desc(wined3d_resource
, &desc
);
4337 if (desc
.size
< IndexCount
* sizeof(WORD
))
4339 UINT size
= max(desc
.size
* 2, IndexCount
* sizeof(WORD
));
4340 struct wined3d_buffer
*buffer
;
4342 TRACE("Growing index buffer to %u bytes\n", size
);
4344 hr
= wined3d_buffer_create_ib(This
->wined3d_device
, size
, WINED3DUSAGE_DYNAMIC
/* Usage */,
4345 WINED3DPOOL_DEFAULT
, NULL
, &ddraw_null_wined3d_parent_ops
, &buffer
);
4348 ERR("(%p) IWineD3DDevice::CreateIndexBuffer failed with hr = %08x\n", This
, hr
);
4349 wined3d_mutex_unlock();
4353 wined3d_buffer_decref(This
->indexbuffer
);
4354 This
->indexbuffer
= buffer
;
4357 /* Copy the index stream into the index buffer. A new IWineD3DDevice
4358 * method could be created which takes an user pointer containing the
4359 * indices or a SetData-Method for the index buffer, which overrides the
4360 * index buffer data with our pointer. */
4361 hr
= wined3d_buffer_map(This
->indexbuffer
, 0, IndexCount
* sizeof(WORD
),
4362 (BYTE
**)&LockedIndices
, 0);
4365 ERR("Failed to map buffer, hr %#x.\n", hr
);
4366 wined3d_mutex_unlock();
4369 memcpy(LockedIndices
, Indices
, IndexCount
* sizeof(WORD
));
4370 wined3d_buffer_unmap(This
->indexbuffer
);
4372 /* Set the index stream */
4373 wined3d_device_set_base_vertex_index(This
->wined3d_device
, StartVertex
);
4374 hr
= wined3d_device_set_index_buffer(This
->wined3d_device
, This
->indexbuffer
, WINED3DFMT_R16_UINT
);
4376 /* Set the vertex stream source */
4377 hr
= wined3d_device_set_stream_source(This
->wined3d_device
, 0, vb
->wineD3DVertexBuffer
, 0, stride
);
4380 ERR("(%p) IDirect3DDevice::SetStreamSource failed with hr = %08x\n", This
, hr
);
4381 wined3d_mutex_unlock();
4386 wined3d_device_set_primitive_type(This
->wined3d_device
, PrimitiveType
);
4387 hr
= wined3d_device_draw_indexed_primitive(This
->wined3d_device
, 0, IndexCount
);
4389 wined3d_mutex_unlock();
4394 static HRESULT WINAPI
4395 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUSetup(IDirect3DDevice7
*iface
,
4396 D3DPRIMITIVETYPE PrimitiveType
,
4397 IDirect3DVertexBuffer7
*D3DVertexBuf
,
4404 return IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB(iface
, PrimitiveType
, D3DVertexBuf
, StartVertex
, NumVertices
, Indices
, IndexCount
, Flags
);
4407 static HRESULT WINAPI
4408 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUPreserve(IDirect3DDevice7
*iface
,
4409 D3DPRIMITIVETYPE PrimitiveType
,
4410 IDirect3DVertexBuffer7
*D3DVertexBuf
,
4420 old_fpucw
= d3d_fpu_setup();
4421 hr
= IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB(iface
, PrimitiveType
, D3DVertexBuf
, StartVertex
, NumVertices
, Indices
, IndexCount
, Flags
);
4422 set_fpu_control_word(old_fpucw
);
4427 static HRESULT WINAPI
IDirect3DDeviceImpl_3_DrawIndexedPrimitiveVB(IDirect3DDevice3
*iface
,
4428 D3DPRIMITIVETYPE PrimitiveType
, IDirect3DVertexBuffer
*D3DVertexBuf
, WORD
*Indices
,
4429 DWORD IndexCount
, DWORD Flags
)
4431 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
4432 IDirect3DVertexBufferImpl
*vb
= unsafe_impl_from_IDirect3DVertexBuffer(D3DVertexBuf
);
4434 TRACE("iface %p, primitive_type %#x, vb %p, indices %p, index_count %u, flags %#x.\n",
4435 iface
, PrimitiveType
, D3DVertexBuf
, Indices
, IndexCount
, Flags
);
4437 return IDirect3DDevice7_DrawIndexedPrimitiveVB(&This
->IDirect3DDevice7_iface
,
4438 PrimitiveType
, &vb
->IDirect3DVertexBuffer7_iface
, 0, IndexCount
, Indices
, IndexCount
,
4442 /*****************************************************************************
4443 * IDirect3DDevice7::ComputeSphereVisibility
4445 * Calculates the visibility of spheres in the current viewport. The spheres
4446 * are passed in the Centers and Radii arrays, the results are passed back
4447 * in the ReturnValues array. Return values are either completely visible,
4448 * partially visible or completely invisible.
4449 * The return value consist of a combination of D3DCLIP_* flags, or it's
4450 * 0 if the sphere is completely visible(according to the SDK, not checked)
4455 * Centers: Array containing the sphere centers
4456 * Radii: Array containing the sphere radii
4457 * NumSpheres: The number of centers and radii in the arrays
4459 * ReturnValues: Array to write the results to
4463 * (DDERR_INVALIDPARAMS if Centers, Radii or ReturnValues are NULL)
4464 * (D3DERR_INVALIDMATRIX if the combined world, view and proj matrix
4467 *****************************************************************************/
4469 static DWORD
in_plane(UINT plane
, D3DVECTOR normal
, D3DVALUE origin_plane
, D3DVECTOR center
, D3DVALUE radius
)
4471 float distance
, norm
;
4473 norm
= sqrt( normal
.u1
.x
* normal
.u1
.x
+ normal
.u2
.y
* normal
.u2
.y
+ normal
.u3
.z
* normal
.u3
.z
);
4474 distance
= ( origin_plane
+ normal
.u1
.x
* center
.u1
.x
+ normal
.u2
.y
* center
.u2
.y
+ normal
.u3
.z
* center
.u3
.z
) / norm
;
4476 if ( fabs( distance
) < radius
) return D3DSTATUS_CLIPUNIONLEFT
<< plane
;
4477 if ( distance
< -radius
) return (D3DSTATUS_CLIPUNIONLEFT
| D3DSTATUS_CLIPINTERSECTIONLEFT
) << plane
;
4481 static HRESULT WINAPI
4482 IDirect3DDeviceImpl_7_ComputeSphereVisibility(IDirect3DDevice7
*iface
,
4487 DWORD
*ReturnValues
)
4490 D3DVALUE origin_plane
[6];
4495 TRACE("iface %p, centers %p, radii %p, sphere_count %u, flags %#x, return_values %p.\n",
4496 iface
, Centers
, Radii
, NumSpheres
, Flags
, ReturnValues
);
4498 hr
= IDirect3DDeviceImpl_7_GetTransform(iface
, D3DTRANSFORMSTATE_WORLD
, &m
);
4499 if ( hr
!= DD_OK
) return DDERR_INVALIDPARAMS
;
4500 hr
= IDirect3DDeviceImpl_7_GetTransform(iface
, D3DTRANSFORMSTATE_VIEW
, &temp
);
4501 if ( hr
!= DD_OK
) return DDERR_INVALIDPARAMS
;
4502 multiply_matrix(&m
, &temp
, &m
);
4504 hr
= IDirect3DDeviceImpl_7_GetTransform(iface
, D3DTRANSFORMSTATE_PROJECTION
, &temp
);
4505 if ( hr
!= DD_OK
) return DDERR_INVALIDPARAMS
;
4506 multiply_matrix(&m
, &temp
, &m
);
4509 vec
[0].u1
.x
= m
._14
+ m
._11
;
4510 vec
[0].u2
.y
= m
._24
+ m
._21
;
4511 vec
[0].u3
.z
= m
._34
+ m
._31
;
4512 origin_plane
[0] = m
._44
+ m
._41
;
4515 vec
[1].u1
.x
= m
._14
- m
._11
;
4516 vec
[1].u2
.y
= m
._24
- m
._21
;
4517 vec
[1].u3
.z
= m
._34
- m
._31
;
4518 origin_plane
[1] = m
._44
- m
._41
;
4521 vec
[2].u1
.x
= m
._14
- m
._12
;
4522 vec
[2].u2
.y
= m
._24
- m
._22
;
4523 vec
[2].u3
.z
= m
._34
- m
._32
;
4524 origin_plane
[2] = m
._44
- m
._42
;
4527 vec
[3].u1
.x
= m
._14
+ m
._12
;
4528 vec
[3].u2
.y
= m
._24
+ m
._22
;
4529 vec
[3].u3
.z
= m
._34
+ m
._32
;
4530 origin_plane
[3] = m
._44
+ m
._42
;
4533 vec
[4].u1
.x
= m
._13
;
4534 vec
[4].u2
.y
= m
._23
;
4535 vec
[4].u3
.z
= m
._33
;
4536 origin_plane
[4] = m
._43
;
4539 vec
[5].u1
.x
= m
._14
- m
._13
;
4540 vec
[5].u2
.y
= m
._24
- m
._23
;
4541 vec
[5].u3
.z
= m
._34
- m
._33
;
4542 origin_plane
[5] = m
._44
- m
._43
;
4544 for(i
=0; i
<NumSpheres
; i
++)
4546 ReturnValues
[i
] = 0;
4547 for(j
=0; j
<6; j
++) ReturnValues
[i
] |= in_plane(j
, vec
[j
], origin_plane
[j
], Centers
[i
], Radii
[i
]);
4553 static HRESULT WINAPI
IDirect3DDeviceImpl_3_ComputeSphereVisibility(IDirect3DDevice3
*iface
,
4554 D3DVECTOR
*Centers
, D3DVALUE
*Radii
, DWORD NumSpheres
, DWORD Flags
, DWORD
*ReturnValues
)
4556 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
4558 TRACE("iface %p, centers %p, radii %p, sphere_count %u, flags %#x, return_values %p.\n",
4559 iface
, Centers
, Radii
, NumSpheres
, Flags
, ReturnValues
);
4561 return IDirect3DDevice7_ComputeSphereVisibility(&This
->IDirect3DDevice7_iface
,
4562 Centers
, Radii
, NumSpheres
, Flags
, ReturnValues
);
4565 /*****************************************************************************
4566 * IDirect3DDevice7::GetTexture
4568 * Returns the texture interface handle assigned to a texture stage.
4569 * The returned texture is AddRefed. This is taken from old ddraw,
4570 * not checked in Windows.
4575 * Stage: Texture stage to read the texture from
4576 * Texture: Address to store the interface pointer at
4580 * DDERR_INVALIDPARAMS if Texture is NULL
4581 * For details, see IWineD3DDevice::GetTexture
4583 *****************************************************************************/
4585 IDirect3DDeviceImpl_7_GetTexture(IDirect3DDevice7
*iface
,
4587 IDirectDrawSurface7
**Texture
)
4589 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
4590 struct wined3d_texture
*wined3d_texture
;
4593 TRACE("iface %p, stage %u, texture %p.\n", iface
, Stage
, Texture
);
4597 TRACE("Texture == NULL, failing with DDERR_INVALIDPARAMS\n");
4598 return DDERR_INVALIDPARAMS
;
4601 wined3d_mutex_lock();
4602 hr
= wined3d_device_get_texture(This
->wined3d_device
, Stage
, &wined3d_texture
);
4603 if (FAILED(hr
) || !wined3d_texture
)
4606 wined3d_mutex_unlock();
4610 *Texture
= wined3d_texture_get_parent(wined3d_texture
);
4611 IDirectDrawSurface7_AddRef(*Texture
);
4612 wined3d_texture_decref(wined3d_texture
);
4613 wined3d_mutex_unlock();
4618 static HRESULT WINAPI
4619 IDirect3DDeviceImpl_7_GetTexture_FPUSetup(IDirect3DDevice7
*iface
,
4621 IDirectDrawSurface7
**Texture
)
4623 return IDirect3DDeviceImpl_7_GetTexture(iface
, Stage
, Texture
);
4626 static HRESULT WINAPI
4627 IDirect3DDeviceImpl_7_GetTexture_FPUPreserve(IDirect3DDevice7
*iface
,
4629 IDirectDrawSurface7
**Texture
)
4634 old_fpucw
= d3d_fpu_setup();
4635 hr
= IDirect3DDeviceImpl_7_GetTexture(iface
, Stage
, Texture
);
4636 set_fpu_control_word(old_fpucw
);
4641 static HRESULT WINAPI
IDirect3DDeviceImpl_3_GetTexture(IDirect3DDevice3
*iface
, DWORD Stage
,
4642 IDirect3DTexture2
**Texture2
)
4644 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
4646 IDirectDrawSurface7
*ret_val
;
4647 IDirectDrawSurfaceImpl
*ret_val_impl
;
4649 TRACE("iface %p, stage %u, texture %p.\n", iface
, Stage
, Texture2
);
4651 ret
= IDirect3DDevice7_GetTexture(&This
->IDirect3DDevice7_iface
, Stage
, &ret_val
);
4653 ret_val_impl
= unsafe_impl_from_IDirectDrawSurface7(ret_val
);
4654 *Texture2
= ret_val_impl
? &ret_val_impl
->IDirect3DTexture2_iface
: NULL
;
4656 TRACE("Returning texture %p.\n", *Texture2
);
4661 /*****************************************************************************
4662 * IDirect3DDevice7::SetTexture
4664 * Assigns a texture to a texture stage. Is the texture AddRef-ed?
4669 * Stage: The stage to assign the texture to
4670 * Texture: Interface pointer to the texture surface
4674 * For details, see IWineD3DDevice::SetTexture
4676 *****************************************************************************/
4678 IDirect3DDeviceImpl_7_SetTexture(IDirect3DDevice7
*iface
,
4680 IDirectDrawSurface7
*Texture
)
4682 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
4683 IDirectDrawSurfaceImpl
*surf
= unsafe_impl_from_IDirectDrawSurface7(Texture
);
4686 TRACE("iface %p, stage %u, texture %p.\n", iface
, Stage
, Texture
);
4688 /* Texture may be NULL here */
4689 wined3d_mutex_lock();
4690 hr
= wined3d_device_set_texture(This
->wined3d_device
,
4691 Stage
, surf
? surf
->wined3d_texture
: NULL
);
4692 wined3d_mutex_unlock();
4697 static HRESULT WINAPI
4698 IDirect3DDeviceImpl_7_SetTexture_FPUSetup(IDirect3DDevice7
*iface
,
4700 IDirectDrawSurface7
*Texture
)
4702 return IDirect3DDeviceImpl_7_SetTexture(iface
, Stage
, Texture
);
4705 static HRESULT WINAPI
4706 IDirect3DDeviceImpl_7_SetTexture_FPUPreserve(IDirect3DDevice7
*iface
,
4708 IDirectDrawSurface7
*Texture
)
4713 old_fpucw
= d3d_fpu_setup();
4714 hr
= IDirect3DDeviceImpl_7_SetTexture(iface
, Stage
, Texture
);
4715 set_fpu_control_word(old_fpucw
);
4720 static HRESULT WINAPI
4721 IDirect3DDeviceImpl_3_SetTexture(IDirect3DDevice3
*iface
,
4723 IDirect3DTexture2
*Texture2
)
4725 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
4726 IDirectDrawSurfaceImpl
*tex
= unsafe_impl_from_IDirect3DTexture2(Texture2
);
4730 TRACE("iface %p, stage %u, texture %p.\n", iface
, Stage
, Texture2
);
4732 wined3d_mutex_lock();
4734 if (This
->legacyTextureBlending
)
4735 IDirect3DDevice3_GetRenderState(iface
, D3DRENDERSTATE_TEXTUREMAPBLEND
, &texmapblend
);
4737 hr
= IDirect3DDevice7_SetTexture(&This
->IDirect3DDevice7_iface
, Stage
, &tex
->IDirectDrawSurface7_iface
);
4739 if (This
->legacyTextureBlending
&& texmapblend
== D3DTBLEND_MODULATE
)
4741 /* This fixup is required by the way D3DTBLEND_MODULATE maps to texture stage states.
4742 See IDirect3DDeviceImpl_3_SetRenderState for details. */
4743 struct wined3d_texture
*tex
= NULL
;
4744 BOOL tex_alpha
= FALSE
;
4745 DDPIXELFORMAT ddfmt
;
4748 result
= wined3d_device_get_texture(This
->wined3d_device
, 0, &tex
);
4749 if (result
== WINED3D_OK
&& tex
)
4751 struct wined3d_resource
*sub_resource
;
4753 if ((sub_resource
= wined3d_texture_get_sub_resource(tex
, 0)))
4755 struct wined3d_resource_desc desc
;
4757 wined3d_resource_get_desc(sub_resource
, &desc
);
4758 ddfmt
.dwSize
= sizeof(ddfmt
);
4759 PixelFormat_WineD3DtoDD(&ddfmt
, desc
.format
);
4760 if (ddfmt
.u5
.dwRGBAlphaBitMask
) tex_alpha
= TRUE
;
4763 wined3d_texture_decref(tex
);
4766 /* Arg 1/2 are already set to WINED3DTA_TEXTURE/WINED3DTA_CURRENT in case of D3DTBLEND_MODULATE */
4768 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
4769 0, WINED3D_TSS_ALPHA_OP
, WINED3DTOP_SELECTARG1
);
4771 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
4772 0, WINED3D_TSS_ALPHA_OP
, WINED3DTOP_SELECTARG2
);
4775 wined3d_mutex_unlock();
4780 static const struct tss_lookup
4783 enum wined3d_texture_stage_state state
;
4787 {FALSE
, WINED3D_TSS_INVALID
}, /* 0, unused */
4788 {FALSE
, WINED3D_TSS_COLOR_OP
}, /* 1, D3DTSS_COLOROP */
4789 {FALSE
, WINED3D_TSS_COLOR_ARG1
}, /* 2, D3DTSS_COLORARG1 */
4790 {FALSE
, WINED3D_TSS_COLOR_ARG2
}, /* 3, D3DTSS_COLORARG2 */
4791 {FALSE
, WINED3D_TSS_ALPHA_OP
}, /* 4, D3DTSS_ALPHAOP */
4792 {FALSE
, WINED3D_TSS_ALPHA_ARG1
}, /* 5, D3DTSS_ALPHAARG1 */
4793 {FALSE
, WINED3D_TSS_ALPHA_ARG2
}, /* 6, D3DTSS_ALPHAARG2 */
4794 {FALSE
, WINED3D_TSS_BUMPENV_MAT00
}, /* 7, D3DTSS_BUMPENVMAT00 */
4795 {FALSE
, WINED3D_TSS_BUMPENV_MAT01
}, /* 8, D3DTSS_BUMPENVMAT01 */
4796 {FALSE
, WINED3D_TSS_BUMPENV_MAT10
}, /* 9, D3DTSS_BUMPENVMAT10 */
4797 {FALSE
, WINED3D_TSS_BUMPENV_MAT11
}, /* 10, D3DTSS_BUMPENVMAT11 */
4798 {FALSE
, WINED3D_TSS_TEXCOORD_INDEX
}, /* 11, D3DTSS_TEXCOORDINDEX */
4799 {TRUE
, WINED3D_SAMP_ADDRESS_U
}, /* 12, D3DTSS_ADDRESS */
4800 {TRUE
, WINED3D_SAMP_ADDRESS_U
}, /* 13, D3DTSS_ADDRESSU */
4801 {TRUE
, WINED3D_SAMP_ADDRESS_V
}, /* 14, D3DTSS_ADDRESSV */
4802 {TRUE
, WINED3D_SAMP_BORDER_COLOR
}, /* 15, D3DTSS_BORDERCOLOR */
4803 {TRUE
, WINED3D_SAMP_MAG_FILTER
}, /* 16, D3DTSS_MAGFILTER */
4804 {TRUE
, WINED3D_SAMP_MIN_FILTER
}, /* 17, D3DTSS_MINFILTER */
4805 {TRUE
, WINED3D_SAMP_MIP_FILTER
}, /* 18, D3DTSS_MIPFILTER */
4806 {TRUE
, WINED3D_SAMP_MIPMAP_LOD_BIAS
}, /* 19, D3DTSS_MIPMAPLODBIAS */
4807 {TRUE
, WINED3D_SAMP_MAX_MIP_LEVEL
}, /* 20, D3DTSS_MAXMIPLEVEL */
4808 {TRUE
, WINED3D_SAMP_MAX_ANISOTROPY
}, /* 21, D3DTSS_MAXANISOTROPY */
4809 {FALSE
, WINED3D_TSS_BUMPENV_LSCALE
}, /* 22, D3DTSS_BUMPENVLSCALE */
4810 {FALSE
, WINED3D_TSS_BUMPENV_LOFFSET
}, /* 23, D3DTSS_BUMPENVLOFFSET */
4811 {FALSE
, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS
}, /* 24, D3DTSS_TEXTURETRANSFORMFLAGS */
4814 /*****************************************************************************
4815 * IDirect3DDevice7::GetTextureStageState
4817 * Retrieves a state from a texture stage.
4822 * Stage: The stage to retrieve the state from
4823 * TexStageStateType: The state type to retrieve
4824 * State: Address to store the state's value at
4828 * DDERR_INVALIDPARAMS if State is NULL
4829 * For details, see IWineD3DDevice::GetTextureStageState
4831 *****************************************************************************/
4833 IDirect3DDeviceImpl_7_GetTextureStageState(IDirect3DDevice7
*iface
,
4835 D3DTEXTURESTAGESTATETYPE TexStageStateType
,
4838 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
4840 const struct tss_lookup
*l
;
4842 TRACE("iface %p, stage %u, state %#x, value %p.\n",
4843 iface
, Stage
, TexStageStateType
, State
);
4846 return DDERR_INVALIDPARAMS
;
4848 if (TexStageStateType
> D3DTSS_TEXTURETRANSFORMFLAGS
)
4850 WARN("Invalid TexStageStateType %#x passed.\n", TexStageStateType
);
4854 l
= &tss_lookup
[TexStageStateType
];
4856 wined3d_mutex_lock();
4858 if (l
->sampler_state
)
4860 hr
= wined3d_device_get_sampler_state(This
->wined3d_device
, Stage
, l
->state
, State
);
4862 switch(TexStageStateType
)
4864 /* Mipfilter is a sampler state with different values */
4865 case D3DTSS_MIPFILTER
:
4869 case WINED3DTEXF_NONE
: *State
= D3DTFP_NONE
; break;
4870 case WINED3DTEXF_POINT
: *State
= D3DTFP_POINT
; break;
4871 case WINED3DTEXF_LINEAR
: *State
= D3DTFP_LINEAR
; break;
4873 ERR("Unexpected mipfilter value %#x\n", *State
);
4874 *State
= D3DTFP_NONE
;
4880 /* Magfilter has slightly different values */
4881 case D3DTSS_MAGFILTER
:
4885 case WINED3DTEXF_POINT
: *State
= D3DTFG_POINT
; break;
4886 case WINED3DTEXF_LINEAR
: *State
= D3DTFG_LINEAR
; break;
4887 case WINED3DTEXF_ANISOTROPIC
: *State
= D3DTFG_ANISOTROPIC
; break;
4888 case WINED3DTEXF_FLATCUBIC
: *State
= D3DTFG_FLATCUBIC
; break;
4889 case WINED3DTEXF_GAUSSIANCUBIC
: *State
= D3DTFG_GAUSSIANCUBIC
; break;
4891 ERR("Unexpected wined3d mag filter value %#x\n", *State
);
4892 *State
= D3DTFG_POINT
;
4904 hr
= wined3d_device_get_texture_stage_state(This
->wined3d_device
, Stage
, l
->state
, State
);
4907 wined3d_mutex_unlock();
4912 static HRESULT WINAPI
4913 IDirect3DDeviceImpl_7_GetTextureStageState_FPUSetup(IDirect3DDevice7
*iface
,
4915 D3DTEXTURESTAGESTATETYPE TexStageStateType
,
4918 return IDirect3DDeviceImpl_7_GetTextureStageState(iface
, Stage
, TexStageStateType
, State
);
4921 static HRESULT WINAPI
4922 IDirect3DDeviceImpl_7_GetTextureStageState_FPUPreserve(IDirect3DDevice7
*iface
,
4924 D3DTEXTURESTAGESTATETYPE TexStageStateType
,
4930 old_fpucw
= d3d_fpu_setup();
4931 hr
= IDirect3DDeviceImpl_7_GetTextureStageState(iface
, Stage
, TexStageStateType
, State
);
4932 set_fpu_control_word(old_fpucw
);
4937 static HRESULT WINAPI
IDirect3DDeviceImpl_3_GetTextureStageState(IDirect3DDevice3
*iface
,
4938 DWORD Stage
, D3DTEXTURESTAGESTATETYPE TexStageStateType
, DWORD
*State
)
4940 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
4942 TRACE("iface %p, stage %u, state %#x, value %p.\n",
4943 iface
, Stage
, TexStageStateType
, State
);
4945 return IDirect3DDevice7_GetTextureStageState(&This
->IDirect3DDevice7_iface
,
4946 Stage
, TexStageStateType
, State
);
4949 /*****************************************************************************
4950 * IDirect3DDevice7::SetTextureStageState
4952 * Sets a texture stage state. Some stage types need to be handled specially,
4953 * because they do not exist in WineD3D and were moved to another place
4958 * Stage: The stage to modify
4959 * TexStageStateType: The state to change
4960 * State: The new value for the state
4964 * For details, see IWineD3DDevice::SetTextureStageState
4966 *****************************************************************************/
4968 IDirect3DDeviceImpl_7_SetTextureStageState(IDirect3DDevice7
*iface
,
4970 D3DTEXTURESTAGESTATETYPE TexStageStateType
,
4973 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
4974 const struct tss_lookup
*l
;
4977 TRACE("iface %p, stage %u, state %#x, value %#x.\n",
4978 iface
, Stage
, TexStageStateType
, State
);
4980 if (TexStageStateType
> D3DTSS_TEXTURETRANSFORMFLAGS
)
4982 WARN("Invalid TexStageStateType %#x passed.\n", TexStageStateType
);
4986 l
= &tss_lookup
[TexStageStateType
];
4988 wined3d_mutex_lock();
4990 if (l
->sampler_state
)
4992 switch(TexStageStateType
)
4994 /* Mipfilter is a sampler state with different values */
4995 case D3DTSS_MIPFILTER
:
4999 case D3DTFP_NONE
: State
= WINED3DTEXF_NONE
; break;
5000 case D3DTFP_POINT
: State
= WINED3DTEXF_POINT
; break;
5001 case 0: /* Unchecked */
5002 case D3DTFP_LINEAR
: State
= WINED3DTEXF_LINEAR
; break;
5004 ERR("Unexpected mipfilter value %d\n", State
);
5005 State
= WINED3DTEXF_NONE
;
5011 /* Magfilter has slightly different values */
5012 case D3DTSS_MAGFILTER
:
5016 case D3DTFG_POINT
: State
= WINED3DTEXF_POINT
; break;
5017 case D3DTFG_LINEAR
: State
= WINED3DTEXF_LINEAR
; break;
5018 case D3DTFG_FLATCUBIC
: State
= WINED3DTEXF_FLATCUBIC
; break;
5019 case D3DTFG_GAUSSIANCUBIC
: State
= WINED3DTEXF_GAUSSIANCUBIC
; break;
5020 case D3DTFG_ANISOTROPIC
: State
= WINED3DTEXF_ANISOTROPIC
; break;
5022 ERR("Unexpected d3d7 mag filter type %d\n", State
);
5023 State
= WINED3DTEXF_POINT
;
5029 case D3DTSS_ADDRESS
:
5030 wined3d_device_set_sampler_state(This
->wined3d_device
, Stage
, WINED3D_SAMP_ADDRESS_V
, State
);
5037 hr
= wined3d_device_set_sampler_state(This
->wined3d_device
, Stage
, l
->state
, State
);
5041 hr
= wined3d_device_set_texture_stage_state(This
->wined3d_device
, Stage
, l
->state
, State
);
5044 wined3d_mutex_unlock();
5049 static HRESULT WINAPI
5050 IDirect3DDeviceImpl_7_SetTextureStageState_FPUSetup(IDirect3DDevice7
*iface
,
5052 D3DTEXTURESTAGESTATETYPE TexStageStateType
,
5055 return IDirect3DDeviceImpl_7_SetTextureStageState(iface
, Stage
, TexStageStateType
, State
);
5058 static HRESULT WINAPI
5059 IDirect3DDeviceImpl_7_SetTextureStageState_FPUPreserve(IDirect3DDevice7
*iface
,
5061 D3DTEXTURESTAGESTATETYPE TexStageStateType
,
5067 old_fpucw
= d3d_fpu_setup();
5068 hr
= IDirect3DDeviceImpl_7_SetTextureStageState(iface
, Stage
, TexStageStateType
, State
);
5069 set_fpu_control_word(old_fpucw
);
5074 static HRESULT WINAPI
IDirect3DDeviceImpl_3_SetTextureStageState(IDirect3DDevice3
*iface
,
5075 DWORD Stage
, D3DTEXTURESTAGESTATETYPE TexStageStateType
, DWORD State
)
5077 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
5079 TRACE("iface %p, stage %u, state %#x, value %#x.\n",
5080 iface
, Stage
, TexStageStateType
, State
);
5082 return IDirect3DDevice7_SetTextureStageState(&This
->IDirect3DDevice7_iface
,
5083 Stage
, TexStageStateType
, State
);
5086 /*****************************************************************************
5087 * IDirect3DDevice7::ValidateDevice
5089 * SDK: "Reports the device's ability to render the currently set
5090 * texture-blending operations in a single pass". Whatever that means
5096 * NumPasses: Address to write the number of necessary passes for the
5097 * desired effect to.
5101 * See IWineD3DDevice::ValidateDevice for more details
5103 *****************************************************************************/
5105 IDirect3DDeviceImpl_7_ValidateDevice(IDirect3DDevice7
*iface
,
5108 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
5111 TRACE("iface %p, pass_count %p.\n", iface
, NumPasses
);
5113 wined3d_mutex_lock();
5114 hr
= wined3d_device_validate_device(This
->wined3d_device
, NumPasses
);
5115 wined3d_mutex_unlock();
5120 static HRESULT WINAPI
5121 IDirect3DDeviceImpl_7_ValidateDevice_FPUSetup(IDirect3DDevice7
*iface
,
5124 return IDirect3DDeviceImpl_7_ValidateDevice(iface
, NumPasses
);
5127 static HRESULT WINAPI
5128 IDirect3DDeviceImpl_7_ValidateDevice_FPUPreserve(IDirect3DDevice7
*iface
,
5134 old_fpucw
= d3d_fpu_setup();
5135 hr
= IDirect3DDeviceImpl_7_ValidateDevice(iface
, NumPasses
);
5136 set_fpu_control_word(old_fpucw
);
5141 static HRESULT WINAPI
IDirect3DDeviceImpl_3_ValidateDevice(IDirect3DDevice3
*iface
, DWORD
*Passes
)
5143 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
5145 TRACE("iface %p, pass_count %p.\n", iface
, Passes
);
5147 return IDirect3DDevice7_ValidateDevice(&This
->IDirect3DDevice7_iface
, Passes
);
5150 /*****************************************************************************
5151 * IDirect3DDevice7::Clear
5153 * Fills the render target, the z buffer and the stencil buffer with a
5154 * clear color / value
5159 * Count: Number of rectangles in Rects must be 0 if Rects is NULL
5160 * Rects: Rectangles to clear. If NULL, the whole surface is cleared
5161 * Flags: Some flags, as usual
5162 * Color: Clear color for the render target
5163 * Z: Clear value for the Z buffer
5164 * Stencil: Clear value to store in each stencil buffer entry
5168 * For details, see IWineD3DDevice::Clear
5170 *****************************************************************************/
5171 static HRESULT
IDirect3DDeviceImpl_7_Clear(IDirect3DDevice7
*iface
, DWORD count
,
5172 D3DRECT
*rects
, DWORD flags
, D3DCOLOR color
, D3DVALUE z
, DWORD stencil
)
5174 const struct wined3d_color c
=
5176 ((color
>> 16) & 0xff) / 255.0f
,
5177 ((color
>> 8) & 0xff) / 255.0f
,
5178 (color
& 0xff) / 255.0f
,
5179 ((color
>> 24) & 0xff) / 255.0f
,
5181 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
5184 TRACE("iface %p, count %u, rects %p, flags %#x, color 0x%08x, z %.8e, stencil %#x.\n",
5185 iface
, count
, rects
, flags
, color
, z
, stencil
);
5187 wined3d_mutex_lock();
5188 hr
= wined3d_device_clear(This
->wined3d_device
, count
, (RECT
*)rects
, flags
, &c
, z
, stencil
);
5189 wined3d_mutex_unlock();
5194 static HRESULT WINAPI
5195 IDirect3DDeviceImpl_7_Clear_FPUSetup(IDirect3DDevice7
*iface
,
5203 return IDirect3DDeviceImpl_7_Clear(iface
, Count
, Rects
, Flags
, Color
, Z
, Stencil
);
5206 static HRESULT WINAPI
5207 IDirect3DDeviceImpl_7_Clear_FPUPreserve(IDirect3DDevice7
*iface
,
5218 old_fpucw
= d3d_fpu_setup();
5219 hr
= IDirect3DDeviceImpl_7_Clear(iface
, Count
, Rects
, Flags
, Color
, Z
, Stencil
);
5220 set_fpu_control_word(old_fpucw
);
5225 /*****************************************************************************
5226 * IDirect3DDevice7::SetViewport
5228 * Sets the current viewport.
5230 * Version 7 only, but IDirect3DViewport uses this call for older
5234 * Data: The new viewport to set
5238 * DDERR_INVALIDPARAMS if Data is NULL
5239 * For more details, see IWineDDDevice::SetViewport
5241 *****************************************************************************/
5243 IDirect3DDeviceImpl_7_SetViewport(IDirect3DDevice7
*iface
,
5246 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
5249 TRACE("iface %p, viewport %p.\n", iface
, Data
);
5252 return DDERR_INVALIDPARAMS
;
5254 /* Note: D3DVIEWPORT7 is compatible with struct wined3d_viewport. */
5255 wined3d_mutex_lock();
5256 hr
= wined3d_device_set_viewport(This
->wined3d_device
, (struct wined3d_viewport
*)Data
);
5257 wined3d_mutex_unlock();
5262 static HRESULT WINAPI
5263 IDirect3DDeviceImpl_7_SetViewport_FPUSetup(IDirect3DDevice7
*iface
,
5266 return IDirect3DDeviceImpl_7_SetViewport(iface
, Data
);
5269 static HRESULT WINAPI
5270 IDirect3DDeviceImpl_7_SetViewport_FPUPreserve(IDirect3DDevice7
*iface
,
5276 old_fpucw
= d3d_fpu_setup();
5277 hr
= IDirect3DDeviceImpl_7_SetViewport(iface
, Data
);
5278 set_fpu_control_word(old_fpucw
);
5283 /*****************************************************************************
5284 * IDirect3DDevice::GetViewport
5286 * Returns the current viewport
5291 * Data: D3D7Viewport structure to write the viewport information to
5295 * DDERR_INVALIDPARAMS if Data is NULL
5296 * For more details, see IWineD3DDevice::GetViewport
5298 *****************************************************************************/
5300 IDirect3DDeviceImpl_7_GetViewport(IDirect3DDevice7
*iface
,
5303 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
5306 TRACE("iface %p, viewport %p.\n", iface
, Data
);
5309 return DDERR_INVALIDPARAMS
;
5311 /* Note: D3DVIEWPORT7 is compatible with struct wined3d_viewport. */
5312 wined3d_mutex_lock();
5313 hr
= wined3d_device_get_viewport(This
->wined3d_device
, (struct wined3d_viewport
*)Data
);
5314 wined3d_mutex_unlock();
5316 return hr_ddraw_from_wined3d(hr
);
5319 static HRESULT WINAPI
5320 IDirect3DDeviceImpl_7_GetViewport_FPUSetup(IDirect3DDevice7
*iface
,
5323 return IDirect3DDeviceImpl_7_GetViewport(iface
, Data
);
5326 static HRESULT WINAPI
5327 IDirect3DDeviceImpl_7_GetViewport_FPUPreserve(IDirect3DDevice7
*iface
,
5333 old_fpucw
= d3d_fpu_setup();
5334 hr
= IDirect3DDeviceImpl_7_GetViewport(iface
, Data
);
5335 set_fpu_control_word(old_fpucw
);
5340 /*****************************************************************************
5341 * IDirect3DDevice7::SetMaterial
5348 * Mat: The material to set
5352 * DDERR_INVALIDPARAMS if Mat is NULL.
5353 * For more details, see IWineD3DDevice::SetMaterial
5355 *****************************************************************************/
5357 IDirect3DDeviceImpl_7_SetMaterial(IDirect3DDevice7
*iface
,
5360 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
5363 TRACE("iface %p, material %p.\n", iface
, Mat
);
5365 if (!Mat
) return DDERR_INVALIDPARAMS
;
5367 wined3d_mutex_lock();
5368 /* Note: D3DMATERIAL7 is compatible with struct wined3d_material. */
5369 hr
= wined3d_device_set_material(This
->wined3d_device
, (struct wined3d_material
*)Mat
);
5370 wined3d_mutex_unlock();
5372 return hr_ddraw_from_wined3d(hr
);
5375 static HRESULT WINAPI
5376 IDirect3DDeviceImpl_7_SetMaterial_FPUSetup(IDirect3DDevice7
*iface
,
5379 return IDirect3DDeviceImpl_7_SetMaterial(iface
, Mat
);
5382 static HRESULT WINAPI
5383 IDirect3DDeviceImpl_7_SetMaterial_FPUPreserve(IDirect3DDevice7
*iface
,
5389 old_fpucw
= d3d_fpu_setup();
5390 hr
= IDirect3DDeviceImpl_7_SetMaterial(iface
, Mat
);
5391 set_fpu_control_word(old_fpucw
);
5396 /*****************************************************************************
5397 * IDirect3DDevice7::GetMaterial
5399 * Returns the current material
5404 * Mat: D3DMATERIAL7 structure to write the material parameters to
5408 * DDERR_INVALIDPARAMS if Mat is NULL
5409 * For more details, see IWineD3DDevice::GetMaterial
5411 *****************************************************************************/
5413 IDirect3DDeviceImpl_7_GetMaterial(IDirect3DDevice7
*iface
,
5416 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
5419 TRACE("iface %p, material %p.\n", iface
, Mat
);
5421 wined3d_mutex_lock();
5422 /* Note: D3DMATERIAL7 is compatible with struct wined3d_material. */
5423 hr
= wined3d_device_get_material(This
->wined3d_device
, (struct wined3d_material
*)Mat
);
5424 wined3d_mutex_unlock();
5426 return hr_ddraw_from_wined3d(hr
);
5429 static HRESULT WINAPI
5430 IDirect3DDeviceImpl_7_GetMaterial_FPUSetup(IDirect3DDevice7
*iface
,
5433 return IDirect3DDeviceImpl_7_GetMaterial(iface
, Mat
);
5436 static HRESULT WINAPI
5437 IDirect3DDeviceImpl_7_GetMaterial_FPUPreserve(IDirect3DDevice7
*iface
,
5443 old_fpucw
= d3d_fpu_setup();
5444 hr
= IDirect3DDeviceImpl_7_GetMaterial(iface
, Mat
);
5445 set_fpu_control_word(old_fpucw
);
5450 /*****************************************************************************
5451 * IDirect3DDevice7::SetLight
5453 * Assigns a light to a light index, but doesn't activate it yet.
5455 * Version 7, IDirect3DLight uses this method for older versions
5458 * LightIndex: The index of the new light
5459 * Light: A D3DLIGHT7 structure describing the light
5463 * For more details, see IWineD3DDevice::SetLight
5465 *****************************************************************************/
5467 IDirect3DDeviceImpl_7_SetLight(IDirect3DDevice7
*iface
,
5471 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
5474 TRACE("iface %p, light_idx %u, light %p.\n", iface
, LightIndex
, Light
);
5476 wined3d_mutex_lock();
5477 /* Note: D3DLIGHT7 is compatible with struct wined3d_light. */
5478 hr
= wined3d_device_set_light(This
->wined3d_device
, LightIndex
, (struct wined3d_light
*)Light
);
5479 wined3d_mutex_unlock();
5481 return hr_ddraw_from_wined3d(hr
);
5484 static HRESULT WINAPI
5485 IDirect3DDeviceImpl_7_SetLight_FPUSetup(IDirect3DDevice7
*iface
,
5489 return IDirect3DDeviceImpl_7_SetLight(iface
, LightIndex
, Light
);
5492 static HRESULT WINAPI
5493 IDirect3DDeviceImpl_7_SetLight_FPUPreserve(IDirect3DDevice7
*iface
,
5500 old_fpucw
= d3d_fpu_setup();
5501 hr
= IDirect3DDeviceImpl_7_SetLight(iface
, LightIndex
, Light
);
5502 set_fpu_control_word(old_fpucw
);
5507 /*****************************************************************************
5508 * IDirect3DDevice7::GetLight
5510 * Returns the light assigned to a light index
5513 * Light: Structure to write the light information to
5517 * DDERR_INVALIDPARAMS if Light is NULL
5518 * For details, see IWineD3DDevice::GetLight
5520 *****************************************************************************/
5522 IDirect3DDeviceImpl_7_GetLight(IDirect3DDevice7
*iface
,
5526 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
5529 TRACE("iface %p, light_idx %u, light %p.\n", iface
, LightIndex
, Light
);
5531 wined3d_mutex_lock();
5532 /* Note: D3DLIGHT7 is compatible with struct wined3d_light. */
5533 rc
= wined3d_device_get_light(This
->wined3d_device
, LightIndex
, (struct wined3d_light
*)Light
);
5534 wined3d_mutex_unlock();
5536 /* Translate the result. WineD3D returns other values than D3D7 */
5537 return hr_ddraw_from_wined3d(rc
);
5540 static HRESULT WINAPI
5541 IDirect3DDeviceImpl_7_GetLight_FPUSetup(IDirect3DDevice7
*iface
,
5545 return IDirect3DDeviceImpl_7_GetLight(iface
, LightIndex
, Light
);
5548 static HRESULT WINAPI
5549 IDirect3DDeviceImpl_7_GetLight_FPUPreserve(IDirect3DDevice7
*iface
,
5556 old_fpucw
= d3d_fpu_setup();
5557 hr
= IDirect3DDeviceImpl_7_GetLight(iface
, LightIndex
, Light
);
5558 set_fpu_control_word(old_fpucw
);
5563 /*****************************************************************************
5564 * IDirect3DDevice7::BeginStateBlock
5566 * Begins recording to a stateblock
5572 * For details see IWineD3DDevice::BeginStateBlock
5574 *****************************************************************************/
5576 IDirect3DDeviceImpl_7_BeginStateBlock(IDirect3DDevice7
*iface
)
5578 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
5581 TRACE("iface %p.\n", iface
);
5583 wined3d_mutex_lock();
5584 hr
= wined3d_device_begin_stateblock(This
->wined3d_device
);
5585 wined3d_mutex_unlock();
5587 return hr_ddraw_from_wined3d(hr
);
5590 static HRESULT WINAPI
5591 IDirect3DDeviceImpl_7_BeginStateBlock_FPUSetup(IDirect3DDevice7
*iface
)
5593 return IDirect3DDeviceImpl_7_BeginStateBlock(iface
);
5596 static HRESULT WINAPI
5597 IDirect3DDeviceImpl_7_BeginStateBlock_FPUPreserve(IDirect3DDevice7
*iface
)
5602 old_fpucw
= d3d_fpu_setup();
5603 hr
= IDirect3DDeviceImpl_7_BeginStateBlock(iface
);
5604 set_fpu_control_word(old_fpucw
);
5609 /*****************************************************************************
5610 * IDirect3DDevice7::EndStateBlock
5612 * Stops recording to a state block and returns the created stateblock
5618 * BlockHandle: Address to store the stateblock's handle to
5622 * DDERR_INVALIDPARAMS if BlockHandle is NULL
5623 * See IWineD3DDevice::EndStateBlock for more details
5625 *****************************************************************************/
5627 IDirect3DDeviceImpl_7_EndStateBlock(IDirect3DDevice7
*iface
,
5630 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
5631 struct wined3d_stateblock
*wined3d_sb
;
5635 TRACE("iface %p, stateblock %p.\n", iface
, BlockHandle
);
5639 WARN("BlockHandle == NULL, returning DDERR_INVALIDPARAMS\n");
5640 return DDERR_INVALIDPARAMS
;
5643 wined3d_mutex_lock();
5645 hr
= wined3d_device_end_stateblock(This
->wined3d_device
, &wined3d_sb
);
5648 WARN("Failed to end stateblock, hr %#x.\n", hr
);
5649 wined3d_mutex_unlock();
5651 return hr_ddraw_from_wined3d(hr
);
5654 h
= ddraw_allocate_handle(&This
->handle_table
, wined3d_sb
, DDRAW_HANDLE_STATEBLOCK
);
5655 if (h
== DDRAW_INVALID_HANDLE
)
5657 ERR("Failed to allocate a stateblock handle.\n");
5658 wined3d_stateblock_decref(wined3d_sb
);
5659 wined3d_mutex_unlock();
5661 return DDERR_OUTOFMEMORY
;
5664 wined3d_mutex_unlock();
5665 *BlockHandle
= h
+ 1;
5667 return hr_ddraw_from_wined3d(hr
);
5670 static HRESULT WINAPI
5671 IDirect3DDeviceImpl_7_EndStateBlock_FPUSetup(IDirect3DDevice7
*iface
,
5674 return IDirect3DDeviceImpl_7_EndStateBlock(iface
, BlockHandle
);
5677 static HRESULT WINAPI
5678 IDirect3DDeviceImpl_7_EndStateBlock_FPUPreserve(IDirect3DDevice7
*iface
,
5684 old_fpucw
= d3d_fpu_setup();
5685 hr
= IDirect3DDeviceImpl_7_EndStateBlock(iface
, BlockHandle
);
5686 set_fpu_control_word(old_fpucw
);
5691 /*****************************************************************************
5692 * IDirect3DDevice7::PreLoad
5694 * Allows the app to signal that a texture will be used soon, to allow
5695 * the Direct3DDevice to load it to the video card in the meantime.
5700 * Texture: The texture to preload
5704 * DDERR_INVALIDPARAMS if Texture is NULL
5705 * See IWineD3DSurface::PreLoad for details
5707 *****************************************************************************/
5709 IDirect3DDeviceImpl_7_PreLoad(IDirect3DDevice7
*iface
,
5710 IDirectDrawSurface7
*Texture
)
5712 IDirectDrawSurfaceImpl
*surf
= unsafe_impl_from_IDirectDrawSurface7(Texture
);
5714 TRACE("iface %p, texture %p.\n", iface
, Texture
);
5717 return DDERR_INVALIDPARAMS
;
5719 wined3d_mutex_lock();
5720 wined3d_surface_preload(surf
->wined3d_surface
);
5721 wined3d_mutex_unlock();
5726 static HRESULT WINAPI
5727 IDirect3DDeviceImpl_7_PreLoad_FPUSetup(IDirect3DDevice7
*iface
,
5728 IDirectDrawSurface7
*Texture
)
5730 return IDirect3DDeviceImpl_7_PreLoad(iface
, Texture
);
5733 static HRESULT WINAPI
5734 IDirect3DDeviceImpl_7_PreLoad_FPUPreserve(IDirect3DDevice7
*iface
,
5735 IDirectDrawSurface7
*Texture
)
5740 old_fpucw
= d3d_fpu_setup();
5741 hr
= IDirect3DDeviceImpl_7_PreLoad(iface
, Texture
);
5742 set_fpu_control_word(old_fpucw
);
5747 /*****************************************************************************
5748 * IDirect3DDevice7::ApplyStateBlock
5750 * Activates the state stored in a state block handle.
5753 * BlockHandle: The stateblock handle to activate
5757 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is NULL
5759 *****************************************************************************/
5761 IDirect3DDeviceImpl_7_ApplyStateBlock(IDirect3DDevice7
*iface
,
5764 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
5765 struct wined3d_stateblock
*wined3d_sb
;
5768 TRACE("iface %p, stateblock %#x.\n", iface
, BlockHandle
);
5770 wined3d_mutex_lock();
5771 wined3d_sb
= ddraw_get_object(&This
->handle_table
, BlockHandle
- 1, DDRAW_HANDLE_STATEBLOCK
);
5774 WARN("Invalid stateblock handle.\n");
5775 wined3d_mutex_unlock();
5776 return D3DERR_INVALIDSTATEBLOCK
;
5779 hr
= wined3d_stateblock_apply(wined3d_sb
);
5780 wined3d_mutex_unlock();
5782 return hr_ddraw_from_wined3d(hr
);
5785 static HRESULT WINAPI
5786 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUSetup(IDirect3DDevice7
*iface
,
5789 return IDirect3DDeviceImpl_7_ApplyStateBlock(iface
, BlockHandle
);
5792 static HRESULT WINAPI
5793 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUPreserve(IDirect3DDevice7
*iface
,
5799 old_fpucw
= d3d_fpu_setup();
5800 hr
= IDirect3DDeviceImpl_7_ApplyStateBlock(iface
, BlockHandle
);
5801 set_fpu_control_word(old_fpucw
);
5806 /*****************************************************************************
5807 * IDirect3DDevice7::CaptureStateBlock
5809 * Updates a stateblock's values to the values currently set for the device
5814 * BlockHandle: Stateblock to update
5818 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is NULL
5819 * See IWineD3DDevice::CaptureStateBlock for more details
5821 *****************************************************************************/
5823 IDirect3DDeviceImpl_7_CaptureStateBlock(IDirect3DDevice7
*iface
,
5826 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
5827 struct wined3d_stateblock
*wined3d_sb
;
5830 TRACE("iface %p, stateblock %#x.\n", iface
, BlockHandle
);
5832 wined3d_mutex_lock();
5833 wined3d_sb
= ddraw_get_object(&This
->handle_table
, BlockHandle
- 1, DDRAW_HANDLE_STATEBLOCK
);
5836 WARN("Invalid stateblock handle.\n");
5837 wined3d_mutex_unlock();
5838 return D3DERR_INVALIDSTATEBLOCK
;
5841 hr
= wined3d_stateblock_capture(wined3d_sb
);
5842 wined3d_mutex_unlock();
5844 return hr_ddraw_from_wined3d(hr
);
5847 static HRESULT WINAPI
5848 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUSetup(IDirect3DDevice7
*iface
,
5851 return IDirect3DDeviceImpl_7_CaptureStateBlock(iface
, BlockHandle
);
5854 static HRESULT WINAPI
5855 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUPreserve(IDirect3DDevice7
*iface
,
5861 old_fpucw
= d3d_fpu_setup();
5862 hr
= IDirect3DDeviceImpl_7_CaptureStateBlock(iface
, BlockHandle
);
5863 set_fpu_control_word(old_fpucw
);
5868 /*****************************************************************************
5869 * IDirect3DDevice7::DeleteStateBlock
5871 * Deletes a stateblock handle. This means releasing the WineD3DStateBlock
5876 * BlockHandle: Stateblock handle to delete
5880 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is 0
5882 *****************************************************************************/
5884 IDirect3DDeviceImpl_7_DeleteStateBlock(IDirect3DDevice7
*iface
,
5887 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
5888 struct wined3d_stateblock
*wined3d_sb
;
5891 TRACE("iface %p, stateblock %#x.\n", iface
, BlockHandle
);
5893 wined3d_mutex_lock();
5895 wined3d_sb
= ddraw_free_handle(&This
->handle_table
, BlockHandle
- 1, DDRAW_HANDLE_STATEBLOCK
);
5898 WARN("Invalid stateblock handle.\n");
5899 wined3d_mutex_unlock();
5900 return D3DERR_INVALIDSTATEBLOCK
;
5903 if ((ref
= wined3d_stateblock_decref(wined3d_sb
)))
5905 ERR("Something is still holding stateblock %p (refcount %u).\n", wined3d_sb
, ref
);
5908 wined3d_mutex_unlock();
5913 static HRESULT WINAPI
5914 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUSetup(IDirect3DDevice7
*iface
,
5917 return IDirect3DDeviceImpl_7_DeleteStateBlock(iface
, BlockHandle
);
5920 static HRESULT WINAPI
5921 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUPreserve(IDirect3DDevice7
*iface
,
5927 old_fpucw
= d3d_fpu_setup();
5928 hr
= IDirect3DDeviceImpl_7_DeleteStateBlock(iface
, BlockHandle
);
5929 set_fpu_control_word(old_fpucw
);
5934 /*****************************************************************************
5935 * IDirect3DDevice7::CreateStateBlock
5937 * Creates a new state block handle.
5942 * Type: The state block type
5943 * BlockHandle: Address to write the created handle to
5947 * DDERR_INVALIDPARAMS if BlockHandle is NULL
5949 *****************************************************************************/
5951 IDirect3DDeviceImpl_7_CreateStateBlock(IDirect3DDevice7
*iface
,
5952 D3DSTATEBLOCKTYPE Type
,
5955 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
5956 struct wined3d_stateblock
*wined3d_sb
;
5960 TRACE("iface %p, type %#x, stateblock %p.\n", iface
, Type
, BlockHandle
);
5964 WARN("BlockHandle == NULL, returning DDERR_INVALIDPARAMS\n");
5965 return DDERR_INVALIDPARAMS
;
5967 if(Type
!= D3DSBT_ALL
&& Type
!= D3DSBT_PIXELSTATE
&&
5968 Type
!= D3DSBT_VERTEXSTATE
) {
5969 WARN("Unexpected stateblock type, returning DDERR_INVALIDPARAMS\n");
5970 return DDERR_INVALIDPARAMS
;
5973 wined3d_mutex_lock();
5975 /* The D3DSTATEBLOCKTYPE enum is fine here. */
5976 hr
= wined3d_stateblock_create(This
->wined3d_device
, Type
, &wined3d_sb
);
5979 WARN("Failed to create stateblock, hr %#x.\n", hr
);
5980 wined3d_mutex_unlock();
5981 return hr_ddraw_from_wined3d(hr
);
5984 h
= ddraw_allocate_handle(&This
->handle_table
, wined3d_sb
, DDRAW_HANDLE_STATEBLOCK
);
5985 if (h
== DDRAW_INVALID_HANDLE
)
5987 ERR("Failed to allocate stateblock handle.\n");
5988 wined3d_stateblock_decref(wined3d_sb
);
5989 wined3d_mutex_unlock();
5990 return DDERR_OUTOFMEMORY
;
5993 *BlockHandle
= h
+ 1;
5994 wined3d_mutex_unlock();
5996 return hr_ddraw_from_wined3d(hr
);
5999 static HRESULT WINAPI
6000 IDirect3DDeviceImpl_7_CreateStateBlock_FPUSetup(IDirect3DDevice7
*iface
,
6001 D3DSTATEBLOCKTYPE Type
,
6004 return IDirect3DDeviceImpl_7_CreateStateBlock(iface
, Type
, BlockHandle
);
6007 static HRESULT WINAPI
6008 IDirect3DDeviceImpl_7_CreateStateBlock_FPUPreserve(IDirect3DDevice7
*iface
,
6009 D3DSTATEBLOCKTYPE Type
,
6015 old_fpucw
= d3d_fpu_setup();
6016 hr
=IDirect3DDeviceImpl_7_CreateStateBlock(iface
, Type
, BlockHandle
);
6017 set_fpu_control_word(old_fpucw
);
6022 /* Helper function for IDirect3DDeviceImpl_7_Load. */
6023 static BOOL
is_mip_level_subset(IDirectDrawSurfaceImpl
*dest
,
6024 IDirectDrawSurfaceImpl
*src
)
6026 IDirectDrawSurfaceImpl
*src_level
, *dest_level
;
6027 IDirectDrawSurface7
*temp
;
6028 DDSURFACEDESC2 ddsd
;
6029 BOOL levelFound
; /* at least one suitable sublevel in dest found */
6031 /* To satisfy "destination is mip level subset of source" criteria (regular texture counts as 1 level),
6032 * 1) there must be at least one mip level in destination that matched dimensions of some mip level in source and
6033 * 2) there must be no destination levels that don't match any levels in source. Otherwise it's INVALIDPARAMS.
6040 for (;src_level
&& dest_level
;)
6042 if (src_level
->surface_desc
.dwWidth
== dest_level
->surface_desc
.dwWidth
&&
6043 src_level
->surface_desc
.dwHeight
== dest_level
->surface_desc
.dwHeight
)
6047 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
6048 ddsd
.ddsCaps
.dwCaps2
= DDSCAPS2_MIPMAPSUBLEVEL
;
6049 IDirectDrawSurface7_GetAttachedSurface(&dest_level
->IDirectDrawSurface7_iface
, &ddsd
.ddsCaps
, &temp
);
6051 if (dest_level
!= dest
) IDirectDrawSurface7_Release(&dest_level
->IDirectDrawSurface7_iface
);
6053 dest_level
= unsafe_impl_from_IDirectDrawSurface7(temp
);
6056 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
6057 ddsd
.ddsCaps
.dwCaps2
= DDSCAPS2_MIPMAPSUBLEVEL
;
6058 IDirectDrawSurface7_GetAttachedSurface(&src_level
->IDirectDrawSurface7_iface
, &ddsd
.ddsCaps
, &temp
);
6060 if (src_level
!= src
) IDirectDrawSurface7_Release(&src_level
->IDirectDrawSurface7_iface
);
6062 src_level
= unsafe_impl_from_IDirectDrawSurface7(temp
);
6065 if (src_level
&& src_level
!= src
) IDirectDrawSurface7_Release(&src_level
->IDirectDrawSurface7_iface
);
6066 if (dest_level
&& dest_level
!= dest
) IDirectDrawSurface7_Release(&dest_level
->IDirectDrawSurface7_iface
);
6068 return !dest_level
&& levelFound
;
6071 /* Helper function for IDirect3DDeviceImpl_7_Load. */
6072 static void copy_mipmap_chain(IDirect3DDeviceImpl
*device
,
6073 IDirectDrawSurfaceImpl
*dest
,
6074 IDirectDrawSurfaceImpl
*src
,
6075 const POINT
*DestPoint
,
6076 const RECT
*SrcRect
)
6078 IDirectDrawSurfaceImpl
*src_level
, *dest_level
;
6079 IDirectDrawSurface7
*temp
;
6080 DDSURFACEDESC2 ddsd
;
6084 IDirectDrawPalette
*pal
= NULL
, *pal_src
= NULL
;
6088 /* Copy palette, if possible. */
6089 IDirectDrawSurface7_GetPalette(&src
->IDirectDrawSurface7_iface
, &pal_src
);
6090 IDirectDrawSurface7_GetPalette(&dest
->IDirectDrawSurface7_iface
, &pal
);
6092 if (pal_src
!= NULL
&& pal
!= NULL
)
6094 PALETTEENTRY palent
[256];
6096 IDirectDrawPalette_GetEntries(pal_src
, 0, 0, 256, palent
);
6097 IDirectDrawPalette_SetEntries(pal
, 0, 0, 256, palent
);
6100 if (pal
) IDirectDrawPalette_Release(pal
);
6101 if (pal_src
) IDirectDrawPalette_Release(pal_src
);
6103 /* Copy colorkeys, if present. */
6104 for (ckeyflag
= DDCKEY_DESTBLT
; ckeyflag
<= DDCKEY_SRCOVERLAY
; ckeyflag
<<= 1)
6106 hr
= IDirectDrawSurface7_GetColorKey(&src
->IDirectDrawSurface7_iface
, ckeyflag
, &ddckey
);
6110 IDirectDrawSurface7_SetColorKey(&dest
->IDirectDrawSurface7_iface
, ckeyflag
, &ddckey
);
6118 src_rect
= *SrcRect
;
6120 for (;src_level
&& dest_level
;)
6122 if (src_level
->surface_desc
.dwWidth
== dest_level
->surface_desc
.dwWidth
&&
6123 src_level
->surface_desc
.dwHeight
== dest_level
->surface_desc
.dwHeight
)
6125 UINT src_w
= src_rect
.right
- src_rect
.left
;
6126 UINT src_h
= src_rect
.bottom
- src_rect
.top
;
6127 RECT dst_rect
= {point
.x
, point
.y
, point
.x
+ src_w
, point
.y
+ src_h
};
6129 if (FAILED(hr
= wined3d_surface_blt(dest_level
->wined3d_surface
, &dst_rect
,
6130 src_level
->wined3d_surface
, &src_rect
, 0, NULL
, WINED3DTEXF_POINT
)))
6131 ERR("Blit failed, hr %#x.\n", hr
);
6133 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
6134 ddsd
.ddsCaps
.dwCaps2
= DDSCAPS2_MIPMAPSUBLEVEL
;
6135 IDirectDrawSurface7_GetAttachedSurface(&dest_level
->IDirectDrawSurface7_iface
, &ddsd
.ddsCaps
, &temp
);
6137 if (dest_level
!= dest
) IDirectDrawSurface7_Release(&dest_level
->IDirectDrawSurface7_iface
);
6139 dest_level
= unsafe_impl_from_IDirectDrawSurface7(temp
);
6142 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
6143 ddsd
.ddsCaps
.dwCaps2
= DDSCAPS2_MIPMAPSUBLEVEL
;
6144 IDirectDrawSurface7_GetAttachedSurface(&src_level
->IDirectDrawSurface7_iface
, &ddsd
.ddsCaps
, &temp
);
6146 if (src_level
!= src
) IDirectDrawSurface7_Release(&src_level
->IDirectDrawSurface7_iface
);
6148 src_level
= unsafe_impl_from_IDirectDrawSurface7(temp
);
6155 src_rect
.right
= (src_rect
.right
+ 1) / 2;
6156 src_rect
.bottom
= (src_rect
.bottom
+ 1) / 2;
6159 if (src_level
&& src_level
!= src
) IDirectDrawSurface7_Release(&src_level
->IDirectDrawSurface7_iface
);
6160 if (dest_level
&& dest_level
!= dest
) IDirectDrawSurface7_Release(&dest_level
->IDirectDrawSurface7_iface
);
6163 /*****************************************************************************
6164 * IDirect3DDevice7::Load
6166 * Loads a rectangular area from the source into the destination texture.
6167 * It can also copy the source to the faces of a cubic environment map
6172 * DestTex: Destination texture
6173 * DestPoint: Point in the destination where the source image should be
6175 * SrcTex: Source texture
6176 * SrcRect: Source rectangle
6177 * Flags: Cubemap faces to load (DDSCAPS2_CUBEMAP_ALLFACES, DDSCAPS2_CUBEMAP_POSITIVEX,
6178 * DDSCAPS2_CUBEMAP_NEGATIVEX, DDSCAPS2_CUBEMAP_POSITIVEY, DDSCAPS2_CUBEMAP_NEGATIVEY,
6179 * DDSCAPS2_CUBEMAP_POSITIVEZ, DDSCAPS2_CUBEMAP_NEGATIVEZ)
6183 * DDERR_INVALIDPARAMS if DestTex or SrcTex are NULL, broken coordinates or anything unexpected.
6186 *****************************************************************************/
6189 IDirect3DDeviceImpl_7_Load(IDirect3DDevice7
*iface
,
6190 IDirectDrawSurface7
*DestTex
,
6192 IDirectDrawSurface7
*SrcTex
,
6196 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
6197 IDirectDrawSurfaceImpl
*dest
= unsafe_impl_from_IDirectDrawSurface7(DestTex
);
6198 IDirectDrawSurfaceImpl
*src
= unsafe_impl_from_IDirectDrawSurface7(SrcTex
);
6202 TRACE("iface %p, dst_texture %p, dst_pos %s, src_texture %p, src_rect %s, flags %#x.\n",
6203 iface
, DestTex
, wine_dbgstr_point(DestPoint
), SrcTex
, wine_dbgstr_rect(SrcRect
), Flags
);
6205 if( (!src
) || (!dest
) )
6206 return DDERR_INVALIDPARAMS
;
6208 wined3d_mutex_lock();
6210 if (SrcRect
) srcrect
= *SrcRect
;
6213 srcrect
.left
= srcrect
.top
= 0;
6214 srcrect
.right
= src
->surface_desc
.dwWidth
;
6215 srcrect
.bottom
= src
->surface_desc
.dwHeight
;
6218 if (DestPoint
) destpoint
= *DestPoint
;
6221 destpoint
.x
= destpoint
.y
= 0;
6223 /* Check bad dimensions. DestPoint is validated against src, not dest, because
6224 * destination can be a subset of mip levels, in which case actual coordinates used
6225 * for it may be divided. If any dimension of dest is larger than source, it can't be
6226 * mip level subset, so an error can be returned early.
6228 if (srcrect
.left
>= srcrect
.right
|| srcrect
.top
>= srcrect
.bottom
||
6229 srcrect
.right
> src
->surface_desc
.dwWidth
||
6230 srcrect
.bottom
> src
->surface_desc
.dwHeight
||
6231 destpoint
.x
+ srcrect
.right
- srcrect
.left
> src
->surface_desc
.dwWidth
||
6232 destpoint
.y
+ srcrect
.bottom
- srcrect
.top
> src
->surface_desc
.dwHeight
||
6233 dest
->surface_desc
.dwWidth
> src
->surface_desc
.dwWidth
||
6234 dest
->surface_desc
.dwHeight
> src
->surface_desc
.dwHeight
)
6236 wined3d_mutex_unlock();
6237 return DDERR_INVALIDPARAMS
;
6240 /* Must be top level surfaces. */
6241 if (src
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_MIPMAPSUBLEVEL
||
6242 dest
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_MIPMAPSUBLEVEL
)
6244 wined3d_mutex_unlock();
6245 return DDERR_INVALIDPARAMS
;
6248 if (src
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_CUBEMAP
)
6250 DWORD src_face_flag
, dest_face_flag
;
6251 IDirectDrawSurfaceImpl
*src_face
, *dest_face
;
6252 IDirectDrawSurface7
*temp
;
6253 DDSURFACEDESC2 ddsd
;
6256 if (!(dest
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_CUBEMAP
))
6258 wined3d_mutex_unlock();
6259 return DDERR_INVALIDPARAMS
;
6262 /* Iterate through cube faces 2 times. First time is just to check INVALIDPARAMS conditions, second
6263 * time it's actual surface loading. */
6264 for (i
= 0; i
< 2; i
++)
6269 for (;dest_face
&& src_face
;)
6271 src_face_flag
= src_face
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_CUBEMAP_ALLFACES
;
6272 dest_face_flag
= dest_face
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_CUBEMAP_ALLFACES
;
6274 if (src_face_flag
== dest_face_flag
)
6278 /* Destination mip levels must be subset of source mip levels. */
6279 if (!is_mip_level_subset(dest_face
, src_face
))
6281 wined3d_mutex_unlock();
6282 return DDERR_INVALIDPARAMS
;
6285 else if (Flags
& dest_face_flag
)
6287 copy_mipmap_chain(This
, dest_face
, src_face
, &destpoint
, &srcrect
);
6290 if (src_face_flag
< DDSCAPS2_CUBEMAP_NEGATIVEZ
)
6292 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
6293 ddsd
.ddsCaps
.dwCaps2
= DDSCAPS2_CUBEMAP
| (src_face_flag
<< 1);
6294 IDirectDrawSurface7_GetAttachedSurface(&src
->IDirectDrawSurface7_iface
, &ddsd
.ddsCaps
, &temp
);
6296 if (src_face
!= src
) IDirectDrawSurface7_Release(&src_face
->IDirectDrawSurface7_iface
);
6298 src_face
= unsafe_impl_from_IDirectDrawSurface7(temp
);
6302 if (src_face
!= src
) IDirectDrawSurface7_Release(&src_face
->IDirectDrawSurface7_iface
);
6308 if (dest_face_flag
< DDSCAPS2_CUBEMAP_NEGATIVEZ
)
6310 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
6311 ddsd
.ddsCaps
.dwCaps2
= DDSCAPS2_CUBEMAP
| (dest_face_flag
<< 1);
6312 IDirectDrawSurface7_GetAttachedSurface(&dest
->IDirectDrawSurface7_iface
, &ddsd
.ddsCaps
, &temp
);
6314 if (dest_face
!= dest
) IDirectDrawSurface7_Release(&dest_face
->IDirectDrawSurface7_iface
);
6316 dest_face
= unsafe_impl_from_IDirectDrawSurface7(temp
);
6320 if (dest_face
!= dest
) IDirectDrawSurface7_Release(&dest_face
->IDirectDrawSurface7_iface
);
6328 /* Native returns error if src faces are not subset of dest faces. */
6331 wined3d_mutex_unlock();
6332 return DDERR_INVALIDPARAMS
;
6337 wined3d_mutex_unlock();
6340 else if (dest
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_CUBEMAP
)
6342 wined3d_mutex_unlock();
6343 return DDERR_INVALIDPARAMS
;
6346 /* Handle non cube map textures. */
6348 /* Destination mip levels must be subset of source mip levels. */
6349 if (!is_mip_level_subset(dest
, src
))
6351 wined3d_mutex_unlock();
6352 return DDERR_INVALIDPARAMS
;
6355 copy_mipmap_chain(This
, dest
, src
, &destpoint
, &srcrect
);
6357 wined3d_mutex_unlock();
6362 static HRESULT WINAPI
6363 IDirect3DDeviceImpl_7_Load_FPUSetup(IDirect3DDevice7
*iface
,
6364 IDirectDrawSurface7
*DestTex
,
6366 IDirectDrawSurface7
*SrcTex
,
6370 return IDirect3DDeviceImpl_7_Load(iface
, DestTex
, DestPoint
, SrcTex
, SrcRect
, Flags
);
6373 static HRESULT WINAPI
6374 IDirect3DDeviceImpl_7_Load_FPUPreserve(IDirect3DDevice7
*iface
,
6375 IDirectDrawSurface7
*DestTex
,
6377 IDirectDrawSurface7
*SrcTex
,
6384 old_fpucw
= d3d_fpu_setup();
6385 hr
= IDirect3DDeviceImpl_7_Load(iface
, DestTex
, DestPoint
, SrcTex
, SrcRect
, Flags
);
6386 set_fpu_control_word(old_fpucw
);
6391 /*****************************************************************************
6392 * IDirect3DDevice7::LightEnable
6394 * Enables or disables a light
6396 * Version 7, IDirect3DLight uses this method too.
6399 * LightIndex: The index of the light to enable / disable
6400 * Enable: Enable or disable the light
6404 * For more details, see IWineD3DDevice::SetLightEnable
6406 *****************************************************************************/
6408 IDirect3DDeviceImpl_7_LightEnable(IDirect3DDevice7
*iface
,
6412 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
6415 TRACE("iface %p, light_idx %u, enabled %#x.\n", iface
, LightIndex
, Enable
);
6417 wined3d_mutex_lock();
6418 hr
= wined3d_device_set_light_enable(This
->wined3d_device
, LightIndex
, Enable
);
6419 wined3d_mutex_unlock();
6421 return hr_ddraw_from_wined3d(hr
);
6424 static HRESULT WINAPI
6425 IDirect3DDeviceImpl_7_LightEnable_FPUSetup(IDirect3DDevice7
*iface
,
6429 return IDirect3DDeviceImpl_7_LightEnable(iface
, LightIndex
, Enable
);
6432 static HRESULT WINAPI
6433 IDirect3DDeviceImpl_7_LightEnable_FPUPreserve(IDirect3DDevice7
*iface
,
6440 old_fpucw
= d3d_fpu_setup();
6441 hr
= IDirect3DDeviceImpl_7_LightEnable(iface
, LightIndex
, Enable
);
6442 set_fpu_control_word(old_fpucw
);
6447 /*****************************************************************************
6448 * IDirect3DDevice7::GetLightEnable
6450 * Retrieves if the light with the given index is enabled or not
6455 * LightIndex: Index of desired light
6456 * Enable: Pointer to a BOOL which contains the result
6460 * DDERR_INVALIDPARAMS if Enable is NULL
6461 * See IWineD3DDevice::GetLightEnable for more details
6463 *****************************************************************************/
6465 IDirect3DDeviceImpl_7_GetLightEnable(IDirect3DDevice7
*iface
,
6469 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
6472 TRACE("iface %p, light_idx %u, enabled %p.\n", iface
, LightIndex
, Enable
);
6475 return DDERR_INVALIDPARAMS
;
6477 wined3d_mutex_lock();
6478 hr
= wined3d_device_get_light_enable(This
->wined3d_device
, LightIndex
, Enable
);
6479 wined3d_mutex_unlock();
6481 return hr_ddraw_from_wined3d(hr
);
6484 static HRESULT WINAPI
6485 IDirect3DDeviceImpl_7_GetLightEnable_FPUSetup(IDirect3DDevice7
*iface
,
6489 return IDirect3DDeviceImpl_7_GetLightEnable(iface
, LightIndex
, Enable
);
6492 static HRESULT WINAPI
6493 IDirect3DDeviceImpl_7_GetLightEnable_FPUPreserve(IDirect3DDevice7
*iface
,
6500 old_fpucw
= d3d_fpu_setup();
6501 hr
= IDirect3DDeviceImpl_7_GetLightEnable(iface
, LightIndex
, Enable
);
6502 set_fpu_control_word(old_fpucw
);
6507 /*****************************************************************************
6508 * IDirect3DDevice7::SetClipPlane
6510 * Sets custom clipping plane
6515 * Index: The index of the clipping plane
6516 * PlaneEquation: An equation defining the clipping plane
6520 * DDERR_INVALIDPARAMS if PlaneEquation is NULL
6521 * See IWineD3DDevice::SetClipPlane for more details
6523 *****************************************************************************/
6525 IDirect3DDeviceImpl_7_SetClipPlane(IDirect3DDevice7
*iface
,
6527 D3DVALUE
* PlaneEquation
)
6529 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
6532 TRACE("iface %p, idx %u, plane %p.\n", iface
, Index
, PlaneEquation
);
6535 return DDERR_INVALIDPARAMS
;
6537 wined3d_mutex_lock();
6538 hr
= wined3d_device_set_clip_plane(This
->wined3d_device
, Index
, PlaneEquation
);
6539 wined3d_mutex_unlock();
6544 static HRESULT WINAPI
6545 IDirect3DDeviceImpl_7_SetClipPlane_FPUSetup(IDirect3DDevice7
*iface
,
6547 D3DVALUE
* PlaneEquation
)
6549 return IDirect3DDeviceImpl_7_SetClipPlane(iface
, Index
, PlaneEquation
);
6552 static HRESULT WINAPI
6553 IDirect3DDeviceImpl_7_SetClipPlane_FPUPreserve(IDirect3DDevice7
*iface
,
6555 D3DVALUE
* PlaneEquation
)
6560 old_fpucw
= d3d_fpu_setup();
6561 hr
= IDirect3DDeviceImpl_7_SetClipPlane(iface
, Index
, PlaneEquation
);
6562 set_fpu_control_word(old_fpucw
);
6567 /*****************************************************************************
6568 * IDirect3DDevice7::GetClipPlane
6570 * Returns the clipping plane with a specific index
6573 * Index: The index of the desired plane
6574 * PlaneEquation: Address to store the plane equation to
6578 * DDERR_INVALIDPARAMS if PlaneEquation is NULL
6579 * See IWineD3DDevice::GetClipPlane for more details
6581 *****************************************************************************/
6583 IDirect3DDeviceImpl_7_GetClipPlane(IDirect3DDevice7
*iface
,
6585 D3DVALUE
* PlaneEquation
)
6587 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
6590 TRACE("iface %p, idx %u, plane %p.\n", iface
, Index
, PlaneEquation
);
6593 return DDERR_INVALIDPARAMS
;
6595 wined3d_mutex_lock();
6596 hr
= wined3d_device_get_clip_plane(This
->wined3d_device
, Index
, PlaneEquation
);
6597 wined3d_mutex_unlock();
6602 static HRESULT WINAPI
6603 IDirect3DDeviceImpl_7_GetClipPlane_FPUSetup(IDirect3DDevice7
*iface
,
6605 D3DVALUE
* PlaneEquation
)
6607 return IDirect3DDeviceImpl_7_GetClipPlane(iface
, Index
, PlaneEquation
);
6610 static HRESULT WINAPI
6611 IDirect3DDeviceImpl_7_GetClipPlane_FPUPreserve(IDirect3DDevice7
*iface
,
6613 D3DVALUE
* PlaneEquation
)
6618 old_fpucw
= d3d_fpu_setup();
6619 hr
= IDirect3DDeviceImpl_7_GetClipPlane(iface
, Index
, PlaneEquation
);
6620 set_fpu_control_word(old_fpucw
);
6625 /*****************************************************************************
6626 * IDirect3DDevice7::GetInfo
6628 * Retrieves some information about the device. The DirectX sdk says that
6629 * this version returns S_FALSE for all retail builds of DirectX, that's what
6630 * this implementation does.
6633 * DevInfoID: Information type requested
6634 * DevInfoStruct: Pointer to a structure to store the info to
6635 * Size: Size of the structure
6638 * S_FALSE, because it's a non-debug driver
6640 *****************************************************************************/
6641 static HRESULT WINAPI
6642 IDirect3DDeviceImpl_7_GetInfo(IDirect3DDevice7
*iface
,
6644 void *DevInfoStruct
,
6647 TRACE("iface %p, info_id %#x, info %p, info_size %u.\n",
6648 iface
, DevInfoID
, DevInfoStruct
, Size
);
6650 if (TRACE_ON(ddraw
))
6652 TRACE(" info requested : ");
6655 case D3DDEVINFOID_TEXTUREMANAGER
: TRACE("D3DDEVINFOID_TEXTUREMANAGER\n"); break;
6656 case D3DDEVINFOID_D3DTEXTUREMANAGER
: TRACE("D3DDEVINFOID_D3DTEXTUREMANAGER\n"); break;
6657 case D3DDEVINFOID_TEXTURING
: TRACE("D3DDEVINFOID_TEXTURING\n"); break;
6658 default: ERR(" invalid flag !!!\n"); return DDERR_INVALIDPARAMS
;
6662 return S_FALSE
; /* According to MSDN, this is valid for a non-debug driver */
6665 /* For performance optimization, devices created in FPUSETUP and FPUPRESERVE modes
6666 * have separate vtables. Simple functions where this doesn't matter like GetDirect3D
6667 * are not duplicated.
6669 * Device created with DDSCL_FPUSETUP (d3d7 default) - device methods assume that FPU
6670 * has already been setup for optimal d3d operation.
6672 * Device created with DDSCL_FPUPRESERVE - resets and restores FPU mode when necessary in
6673 * d3d calls (FPU may be in a mode non-suitable for d3d when the app calls d3d). Required
6674 * by Sacrifice (game). */
6675 static const struct IDirect3DDevice7Vtbl d3d_device7_fpu_setup_vtbl
=
6677 /*** IUnknown Methods ***/
6678 IDirect3DDeviceImpl_7_QueryInterface
,
6679 IDirect3DDeviceImpl_7_AddRef
,
6680 IDirect3DDeviceImpl_7_Release
,
6681 /*** IDirect3DDevice7 ***/
6682 IDirect3DDeviceImpl_7_GetCaps_FPUSetup
,
6683 IDirect3DDeviceImpl_7_EnumTextureFormats_FPUSetup
,
6684 IDirect3DDeviceImpl_7_BeginScene_FPUSetup
,
6685 IDirect3DDeviceImpl_7_EndScene_FPUSetup
,
6686 IDirect3DDeviceImpl_7_GetDirect3D
,
6687 IDirect3DDeviceImpl_7_SetRenderTarget_FPUSetup
,
6688 IDirect3DDeviceImpl_7_GetRenderTarget
,
6689 IDirect3DDeviceImpl_7_Clear_FPUSetup
,
6690 IDirect3DDeviceImpl_7_SetTransform_FPUSetup
,
6691 IDirect3DDeviceImpl_7_GetTransform_FPUSetup
,
6692 IDirect3DDeviceImpl_7_SetViewport_FPUSetup
,
6693 IDirect3DDeviceImpl_7_MultiplyTransform_FPUSetup
,
6694 IDirect3DDeviceImpl_7_GetViewport_FPUSetup
,
6695 IDirect3DDeviceImpl_7_SetMaterial_FPUSetup
,
6696 IDirect3DDeviceImpl_7_GetMaterial_FPUSetup
,
6697 IDirect3DDeviceImpl_7_SetLight_FPUSetup
,
6698 IDirect3DDeviceImpl_7_GetLight_FPUSetup
,
6699 IDirect3DDeviceImpl_7_SetRenderState_FPUSetup
,
6700 IDirect3DDeviceImpl_7_GetRenderState_FPUSetup
,
6701 IDirect3DDeviceImpl_7_BeginStateBlock_FPUSetup
,
6702 IDirect3DDeviceImpl_7_EndStateBlock_FPUSetup
,
6703 IDirect3DDeviceImpl_7_PreLoad_FPUSetup
,
6704 IDirect3DDeviceImpl_7_DrawPrimitive_FPUSetup
,
6705 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUSetup
,
6706 IDirect3DDeviceImpl_7_SetClipStatus
,
6707 IDirect3DDeviceImpl_7_GetClipStatus
,
6708 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUSetup
,
6709 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUSetup
,
6710 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUSetup
,
6711 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUSetup
,
6712 IDirect3DDeviceImpl_7_ComputeSphereVisibility
,
6713 IDirect3DDeviceImpl_7_GetTexture_FPUSetup
,
6714 IDirect3DDeviceImpl_7_SetTexture_FPUSetup
,
6715 IDirect3DDeviceImpl_7_GetTextureStageState_FPUSetup
,
6716 IDirect3DDeviceImpl_7_SetTextureStageState_FPUSetup
,
6717 IDirect3DDeviceImpl_7_ValidateDevice_FPUSetup
,
6718 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUSetup
,
6719 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUSetup
,
6720 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUSetup
,
6721 IDirect3DDeviceImpl_7_CreateStateBlock_FPUSetup
,
6722 IDirect3DDeviceImpl_7_Load_FPUSetup
,
6723 IDirect3DDeviceImpl_7_LightEnable_FPUSetup
,
6724 IDirect3DDeviceImpl_7_GetLightEnable_FPUSetup
,
6725 IDirect3DDeviceImpl_7_SetClipPlane_FPUSetup
,
6726 IDirect3DDeviceImpl_7_GetClipPlane_FPUSetup
,
6727 IDirect3DDeviceImpl_7_GetInfo
6730 static const struct IDirect3DDevice7Vtbl d3d_device7_fpu_preserve_vtbl
=
6732 /*** IUnknown Methods ***/
6733 IDirect3DDeviceImpl_7_QueryInterface
,
6734 IDirect3DDeviceImpl_7_AddRef
,
6735 IDirect3DDeviceImpl_7_Release
,
6736 /*** IDirect3DDevice7 ***/
6737 IDirect3DDeviceImpl_7_GetCaps_FPUPreserve
,
6738 IDirect3DDeviceImpl_7_EnumTextureFormats_FPUPreserve
,
6739 IDirect3DDeviceImpl_7_BeginScene_FPUPreserve
,
6740 IDirect3DDeviceImpl_7_EndScene_FPUPreserve
,
6741 IDirect3DDeviceImpl_7_GetDirect3D
,
6742 IDirect3DDeviceImpl_7_SetRenderTarget_FPUPreserve
,
6743 IDirect3DDeviceImpl_7_GetRenderTarget
,
6744 IDirect3DDeviceImpl_7_Clear_FPUPreserve
,
6745 IDirect3DDeviceImpl_7_SetTransform_FPUPreserve
,
6746 IDirect3DDeviceImpl_7_GetTransform_FPUPreserve
,
6747 IDirect3DDeviceImpl_7_SetViewport_FPUPreserve
,
6748 IDirect3DDeviceImpl_7_MultiplyTransform_FPUPreserve
,
6749 IDirect3DDeviceImpl_7_GetViewport_FPUPreserve
,
6750 IDirect3DDeviceImpl_7_SetMaterial_FPUPreserve
,
6751 IDirect3DDeviceImpl_7_GetMaterial_FPUPreserve
,
6752 IDirect3DDeviceImpl_7_SetLight_FPUPreserve
,
6753 IDirect3DDeviceImpl_7_GetLight_FPUPreserve
,
6754 IDirect3DDeviceImpl_7_SetRenderState_FPUPreserve
,
6755 IDirect3DDeviceImpl_7_GetRenderState_FPUPreserve
,
6756 IDirect3DDeviceImpl_7_BeginStateBlock_FPUPreserve
,
6757 IDirect3DDeviceImpl_7_EndStateBlock_FPUPreserve
,
6758 IDirect3DDeviceImpl_7_PreLoad_FPUPreserve
,
6759 IDirect3DDeviceImpl_7_DrawPrimitive_FPUPreserve
,
6760 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUPreserve
,
6761 IDirect3DDeviceImpl_7_SetClipStatus
,
6762 IDirect3DDeviceImpl_7_GetClipStatus
,
6763 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUPreserve
,
6764 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUPreserve
,
6765 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUPreserve
,
6766 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUPreserve
,
6767 IDirect3DDeviceImpl_7_ComputeSphereVisibility
,
6768 IDirect3DDeviceImpl_7_GetTexture_FPUPreserve
,
6769 IDirect3DDeviceImpl_7_SetTexture_FPUPreserve
,
6770 IDirect3DDeviceImpl_7_GetTextureStageState_FPUPreserve
,
6771 IDirect3DDeviceImpl_7_SetTextureStageState_FPUPreserve
,
6772 IDirect3DDeviceImpl_7_ValidateDevice_FPUPreserve
,
6773 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUPreserve
,
6774 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUPreserve
,
6775 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUPreserve
,
6776 IDirect3DDeviceImpl_7_CreateStateBlock_FPUPreserve
,
6777 IDirect3DDeviceImpl_7_Load_FPUPreserve
,
6778 IDirect3DDeviceImpl_7_LightEnable_FPUPreserve
,
6779 IDirect3DDeviceImpl_7_GetLightEnable_FPUPreserve
,
6780 IDirect3DDeviceImpl_7_SetClipPlane_FPUPreserve
,
6781 IDirect3DDeviceImpl_7_GetClipPlane_FPUPreserve
,
6782 IDirect3DDeviceImpl_7_GetInfo
6785 static const struct IDirect3DDevice3Vtbl d3d_device3_vtbl
=
6787 /*** IUnknown Methods ***/
6788 IDirect3DDeviceImpl_3_QueryInterface
,
6789 IDirect3DDeviceImpl_3_AddRef
,
6790 IDirect3DDeviceImpl_3_Release
,
6791 /*** IDirect3DDevice3 ***/
6792 IDirect3DDeviceImpl_3_GetCaps
,
6793 IDirect3DDeviceImpl_3_GetStats
,
6794 IDirect3DDeviceImpl_3_AddViewport
,
6795 IDirect3DDeviceImpl_3_DeleteViewport
,
6796 IDirect3DDeviceImpl_3_NextViewport
,
6797 IDirect3DDeviceImpl_3_EnumTextureFormats
,
6798 IDirect3DDeviceImpl_3_BeginScene
,
6799 IDirect3DDeviceImpl_3_EndScene
,
6800 IDirect3DDeviceImpl_3_GetDirect3D
,
6801 IDirect3DDeviceImpl_3_SetCurrentViewport
,
6802 IDirect3DDeviceImpl_3_GetCurrentViewport
,
6803 IDirect3DDeviceImpl_3_SetRenderTarget
,
6804 IDirect3DDeviceImpl_3_GetRenderTarget
,
6805 IDirect3DDeviceImpl_3_Begin
,
6806 IDirect3DDeviceImpl_3_BeginIndexed
,
6807 IDirect3DDeviceImpl_3_Vertex
,
6808 IDirect3DDeviceImpl_3_Index
,
6809 IDirect3DDeviceImpl_3_End
,
6810 IDirect3DDeviceImpl_3_GetRenderState
,
6811 IDirect3DDeviceImpl_3_SetRenderState
,
6812 IDirect3DDeviceImpl_3_GetLightState
,
6813 IDirect3DDeviceImpl_3_SetLightState
,
6814 IDirect3DDeviceImpl_3_SetTransform
,
6815 IDirect3DDeviceImpl_3_GetTransform
,
6816 IDirect3DDeviceImpl_3_MultiplyTransform
,
6817 IDirect3DDeviceImpl_3_DrawPrimitive
,
6818 IDirect3DDeviceImpl_3_DrawIndexedPrimitive
,
6819 IDirect3DDeviceImpl_3_SetClipStatus
,
6820 IDirect3DDeviceImpl_3_GetClipStatus
,
6821 IDirect3DDeviceImpl_3_DrawPrimitiveStrided
,
6822 IDirect3DDeviceImpl_3_DrawIndexedPrimitiveStrided
,
6823 IDirect3DDeviceImpl_3_DrawPrimitiveVB
,
6824 IDirect3DDeviceImpl_3_DrawIndexedPrimitiveVB
,
6825 IDirect3DDeviceImpl_3_ComputeSphereVisibility
,
6826 IDirect3DDeviceImpl_3_GetTexture
,
6827 IDirect3DDeviceImpl_3_SetTexture
,
6828 IDirect3DDeviceImpl_3_GetTextureStageState
,
6829 IDirect3DDeviceImpl_3_SetTextureStageState
,
6830 IDirect3DDeviceImpl_3_ValidateDevice
6833 static const struct IDirect3DDevice2Vtbl d3d_device2_vtbl
=
6835 /*** IUnknown Methods ***/
6836 IDirect3DDeviceImpl_2_QueryInterface
,
6837 IDirect3DDeviceImpl_2_AddRef
,
6838 IDirect3DDeviceImpl_2_Release
,
6839 /*** IDirect3DDevice2 ***/
6840 IDirect3DDeviceImpl_2_GetCaps
,
6841 IDirect3DDeviceImpl_2_SwapTextureHandles
,
6842 IDirect3DDeviceImpl_2_GetStats
,
6843 IDirect3DDeviceImpl_2_AddViewport
,
6844 IDirect3DDeviceImpl_2_DeleteViewport
,
6845 IDirect3DDeviceImpl_2_NextViewport
,
6846 IDirect3DDeviceImpl_2_EnumTextureFormats
,
6847 IDirect3DDeviceImpl_2_BeginScene
,
6848 IDirect3DDeviceImpl_2_EndScene
,
6849 IDirect3DDeviceImpl_2_GetDirect3D
,
6850 IDirect3DDeviceImpl_2_SetCurrentViewport
,
6851 IDirect3DDeviceImpl_2_GetCurrentViewport
,
6852 IDirect3DDeviceImpl_2_SetRenderTarget
,
6853 IDirect3DDeviceImpl_2_GetRenderTarget
,
6854 IDirect3DDeviceImpl_2_Begin
,
6855 IDirect3DDeviceImpl_2_BeginIndexed
,
6856 IDirect3DDeviceImpl_2_Vertex
,
6857 IDirect3DDeviceImpl_2_Index
,
6858 IDirect3DDeviceImpl_2_End
,
6859 IDirect3DDeviceImpl_2_GetRenderState
,
6860 IDirect3DDeviceImpl_2_SetRenderState
,
6861 IDirect3DDeviceImpl_2_GetLightState
,
6862 IDirect3DDeviceImpl_2_SetLightState
,
6863 IDirect3DDeviceImpl_2_SetTransform
,
6864 IDirect3DDeviceImpl_2_GetTransform
,
6865 IDirect3DDeviceImpl_2_MultiplyTransform
,
6866 IDirect3DDeviceImpl_2_DrawPrimitive
,
6867 IDirect3DDeviceImpl_2_DrawIndexedPrimitive
,
6868 IDirect3DDeviceImpl_2_SetClipStatus
,
6869 IDirect3DDeviceImpl_2_GetClipStatus
6872 static const struct IDirect3DDeviceVtbl d3d_device1_vtbl
=
6874 /*** IUnknown Methods ***/
6875 IDirect3DDeviceImpl_1_QueryInterface
,
6876 IDirect3DDeviceImpl_1_AddRef
,
6877 IDirect3DDeviceImpl_1_Release
,
6878 /*** IDirect3DDevice1 ***/
6879 IDirect3DDeviceImpl_1_Initialize
,
6880 IDirect3DDeviceImpl_1_GetCaps
,
6881 IDirect3DDeviceImpl_1_SwapTextureHandles
,
6882 IDirect3DDeviceImpl_1_CreateExecuteBuffer
,
6883 IDirect3DDeviceImpl_1_GetStats
,
6884 IDirect3DDeviceImpl_1_Execute
,
6885 IDirect3DDeviceImpl_1_AddViewport
,
6886 IDirect3DDeviceImpl_1_DeleteViewport
,
6887 IDirect3DDeviceImpl_1_NextViewport
,
6888 IDirect3DDeviceImpl_1_Pick
,
6889 IDirect3DDeviceImpl_1_GetPickRecords
,
6890 IDirect3DDeviceImpl_1_EnumTextureFormats
,
6891 IDirect3DDeviceImpl_1_CreateMatrix
,
6892 IDirect3DDeviceImpl_1_SetMatrix
,
6893 IDirect3DDeviceImpl_1_GetMatrix
,
6894 IDirect3DDeviceImpl_1_DeleteMatrix
,
6895 IDirect3DDeviceImpl_1_BeginScene
,
6896 IDirect3DDeviceImpl_1_EndScene
,
6897 IDirect3DDeviceImpl_1_GetDirect3D
6900 IDirect3DDeviceImpl
*unsafe_impl_from_IDirect3DDevice7(IDirect3DDevice7
*iface
)
6902 if (!iface
) return NULL
;
6903 assert((iface
->lpVtbl
== &d3d_device7_fpu_preserve_vtbl
) || (iface
->lpVtbl
== &d3d_device7_fpu_setup_vtbl
));
6904 return CONTAINING_RECORD(iface
, IDirect3DDeviceImpl
, IDirect3DDevice7_iface
);
6907 IDirect3DDeviceImpl
*unsafe_impl_from_IDirect3DDevice3(IDirect3DDevice3
*iface
)
6909 if (!iface
) return NULL
;
6910 assert(iface
->lpVtbl
== &d3d_device3_vtbl
);
6911 return CONTAINING_RECORD(iface
, IDirect3DDeviceImpl
, IDirect3DDevice3_iface
);
6914 IDirect3DDeviceImpl
*unsafe_impl_from_IDirect3DDevice2(IDirect3DDevice2
*iface
)
6916 if (!iface
) return NULL
;
6917 assert(iface
->lpVtbl
== &d3d_device2_vtbl
);
6918 return CONTAINING_RECORD(iface
, IDirect3DDeviceImpl
, IDirect3DDevice2_iface
);
6921 IDirect3DDeviceImpl
*unsafe_impl_from_IDirect3DDevice(IDirect3DDevice
*iface
)
6923 if (!iface
) return NULL
;
6924 assert(iface
->lpVtbl
== &d3d_device1_vtbl
);
6925 return CONTAINING_RECORD(iface
, IDirect3DDeviceImpl
, IDirect3DDevice_iface
);
6928 /*****************************************************************************
6929 * IDirect3DDeviceImpl_UpdateDepthStencil
6931 * Checks the current render target for attached depth stencils and sets the
6932 * WineD3D depth stencil accordingly.
6935 * The depth stencil state to set if creating the device
6937 *****************************************************************************/
6938 enum wined3d_depth_buffer_type
IDirect3DDeviceImpl_UpdateDepthStencil(IDirect3DDeviceImpl
*This
)
6940 IDirectDrawSurface7
*depthStencil
= NULL
;
6941 IDirectDrawSurfaceImpl
*dsi
;
6942 static DDSCAPS2 depthcaps
= { DDSCAPS_ZBUFFER
, 0, 0, 0 };
6944 IDirectDrawSurface7_GetAttachedSurface(&This
->target
->IDirectDrawSurface7_iface
, &depthcaps
, &depthStencil
);
6947 TRACE("Setting wined3d depth stencil to NULL\n");
6948 wined3d_device_set_depth_stencil(This
->wined3d_device
, NULL
);
6949 return WINED3D_ZB_FALSE
;
6952 dsi
= impl_from_IDirectDrawSurface7(depthStencil
);
6953 TRACE("Setting wined3d depth stencil to %p (wined3d %p)\n", dsi
, dsi
->wined3d_surface
);
6954 wined3d_device_set_depth_stencil(This
->wined3d_device
, dsi
->wined3d_surface
);
6956 IDirectDrawSurface7_Release(depthStencil
);
6957 return WINED3D_ZB_TRUE
;
6960 HRESULT
d3d_device_init(IDirect3DDeviceImpl
*device
, IDirectDrawImpl
*ddraw
, IDirectDrawSurfaceImpl
*target
)
6962 static const D3DMATRIX ident
=
6964 1.0f
, 0.0f
, 0.0f
, 0.0f
,
6965 0.0f
, 1.0f
, 0.0f
, 0.0f
,
6966 0.0f
, 0.0f
, 1.0f
, 0.0f
,
6967 0.0f
, 0.0f
, 0.0f
, 1.0f
,
6971 if (ddraw
->cooperative_level
& DDSCL_FPUPRESERVE
)
6972 device
->IDirect3DDevice7_iface
.lpVtbl
= &d3d_device7_fpu_preserve_vtbl
;
6974 device
->IDirect3DDevice7_iface
.lpVtbl
= &d3d_device7_fpu_setup_vtbl
;
6976 device
->IDirect3DDevice3_iface
.lpVtbl
= &d3d_device3_vtbl
;
6977 device
->IDirect3DDevice2_iface
.lpVtbl
= &d3d_device2_vtbl
;
6978 device
->IDirect3DDevice_iface
.lpVtbl
= &d3d_device1_vtbl
;
6980 device
->ddraw
= ddraw
;
6981 device
->target
= target
;
6982 list_init(&device
->viewport_list
);
6984 if (!ddraw_handle_table_init(&device
->handle_table
, 64))
6986 ERR("Failed to initialize handle table.\n");
6987 return DDERR_OUTOFMEMORY
;
6990 device
->legacyTextureBlending
= FALSE
;
6991 device
->legacy_projection
= ident
;
6992 device
->legacy_clipspace
= ident
;
6994 /* Create an index buffer, it's needed for indexed drawing */
6995 hr
= wined3d_buffer_create_ib(ddraw
->wined3d_device
, 0x40000 /* Length. Don't know how long it should be */,
6996 WINED3DUSAGE_DYNAMIC
/* Usage */, WINED3DPOOL_DEFAULT
, NULL
,
6997 &ddraw_null_wined3d_parent_ops
, &device
->indexbuffer
);
7000 ERR("Failed to create an index buffer, hr %#x.\n", hr
);
7001 ddraw_handle_table_destroy(&device
->handle_table
);
7005 /* This is for convenience. */
7006 device
->wined3d_device
= ddraw
->wined3d_device
;
7007 wined3d_device_incref(ddraw
->wined3d_device
);
7009 /* Render to the back buffer */
7010 hr
= wined3d_device_set_render_target(ddraw
->wined3d_device
, 0, target
->wined3d_surface
, TRUE
);
7013 ERR("Failed to set render target, hr %#x.\n", hr
);
7014 wined3d_buffer_decref(device
->indexbuffer
);
7015 ddraw_handle_table_destroy(&device
->handle_table
);
7019 /* FIXME: This is broken. The target AddRef() makes some sense, because
7020 * we store a pointer during initialization, but then that's also where
7021 * the AddRef() should be. We don't store ddraw->d3d_target anywhere. */
7022 /* AddRef the render target. Also AddRef the render target from ddraw,
7023 * because if it is released before the app releases the D3D device, the
7024 * D3D capabilities of wined3d will be uninitialized, which has bad effects.
7026 * In most cases, those surfaces are the same anyway, but this will simply
7027 * add another ref which is released when the device is destroyed. */
7028 IDirectDrawSurface7_AddRef(&target
->IDirectDrawSurface7_iface
);
7030 ddraw
->d3ddevice
= device
;
7032 wined3d_device_set_render_state(ddraw
->wined3d_device
, WINED3D_RS_ZENABLE
,
7033 IDirect3DDeviceImpl_UpdateDepthStencil(device
));