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 EnterCriticalSection(&ddraw_cs
);
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
->d3d_target
->wined3d_surface
, 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 %p\n", This
->target
, This
->ddraw
->d3d_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 IDirectDrawSurface7_Release(&This
->ddraw
->d3d_target
->IDirectDrawSurface7_iface
);
370 TRACE("Target release done\n");
372 This
->ddraw
->d3ddevice
= NULL
;
374 /* Now free the structure */
375 HeapFree(GetProcessHeap(), 0, This
);
376 LeaveCriticalSection(&ddraw_cs
);
383 static ULONG WINAPI
IDirect3DDeviceImpl_3_Release(IDirect3DDevice3
*iface
)
385 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
386 TRACE("iface %p.\n", iface
);
388 return IDirect3DDevice7_Release(&This
->IDirect3DDevice7_iface
);
391 static ULONG WINAPI
IDirect3DDeviceImpl_2_Release(IDirect3DDevice2
*iface
)
393 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
394 TRACE("iface %p.\n", iface
);
396 return IDirect3DDevice7_Release(&This
->IDirect3DDevice7_iface
);
399 static ULONG WINAPI
IDirect3DDeviceImpl_1_Release(IDirect3DDevice
*iface
)
401 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
402 TRACE("iface %p.\n", iface
);
404 return IDirect3DDevice7_Release(&This
->IDirect3DDevice7_iface
);
407 /*****************************************************************************
408 * IDirect3DDevice Methods
409 *****************************************************************************/
411 /*****************************************************************************
412 * IDirect3DDevice::Initialize
414 * Initializes a Direct3DDevice. This implementation is a no-op, as all
415 * initialization is done at create time.
417 * Exists in Version 1
420 * No idea what they mean, as the MSDN page is gone
424 *****************************************************************************/
425 static HRESULT WINAPI
426 IDirect3DDeviceImpl_1_Initialize(IDirect3DDevice
*iface
,
427 IDirect3D
*Direct3D
, GUID
*guid
,
430 /* It shouldn't be crucial, but print a FIXME, I'm interested if
431 * any game calls it and when. */
432 FIXME("iface %p, d3d %p, guid %s, device_desc %p nop!\n",
433 iface
, Direct3D
, debugstr_guid(guid
), Desc
);
438 /*****************************************************************************
439 * IDirect3DDevice7::GetCaps
441 * Retrieves the device's capabilities
443 * This implementation is used for Version 7 only, the older versions have
444 * their own implementation.
447 * Desc: Pointer to a D3DDEVICEDESC7 structure to fill
451 * D3DERR_* if a problem occurs. See WineD3D
453 *****************************************************************************/
455 IDirect3DDeviceImpl_7_GetCaps(IDirect3DDevice7
*iface
,
456 D3DDEVICEDESC7
*Desc
)
458 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
459 D3DDEVICEDESC OldDesc
;
461 TRACE("iface %p, device_desc %p.\n", iface
, Desc
);
463 /* Call the same function used by IDirect3D, this saves code */
464 return IDirect3DImpl_GetCaps(This
->ddraw
->wineD3D
, &OldDesc
, Desc
);
467 static HRESULT WINAPI
468 IDirect3DDeviceImpl_7_GetCaps_FPUSetup(IDirect3DDevice7
*iface
,
469 D3DDEVICEDESC7
*Desc
)
471 return IDirect3DDeviceImpl_7_GetCaps(iface
, Desc
);
474 static HRESULT WINAPI
475 IDirect3DDeviceImpl_7_GetCaps_FPUPreserve(IDirect3DDevice7
*iface
,
476 D3DDEVICEDESC7
*Desc
)
481 old_fpucw
= d3d_fpu_setup();
482 hr
= IDirect3DDeviceImpl_7_GetCaps(iface
, Desc
);
483 set_fpu_control_word(old_fpucw
);
487 /*****************************************************************************
488 * IDirect3DDevice3::GetCaps
490 * Retrieves the capabilities of the hardware device and the emulation
491 * device. For Wine, hardware and emulation are the same (it's all HW).
493 * This implementation is used for Version 1, 2, and 3. Version 7 has its own
496 * HWDesc: Structure to fill with the HW caps
497 * HelDesc: Structure to fill with the hardware emulation caps
501 * D3DERR_* if a problem occurs. See WineD3D
503 *****************************************************************************/
504 static HRESULT WINAPI
505 IDirect3DDeviceImpl_3_GetCaps(IDirect3DDevice3
*iface
,
506 D3DDEVICEDESC
*HWDesc
,
507 D3DDEVICEDESC
*HelDesc
)
509 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
510 D3DDEVICEDESC7 newDesc
;
513 TRACE("iface %p, hw_desc %p, hel_desc %p.\n", iface
, HWDesc
, HelDesc
);
515 hr
= IDirect3DImpl_GetCaps(This
->ddraw
->wineD3D
, HWDesc
, &newDesc
);
516 if(hr
!= D3D_OK
) return hr
;
522 static HRESULT WINAPI
IDirect3DDeviceImpl_2_GetCaps(IDirect3DDevice2
*iface
,
523 D3DDEVICEDESC
*D3DHWDevDesc
, D3DDEVICEDESC
*D3DHELDevDesc
)
525 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
526 TRACE("iface %p, hw_desc %p, hel_desc %p.\n", iface
, D3DHWDevDesc
, D3DHELDevDesc
);
527 return IDirect3DDevice3_GetCaps(&This
->IDirect3DDevice3_iface
, D3DHWDevDesc
, D3DHELDevDesc
);
530 static HRESULT WINAPI
IDirect3DDeviceImpl_1_GetCaps(IDirect3DDevice
*iface
,
531 D3DDEVICEDESC
*D3DHWDevDesc
, D3DDEVICEDESC
*D3DHELDevDesc
)
533 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
534 TRACE("iface %p, hw_desc %p, hel_desc %p.\n", iface
, D3DHWDevDesc
, D3DHELDevDesc
);
535 return IDirect3DDevice3_GetCaps(&This
->IDirect3DDevice3_iface
, D3DHWDevDesc
, D3DHELDevDesc
);
538 /*****************************************************************************
539 * IDirect3DDevice2::SwapTextureHandles
541 * Swaps the texture handles of 2 Texture interfaces. Version 1 and 2
544 * Tex1, Tex2: The 2 Textures to swap
549 *****************************************************************************/
550 static HRESULT WINAPI
551 IDirect3DDeviceImpl_2_SwapTextureHandles(IDirect3DDevice2
*iface
,
552 IDirect3DTexture2
*Tex1
,
553 IDirect3DTexture2
*Tex2
)
555 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
556 IDirectDrawSurfaceImpl
*surf1
= unsafe_impl_from_IDirect3DTexture2(Tex1
);
557 IDirectDrawSurfaceImpl
*surf2
= unsafe_impl_from_IDirect3DTexture2(Tex2
);
560 TRACE("iface %p, tex1 %p, tex2 %p.\n", iface
, Tex1
, Tex2
);
562 EnterCriticalSection(&ddraw_cs
);
564 h1
= surf1
->Handle
- 1;
565 h2
= surf2
->Handle
- 1;
566 This
->handle_table
.entries
[h1
].object
= surf2
;
567 This
->handle_table
.entries
[h2
].object
= surf1
;
568 surf2
->Handle
= h1
+ 1;
569 surf1
->Handle
= h2
+ 1;
571 LeaveCriticalSection(&ddraw_cs
);
576 static HRESULT WINAPI
IDirect3DDeviceImpl_1_SwapTextureHandles(IDirect3DDevice
*iface
,
577 IDirect3DTexture
*D3DTex1
, IDirect3DTexture
*D3DTex2
)
579 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
580 IDirectDrawSurfaceImpl
*surf1
= unsafe_impl_from_IDirect3DTexture(D3DTex1
);
581 IDirectDrawSurfaceImpl
*surf2
= unsafe_impl_from_IDirect3DTexture(D3DTex2
);
582 IDirect3DTexture2
*t1
= surf1
? &surf1
->IDirect3DTexture2_iface
: NULL
;
583 IDirect3DTexture2
*t2
= surf2
? &surf2
->IDirect3DTexture2_iface
: NULL
;
585 TRACE("iface %p, tex1 %p, tex2 %p.\n", iface
, D3DTex1
, D3DTex2
);
587 return IDirect3DDevice2_SwapTextureHandles(&This
->IDirect3DDevice2_iface
, t1
, t2
);
590 /*****************************************************************************
591 * IDirect3DDevice3::GetStats
593 * This method seems to retrieve some stats from the device.
594 * The MSDN documentation doesn't exist any more, but the D3DSTATS
595 * structure suggests that the amount of drawn primitives and processed
596 * vertices is returned.
598 * Exists in Version 1, 2 and 3
601 * Stats: Pointer to a D3DSTATS structure to be filled
605 * DDERR_INVALIDPARAMS if Stats == NULL
607 *****************************************************************************/
608 static HRESULT WINAPI
609 IDirect3DDeviceImpl_3_GetStats(IDirect3DDevice3
*iface
,
612 FIXME("iface %p, stats %p stub!\n", iface
, Stats
);
615 return DDERR_INVALIDPARAMS
;
617 /* Fill the Stats with 0 */
618 Stats
->dwTrianglesDrawn
= 0;
619 Stats
->dwLinesDrawn
= 0;
620 Stats
->dwPointsDrawn
= 0;
621 Stats
->dwSpansDrawn
= 0;
622 Stats
->dwVerticesProcessed
= 0;
627 static HRESULT WINAPI
IDirect3DDeviceImpl_2_GetStats(IDirect3DDevice2
*iface
, D3DSTATS
*Stats
)
629 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
631 TRACE("iface %p, stats %p.\n", iface
, Stats
);
633 return IDirect3DDevice3_GetStats(&This
->IDirect3DDevice3_iface
, Stats
);
636 static HRESULT WINAPI
IDirect3DDeviceImpl_1_GetStats(IDirect3DDevice
*iface
, D3DSTATS
*Stats
)
638 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
640 TRACE("iface %p, stats %p.\n", iface
, Stats
);
642 return IDirect3DDevice3_GetStats(&This
->IDirect3DDevice3_iface
, Stats
);
645 /*****************************************************************************
646 * IDirect3DDevice::CreateExecuteBuffer
648 * Creates an IDirect3DExecuteBuffer, used for rendering with a
654 * Desc: Buffer description
655 * ExecuteBuffer: Address to return the Interface pointer at
656 * UnkOuter: Must be NULL. Basically for aggregation, which ddraw doesn't
660 * CLASS_E_NOAGGREGATION if UnkOuter != NULL
661 * DDERR_OUTOFMEMORY if we ran out of memory
664 *****************************************************************************/
665 static HRESULT WINAPI
666 IDirect3DDeviceImpl_1_CreateExecuteBuffer(IDirect3DDevice
*iface
,
667 D3DEXECUTEBUFFERDESC
*Desc
,
668 IDirect3DExecuteBuffer
**ExecuteBuffer
,
671 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
672 IDirect3DExecuteBufferImpl
* object
;
675 TRACE("iface %p, buffer_desc %p, buffer %p, outer_unknown %p.\n",
676 iface
, Desc
, ExecuteBuffer
, UnkOuter
);
679 return CLASS_E_NOAGGREGATION
;
681 /* Allocate the new Execute Buffer */
682 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirect3DExecuteBufferImpl
));
685 ERR("Out of memory when allocating a IDirect3DExecuteBufferImpl structure\n");
686 return DDERR_OUTOFMEMORY
;
689 hr
= d3d_execute_buffer_init(object
, This
, Desc
);
692 WARN("Failed to initialize execute buffer, hr %#x.\n", hr
);
693 HeapFree(GetProcessHeap(), 0, object
);
697 *ExecuteBuffer
= &object
->IDirect3DExecuteBuffer_iface
;
699 TRACE(" Returning IDirect3DExecuteBuffer at %p, implementation is at %p\n", *ExecuteBuffer
, object
);
704 /*****************************************************************************
705 * IDirect3DDevice::Execute
707 * Executes all the stuff in an execute buffer.
710 * ExecuteBuffer: The buffer to execute
711 * Viewport: The viewport used for rendering
715 * DDERR_INVALIDPARAMS if ExecuteBuffer == NULL
718 *****************************************************************************/
719 static HRESULT WINAPI
IDirect3DDeviceImpl_1_Execute(IDirect3DDevice
*iface
,
720 IDirect3DExecuteBuffer
*ExecuteBuffer
, IDirect3DViewport
*Viewport
, DWORD Flags
)
722 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
723 IDirect3DExecuteBufferImpl
*buffer
= unsafe_impl_from_IDirect3DExecuteBuffer(ExecuteBuffer
);
724 IDirect3DViewportImpl
*Direct3DViewportImpl
= unsafe_impl_from_IDirect3DViewport(Viewport
);
727 TRACE("iface %p, buffer %p, viewport %p, flags %#x.\n", iface
, ExecuteBuffer
, Viewport
, Flags
);
730 return DDERR_INVALIDPARAMS
;
733 EnterCriticalSection(&ddraw_cs
);
734 hr
= d3d_execute_buffer_execute(buffer
, This
, Direct3DViewportImpl
);
735 LeaveCriticalSection(&ddraw_cs
);
740 /*****************************************************************************
741 * IDirect3DDevice3::AddViewport
743 * Add a Direct3DViewport to the device's viewport list. These viewports
744 * are wrapped to IDirect3DDevice7 viewports in viewport.c
746 * Exists in Version 1, 2 and 3. Note that IDirect3DViewport 1, 2 and 3
747 * are the same interfaces.
750 * Viewport: The viewport to add
753 * DDERR_INVALIDPARAMS if Viewport == NULL
756 *****************************************************************************/
757 static HRESULT WINAPI
758 IDirect3DDeviceImpl_3_AddViewport(IDirect3DDevice3
*iface
,
759 IDirect3DViewport3
*Viewport
)
761 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
762 IDirect3DViewportImpl
*vp
= unsafe_impl_from_IDirect3DViewport3(Viewport
);
764 TRACE("iface %p, viewport %p.\n", iface
, Viewport
);
768 return DDERR_INVALIDPARAMS
;
770 EnterCriticalSection(&ddraw_cs
);
771 list_add_head(&This
->viewport_list
, &vp
->entry
);
772 vp
->active_device
= This
; /* Viewport must be usable for Clear() after AddViewport,
773 so set active_device here. */
774 LeaveCriticalSection(&ddraw_cs
);
779 static HRESULT WINAPI
IDirect3DDeviceImpl_2_AddViewport(IDirect3DDevice2
*iface
,
780 IDirect3DViewport2
*Direct3DViewport2
)
782 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
783 IDirect3DViewportImpl
*vp
= unsafe_impl_from_IDirect3DViewport2(Direct3DViewport2
);
785 TRACE("iface %p, viewport %p.\n", iface
, Direct3DViewport2
);
787 return IDirect3DDevice3_AddViewport(&This
->IDirect3DDevice3_iface
, &vp
->IDirect3DViewport3_iface
);
790 static HRESULT WINAPI
IDirect3DDeviceImpl_1_AddViewport(IDirect3DDevice
*iface
,
791 IDirect3DViewport
*Direct3DViewport
)
793 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
794 IDirect3DViewportImpl
*vp
= unsafe_impl_from_IDirect3DViewport(Direct3DViewport
);
796 TRACE("iface %p, viewport %p.\n", iface
, Direct3DViewport
);
798 return IDirect3DDevice3_AddViewport(&This
->IDirect3DDevice3_iface
, &vp
->IDirect3DViewport3_iface
);
801 /*****************************************************************************
802 * IDirect3DDevice3::DeleteViewport
804 * Deletes a Direct3DViewport from the device's viewport list.
806 * Exists in Version 1, 2 and 3. Note that all Viewport interface versions
810 * Viewport: The viewport to delete
814 * DDERR_INVALIDPARAMS if the viewport wasn't found in the list
816 *****************************************************************************/
817 static HRESULT WINAPI
IDirect3DDeviceImpl_3_DeleteViewport(IDirect3DDevice3
*iface
, IDirect3DViewport3
*viewport
)
819 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
820 IDirect3DViewportImpl
*vp
= unsafe_impl_from_IDirect3DViewport3(viewport
);
822 TRACE("iface %p, viewport %p.\n", iface
, viewport
);
824 EnterCriticalSection(&ddraw_cs
);
826 if (vp
->active_device
!= This
)
828 WARN("Viewport %p active device is %p.\n", vp
, vp
->active_device
);
829 LeaveCriticalSection(&ddraw_cs
);
830 return DDERR_INVALIDPARAMS
;
833 vp
->active_device
= NULL
;
834 list_remove(&vp
->entry
);
836 LeaveCriticalSection(&ddraw_cs
);
840 static HRESULT WINAPI
IDirect3DDeviceImpl_2_DeleteViewport(IDirect3DDevice2
*iface
,
841 IDirect3DViewport2
*Direct3DViewport2
)
843 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
844 IDirect3DViewportImpl
*vp
= unsafe_impl_from_IDirect3DViewport2(Direct3DViewport2
);
846 TRACE("iface %p, viewport %p.\n", iface
, Direct3DViewport2
);
848 return IDirect3DDevice3_DeleteViewport(&This
->IDirect3DDevice3_iface
, &vp
->IDirect3DViewport3_iface
);
851 static HRESULT WINAPI
IDirect3DDeviceImpl_1_DeleteViewport(IDirect3DDevice
*iface
,
852 IDirect3DViewport
*Direct3DViewport
)
854 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
855 IDirect3DViewportImpl
*vp
= unsafe_impl_from_IDirect3DViewport(Direct3DViewport
);
857 TRACE("iface %p, viewport %p.\n", iface
, Direct3DViewport
);
859 return IDirect3DDevice3_DeleteViewport(&This
->IDirect3DDevice3_iface
, &vp
->IDirect3DViewport3_iface
);
862 /*****************************************************************************
863 * IDirect3DDevice3::NextViewport
865 * Returns a viewport from the viewport list, depending on the
866 * passed viewport and the flags.
868 * Exists in Version 1, 2 and 3. Note that all Viewport interface versions
872 * Viewport: Viewport to use for beginning the search
873 * Flags: D3DNEXT_NEXT, D3DNEXT_HEAD or D3DNEXT_TAIL
877 * DDERR_INVALIDPARAMS if the flags were wrong, or Viewport was NULL
879 *****************************************************************************/
880 static HRESULT WINAPI
881 IDirect3DDeviceImpl_3_NextViewport(IDirect3DDevice3
*iface
,
882 IDirect3DViewport3
*Viewport3
,
883 IDirect3DViewport3
**lplpDirect3DViewport3
,
886 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
887 IDirect3DViewportImpl
*vp
= unsafe_impl_from_IDirect3DViewport3(Viewport3
);
888 IDirect3DViewportImpl
*next
;
891 TRACE("iface %p, viewport %p, next %p, flags %#x.\n",
892 iface
, Viewport3
, lplpDirect3DViewport3
, Flags
);
896 *lplpDirect3DViewport3
= NULL
;
897 return DDERR_INVALIDPARAMS
;
901 EnterCriticalSection(&ddraw_cs
);
905 entry
= list_next(&This
->viewport_list
, &vp
->entry
);
909 entry
= list_head(&This
->viewport_list
);
913 entry
= list_tail(&This
->viewport_list
);
917 WARN("Invalid flags %#x.\n", Flags
);
918 *lplpDirect3DViewport3
= NULL
;
919 LeaveCriticalSection(&ddraw_cs
);
920 return DDERR_INVALIDPARAMS
;
925 next
= LIST_ENTRY(entry
, IDirect3DViewportImpl
, entry
);
926 *lplpDirect3DViewport3
= &next
->IDirect3DViewport3_iface
;
929 *lplpDirect3DViewport3
= NULL
;
931 LeaveCriticalSection(&ddraw_cs
);
935 static HRESULT WINAPI
IDirect3DDeviceImpl_2_NextViewport(IDirect3DDevice2
*iface
,
936 IDirect3DViewport2
*Viewport2
, IDirect3DViewport2
**lplpDirect3DViewport2
, DWORD Flags
)
938 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
939 IDirect3DViewportImpl
*vp
= unsafe_impl_from_IDirect3DViewport2(Viewport2
);
940 IDirect3DViewport3
*res
;
943 TRACE("iface %p, viewport %p, next %p, flags %#x.\n",
944 iface
, Viewport2
, lplpDirect3DViewport2
, Flags
);
946 hr
= IDirect3DDevice3_NextViewport(&This
->IDirect3DDevice3_iface
,
947 &vp
->IDirect3DViewport3_iface
, &res
, Flags
);
948 *lplpDirect3DViewport2
= (IDirect3DViewport2
*)res
;
952 static HRESULT WINAPI
IDirect3DDeviceImpl_1_NextViewport(IDirect3DDevice
*iface
,
953 IDirect3DViewport
*Viewport
, IDirect3DViewport
**lplpDirect3DViewport
, DWORD Flags
)
955 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
956 IDirect3DViewportImpl
*vp
= unsafe_impl_from_IDirect3DViewport(Viewport
);
957 IDirect3DViewport3
*res
;
960 TRACE("iface %p, viewport %p, next %p, flags %#x.\n",
961 iface
, Viewport
, lplpDirect3DViewport
, Flags
);
963 hr
= IDirect3DDevice3_NextViewport(&This
->IDirect3DDevice3_iface
,
964 &vp
->IDirect3DViewport3_iface
, &res
, Flags
);
965 *lplpDirect3DViewport
= (IDirect3DViewport
*)res
;
969 /*****************************************************************************
970 * IDirect3DDevice::Pick
972 * Executes an execute buffer without performing rendering. Instead, a
973 * list of primitives that intersect with (x1,y1) of the passed rectangle
974 * is created. IDirect3DDevice::GetPickRecords can be used to retrieve
980 * ExecuteBuffer: Buffer to execute
981 * Viewport: Viewport to use for execution
982 * Flags: None are defined, according to the SDK
983 * Rect: Specifies the coordinates to be picked. Only x1 and y2 are used,
984 * x2 and y2 are ignored.
987 * D3D_OK because it's a stub
989 *****************************************************************************/
990 static HRESULT WINAPI
991 IDirect3DDeviceImpl_1_Pick(IDirect3DDevice
*iface
,
992 IDirect3DExecuteBuffer
*ExecuteBuffer
,
993 IDirect3DViewport
*Viewport
,
997 FIXME("iface %p, buffer %p, viewport %p, flags %#x, rect %s stub!\n",
998 iface
, ExecuteBuffer
, Viewport
, Flags
, wine_dbgstr_rect((RECT
*)Rect
));
1003 /*****************************************************************************
1004 * IDirect3DDevice::GetPickRecords
1006 * Retrieves the pick records generated by IDirect3DDevice::GetPickRecords
1011 * Count: Pointer to a DWORD containing the numbers of pick records to
1013 * D3DPickRec: Address to store the resulting D3DPICKRECORD array.
1016 * D3D_OK, because it's a stub
1018 *****************************************************************************/
1019 static HRESULT WINAPI
1020 IDirect3DDeviceImpl_1_GetPickRecords(IDirect3DDevice
*iface
,
1022 D3DPICKRECORD
*D3DPickRec
)
1024 FIXME("iface %p, count %p, records %p stub!\n", iface
, Count
, D3DPickRec
);
1029 /*****************************************************************************
1030 * IDirect3DDevice7::EnumTextureformats
1032 * Enumerates the supported texture formats. It has a list of all possible
1033 * formats and calls IWineD3D::CheckDeviceFormat for each format to see if
1034 * WineD3D supports it. If so, then it is passed to the app.
1036 * This is for Version 7 and 3, older versions have a different
1037 * callback function and their own implementation
1040 * Callback: Callback to call for each enumerated format
1041 * Arg: Argument to pass to the callback
1045 * DDERR_INVALIDPARAMS if Callback == NULL
1047 *****************************************************************************/
1049 IDirect3DDeviceImpl_7_EnumTextureFormats(IDirect3DDevice7
*iface
,
1050 LPD3DENUMPIXELFORMATSCALLBACK Callback
,
1053 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
1055 WINED3DDISPLAYMODE mode
;
1058 static const enum wined3d_format_id FormatList
[] =
1061 WINED3DFMT_B8G8R8A8_UNORM
,
1062 WINED3DFMT_B8G8R8X8_UNORM
,
1064 WINED3DFMT_B8G8R8_UNORM
,
1066 WINED3DFMT_B5G5R5A1_UNORM
,
1067 WINED3DFMT_B4G4R4A4_UNORM
,
1068 WINED3DFMT_B5G6R5_UNORM
,
1069 WINED3DFMT_B5G5R5X1_UNORM
,
1071 WINED3DFMT_B2G3R3_UNORM
,
1079 static const enum wined3d_format_id BumpFormatList
[] =
1081 WINED3DFMT_R8G8_SNORM
,
1082 WINED3DFMT_R5G5_SNORM_L6_UNORM
,
1083 WINED3DFMT_R8G8_SNORM_L8X8_UNORM
,
1084 WINED3DFMT_R16G16_SNORM
,
1085 WINED3DFMT_R10G11B11_SNORM
,
1086 WINED3DFMT_R10G10B10_SNORM_A2_UNORM
1089 TRACE("iface %p, callback %p, context %p.\n", iface
, Callback
, Arg
);
1092 return DDERR_INVALIDPARAMS
;
1094 EnterCriticalSection(&ddraw_cs
);
1096 memset(&mode
, 0, sizeof(mode
));
1097 hr
= wined3d_device_get_display_mode(This
->ddraw
->wined3d_device
, 0, &mode
);
1100 LeaveCriticalSection(&ddraw_cs
);
1101 WARN("Cannot get the current adapter format\n");
1105 for (i
= 0; i
< sizeof(FormatList
) / sizeof(*FormatList
); ++i
)
1107 hr
= wined3d_check_device_format(This
->ddraw
->wineD3D
, WINED3DADAPTER_DEFAULT
, WINED3DDEVTYPE_HAL
,
1108 mode
.Format
, 0, WINED3DRTYPE_TEXTURE
, FormatList
[i
], SURFACE_OPENGL
);
1111 DDPIXELFORMAT pformat
;
1113 memset(&pformat
, 0, sizeof(pformat
));
1114 pformat
.dwSize
= sizeof(pformat
);
1115 PixelFormat_WineD3DtoDD(&pformat
, FormatList
[i
]);
1117 TRACE("Enumerating WineD3DFormat %d\n", FormatList
[i
]);
1118 hr
= Callback(&pformat
, Arg
);
1119 if(hr
!= DDENUMRET_OK
)
1121 TRACE("Format enumeration cancelled by application\n");
1122 LeaveCriticalSection(&ddraw_cs
);
1128 for (i
= 0; i
< sizeof(BumpFormatList
) / sizeof(*BumpFormatList
); ++i
)
1130 hr
= wined3d_check_device_format(This
->ddraw
->wineD3D
, WINED3DADAPTER_DEFAULT
,
1131 WINED3DDEVTYPE_HAL
, mode
.Format
, WINED3DUSAGE_QUERY_LEGACYBUMPMAP
,
1132 WINED3DRTYPE_TEXTURE
, BumpFormatList
[i
], SURFACE_OPENGL
);
1135 DDPIXELFORMAT pformat
;
1137 memset(&pformat
, 0, sizeof(pformat
));
1138 pformat
.dwSize
= sizeof(pformat
);
1139 PixelFormat_WineD3DtoDD(&pformat
, BumpFormatList
[i
]);
1141 TRACE("Enumerating WineD3DFormat %d\n", BumpFormatList
[i
]);
1142 hr
= Callback(&pformat
, Arg
);
1143 if(hr
!= DDENUMRET_OK
)
1145 TRACE("Format enumeration cancelled by application\n");
1146 LeaveCriticalSection(&ddraw_cs
);
1151 TRACE("End of enumeration\n");
1152 LeaveCriticalSection(&ddraw_cs
);
1156 static HRESULT WINAPI
1157 IDirect3DDeviceImpl_7_EnumTextureFormats_FPUSetup(IDirect3DDevice7
*iface
,
1158 LPD3DENUMPIXELFORMATSCALLBACK Callback
,
1161 return IDirect3DDeviceImpl_7_EnumTextureFormats(iface
, Callback
, Arg
);
1164 static HRESULT WINAPI
1165 IDirect3DDeviceImpl_7_EnumTextureFormats_FPUPreserve(IDirect3DDevice7
*iface
,
1166 LPD3DENUMPIXELFORMATSCALLBACK Callback
,
1172 old_fpucw
= d3d_fpu_setup();
1173 hr
= IDirect3DDeviceImpl_7_EnumTextureFormats(iface
, Callback
, Arg
);
1174 set_fpu_control_word(old_fpucw
);
1179 static HRESULT WINAPI
IDirect3DDeviceImpl_3_EnumTextureFormats(IDirect3DDevice3
*iface
,
1180 LPD3DENUMPIXELFORMATSCALLBACK Callback
, void *Arg
)
1182 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
1184 TRACE("iface %p, callback %p, context %p.\n", iface
, Callback
, Arg
);
1186 return IDirect3DDevice7_EnumTextureFormats(&This
->IDirect3DDevice7_iface
, Callback
, Arg
);
1189 /*****************************************************************************
1190 * IDirect3DDevice2::EnumTextureformats
1192 * EnumTextureFormats for Version 1 and 2, see
1193 * IDirect3DDevice7::EnumTexureFormats for a more detailed description.
1195 * This version has a different callback and does not enumerate FourCC
1198 *****************************************************************************/
1199 static HRESULT WINAPI
1200 IDirect3DDeviceImpl_2_EnumTextureFormats(IDirect3DDevice2
*iface
,
1201 LPD3DENUMTEXTUREFORMATSCALLBACK Callback
,
1204 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
1207 WINED3DDISPLAYMODE mode
;
1209 static const enum wined3d_format_id FormatList
[] =
1212 WINED3DFMT_B8G8R8A8_UNORM
,
1213 WINED3DFMT_B8G8R8X8_UNORM
,
1215 WINED3DFMT_B8G8R8_UNORM
,
1217 WINED3DFMT_B5G5R5A1_UNORM
,
1218 WINED3DFMT_B4G4R4A4_UNORM
,
1219 WINED3DFMT_B5G6R5_UNORM
,
1220 WINED3DFMT_B5G5R5X1_UNORM
,
1222 WINED3DFMT_B2G3R3_UNORM
,
1224 /* FOURCC codes - Not in this version*/
1227 TRACE("iface %p, callback %p, context %p.\n", iface
, Callback
, Arg
);
1230 return DDERR_INVALIDPARAMS
;
1232 EnterCriticalSection(&ddraw_cs
);
1234 memset(&mode
, 0, sizeof(mode
));
1235 hr
= wined3d_device_get_display_mode(This
->ddraw
->wined3d_device
, 0, &mode
);
1238 LeaveCriticalSection(&ddraw_cs
);
1239 WARN("Cannot get the current adapter format\n");
1243 for (i
= 0; i
< sizeof(FormatList
) / sizeof(*FormatList
); ++i
)
1245 hr
= wined3d_check_device_format(This
->ddraw
->wineD3D
, 0, WINED3DDEVTYPE_HAL
,
1246 mode
.Format
, 0, WINED3DRTYPE_TEXTURE
, FormatList
[i
], SURFACE_OPENGL
);
1249 DDSURFACEDESC sdesc
;
1251 memset(&sdesc
, 0, sizeof(sdesc
));
1252 sdesc
.dwSize
= sizeof(sdesc
);
1253 sdesc
.dwFlags
= DDSD_PIXELFORMAT
| DDSD_CAPS
;
1254 sdesc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
1255 sdesc
.ddpfPixelFormat
.dwSize
= sizeof(sdesc
.ddpfPixelFormat
);
1256 PixelFormat_WineD3DtoDD(&sdesc
.ddpfPixelFormat
, FormatList
[i
]);
1258 TRACE("Enumerating WineD3DFormat %d\n", FormatList
[i
]);
1259 hr
= Callback(&sdesc
, Arg
);
1260 if(hr
!= DDENUMRET_OK
)
1262 TRACE("Format enumeration cancelled by application\n");
1263 LeaveCriticalSection(&ddraw_cs
);
1268 TRACE("End of enumeration\n");
1269 LeaveCriticalSection(&ddraw_cs
);
1273 static HRESULT WINAPI
IDirect3DDeviceImpl_1_EnumTextureFormats(IDirect3DDevice
*iface
,
1274 LPD3DENUMTEXTUREFORMATSCALLBACK Callback
, void *Arg
)
1276 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
1278 TRACE("iface %p, callback %p, context %p.\n", iface
, Callback
, Arg
);
1280 return IDirect3DDevice2_EnumTextureFormats(&This
->IDirect3DDevice2_iface
, Callback
, Arg
);
1283 /*****************************************************************************
1284 * IDirect3DDevice::CreateMatrix
1286 * Creates a matrix handle. A handle is created and memory for a D3DMATRIX is
1287 * allocated for the handle.
1292 * D3DMatHandle: Address to return the handle at
1296 * DDERR_INVALIDPARAMS if D3DMatHandle = NULL
1298 *****************************************************************************/
1299 static HRESULT WINAPI
1300 IDirect3DDeviceImpl_1_CreateMatrix(IDirect3DDevice
*iface
, D3DMATRIXHANDLE
*D3DMatHandle
)
1302 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
1306 TRACE("iface %p, matrix_handle %p.\n", iface
, D3DMatHandle
);
1309 return DDERR_INVALIDPARAMS
;
1311 Matrix
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(D3DMATRIX
));
1314 ERR("Out of memory when allocating a D3DMATRIX\n");
1315 return DDERR_OUTOFMEMORY
;
1318 EnterCriticalSection(&ddraw_cs
);
1320 h
= ddraw_allocate_handle(&This
->handle_table
, Matrix
, DDRAW_HANDLE_MATRIX
);
1321 if (h
== DDRAW_INVALID_HANDLE
)
1323 ERR("Failed to allocate a matrix handle.\n");
1324 HeapFree(GetProcessHeap(), 0, Matrix
);
1325 LeaveCriticalSection(&ddraw_cs
);
1326 return DDERR_OUTOFMEMORY
;
1329 *D3DMatHandle
= h
+ 1;
1331 TRACE(" returning matrix handle %d\n", *D3DMatHandle
);
1333 LeaveCriticalSection(&ddraw_cs
);
1337 /*****************************************************************************
1338 * IDirect3DDevice::SetMatrix
1340 * Sets a matrix for a matrix handle. The matrix is copied into the memory
1341 * allocated for the handle
1346 * D3DMatHandle: Handle to set the matrix to
1347 * D3DMatrix: Matrix to set
1351 * DDERR_INVALIDPARAMS if the handle of the matrix is invalid or the matrix
1354 *****************************************************************************/
1355 static HRESULT WINAPI
1356 IDirect3DDeviceImpl_1_SetMatrix(IDirect3DDevice
*iface
,
1357 D3DMATRIXHANDLE D3DMatHandle
,
1358 D3DMATRIX
*D3DMatrix
)
1360 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
1363 TRACE("iface %p, matrix_handle %#x, matrix %p.\n", iface
, D3DMatHandle
, D3DMatrix
);
1365 if (!D3DMatrix
) return DDERR_INVALIDPARAMS
;
1367 EnterCriticalSection(&ddraw_cs
);
1369 m
= ddraw_get_object(&This
->handle_table
, D3DMatHandle
- 1, DDRAW_HANDLE_MATRIX
);
1372 WARN("Invalid matrix handle.\n");
1373 LeaveCriticalSection(&ddraw_cs
);
1374 return DDERR_INVALIDPARAMS
;
1377 if (TRACE_ON(ddraw
))
1378 dump_D3DMATRIX(D3DMatrix
);
1382 if (D3DMatHandle
== This
->world
)
1383 wined3d_device_set_transform(This
->wined3d_device
, WINED3DTS_WORLDMATRIX(0), (WINED3DMATRIX
*)D3DMatrix
);
1385 if (D3DMatHandle
== This
->view
)
1386 wined3d_device_set_transform(This
->wined3d_device
, WINED3DTS_VIEW
, (WINED3DMATRIX
*)D3DMatrix
);
1388 if (D3DMatHandle
== This
->proj
)
1389 wined3d_device_set_transform(This
->wined3d_device
, WINED3DTS_PROJECTION
, (WINED3DMATRIX
*)D3DMatrix
);
1391 LeaveCriticalSection(&ddraw_cs
);
1395 /*****************************************************************************
1396 * IDirect3DDevice::GetMatrix
1398 * Returns the content of a D3DMATRIX handle
1403 * D3DMatHandle: Matrix handle to read the content from
1404 * D3DMatrix: Address to store the content at
1408 * DDERR_INVALIDPARAMS if D3DMatHandle is invalid or D3DMatrix is NULL
1410 *****************************************************************************/
1411 static HRESULT WINAPI
1412 IDirect3DDeviceImpl_1_GetMatrix(IDirect3DDevice
*iface
,
1413 D3DMATRIXHANDLE D3DMatHandle
,
1414 D3DMATRIX
*D3DMatrix
)
1416 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
1419 TRACE("iface %p, matrix_handle %#x, matrix %p.\n", iface
, D3DMatHandle
, D3DMatrix
);
1421 if (!D3DMatrix
) return DDERR_INVALIDPARAMS
;
1423 EnterCriticalSection(&ddraw_cs
);
1425 m
= ddraw_get_object(&This
->handle_table
, D3DMatHandle
- 1, DDRAW_HANDLE_MATRIX
);
1428 WARN("Invalid matrix handle.\n");
1429 LeaveCriticalSection(&ddraw_cs
);
1430 return DDERR_INVALIDPARAMS
;
1435 LeaveCriticalSection(&ddraw_cs
);
1439 /*****************************************************************************
1440 * IDirect3DDevice::DeleteMatrix
1442 * Destroys a Matrix handle. Frees the memory and unsets the handle data
1447 * D3DMatHandle: Handle to destroy
1451 * DDERR_INVALIDPARAMS if D3DMatHandle is invalid
1453 *****************************************************************************/
1454 static HRESULT WINAPI
1455 IDirect3DDeviceImpl_1_DeleteMatrix(IDirect3DDevice
*iface
,
1456 D3DMATRIXHANDLE D3DMatHandle
)
1458 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
1461 TRACE("iface %p, matrix_handle %#x.\n", iface
, D3DMatHandle
);
1463 EnterCriticalSection(&ddraw_cs
);
1465 m
= ddraw_free_handle(&This
->handle_table
, D3DMatHandle
- 1, DDRAW_HANDLE_MATRIX
);
1468 WARN("Invalid matrix handle.\n");
1469 LeaveCriticalSection(&ddraw_cs
);
1470 return DDERR_INVALIDPARAMS
;
1473 LeaveCriticalSection(&ddraw_cs
);
1475 HeapFree(GetProcessHeap(), 0, m
);
1480 /*****************************************************************************
1481 * IDirect3DDevice7::BeginScene
1483 * This method must be called before any rendering is performed.
1484 * IDirect3DDevice::EndScene has to be called after the scene is complete
1486 * Version 1, 2, 3 and 7
1489 * D3D_OK on success, for details see IWineD3DDevice::BeginScene
1490 * D3DERR_SCENE_IN_SCENE if WineD3D returns an error(Only in case of an already
1493 *****************************************************************************/
1495 IDirect3DDeviceImpl_7_BeginScene(IDirect3DDevice7
*iface
)
1497 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
1500 TRACE("iface %p.\n", iface
);
1502 EnterCriticalSection(&ddraw_cs
);
1503 hr
= wined3d_device_begin_scene(This
->wined3d_device
);
1504 LeaveCriticalSection(&ddraw_cs
);
1505 if(hr
== WINED3D_OK
) return D3D_OK
;
1506 else return D3DERR_SCENE_IN_SCENE
; /* TODO: Other possible causes of failure */
1509 static HRESULT WINAPI
1510 IDirect3DDeviceImpl_7_BeginScene_FPUSetup(IDirect3DDevice7
*iface
)
1512 return IDirect3DDeviceImpl_7_BeginScene(iface
);
1515 static HRESULT WINAPI
1516 IDirect3DDeviceImpl_7_BeginScene_FPUPreserve(IDirect3DDevice7
*iface
)
1521 old_fpucw
= d3d_fpu_setup();
1522 hr
= IDirect3DDeviceImpl_7_BeginScene(iface
);
1523 set_fpu_control_word(old_fpucw
);
1528 static HRESULT WINAPI
IDirect3DDeviceImpl_3_BeginScene(IDirect3DDevice3
*iface
)
1530 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
1531 TRACE("iface %p.\n", iface
);
1533 return IDirect3DDevice7_BeginScene(&This
->IDirect3DDevice7_iface
);
1536 static HRESULT WINAPI
IDirect3DDeviceImpl_2_BeginScene(IDirect3DDevice2
*iface
)
1538 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
1539 TRACE("iface %p.\n", iface
);
1541 return IDirect3DDevice7_BeginScene(&This
->IDirect3DDevice7_iface
);
1544 static HRESULT WINAPI
IDirect3DDeviceImpl_1_BeginScene(IDirect3DDevice
*iface
)
1546 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
1547 TRACE("iface %p.\n", iface
);
1549 return IDirect3DDevice7_BeginScene(&This
->IDirect3DDevice7_iface
);
1552 /*****************************************************************************
1553 * IDirect3DDevice7::EndScene
1555 * Ends a scene that has been begun with IDirect3DDevice7::BeginScene.
1556 * This method must be called after rendering is finished.
1558 * Version 1, 2, 3 and 7
1561 * D3D_OK on success, for details see IWineD3DDevice::EndScene
1562 * D3DERR_SCENE_NOT_IN_SCENE is returned if WineD3D returns an error. It does
1563 * that only if the scene was already ended.
1565 *****************************************************************************/
1567 IDirect3DDeviceImpl_7_EndScene(IDirect3DDevice7
*iface
)
1569 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
1572 TRACE("iface %p.\n", iface
);
1574 EnterCriticalSection(&ddraw_cs
);
1575 hr
= wined3d_device_end_scene(This
->wined3d_device
);
1576 LeaveCriticalSection(&ddraw_cs
);
1577 if(hr
== WINED3D_OK
) return D3D_OK
;
1578 else return D3DERR_SCENE_NOT_IN_SCENE
;
1581 static HRESULT WINAPI DECLSPEC_HOTPATCH
1582 IDirect3DDeviceImpl_7_EndScene_FPUSetup(IDirect3DDevice7
*iface
)
1584 return IDirect3DDeviceImpl_7_EndScene(iface
);
1587 static HRESULT WINAPI DECLSPEC_HOTPATCH
1588 IDirect3DDeviceImpl_7_EndScene_FPUPreserve(IDirect3DDevice7
*iface
)
1593 old_fpucw
= d3d_fpu_setup();
1594 hr
= IDirect3DDeviceImpl_7_EndScene(iface
);
1595 set_fpu_control_word(old_fpucw
);
1600 static HRESULT WINAPI DECLSPEC_HOTPATCH
IDirect3DDeviceImpl_3_EndScene(IDirect3DDevice3
*iface
)
1602 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
1603 TRACE("iface %p.\n", iface
);
1605 return IDirect3DDevice7_EndScene(&This
->IDirect3DDevice7_iface
);
1608 static HRESULT WINAPI DECLSPEC_HOTPATCH
IDirect3DDeviceImpl_2_EndScene(IDirect3DDevice2
*iface
)
1610 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
1611 TRACE("iface %p.\n", iface
);
1613 return IDirect3DDevice7_EndScene(&This
->IDirect3DDevice7_iface
);
1616 static HRESULT WINAPI DECLSPEC_HOTPATCH
IDirect3DDeviceImpl_1_EndScene(IDirect3DDevice
*iface
)
1618 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
1619 TRACE("iface %p.\n", iface
);
1621 return IDirect3DDevice7_EndScene(&This
->IDirect3DDevice7_iface
);
1624 /*****************************************************************************
1625 * IDirect3DDevice7::GetDirect3D
1627 * Returns the IDirect3D(= interface to the DirectDraw object) used to create
1631 * Direct3D7: Address to store the interface pointer at
1635 * DDERR_INVALIDPARAMS if Direct3D7 == NULL
1637 *****************************************************************************/
1638 static HRESULT WINAPI
1639 IDirect3DDeviceImpl_7_GetDirect3D(IDirect3DDevice7
*iface
,
1640 IDirect3D7
**Direct3D7
)
1642 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
1644 TRACE("iface %p, d3d %p.\n", iface
, Direct3D7
);
1647 return DDERR_INVALIDPARAMS
;
1649 *Direct3D7
= &This
->ddraw
->IDirect3D7_iface
;
1650 IDirect3D7_AddRef(*Direct3D7
);
1652 TRACE(" returning interface %p\n", *Direct3D7
);
1656 static HRESULT WINAPI
IDirect3DDeviceImpl_3_GetDirect3D(IDirect3DDevice3
*iface
,
1657 IDirect3D3
**Direct3D3
)
1659 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
1661 TRACE("iface %p, d3d %p.\n", iface
, Direct3D3
);
1664 return DDERR_INVALIDPARAMS
;
1666 IDirect3D3_AddRef(&This
->ddraw
->IDirect3D3_iface
);
1667 *Direct3D3
= &This
->ddraw
->IDirect3D3_iface
;
1668 TRACE(" returning interface %p\n", *Direct3D3
);
1672 static HRESULT WINAPI
IDirect3DDeviceImpl_2_GetDirect3D(IDirect3DDevice2
*iface
,
1673 IDirect3D2
**Direct3D2
)
1675 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
1677 TRACE("iface %p, d3d %p.\n", iface
, Direct3D2
);
1680 return DDERR_INVALIDPARAMS
;
1682 IDirect3D2_AddRef(&This
->ddraw
->IDirect3D2_iface
);
1683 *Direct3D2
= &This
->ddraw
->IDirect3D2_iface
;
1684 TRACE(" returning interface %p\n", *Direct3D2
);
1688 static HRESULT WINAPI
IDirect3DDeviceImpl_1_GetDirect3D(IDirect3DDevice
*iface
,
1689 IDirect3D
**Direct3D
)
1691 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
1693 TRACE("iface %p, d3d %p.\n", iface
, Direct3D
);
1696 return DDERR_INVALIDPARAMS
;
1698 IDirect3D_AddRef(&This
->ddraw
->IDirect3D_iface
);
1699 *Direct3D
= &This
->ddraw
->IDirect3D_iface
;
1700 TRACE(" returning interface %p\n", *Direct3D
);
1704 /*****************************************************************************
1705 * IDirect3DDevice3::SetCurrentViewport
1707 * Sets a Direct3DViewport as the current viewport.
1708 * For the thunks note that all viewport interface versions are equal
1711 * Direct3DViewport3: The viewport to set
1717 * (Is a NULL viewport valid?)
1719 *****************************************************************************/
1720 static HRESULT WINAPI
1721 IDirect3DDeviceImpl_3_SetCurrentViewport(IDirect3DDevice3
*iface
,
1722 IDirect3DViewport3
*Direct3DViewport3
)
1724 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
1725 IDirect3DViewportImpl
*vp
= unsafe_impl_from_IDirect3DViewport3(Direct3DViewport3
);
1727 TRACE("iface %p, viewport %p.\n", iface
, Direct3DViewport3
);
1729 EnterCriticalSection(&ddraw_cs
);
1730 /* Do nothing if the specified viewport is the same as the current one */
1731 if (This
->current_viewport
== vp
)
1733 LeaveCriticalSection(&ddraw_cs
);
1737 if (vp
->active_device
!= This
)
1739 WARN("Viewport %p active device is %p.\n", vp
, vp
->active_device
);
1740 LeaveCriticalSection(&ddraw_cs
);
1741 return DDERR_INVALIDPARAMS
;
1744 /* Release previous viewport and AddRef the new one */
1745 if (This
->current_viewport
)
1747 TRACE("ViewportImpl is at %p, interface is at %p\n", This
->current_viewport
,
1748 &This
->current_viewport
->IDirect3DViewport3_iface
);
1749 IDirect3DViewport3_Release(&This
->current_viewport
->IDirect3DViewport3_iface
);
1751 IDirect3DViewport3_AddRef(Direct3DViewport3
);
1753 /* Set this viewport as the current viewport */
1754 This
->current_viewport
= vp
;
1756 /* Activate this viewport */
1757 viewport_activate(This
->current_viewport
, FALSE
);
1759 LeaveCriticalSection(&ddraw_cs
);
1763 static HRESULT WINAPI
IDirect3DDeviceImpl_2_SetCurrentViewport(IDirect3DDevice2
*iface
,
1764 IDirect3DViewport2
*Direct3DViewport2
)
1766 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
1767 IDirect3DViewportImpl
*vp
= unsafe_impl_from_IDirect3DViewport2(Direct3DViewport2
);
1769 TRACE("iface %p, viewport %p.\n", iface
, Direct3DViewport2
);
1771 return IDirect3DDevice3_SetCurrentViewport(&This
->IDirect3DDevice3_iface
,
1772 &vp
->IDirect3DViewport3_iface
);
1775 /*****************************************************************************
1776 * IDirect3DDevice3::GetCurrentViewport
1778 * Returns the currently active viewport.
1783 * Direct3DViewport3: Address to return the interface pointer at
1787 * DDERR_INVALIDPARAMS if Direct3DViewport == NULL
1789 *****************************************************************************/
1790 static HRESULT WINAPI
1791 IDirect3DDeviceImpl_3_GetCurrentViewport(IDirect3DDevice3
*iface
,
1792 IDirect3DViewport3
**Direct3DViewport3
)
1794 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
1796 TRACE("iface %p, viewport %p.\n", iface
, Direct3DViewport3
);
1798 if(!Direct3DViewport3
)
1799 return DDERR_INVALIDPARAMS
;
1801 EnterCriticalSection(&ddraw_cs
);
1802 *Direct3DViewport3
= &This
->current_viewport
->IDirect3DViewport3_iface
;
1804 /* AddRef the returned viewport */
1805 if(*Direct3DViewport3
) IDirect3DViewport3_AddRef(*Direct3DViewport3
);
1807 TRACE(" returning interface %p\n", *Direct3DViewport3
);
1809 LeaveCriticalSection(&ddraw_cs
);
1813 static HRESULT WINAPI
IDirect3DDeviceImpl_2_GetCurrentViewport(IDirect3DDevice2
*iface
,
1814 IDirect3DViewport2
**Direct3DViewport2
)
1816 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
1819 TRACE("iface %p, viewport %p.\n", iface
, Direct3DViewport2
);
1821 hr
= IDirect3DDevice3_GetCurrentViewport(&This
->IDirect3DDevice3_iface
,
1822 (IDirect3DViewport3
**)Direct3DViewport2
);
1823 if(hr
!= D3D_OK
) return hr
;
1827 /*****************************************************************************
1828 * IDirect3DDevice7::SetRenderTarget
1830 * Sets the render target for the Direct3DDevice.
1831 * For the thunks note that IDirectDrawSurface7 == IDirectDrawSurface4 and
1832 * IDirectDrawSurface3 == IDirectDrawSurface
1834 * Version 2, 3 and 7
1837 * NewTarget: Pointer to an IDirectDrawSurface7 interface to set as the new
1842 * D3D_OK on success, for details see IWineD3DDevice::SetRenderTarget
1844 *****************************************************************************/
1845 static HRESULT
d3d_device_set_render_target(IDirect3DDeviceImpl
*This
, IDirectDrawSurfaceImpl
*Target
)
1849 EnterCriticalSection(&ddraw_cs
);
1850 /* Flags: Not used */
1852 if(This
->target
== Target
)
1854 TRACE("No-op SetRenderTarget operation, not doing anything\n");
1855 LeaveCriticalSection(&ddraw_cs
);
1858 This
->target
= Target
;
1859 hr
= wined3d_device_set_render_target(This
->wined3d_device
, 0,
1860 Target
? Target
->wined3d_surface
: NULL
, FALSE
);
1863 LeaveCriticalSection(&ddraw_cs
);
1866 IDirect3DDeviceImpl_UpdateDepthStencil(This
);
1867 LeaveCriticalSection(&ddraw_cs
);
1872 IDirect3DDeviceImpl_7_SetRenderTarget(IDirect3DDevice7
*iface
,
1873 IDirectDrawSurface7
*NewTarget
,
1876 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
1877 IDirectDrawSurfaceImpl
*Target
= unsafe_impl_from_IDirectDrawSurface7(NewTarget
);
1879 TRACE("iface %p, target %p, flags %#x.\n", iface
, NewTarget
, Flags
);
1880 /* Flags: Not used */
1882 IDirectDrawSurface7_AddRef(NewTarget
);
1883 IDirectDrawSurface7_Release(&This
->target
->IDirectDrawSurface7_iface
);
1884 return d3d_device_set_render_target(This
, Target
);
1887 static HRESULT WINAPI
1888 IDirect3DDeviceImpl_7_SetRenderTarget_FPUSetup(IDirect3DDevice7
*iface
,
1889 IDirectDrawSurface7
*NewTarget
,
1892 return IDirect3DDeviceImpl_7_SetRenderTarget(iface
, NewTarget
, Flags
);
1895 static HRESULT WINAPI
1896 IDirect3DDeviceImpl_7_SetRenderTarget_FPUPreserve(IDirect3DDevice7
*iface
,
1897 IDirectDrawSurface7
*NewTarget
,
1903 old_fpucw
= d3d_fpu_setup();
1904 hr
= IDirect3DDeviceImpl_7_SetRenderTarget(iface
, NewTarget
, Flags
);
1905 set_fpu_control_word(old_fpucw
);
1910 static HRESULT WINAPI
IDirect3DDeviceImpl_3_SetRenderTarget(IDirect3DDevice3
*iface
,
1911 IDirectDrawSurface4
*NewRenderTarget
, DWORD Flags
)
1913 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
1914 IDirectDrawSurfaceImpl
*Target
= unsafe_impl_from_IDirectDrawSurface4(NewRenderTarget
);
1916 TRACE("iface %p, target %p, flags %#x.\n", iface
, NewRenderTarget
, Flags
);
1918 IDirectDrawSurface4_AddRef(NewRenderTarget
);
1919 IDirectDrawSurface4_Release(&This
->target
->IDirectDrawSurface4_iface
);
1920 return d3d_device_set_render_target(This
, Target
);
1923 static HRESULT WINAPI
IDirect3DDeviceImpl_2_SetRenderTarget(IDirect3DDevice2
*iface
,
1924 IDirectDrawSurface
*NewRenderTarget
, DWORD Flags
)
1926 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
1927 IDirectDrawSurfaceImpl
*Target
= unsafe_impl_from_IDirectDrawSurface(NewRenderTarget
);
1929 TRACE("iface %p, target %p, flags %#x.\n", iface
, NewRenderTarget
, Flags
);
1931 IDirectDrawSurface_AddRef(NewRenderTarget
);
1932 IDirectDrawSurface_Release(&This
->target
->IDirectDrawSurface_iface
);
1933 return d3d_device_set_render_target(This
, Target
);
1936 /*****************************************************************************
1937 * IDirect3DDevice7::GetRenderTarget
1939 * Returns the current render target.
1940 * This is handled locally, because the WineD3D render target's parent
1943 * Version 2, 3 and 7
1946 * RenderTarget: Address to store the surface interface pointer
1950 * DDERR_INVALIDPARAMS if RenderTarget == NULL
1952 *****************************************************************************/
1953 static HRESULT WINAPI
1954 IDirect3DDeviceImpl_7_GetRenderTarget(IDirect3DDevice7
*iface
,
1955 IDirectDrawSurface7
**RenderTarget
)
1957 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
1959 TRACE("iface %p, target %p.\n", iface
, RenderTarget
);
1962 return DDERR_INVALIDPARAMS
;
1964 EnterCriticalSection(&ddraw_cs
);
1965 *RenderTarget
= &This
->target
->IDirectDrawSurface7_iface
;
1966 IDirectDrawSurface7_AddRef(*RenderTarget
);
1968 LeaveCriticalSection(&ddraw_cs
);
1972 static HRESULT WINAPI
IDirect3DDeviceImpl_3_GetRenderTarget(IDirect3DDevice3
*iface
,
1973 IDirectDrawSurface4
**RenderTarget
)
1975 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
1976 IDirectDrawSurface7
*RenderTarget7
;
1977 IDirectDrawSurfaceImpl
*RenderTargetImpl
;
1980 TRACE("iface %p, target %p.\n", iface
, RenderTarget
);
1983 return DDERR_INVALIDPARAMS
;
1985 hr
= IDirect3DDevice7_GetRenderTarget(&This
->IDirect3DDevice7_iface
, &RenderTarget7
);
1986 if(hr
!= D3D_OK
) return hr
;
1987 RenderTargetImpl
= impl_from_IDirectDrawSurface7(RenderTarget7
);
1988 *RenderTarget
= &RenderTargetImpl
->IDirectDrawSurface4_iface
;
1989 IDirectDrawSurface4_AddRef(*RenderTarget
);
1990 IDirectDrawSurface7_Release(RenderTarget7
);
1994 static HRESULT WINAPI
IDirect3DDeviceImpl_2_GetRenderTarget(IDirect3DDevice2
*iface
,
1995 IDirectDrawSurface
**RenderTarget
)
1997 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
1998 IDirectDrawSurface7
*RenderTarget7
;
1999 IDirectDrawSurfaceImpl
*RenderTargetImpl
;
2002 TRACE("iface %p, target %p.\n", iface
, RenderTarget
);
2005 return DDERR_INVALIDPARAMS
;
2007 hr
= IDirect3DDevice7_GetRenderTarget(&This
->IDirect3DDevice7_iface
, &RenderTarget7
);
2008 if(hr
!= D3D_OK
) return hr
;
2009 RenderTargetImpl
= impl_from_IDirectDrawSurface7(RenderTarget7
);
2010 *RenderTarget
= &RenderTargetImpl
->IDirectDrawSurface_iface
;
2011 IDirectDrawSurface_AddRef(*RenderTarget
);
2012 IDirectDrawSurface7_Release(RenderTarget7
);
2016 /*****************************************************************************
2017 * IDirect3DDevice3::Begin
2019 * Begins a description block of vertices. This is similar to glBegin()
2020 * and glEnd(). After a call to IDirect3DDevice3::End, the vertices
2021 * described with IDirect3DDevice::Vertex are drawn.
2026 * PrimitiveType: The type of primitives to draw
2027 * VertexTypeDesc: A flexible vertex format description of the vertices
2028 * Flags: Some flags..
2033 *****************************************************************************/
2034 static HRESULT WINAPI
2035 IDirect3DDeviceImpl_3_Begin(IDirect3DDevice3
*iface
,
2036 D3DPRIMITIVETYPE PrimitiveType
,
2037 DWORD VertexTypeDesc
,
2040 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
2042 TRACE("iface %p, primitive_type %#x, FVF %#x, flags %#x.\n",
2043 iface
, PrimitiveType
, VertexTypeDesc
, Flags
);
2045 EnterCriticalSection(&ddraw_cs
);
2046 This
->primitive_type
= PrimitiveType
;
2047 This
->vertex_type
= VertexTypeDesc
;
2048 This
->render_flags
= Flags
;
2049 This
->vertex_size
= get_flexible_vertex_size(This
->vertex_type
);
2050 This
->nb_vertices
= 0;
2051 LeaveCriticalSection(&ddraw_cs
);
2056 static HRESULT WINAPI
IDirect3DDeviceImpl_2_Begin(IDirect3DDevice2
*iface
, D3DPRIMITIVETYPE d3dpt
,
2057 D3DVERTEXTYPE dwVertexTypeDesc
, DWORD dwFlags
)
2060 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
2062 TRACE("iface %p, primitive_type %#x, vertex_type %#x, flags %#x.\n",
2063 iface
, d3dpt
, dwVertexTypeDesc
, dwFlags
);
2065 switch(dwVertexTypeDesc
)
2067 case D3DVT_VERTEX
: FVF
= D3DFVF_VERTEX
; break;
2068 case D3DVT_LVERTEX
: FVF
= D3DFVF_LVERTEX
; break;
2069 case D3DVT_TLVERTEX
: FVF
= D3DFVF_TLVERTEX
; break;
2071 ERR("Unexpected vertex type %d\n", dwVertexTypeDesc
);
2072 return DDERR_INVALIDPARAMS
; /* Should never happen */
2075 return IDirect3DDevice3_Begin(&This
->IDirect3DDevice3_iface
, d3dpt
, FVF
, dwFlags
);
2078 /*****************************************************************************
2079 * IDirect3DDevice3::BeginIndexed
2081 * Draws primitives based on vertices in a vertex array which are specified
2087 * PrimitiveType: Primitive type to draw
2088 * VertexType: A FVF description of the vertex format
2089 * Vertices: pointer to an array containing the vertices
2090 * NumVertices: The number of vertices in the vertex array
2091 * Flags: Some flags ...
2094 * D3D_OK, because it's a stub
2096 *****************************************************************************/
2097 static HRESULT WINAPI
2098 IDirect3DDeviceImpl_3_BeginIndexed(IDirect3DDevice3
*iface
,
2099 D3DPRIMITIVETYPE PrimitiveType
,
2105 FIXME("iface %p, primitive_type %#x, FVF %#x, vertices %p, vertex_count %u, flags %#x stub!\n",
2106 iface
, PrimitiveType
, VertexType
, Vertices
, NumVertices
, Flags
);
2112 static HRESULT WINAPI
IDirect3DDeviceImpl_2_BeginIndexed(IDirect3DDevice2
*iface
,
2113 D3DPRIMITIVETYPE d3dptPrimitiveType
, D3DVERTEXTYPE d3dvtVertexType
,
2114 void *lpvVertices
, DWORD dwNumVertices
, DWORD dwFlags
)
2117 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
2119 TRACE("iface %p, primitive_type %#x, vertex_type %#x, vertices %p, vertex_count %u, flags %#x stub!\n",
2120 iface
, d3dptPrimitiveType
, d3dvtVertexType
, lpvVertices
, dwNumVertices
, dwFlags
);
2122 switch(d3dvtVertexType
)
2124 case D3DVT_VERTEX
: FVF
= D3DFVF_VERTEX
; break;
2125 case D3DVT_LVERTEX
: FVF
= D3DFVF_LVERTEX
; break;
2126 case D3DVT_TLVERTEX
: FVF
= D3DFVF_TLVERTEX
; break;
2128 ERR("Unexpected vertex type %d\n", d3dvtVertexType
);
2129 return DDERR_INVALIDPARAMS
; /* Should never happen */
2132 return IDirect3DDevice3_BeginIndexed(&This
->IDirect3DDevice3_iface
,
2133 d3dptPrimitiveType
, FVF
, lpvVertices
, dwNumVertices
, dwFlags
);
2136 /*****************************************************************************
2137 * IDirect3DDevice3::Vertex
2139 * Draws a vertex as described by IDirect3DDevice3::Begin. It places all
2140 * drawn vertices in a vertex buffer. If the buffer is too small, its
2141 * size is increased.
2146 * Vertex: Pointer to the vertex
2149 * D3D_OK, on success
2150 * DDERR_INVALIDPARAMS if Vertex is NULL
2152 *****************************************************************************/
2153 static HRESULT WINAPI
2154 IDirect3DDeviceImpl_3_Vertex(IDirect3DDevice3
*iface
,
2157 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
2159 TRACE("iface %p, vertex %p.\n", iface
, Vertex
);
2162 return DDERR_INVALIDPARAMS
;
2164 EnterCriticalSection(&ddraw_cs
);
2165 if ((This
->nb_vertices
+1)*This
->vertex_size
> This
->buffer_size
)
2168 This
->buffer_size
= This
->buffer_size
? This
->buffer_size
* 2 : This
->vertex_size
* 3;
2169 old_buffer
= This
->vertex_buffer
;
2170 This
->vertex_buffer
= HeapAlloc(GetProcessHeap(), 0, This
->buffer_size
);
2173 CopyMemory(This
->vertex_buffer
, old_buffer
, This
->nb_vertices
* This
->vertex_size
);
2174 HeapFree(GetProcessHeap(), 0, old_buffer
);
2178 CopyMemory(This
->vertex_buffer
+ This
->nb_vertices
++ * This
->vertex_size
, Vertex
, This
->vertex_size
);
2180 LeaveCriticalSection(&ddraw_cs
);
2184 static HRESULT WINAPI
IDirect3DDeviceImpl_2_Vertex(IDirect3DDevice2
*iface
, void *lpVertexType
)
2186 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
2188 TRACE("iface %p, vertex %p.\n", iface
, lpVertexType
);
2190 return IDirect3DDevice3_Vertex(&This
->IDirect3DDevice3_iface
, lpVertexType
);
2193 /*****************************************************************************
2194 * IDirect3DDevice3::Index
2196 * Specifies an index to a vertex to be drawn. The vertex array has to
2197 * be specified with BeginIndexed first.
2200 * VertexIndex: The index of the vertex to draw
2203 * D3D_OK because it's a stub
2205 *****************************************************************************/
2206 static HRESULT WINAPI
2207 IDirect3DDeviceImpl_3_Index(IDirect3DDevice3
*iface
,
2210 FIXME("iface %p, index %#x stub!\n", iface
, VertexIndex
);
2215 static HRESULT WINAPI
IDirect3DDeviceImpl_2_Index(IDirect3DDevice2
*iface
, WORD wVertexIndex
)
2217 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
2219 TRACE("iface %p, index %#x.\n", iface
, wVertexIndex
);
2221 return IDirect3DDevice3_Index(&This
->IDirect3DDevice3_iface
, wVertexIndex
);
2224 /*****************************************************************************
2225 * IDirect3DDevice3::End
2227 * Ends a draw begun with IDirect3DDevice3::Begin or
2228 * IDirect3DDevice::BeginIndexed. The vertices specified with
2229 * IDirect3DDevice::Vertex or IDirect3DDevice::Index are drawn using
2230 * the IDirect3DDevice7::DrawPrimitive method. So far only
2231 * non-indexed mode is supported
2236 * Flags: Some flags, as usual. Don't know which are defined
2239 * The return value of IDirect3DDevice7::DrawPrimitive
2241 *****************************************************************************/
2242 static HRESULT WINAPI
2243 IDirect3DDeviceImpl_3_End(IDirect3DDevice3
*iface
,
2246 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
2248 TRACE("iface %p, flags %#x.\n", iface
, Flags
);
2250 return IDirect3DDevice7_DrawPrimitive(&This
->IDirect3DDevice7_iface
, This
->primitive_type
,
2251 This
->vertex_type
, This
->vertex_buffer
, This
->nb_vertices
, This
->render_flags
);
2254 static HRESULT WINAPI
IDirect3DDeviceImpl_2_End(IDirect3DDevice2
*iface
, DWORD dwFlags
)
2256 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
2258 TRACE("iface %p, flags %#x.\n", iface
, dwFlags
);
2260 return IDirect3DDevice3_End(&This
->IDirect3DDevice3_iface
, dwFlags
);
2263 /*****************************************************************************
2264 * IDirect3DDevice7::GetRenderState
2266 * Returns the value of a render state. The possible render states are
2267 * defined in include/d3dtypes.h
2269 * Version 2, 3 and 7
2272 * RenderStateType: Render state to return the current setting of
2273 * Value: Address to store the value at
2276 * D3D_OK on success, for details see IWineD3DDevice::GetRenderState
2277 * DDERR_INVALIDPARAMS if Value == NULL
2279 *****************************************************************************/
2280 static HRESULT
IDirect3DDeviceImpl_7_GetRenderState(IDirect3DDevice7
*iface
,
2281 D3DRENDERSTATETYPE RenderStateType
, DWORD
*Value
)
2283 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
2286 TRACE("iface %p, state %#x, value %p.\n", iface
, RenderStateType
, Value
);
2289 return DDERR_INVALIDPARAMS
;
2291 EnterCriticalSection(&ddraw_cs
);
2292 switch(RenderStateType
)
2294 case D3DRENDERSTATE_TEXTUREMAG
:
2296 WINED3DTEXTUREFILTERTYPE tex_mag
;
2298 hr
= wined3d_device_get_sampler_state(This
->wined3d_device
, 0, WINED3DSAMP_MAGFILTER
, &tex_mag
);
2302 case WINED3DTEXF_POINT
:
2303 *Value
= D3DFILTER_NEAREST
;
2305 case WINED3DTEXF_LINEAR
:
2306 *Value
= D3DFILTER_LINEAR
;
2309 ERR("Unhandled texture mag %d !\n",tex_mag
);
2315 case D3DRENDERSTATE_TEXTUREMIN
:
2317 WINED3DTEXTUREFILTERTYPE tex_min
;
2318 WINED3DTEXTUREFILTERTYPE tex_mip
;
2320 hr
= wined3d_device_get_sampler_state(This
->wined3d_device
,
2321 0, WINED3DSAMP_MINFILTER
, &tex_min
);
2324 LeaveCriticalSection(&ddraw_cs
);
2327 hr
= wined3d_device_get_sampler_state(This
->wined3d_device
,
2328 0, WINED3DSAMP_MIPFILTER
, &tex_mip
);
2332 case WINED3DTEXF_POINT
:
2335 case WINED3DTEXF_NONE
:
2336 *Value
= D3DFILTER_NEAREST
;
2338 case WINED3DTEXF_POINT
:
2339 *Value
= D3DFILTER_MIPNEAREST
;
2341 case WINED3DTEXF_LINEAR
:
2342 *Value
= D3DFILTER_LINEARMIPNEAREST
;
2345 ERR("Unhandled mip filter %#x.\n", tex_mip
);
2346 *Value
= D3DFILTER_NEAREST
;
2350 case WINED3DTEXF_LINEAR
:
2353 case WINED3DTEXF_NONE
:
2354 *Value
= D3DFILTER_LINEAR
;
2356 case WINED3DTEXF_POINT
:
2357 *Value
= D3DFILTER_MIPLINEAR
;
2359 case WINED3DTEXF_LINEAR
:
2360 *Value
= D3DFILTER_LINEARMIPLINEAR
;
2363 ERR("Unhandled mip filter %#x.\n", tex_mip
);
2364 *Value
= D3DFILTER_LINEAR
;
2369 ERR("Unhandled texture min filter %#x.\n",tex_min
);
2370 *Value
= D3DFILTER_NEAREST
;
2376 case D3DRENDERSTATE_TEXTUREADDRESS
:
2377 case D3DRENDERSTATE_TEXTUREADDRESSU
:
2378 hr
= wined3d_device_get_sampler_state(This
->wined3d_device
,
2379 0, WINED3DSAMP_ADDRESSU
, Value
);
2381 case D3DRENDERSTATE_TEXTUREADDRESSV
:
2382 hr
= wined3d_device_get_sampler_state(This
->wined3d_device
,
2383 0, WINED3DSAMP_ADDRESSV
, Value
);
2386 case D3DRENDERSTATE_BORDERCOLOR
:
2387 FIXME("Unhandled render state D3DRENDERSTATE_BORDERCOLOR.\n");
2391 case D3DRENDERSTATE_TEXTUREHANDLE
:
2392 case D3DRENDERSTATE_TEXTUREMAPBLEND
:
2393 WARN("Render state %#x is invalid in d3d7.\n", RenderStateType
);
2394 hr
= DDERR_INVALIDPARAMS
;
2397 case D3DRENDERSTATE_ZBIAS
:
2398 hr
= wined3d_device_get_render_state(This
->wined3d_device
, WINED3DRS_DEPTHBIAS
, Value
);
2402 if (RenderStateType
>= D3DRENDERSTATE_STIPPLEPATTERN00
2403 && RenderStateType
<= D3DRENDERSTATE_STIPPLEPATTERN31
)
2405 FIXME("Unhandled stipple pattern render state (%#x).\n",
2410 hr
= wined3d_device_get_render_state(This
->wined3d_device
, RenderStateType
, Value
);
2412 LeaveCriticalSection(&ddraw_cs
);
2416 static HRESULT WINAPI
2417 IDirect3DDeviceImpl_7_GetRenderState_FPUSetup(IDirect3DDevice7
*iface
,
2418 D3DRENDERSTATETYPE RenderStateType
,
2421 return IDirect3DDeviceImpl_7_GetRenderState(iface
, RenderStateType
, Value
);
2424 static HRESULT WINAPI
2425 IDirect3DDeviceImpl_7_GetRenderState_FPUPreserve(IDirect3DDevice7
*iface
,
2426 D3DRENDERSTATETYPE RenderStateType
,
2432 old_fpucw
= d3d_fpu_setup();
2433 hr
= IDirect3DDeviceImpl_7_GetRenderState(iface
, RenderStateType
, Value
);
2434 set_fpu_control_word(old_fpucw
);
2439 static HRESULT WINAPI
2440 IDirect3DDeviceImpl_3_GetRenderState(IDirect3DDevice3
*iface
,
2441 D3DRENDERSTATETYPE dwRenderStateType
,
2442 DWORD
*lpdwRenderState
)
2444 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
2447 TRACE("iface %p, state %#x, value %p.\n", iface
, dwRenderStateType
, lpdwRenderState
);
2449 switch(dwRenderStateType
)
2451 case D3DRENDERSTATE_TEXTUREHANDLE
:
2453 /* This state is wrapped to SetTexture in SetRenderState, so
2454 * it has to be wrapped to GetTexture here. */
2455 struct wined3d_texture
*tex
= NULL
;
2456 *lpdwRenderState
= 0;
2458 EnterCriticalSection(&ddraw_cs
);
2460 hr
= wined3d_device_get_texture(This
->wined3d_device
, 0, &tex
);
2461 if (SUCCEEDED(hr
) && tex
)
2463 /* The parent of the texture is the IDirectDrawSurface7
2464 * interface of the ddraw surface. */
2465 IDirectDrawSurfaceImpl
*parent
= wined3d_texture_get_parent(tex
);
2466 if (parent
) *lpdwRenderState
= parent
->Handle
;
2467 wined3d_texture_decref(tex
);
2470 LeaveCriticalSection(&ddraw_cs
);
2475 case D3DRENDERSTATE_TEXTUREMAPBLEND
:
2477 /* D3DRENDERSTATE_TEXTUREMAPBLEND is mapped to texture state stages in SetRenderState; reverse
2478 the mapping to get the value. */
2479 DWORD colorop
, colorarg1
, colorarg2
;
2480 DWORD alphaop
, alphaarg1
, alphaarg2
;
2482 EnterCriticalSection(&ddraw_cs
);
2484 This
->legacyTextureBlending
= TRUE
;
2486 wined3d_device_get_texture_stage_state(This
->wined3d_device
, 0, WINED3DTSS_COLOROP
, &colorop
);
2487 wined3d_device_get_texture_stage_state(This
->wined3d_device
, 0, WINED3DTSS_COLORARG1
, &colorarg1
);
2488 wined3d_device_get_texture_stage_state(This
->wined3d_device
, 0, WINED3DTSS_COLORARG2
, &colorarg2
);
2489 wined3d_device_get_texture_stage_state(This
->wined3d_device
, 0, WINED3DTSS_ALPHAOP
, &alphaop
);
2490 wined3d_device_get_texture_stage_state(This
->wined3d_device
, 0, WINED3DTSS_ALPHAARG1
, &alphaarg1
);
2491 wined3d_device_get_texture_stage_state(This
->wined3d_device
, 0, WINED3DTSS_ALPHAARG2
, &alphaarg2
);
2493 if (colorop
== WINED3DTOP_SELECTARG1
&& colorarg1
== WINED3DTA_TEXTURE
&&
2494 alphaop
== WINED3DTOP_SELECTARG1
&& alphaarg1
== WINED3DTA_TEXTURE
)
2496 *lpdwRenderState
= D3DTBLEND_DECAL
;
2498 else if (colorop
== WINED3DTOP_SELECTARG1
&& colorarg1
== WINED3DTA_TEXTURE
&&
2499 alphaop
== WINED3DTOP_MODULATE
&& alphaarg1
== WINED3DTA_TEXTURE
&& alphaarg2
== WINED3DTA_CURRENT
)
2501 *lpdwRenderState
= D3DTBLEND_DECALALPHA
;
2503 else if (colorop
== WINED3DTOP_MODULATE
&& colorarg1
== WINED3DTA_TEXTURE
&& colorarg2
== WINED3DTA_CURRENT
&&
2504 alphaop
== WINED3DTOP_MODULATE
&& alphaarg1
== WINED3DTA_TEXTURE
&& alphaarg2
== WINED3DTA_CURRENT
)
2506 *lpdwRenderState
= D3DTBLEND_MODULATEALPHA
;
2510 struct wined3d_texture
*tex
= NULL
;
2512 BOOL tex_alpha
= FALSE
;
2513 DDPIXELFORMAT ddfmt
;
2515 hr
= wined3d_device_get_texture(This
->wined3d_device
, 0, &tex
);
2517 if(hr
== WINED3D_OK
&& tex
)
2519 struct wined3d_resource
*sub_resource
;
2521 if ((sub_resource
= wined3d_texture_get_sub_resource(tex
, 0)))
2523 struct wined3d_resource_desc desc
;
2525 wined3d_resource_get_desc(sub_resource
, &desc
);
2526 ddfmt
.dwSize
= sizeof(ddfmt
);
2527 PixelFormat_WineD3DtoDD(&ddfmt
, desc
.format
);
2528 if (ddfmt
.u5
.dwRGBAlphaBitMask
) tex_alpha
= TRUE
;
2531 wined3d_texture_decref(tex
);
2534 if (!(colorop
== WINED3DTOP_MODULATE
&& colorarg1
== WINED3DTA_TEXTURE
&& colorarg2
== WINED3DTA_CURRENT
&&
2535 alphaop
== (tex_alpha
? WINED3DTOP_SELECTARG1
: WINED3DTOP_SELECTARG2
) &&
2536 alphaarg1
== WINED3DTA_TEXTURE
&& alphaarg2
== WINED3DTA_CURRENT
))
2538 ERR("Unexpected texture stage state setup, returning D3DTBLEND_MODULATE - likely erroneous\n");
2541 *lpdwRenderState
= D3DTBLEND_MODULATE
;
2544 LeaveCriticalSection(&ddraw_cs
);
2550 return IDirect3DDevice7_GetRenderState(&This
->IDirect3DDevice7_iface
, dwRenderStateType
, lpdwRenderState
);
2554 static HRESULT WINAPI
IDirect3DDeviceImpl_2_GetRenderState(IDirect3DDevice2
*iface
,
2555 D3DRENDERSTATETYPE dwRenderStateType
, DWORD
*lpdwRenderState
)
2557 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
2559 TRACE("iface %p, state %#x, value %p.\n", iface
, dwRenderStateType
, lpdwRenderState
);
2561 return IDirect3DDevice3_GetRenderState(&This
->IDirect3DDevice3_iface
,
2562 dwRenderStateType
, lpdwRenderState
);
2565 /*****************************************************************************
2566 * IDirect3DDevice7::SetRenderState
2568 * Sets a render state. The possible render states are defined in
2569 * include/d3dtypes.h
2571 * Version 2, 3 and 7
2574 * RenderStateType: State to set
2575 * Value: Value to assign to that state
2578 * D3D_OK on success,
2579 * for details see IWineD3DDevice::SetRenderState
2581 *****************************************************************************/
2583 IDirect3DDeviceImpl_7_SetRenderState(IDirect3DDevice7
*iface
,
2584 D3DRENDERSTATETYPE RenderStateType
,
2587 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
2590 TRACE("iface %p, state %#x, value %#x.\n", iface
, RenderStateType
, Value
);
2592 EnterCriticalSection(&ddraw_cs
);
2593 /* Some render states need special care */
2594 switch(RenderStateType
)
2597 * The ddraw texture filter mapping works like this:
2598 * D3DFILTER_NEAREST Point min/mag, no mip
2599 * D3DFILTER_MIPNEAREST Point min/mag, point mip
2600 * D3DFILTER_LINEARMIPNEAREST: Point min/mag, linear mip
2602 * D3DFILTER_LINEAR Linear min/mag, no mip
2603 * D3DFILTER_MIPLINEAR Linear min/mag, point mip
2604 * D3DFILTER_LINEARMIPLINEAR Linear min/mag, linear mip
2606 * This is the opposite of the GL naming convention,
2607 * D3DFILTER_LINEARMIPNEAREST corresponds to GL_NEAREST_MIPMAP_LINEAR.
2609 case D3DRENDERSTATE_TEXTUREMAG
:
2611 WINED3DTEXTUREFILTERTYPE tex_mag
;
2615 case D3DFILTER_NEAREST
:
2616 case D3DFILTER_MIPNEAREST
:
2617 case D3DFILTER_LINEARMIPNEAREST
:
2618 tex_mag
= WINED3DTEXF_POINT
;
2620 case D3DFILTER_LINEAR
:
2621 case D3DFILTER_MIPLINEAR
:
2622 case D3DFILTER_LINEARMIPLINEAR
:
2623 tex_mag
= WINED3DTEXF_LINEAR
;
2626 tex_mag
= WINED3DTEXF_POINT
;
2627 ERR("Unhandled texture mag %d !\n",Value
);
2631 hr
= wined3d_device_set_sampler_state(This
->wined3d_device
, 0, WINED3DSAMP_MAGFILTER
, tex_mag
);
2635 case D3DRENDERSTATE_TEXTUREMIN
:
2637 WINED3DTEXTUREFILTERTYPE tex_min
;
2638 WINED3DTEXTUREFILTERTYPE tex_mip
;
2640 switch ((D3DTEXTUREFILTER
) Value
)
2642 case D3DFILTER_NEAREST
:
2643 tex_min
= WINED3DTEXF_POINT
;
2644 tex_mip
= WINED3DTEXF_NONE
;
2646 case D3DFILTER_LINEAR
:
2647 tex_min
= WINED3DTEXF_LINEAR
;
2648 tex_mip
= WINED3DTEXF_NONE
;
2650 case D3DFILTER_MIPNEAREST
:
2651 tex_min
= WINED3DTEXF_POINT
;
2652 tex_mip
= WINED3DTEXF_POINT
;
2654 case D3DFILTER_MIPLINEAR
:
2655 tex_min
= WINED3DTEXF_LINEAR
;
2656 tex_mip
= WINED3DTEXF_POINT
;
2658 case D3DFILTER_LINEARMIPNEAREST
:
2659 tex_min
= WINED3DTEXF_POINT
;
2660 tex_mip
= WINED3DTEXF_LINEAR
;
2662 case D3DFILTER_LINEARMIPLINEAR
:
2663 tex_min
= WINED3DTEXF_LINEAR
;
2664 tex_mip
= WINED3DTEXF_LINEAR
;
2668 ERR("Unhandled texture min %d !\n",Value
);
2669 tex_min
= WINED3DTEXF_POINT
;
2670 tex_mip
= WINED3DTEXF_NONE
;
2674 wined3d_device_set_sampler_state(This
->wined3d_device
,
2675 0, WINED3DSAMP_MIPFILTER
, tex_mip
);
2676 hr
= wined3d_device_set_sampler_state(This
->wined3d_device
,
2677 0, WINED3DSAMP_MINFILTER
, tex_min
);
2681 case D3DRENDERSTATE_TEXTUREADDRESS
:
2682 wined3d_device_set_sampler_state(This
->wined3d_device
,
2683 0, WINED3DSAMP_ADDRESSV
, Value
);
2685 case D3DRENDERSTATE_TEXTUREADDRESSU
:
2686 hr
= wined3d_device_set_sampler_state(This
->wined3d_device
,
2687 0, WINED3DSAMP_ADDRESSU
, Value
);
2689 case D3DRENDERSTATE_TEXTUREADDRESSV
:
2690 hr
= wined3d_device_set_sampler_state(This
->wined3d_device
,
2691 0, WINED3DSAMP_ADDRESSV
, Value
);
2694 case D3DRENDERSTATE_BORDERCOLOR
:
2695 /* This should probably just forward to the corresponding sampler
2696 * state. Needs tests. */
2697 FIXME("Unhandled render state D3DRENDERSTATE_BORDERCOLOR.\n");
2701 case D3DRENDERSTATE_TEXTUREHANDLE
:
2702 case D3DRENDERSTATE_TEXTUREMAPBLEND
:
2703 WARN("Render state %#x is invalid in d3d7.\n", RenderStateType
);
2704 hr
= DDERR_INVALIDPARAMS
;
2707 case D3DRENDERSTATE_ZBIAS
:
2708 hr
= wined3d_device_set_render_state(This
->wined3d_device
, WINED3DRS_DEPTHBIAS
, Value
);
2712 if (RenderStateType
>= D3DRENDERSTATE_STIPPLEPATTERN00
2713 && RenderStateType
<= D3DRENDERSTATE_STIPPLEPATTERN31
)
2715 FIXME("Unhandled stipple pattern render state (%#x).\n",
2721 hr
= wined3d_device_set_render_state(This
->wined3d_device
, RenderStateType
, Value
);
2724 LeaveCriticalSection(&ddraw_cs
);
2728 static HRESULT WINAPI
2729 IDirect3DDeviceImpl_7_SetRenderState_FPUSetup(IDirect3DDevice7
*iface
,
2730 D3DRENDERSTATETYPE RenderStateType
,
2733 return IDirect3DDeviceImpl_7_SetRenderState(iface
, RenderStateType
, Value
);
2736 static HRESULT WINAPI
2737 IDirect3DDeviceImpl_7_SetRenderState_FPUPreserve(IDirect3DDevice7
*iface
,
2738 D3DRENDERSTATETYPE RenderStateType
,
2744 old_fpucw
= d3d_fpu_setup();
2745 hr
= IDirect3DDeviceImpl_7_SetRenderState(iface
, RenderStateType
, Value
);
2746 set_fpu_control_word(old_fpucw
);
2751 static HRESULT WINAPI
2752 IDirect3DDeviceImpl_3_SetRenderState(IDirect3DDevice3
*iface
,
2753 D3DRENDERSTATETYPE RenderStateType
,
2756 /* Note about D3DRENDERSTATE_TEXTUREMAPBLEND implementation: most of values
2757 for this state can be directly mapped to texture stage colorop and alphaop, but
2758 D3DTBLEND_MODULATE is tricky: it uses alpha from texture when available and alpha
2759 from diffuse otherwise. So changing the texture must be monitored in SetTexture to modify
2760 alphaarg when needed.
2762 Aliens vs Predator 1 depends on accurate D3DTBLEND_MODULATE emulation
2764 Legacy texture blending (TEXTUREMAPBLEND) and texture stage states: directx6 docs state that
2765 TEXTUREMAPBLEND is deprecated, yet can still be used. Games must not use both or results
2766 are undefined. D3DTBLEND_MODULATE mode in particular is dependent on texture pixel format and
2767 requires fixup of stage 0 texture states when texture changes, but this fixup can interfere
2768 with games not using this deprecated state. So a flag 'legacyTextureBlending' has to be kept
2769 in device - TRUE if the app is using TEXTUREMAPBLEND.
2771 Tests show that setting TEXTUREMAPBLEND on native doesn't seem to change values returned by
2772 GetTextureStageState and vice versa. Not so on Wine, but it is 'undefined' anyway so, probably, ok,
2773 unless some broken game will be found that cares. */
2776 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
2778 TRACE("iface %p, state %#x, value %#x.\n", iface
, RenderStateType
, Value
);
2780 EnterCriticalSection(&ddraw_cs
);
2782 switch(RenderStateType
)
2784 case D3DRENDERSTATE_TEXTUREHANDLE
:
2786 IDirectDrawSurfaceImpl
*surf
;
2790 hr
= wined3d_device_set_texture(This
->wined3d_device
, 0, NULL
);
2794 surf
= ddraw_get_object(&This
->handle_table
, Value
- 1, DDRAW_HANDLE_SURFACE
);
2797 WARN("Invalid texture handle.\n");
2798 hr
= DDERR_INVALIDPARAMS
;
2802 hr
= IDirect3DDevice3_SetTexture(iface
, 0, &surf
->IDirect3DTexture2_iface
);
2806 case D3DRENDERSTATE_TEXTUREMAPBLEND
:
2808 This
->legacyTextureBlending
= TRUE
;
2810 switch ( (D3DTEXTUREBLEND
) Value
)
2812 case D3DTBLEND_MODULATE
:
2814 struct wined3d_texture
*tex
= NULL
;
2815 BOOL tex_alpha
= FALSE
;
2816 DDPIXELFORMAT ddfmt
;
2818 hr
= wined3d_device_get_texture(This
->wined3d_device
, 0, &tex
);
2820 if(hr
== WINED3D_OK
&& tex
)
2822 struct wined3d_resource
*sub_resource
;
2824 if ((sub_resource
= wined3d_texture_get_sub_resource(tex
, 0)))
2826 struct wined3d_resource_desc desc
;
2828 wined3d_resource_get_desc(sub_resource
, &desc
);
2829 ddfmt
.dwSize
= sizeof(ddfmt
);
2830 PixelFormat_WineD3DtoDD(&ddfmt
, desc
.format
);
2831 if (ddfmt
.u5
.dwRGBAlphaBitMask
) tex_alpha
= TRUE
;
2834 wined3d_texture_decref(tex
);
2838 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2839 0, WINED3DTSS_ALPHAOP
, WINED3DTOP_SELECTARG1
);
2841 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2842 0, WINED3DTSS_ALPHAOP
, WINED3DTOP_SELECTARG2
);
2843 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2844 0, WINED3DTSS_ALPHAARG1
, WINED3DTA_TEXTURE
);
2845 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2846 0, WINED3DTSS_ALPHAARG2
, WINED3DTA_CURRENT
);
2847 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2848 0, WINED3DTSS_COLORARG1
, WINED3DTA_TEXTURE
);
2849 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2850 0, WINED3DTSS_COLORARG2
, WINED3DTA_CURRENT
);
2851 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2852 0, WINED3DTSS_COLOROP
, WINED3DTOP_MODULATE
);
2857 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2858 0, WINED3DTSS_COLOROP
, WINED3DTOP_ADD
);
2859 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2860 0, WINED3DTSS_COLORARG1
, WINED3DTA_TEXTURE
);
2861 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2862 0, WINED3DTSS_COLORARG2
, WINED3DTA_CURRENT
);
2863 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2864 0, WINED3DTSS_ALPHAOP
, WINED3DTOP_SELECTARG2
);
2865 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2866 0, WINED3DTSS_ALPHAARG2
, WINED3DTA_CURRENT
);
2869 case D3DTBLEND_MODULATEALPHA
:
2870 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2871 0, WINED3DTSS_COLORARG1
, WINED3DTA_TEXTURE
);
2872 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2873 0, WINED3DTSS_ALPHAARG1
, WINED3DTA_TEXTURE
);
2874 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2875 0, WINED3DTSS_COLORARG2
, WINED3DTA_CURRENT
);
2876 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2877 0, WINED3DTSS_ALPHAARG2
, WINED3DTA_CURRENT
);
2878 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2879 0, WINED3DTSS_COLOROP
, WINED3DTOP_MODULATE
);
2880 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2881 0, WINED3DTSS_ALPHAOP
, WINED3DTOP_MODULATE
);
2884 case D3DTBLEND_COPY
:
2885 case D3DTBLEND_DECAL
:
2886 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2887 0, WINED3DTSS_COLORARG1
, WINED3DTA_TEXTURE
);
2888 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2889 0, WINED3DTSS_ALPHAARG1
, WINED3DTA_TEXTURE
);
2890 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2891 0, WINED3DTSS_COLOROP
, WINED3DTOP_SELECTARG1
);
2892 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2893 0, WINED3DTSS_ALPHAOP
, WINED3DTOP_SELECTARG1
);
2896 case D3DTBLEND_DECALALPHA
:
2897 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2898 0, WINED3DTSS_COLOROP
, WINED3DTOP_BLENDTEXTUREALPHA
);
2899 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2900 0, WINED3DTSS_COLORARG1
, WINED3DTA_TEXTURE
);
2901 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2902 0, WINED3DTSS_COLORARG2
, WINED3DTA_CURRENT
);
2903 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2904 0, WINED3DTSS_ALPHAOP
, WINED3DTOP_SELECTARG2
);
2905 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2906 0, WINED3DTSS_ALPHAARG2
, WINED3DTA_CURRENT
);
2910 ERR("Unhandled texture environment %d !\n",Value
);
2918 hr
= IDirect3DDevice7_SetRenderState(&This
->IDirect3DDevice7_iface
, RenderStateType
, Value
);
2922 LeaveCriticalSection(&ddraw_cs
);
2927 static HRESULT WINAPI
IDirect3DDeviceImpl_2_SetRenderState(IDirect3DDevice2
*iface
,
2928 D3DRENDERSTATETYPE RenderStateType
, DWORD Value
)
2930 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
2932 TRACE("iface %p, state %#x, value %#x.\n", iface
, RenderStateType
, Value
);
2934 return IDirect3DDevice3_SetRenderState(&This
->IDirect3DDevice3_iface
, RenderStateType
, Value
);
2937 /*****************************************************************************
2938 * Direct3DDevice3::SetLightState
2940 * Sets a light state for Direct3DDevice3 and Direct3DDevice2. The
2941 * light states are forwarded to Direct3DDevice7 render states
2946 * LightStateType: The light state to change
2947 * Value: The value to assign to that light state
2951 * DDERR_INVALIDPARAMS if the parameters were incorrect
2952 * Also check IDirect3DDevice7::SetRenderState
2954 *****************************************************************************/
2955 static HRESULT WINAPI
2956 IDirect3DDeviceImpl_3_SetLightState(IDirect3DDevice3
*iface
,
2957 D3DLIGHTSTATETYPE LightStateType
,
2960 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
2963 TRACE("iface %p, state %#x, value %#x.\n", iface
, LightStateType
, Value
);
2965 if (!LightStateType
|| (LightStateType
> D3DLIGHTSTATE_COLORVERTEX
))
2967 TRACE("Unexpected Light State Type\n");
2968 return DDERR_INVALIDPARAMS
;
2971 EnterCriticalSection(&ddraw_cs
);
2972 if (LightStateType
== D3DLIGHTSTATE_MATERIAL
/* 1 */)
2974 IDirect3DMaterialImpl
*m
= ddraw_get_object(&This
->handle_table
, Value
- 1, DDRAW_HANDLE_MATERIAL
);
2977 WARN("Invalid material handle.\n");
2978 LeaveCriticalSection(&ddraw_cs
);
2979 return DDERR_INVALIDPARAMS
;
2982 TRACE(" activating material %p.\n", m
);
2983 material_activate(m
);
2985 This
->material
= Value
;
2987 else if (LightStateType
== D3DLIGHTSTATE_COLORMODEL
/* 3 */)
2992 ERR("DDCOLOR_MONO should not happen!\n");
2995 /* We are already in this mode */
2996 TRACE("Setting color model to RGB (no-op).\n");
2999 ERR("Unknown color model!\n");
3000 LeaveCriticalSection(&ddraw_cs
);
3001 return DDERR_INVALIDPARAMS
;
3006 D3DRENDERSTATETYPE rs
;
3007 switch (LightStateType
)
3009 case D3DLIGHTSTATE_AMBIENT
: /* 2 */
3010 rs
= D3DRENDERSTATE_AMBIENT
;
3012 case D3DLIGHTSTATE_FOGMODE
: /* 4 */
3013 rs
= D3DRENDERSTATE_FOGVERTEXMODE
;
3015 case D3DLIGHTSTATE_FOGSTART
: /* 5 */
3016 rs
= D3DRENDERSTATE_FOGSTART
;
3018 case D3DLIGHTSTATE_FOGEND
: /* 6 */
3019 rs
= D3DRENDERSTATE_FOGEND
;
3021 case D3DLIGHTSTATE_FOGDENSITY
: /* 7 */
3022 rs
= D3DRENDERSTATE_FOGDENSITY
;
3024 case D3DLIGHTSTATE_COLORVERTEX
: /* 8 */
3025 rs
= D3DRENDERSTATE_COLORVERTEX
;
3028 ERR("Unknown D3DLIGHTSTATETYPE %d.\n", LightStateType
);
3029 LeaveCriticalSection(&ddraw_cs
);
3030 return DDERR_INVALIDPARAMS
;
3033 hr
= IDirect3DDevice7_SetRenderState(&This
->IDirect3DDevice7_iface
, rs
, Value
);
3034 LeaveCriticalSection(&ddraw_cs
);
3038 LeaveCriticalSection(&ddraw_cs
);
3042 static HRESULT WINAPI
IDirect3DDeviceImpl_2_SetLightState(IDirect3DDevice2
*iface
,
3043 D3DLIGHTSTATETYPE LightStateType
, DWORD Value
)
3045 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
3047 TRACE("iface %p, state %#x, value %#x.\n", iface
, LightStateType
, Value
);
3049 return IDirect3DDevice3_SetLightState(&This
->IDirect3DDevice3_iface
, LightStateType
, Value
);
3052 /*****************************************************************************
3053 * IDirect3DDevice3::GetLightState
3055 * Returns the current setting of a light state. The state is read from
3056 * the Direct3DDevice7 render state.
3061 * LightStateType: The light state to return
3062 * Value: The address to store the light state setting at
3066 * DDDERR_INVALIDPARAMS if the parameters were incorrect
3067 * Also see IDirect3DDevice7::GetRenderState
3069 *****************************************************************************/
3070 static HRESULT WINAPI
3071 IDirect3DDeviceImpl_3_GetLightState(IDirect3DDevice3
*iface
,
3072 D3DLIGHTSTATETYPE LightStateType
,
3075 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
3078 TRACE("iface %p, state %#x, value %p.\n", iface
, LightStateType
, Value
);
3080 if (!LightStateType
|| (LightStateType
> D3DLIGHTSTATE_COLORVERTEX
))
3082 TRACE("Unexpected Light State Type\n");
3083 return DDERR_INVALIDPARAMS
;
3087 return DDERR_INVALIDPARAMS
;
3089 EnterCriticalSection(&ddraw_cs
);
3090 if (LightStateType
== D3DLIGHTSTATE_MATERIAL
/* 1 */)
3092 *Value
= This
->material
;
3094 else if (LightStateType
== D3DLIGHTSTATE_COLORMODEL
/* 3 */)
3096 *Value
= D3DCOLOR_RGB
;
3100 D3DRENDERSTATETYPE rs
;
3101 switch (LightStateType
)
3103 case D3DLIGHTSTATE_AMBIENT
: /* 2 */
3104 rs
= D3DRENDERSTATE_AMBIENT
;
3106 case D3DLIGHTSTATE_FOGMODE
: /* 4 */
3107 rs
= D3DRENDERSTATE_FOGVERTEXMODE
;
3109 case D3DLIGHTSTATE_FOGSTART
: /* 5 */
3110 rs
= D3DRENDERSTATE_FOGSTART
;
3112 case D3DLIGHTSTATE_FOGEND
: /* 6 */
3113 rs
= D3DRENDERSTATE_FOGEND
;
3115 case D3DLIGHTSTATE_FOGDENSITY
: /* 7 */
3116 rs
= D3DRENDERSTATE_FOGDENSITY
;
3118 case D3DLIGHTSTATE_COLORVERTEX
: /* 8 */
3119 rs
= D3DRENDERSTATE_COLORVERTEX
;
3122 ERR("Unknown D3DLIGHTSTATETYPE %d.\n", LightStateType
);
3123 LeaveCriticalSection(&ddraw_cs
);
3124 return DDERR_INVALIDPARAMS
;
3127 hr
= IDirect3DDevice7_GetRenderState(&This
->IDirect3DDevice7_iface
, rs
, Value
);
3128 LeaveCriticalSection(&ddraw_cs
);
3132 LeaveCriticalSection(&ddraw_cs
);
3136 static HRESULT WINAPI
IDirect3DDeviceImpl_2_GetLightState(IDirect3DDevice2
*iface
,
3137 D3DLIGHTSTATETYPE LightStateType
, DWORD
*Value
)
3139 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
3141 TRACE("iface %p, state %#x, value %p.\n", iface
, LightStateType
, Value
);
3143 return IDirect3DDevice3_GetLightState(&This
->IDirect3DDevice3_iface
, LightStateType
, Value
);
3146 /*****************************************************************************
3147 * IDirect3DDevice7::SetTransform
3149 * Assigns a D3DMATRIX to a transform type. The transform types are defined
3150 * in include/d3dtypes.h.
3151 * The D3DTRANSFORMSTATE_WORLD (=1) is translated to D3DTS_WORLDMATRIX(0)
3152 * (=255) for wined3d, because the 1 transform state was removed in d3d8
3153 * and WineD3D already understands the replacement D3DTS_WORLDMATRIX(0)
3155 * Version 2, 3 and 7
3158 * TransformStateType: transform state to set
3159 * Matrix: Matrix to assign to the state
3163 * DDERR_INVALIDPARAMS if Matrix == NULL
3164 * For details see IWineD3DDevice::SetTransform
3166 *****************************************************************************/
3168 IDirect3DDeviceImpl_7_SetTransform(IDirect3DDevice7
*iface
,
3169 D3DTRANSFORMSTATETYPE TransformStateType
,
3172 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
3173 D3DTRANSFORMSTATETYPE type
;
3176 TRACE("iface %p, state %#x, matrix %p.\n", iface
, TransformStateType
, Matrix
);
3178 switch(TransformStateType
)
3180 case D3DTRANSFORMSTATE_WORLD
: type
= WINED3DTS_WORLDMATRIX(0); break;
3181 case D3DTRANSFORMSTATE_WORLD1
: type
= WINED3DTS_WORLDMATRIX(1); break;
3182 case D3DTRANSFORMSTATE_WORLD2
: type
= WINED3DTS_WORLDMATRIX(2); break;
3183 case D3DTRANSFORMSTATE_WORLD3
: type
= WINED3DTS_WORLDMATRIX(3); break;
3184 default: type
= TransformStateType
;
3188 return DDERR_INVALIDPARAMS
;
3190 /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
3191 EnterCriticalSection(&ddraw_cs
);
3192 hr
= wined3d_device_set_transform(This
->wined3d_device
, type
, (WINED3DMATRIX
*)Matrix
);
3193 LeaveCriticalSection(&ddraw_cs
);
3197 static HRESULT WINAPI
3198 IDirect3DDeviceImpl_7_SetTransform_FPUSetup(IDirect3DDevice7
*iface
,
3199 D3DTRANSFORMSTATETYPE TransformStateType
,
3202 return IDirect3DDeviceImpl_7_SetTransform(iface
, TransformStateType
, Matrix
);
3205 static HRESULT WINAPI
3206 IDirect3DDeviceImpl_7_SetTransform_FPUPreserve(IDirect3DDevice7
*iface
,
3207 D3DTRANSFORMSTATETYPE TransformStateType
,
3213 old_fpucw
= d3d_fpu_setup();
3214 hr
= IDirect3DDeviceImpl_7_SetTransform(iface
, TransformStateType
, Matrix
);
3215 set_fpu_control_word(old_fpucw
);
3220 static HRESULT WINAPI
IDirect3DDeviceImpl_3_SetTransform(IDirect3DDevice3
*iface
,
3221 D3DTRANSFORMSTATETYPE TransformStateType
, D3DMATRIX
*D3DMatrix
)
3223 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
3225 TRACE("iface %p, state %#x, matrix %p.\n", iface
, TransformStateType
, D3DMatrix
);
3227 return IDirect3DDevice7_SetTransform(&This
->IDirect3DDevice7_iface
, TransformStateType
, D3DMatrix
);
3230 static HRESULT WINAPI
IDirect3DDeviceImpl_2_SetTransform(IDirect3DDevice2
*iface
,
3231 D3DTRANSFORMSTATETYPE TransformStateType
, D3DMATRIX
*D3DMatrix
)
3233 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
3235 TRACE("iface %p, state %#x, matrix %p.\n", iface
, TransformStateType
, D3DMatrix
);
3237 return IDirect3DDevice7_SetTransform(&This
->IDirect3DDevice7_iface
, TransformStateType
, D3DMatrix
);
3240 /*****************************************************************************
3241 * IDirect3DDevice7::GetTransform
3243 * Returns the matrix assigned to a transform state
3244 * D3DTRANSFORMSTATE_WORLD is translated to D3DTS_WORLDMATRIX(0), see
3248 * TransformStateType: State to read the matrix from
3249 * Matrix: Address to store the matrix at
3253 * DDERR_INVALIDPARAMS if Matrix == NULL
3254 * For details, see IWineD3DDevice::GetTransform
3256 *****************************************************************************/
3258 IDirect3DDeviceImpl_7_GetTransform(IDirect3DDevice7
*iface
,
3259 D3DTRANSFORMSTATETYPE TransformStateType
,
3262 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
3263 D3DTRANSFORMSTATETYPE type
;
3266 TRACE("iface %p, state %#x, matrix %p.\n", iface
, TransformStateType
, Matrix
);
3268 switch(TransformStateType
)
3270 case D3DTRANSFORMSTATE_WORLD
: type
= WINED3DTS_WORLDMATRIX(0); break;
3271 case D3DTRANSFORMSTATE_WORLD1
: type
= WINED3DTS_WORLDMATRIX(1); break;
3272 case D3DTRANSFORMSTATE_WORLD2
: type
= WINED3DTS_WORLDMATRIX(2); break;
3273 case D3DTRANSFORMSTATE_WORLD3
: type
= WINED3DTS_WORLDMATRIX(3); break;
3274 default: type
= TransformStateType
;
3278 return DDERR_INVALIDPARAMS
;
3280 /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
3281 EnterCriticalSection(&ddraw_cs
);
3282 hr
= wined3d_device_get_transform(This
->wined3d_device
, type
, (WINED3DMATRIX
*)Matrix
);
3283 LeaveCriticalSection(&ddraw_cs
);
3287 static HRESULT WINAPI
3288 IDirect3DDeviceImpl_7_GetTransform_FPUSetup(IDirect3DDevice7
*iface
,
3289 D3DTRANSFORMSTATETYPE TransformStateType
,
3292 return IDirect3DDeviceImpl_7_GetTransform(iface
, TransformStateType
, Matrix
);
3295 static HRESULT WINAPI
3296 IDirect3DDeviceImpl_7_GetTransform_FPUPreserve(IDirect3DDevice7
*iface
,
3297 D3DTRANSFORMSTATETYPE TransformStateType
,
3303 old_fpucw
= d3d_fpu_setup();
3304 hr
= IDirect3DDeviceImpl_7_GetTransform(iface
, TransformStateType
, Matrix
);
3305 set_fpu_control_word(old_fpucw
);
3310 static HRESULT WINAPI
IDirect3DDeviceImpl_3_GetTransform(IDirect3DDevice3
*iface
,
3311 D3DTRANSFORMSTATETYPE TransformStateType
, D3DMATRIX
*D3DMatrix
)
3313 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
3315 TRACE("iface %p, state %#x, matrix %p.\n", iface
, TransformStateType
, D3DMatrix
);
3317 return IDirect3DDevice7_GetTransform(&This
->IDirect3DDevice7_iface
, TransformStateType
, D3DMatrix
);
3320 static HRESULT WINAPI
IDirect3DDeviceImpl_2_GetTransform(IDirect3DDevice2
*iface
,
3321 D3DTRANSFORMSTATETYPE TransformStateType
, D3DMATRIX
*D3DMatrix
)
3323 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
3325 TRACE("iface %p, state %#x, matrix %p.\n", iface
, TransformStateType
, D3DMatrix
);
3327 return IDirect3DDevice7_GetTransform(&This
->IDirect3DDevice7_iface
, TransformStateType
, D3DMatrix
);
3330 /*****************************************************************************
3331 * IDirect3DDevice7::MultiplyTransform
3333 * Multiplies the already-set transform matrix of a transform state
3334 * with another matrix. For the world matrix, see SetTransform
3336 * Version 2, 3 and 7
3339 * TransformStateType: Transform state to multiply
3340 * D3DMatrix Matrix to multiply with.
3344 * DDERR_INVALIDPARAMS if D3DMatrix is NULL
3345 * For details, see IWineD3DDevice::MultiplyTransform
3347 *****************************************************************************/
3349 IDirect3DDeviceImpl_7_MultiplyTransform(IDirect3DDevice7
*iface
,
3350 D3DTRANSFORMSTATETYPE TransformStateType
,
3351 D3DMATRIX
*D3DMatrix
)
3353 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
3355 D3DTRANSFORMSTATETYPE type
;
3357 TRACE("iface %p, state %#x, matrix %p.\n", iface
, TransformStateType
, D3DMatrix
);
3359 switch(TransformStateType
)
3361 case D3DTRANSFORMSTATE_WORLD
: type
= WINED3DTS_WORLDMATRIX(0); break;
3362 case D3DTRANSFORMSTATE_WORLD1
: type
= WINED3DTS_WORLDMATRIX(1); break;
3363 case D3DTRANSFORMSTATE_WORLD2
: type
= WINED3DTS_WORLDMATRIX(2); break;
3364 case D3DTRANSFORMSTATE_WORLD3
: type
= WINED3DTS_WORLDMATRIX(3); break;
3365 default: type
= TransformStateType
;
3368 /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
3369 EnterCriticalSection(&ddraw_cs
);
3370 hr
= wined3d_device_multiply_transform(This
->wined3d_device
,
3371 type
, (WINED3DMATRIX
*)D3DMatrix
);
3372 LeaveCriticalSection(&ddraw_cs
);
3376 static HRESULT WINAPI
3377 IDirect3DDeviceImpl_7_MultiplyTransform_FPUSetup(IDirect3DDevice7
*iface
,
3378 D3DTRANSFORMSTATETYPE TransformStateType
,
3379 D3DMATRIX
*D3DMatrix
)
3381 return IDirect3DDeviceImpl_7_MultiplyTransform(iface
, TransformStateType
, D3DMatrix
);
3384 static HRESULT WINAPI
3385 IDirect3DDeviceImpl_7_MultiplyTransform_FPUPreserve(IDirect3DDevice7
*iface
,
3386 D3DTRANSFORMSTATETYPE TransformStateType
,
3387 D3DMATRIX
*D3DMatrix
)
3392 old_fpucw
= d3d_fpu_setup();
3393 hr
= IDirect3DDeviceImpl_7_MultiplyTransform(iface
, TransformStateType
, D3DMatrix
);
3394 set_fpu_control_word(old_fpucw
);
3399 static HRESULT WINAPI
IDirect3DDeviceImpl_3_MultiplyTransform(IDirect3DDevice3
*iface
,
3400 D3DTRANSFORMSTATETYPE TransformStateType
, D3DMATRIX
*D3DMatrix
)
3402 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
3404 TRACE("iface %p, state %#x, matrix %p.\n", iface
, TransformStateType
, D3DMatrix
);
3406 return IDirect3DDevice7_MultiplyTransform(&This
->IDirect3DDevice7_iface
, TransformStateType
, D3DMatrix
);
3409 static HRESULT WINAPI
IDirect3DDeviceImpl_2_MultiplyTransform(IDirect3DDevice2
*iface
,
3410 D3DTRANSFORMSTATETYPE TransformStateType
, D3DMATRIX
*D3DMatrix
)
3412 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
3414 TRACE("iface %p, state %#x, matrix %p.\n", iface
, TransformStateType
, D3DMatrix
);
3416 return IDirect3DDevice7_MultiplyTransform(&This
->IDirect3DDevice7_iface
, TransformStateType
, D3DMatrix
);
3419 /*****************************************************************************
3420 * IDirect3DDevice7::DrawPrimitive
3422 * Draws primitives based on vertices in an application-provided pointer
3424 * Version 2, 3 and 7. The IDirect3DDevice2 thunk converts the fixed vertex type into
3425 * an FVF format for D3D7
3428 * PrimitiveType: The type of the primitives to draw
3429 * Vertex type: Flexible vertex format vertex description
3430 * Vertices: Pointer to the vertex array
3431 * VertexCount: The number of vertices to draw
3432 * Flags: As usual a few flags
3436 * DDERR_INVALIDPARAMS if Vertices is NULL
3437 * For details, see IWineD3DDevice::DrawPrimitiveUP
3439 *****************************************************************************/
3441 IDirect3DDeviceImpl_7_DrawPrimitive(IDirect3DDevice7
*iface
,
3442 D3DPRIMITIVETYPE PrimitiveType
,
3448 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
3452 TRACE("iface %p, primitive_type %#x, FVF %#x, vertices %p, vertex_count %u, flags %#x.\n",
3453 iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Flags
);
3456 return DDERR_INVALIDPARAMS
;
3458 /* Get the stride */
3459 stride
= get_flexible_vertex_size(VertexType
);
3462 EnterCriticalSection(&ddraw_cs
);
3463 hr
= wined3d_device_set_vertex_declaration(This
->wined3d_device
, ddraw_find_decl(This
->ddraw
, VertexType
));
3466 LeaveCriticalSection(&ddraw_cs
);
3470 /* This method translates to the user pointer draw of WineD3D */
3471 wined3d_device_set_primitive_type(This
->wined3d_device
, PrimitiveType
);
3472 hr
= wined3d_device_draw_primitive_up(This
->wined3d_device
, VertexCount
, Vertices
, stride
);
3473 LeaveCriticalSection(&ddraw_cs
);
3477 static HRESULT WINAPI
3478 IDirect3DDeviceImpl_7_DrawPrimitive_FPUSetup(IDirect3DDevice7
*iface
,
3479 D3DPRIMITIVETYPE PrimitiveType
,
3485 return IDirect3DDeviceImpl_7_DrawPrimitive(iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Flags
);
3488 static HRESULT WINAPI
3489 IDirect3DDeviceImpl_7_DrawPrimitive_FPUPreserve(IDirect3DDevice7
*iface
,
3490 D3DPRIMITIVETYPE PrimitiveType
,
3499 old_fpucw
= d3d_fpu_setup();
3500 hr
= IDirect3DDeviceImpl_7_DrawPrimitive(iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Flags
);
3501 set_fpu_control_word(old_fpucw
);
3506 static HRESULT WINAPI
IDirect3DDeviceImpl_3_DrawPrimitive(IDirect3DDevice3
*iface
,
3507 D3DPRIMITIVETYPE PrimitiveType
, DWORD VertexType
, void *Vertices
, DWORD VertexCount
,
3510 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
3511 TRACE("iface %p, primitive_type %#x, FVF %#x, vertices %p, vertex_count %u, flags %#x.\n",
3512 iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Flags
);
3514 return IDirect3DDevice7_DrawPrimitive(&This
->IDirect3DDevice7_iface
,
3515 PrimitiveType
, VertexType
, Vertices
, VertexCount
, Flags
);
3518 static HRESULT WINAPI
IDirect3DDeviceImpl_2_DrawPrimitive(IDirect3DDevice2
*iface
,
3519 D3DPRIMITIVETYPE PrimitiveType
, D3DVERTEXTYPE VertexType
, void *Vertices
,
3520 DWORD VertexCount
, DWORD Flags
)
3522 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
3525 TRACE("iface %p, primitive_type %#x, vertex_type %#x, vertices %p, vertex_count %u, flags %#x.\n",
3526 iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Flags
);
3530 case D3DVT_VERTEX
: FVF
= D3DFVF_VERTEX
; break;
3531 case D3DVT_LVERTEX
: FVF
= D3DFVF_LVERTEX
; break;
3532 case D3DVT_TLVERTEX
: FVF
= D3DFVF_TLVERTEX
; break;
3534 ERR("Unexpected vertex type %d\n", VertexType
);
3535 return DDERR_INVALIDPARAMS
; /* Should never happen */
3538 return IDirect3DDevice7_DrawPrimitive(&This
->IDirect3DDevice7_iface
,
3539 PrimitiveType
, FVF
, Vertices
, VertexCount
, Flags
);
3542 /*****************************************************************************
3543 * IDirect3DDevice7::DrawIndexedPrimitive
3545 * Draws vertices from an application-provided pointer, based on the index
3546 * numbers in a WORD array.
3548 * Version 2, 3 and 7. The version 7 thunk translates the vertex type into
3549 * an FVF format for D3D7
3552 * PrimitiveType: The primitive type to draw
3553 * VertexType: The FVF vertex description
3554 * Vertices: Pointer to the vertex array
3556 * Indices: Pointer to the index array
3557 * IndexCount: Number of indices = Number of vertices to draw
3558 * Flags: As usual, some flags
3562 * DDERR_INVALIDPARAMS if Vertices or Indices is NULL
3563 * For details, see IWineD3DDevice::DrawIndexedPrimitiveUP
3565 *****************************************************************************/
3567 IDirect3DDeviceImpl_7_DrawIndexedPrimitive(IDirect3DDevice7
*iface
,
3568 D3DPRIMITIVETYPE PrimitiveType
,
3576 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
3579 TRACE("iface %p, primitive_type %#x, FVF %#x, vertices %p, vertex_count %u, indices %p, index_count %u, flags %#x.\n",
3580 iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Indices
, IndexCount
, Flags
);
3582 /* Set the D3DDevice's FVF */
3583 EnterCriticalSection(&ddraw_cs
);
3584 hr
= wined3d_device_set_vertex_declaration(This
->wined3d_device
, ddraw_find_decl(This
->ddraw
, VertexType
));
3587 ERR(" (%p) Setting the FVF failed, hr = %x!\n", This
, hr
);
3588 LeaveCriticalSection(&ddraw_cs
);
3592 wined3d_device_set_primitive_type(This
->wined3d_device
, PrimitiveType
);
3593 hr
= wined3d_device_draw_indexed_primitive_up(This
->wined3d_device
, IndexCount
, Indices
,
3594 WINED3DFMT_R16_UINT
, Vertices
, get_flexible_vertex_size(VertexType
));
3595 LeaveCriticalSection(&ddraw_cs
);
3599 static HRESULT WINAPI
3600 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUSetup(IDirect3DDevice7
*iface
,
3601 D3DPRIMITIVETYPE PrimitiveType
,
3609 return IDirect3DDeviceImpl_7_DrawIndexedPrimitive(iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Indices
, IndexCount
, Flags
);
3612 static HRESULT WINAPI
3613 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUPreserve(IDirect3DDevice7
*iface
,
3614 D3DPRIMITIVETYPE PrimitiveType
,
3625 old_fpucw
= d3d_fpu_setup();
3626 hr
= IDirect3DDeviceImpl_7_DrawIndexedPrimitive(iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Indices
, IndexCount
, Flags
);
3627 set_fpu_control_word(old_fpucw
);
3632 static HRESULT WINAPI
IDirect3DDeviceImpl_3_DrawIndexedPrimitive(IDirect3DDevice3
*iface
,
3633 D3DPRIMITIVETYPE PrimitiveType
, DWORD VertexType
, void *Vertices
, DWORD VertexCount
,
3634 WORD
*Indices
, DWORD IndexCount
, DWORD Flags
)
3636 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
3637 TRACE("iface %p, primitive_type %#x, FVF %#x, vertices %p, vertex_count %u, indices %p, index_count %u, flags %#x.\n",
3638 iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Indices
, IndexCount
, Flags
);
3640 return IDirect3DDevice7_DrawIndexedPrimitive(&This
->IDirect3DDevice7_iface
,
3641 PrimitiveType
, VertexType
, Vertices
, VertexCount
, Indices
, IndexCount
, Flags
);
3644 static HRESULT WINAPI
IDirect3DDeviceImpl_2_DrawIndexedPrimitive(IDirect3DDevice2
*iface
,
3645 D3DPRIMITIVETYPE PrimitiveType
, D3DVERTEXTYPE VertexType
, void *Vertices
,
3646 DWORD VertexCount
, WORD
*Indices
, DWORD IndexCount
, DWORD Flags
)
3648 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
3651 TRACE("iface %p, primitive_type %#x, vertex_type %#x, vertices %p, vertex_count %u, indices %p, index_count %u, flags %#x.\n",
3652 iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Indices
, IndexCount
, Flags
);
3656 case D3DVT_VERTEX
: FVF
= D3DFVF_VERTEX
; break;
3657 case D3DVT_LVERTEX
: FVF
= D3DFVF_LVERTEX
; break;
3658 case D3DVT_TLVERTEX
: FVF
= D3DFVF_TLVERTEX
; break;
3660 ERR("Unexpected vertex type %d\n", VertexType
);
3661 return DDERR_INVALIDPARAMS
; /* Should never happen */
3664 return IDirect3DDevice7_DrawIndexedPrimitive(&This
->IDirect3DDevice7_iface
,
3665 PrimitiveType
, FVF
, Vertices
, VertexCount
, Indices
, IndexCount
, Flags
);
3668 /*****************************************************************************
3669 * IDirect3DDevice7::SetClipStatus
3671 * Sets the clip status. This defines things as clipping conditions and
3672 * the extents of the clipping region.
3674 * Version 2, 3 and 7
3680 * D3D_OK because it's a stub
3681 * (DDERR_INVALIDPARAMS if ClipStatus == NULL)
3683 *****************************************************************************/
3684 static HRESULT WINAPI
3685 IDirect3DDeviceImpl_7_SetClipStatus(IDirect3DDevice7
*iface
,
3686 D3DCLIPSTATUS
*ClipStatus
)
3688 FIXME("iface %p, clip_status %p stub!\n", iface
, ClipStatus
);
3690 /* D3DCLIPSTATUS and WINED3DCLIPSTATUS are different. I don't know how to convert them
3691 * Perhaps this needs a new data type and an additional IWineD3DDevice method
3693 /* return IWineD3DDevice_SetClipStatus(This->wineD3DDevice, ClipStatus);*/
3697 static HRESULT WINAPI
IDirect3DDeviceImpl_3_SetClipStatus(IDirect3DDevice3
*iface
,
3698 D3DCLIPSTATUS
*ClipStatus
)
3700 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
3701 TRACE("iface %p, clip_status %p.\n", iface
, ClipStatus
);
3703 return IDirect3DDevice7_SetClipStatus(&This
->IDirect3DDevice7_iface
, ClipStatus
);
3706 static HRESULT WINAPI
IDirect3DDeviceImpl_2_SetClipStatus(IDirect3DDevice2
*iface
,
3707 D3DCLIPSTATUS
*ClipStatus
)
3709 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
3710 TRACE("iface %p, clip_status %p.\n", iface
, ClipStatus
);
3712 return IDirect3DDevice7_SetClipStatus(&This
->IDirect3DDevice7_iface
, ClipStatus
);
3715 /*****************************************************************************
3716 * IDirect3DDevice7::GetClipStatus
3718 * Returns the clip status
3721 * ClipStatus: Address to write the clip status to
3724 * D3D_OK because it's a stub
3726 *****************************************************************************/
3727 static HRESULT WINAPI
3728 IDirect3DDeviceImpl_7_GetClipStatus(IDirect3DDevice7
*iface
,
3729 D3DCLIPSTATUS
*ClipStatus
)
3731 FIXME("iface %p, clip_status %p stub!\n", iface
, ClipStatus
);
3733 /* D3DCLIPSTATUS and WINED3DCLIPSTATUS are different. I don't know how to convert them */
3734 /* return IWineD3DDevice_GetClipStatus(This->wineD3DDevice, ClipStatus);*/
3738 static HRESULT WINAPI
IDirect3DDeviceImpl_3_GetClipStatus(IDirect3DDevice3
*iface
,
3739 D3DCLIPSTATUS
*ClipStatus
)
3741 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
3742 TRACE("iface %p, clip_status %p.\n", iface
, ClipStatus
);
3744 return IDirect3DDevice7_GetClipStatus(&This
->IDirect3DDevice7_iface
, ClipStatus
);
3747 static HRESULT WINAPI
IDirect3DDeviceImpl_2_GetClipStatus(IDirect3DDevice2
*iface
,
3748 D3DCLIPSTATUS
*ClipStatus
)
3750 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
3751 TRACE("iface %p, clip_status %p.\n", iface
, ClipStatus
);
3753 return IDirect3DDevice7_GetClipStatus(&This
->IDirect3DDevice7_iface
, ClipStatus
);
3756 /*****************************************************************************
3757 * IDirect3DDevice::DrawPrimitiveStrided
3759 * Draws vertices described by a D3DDRAWPRIMITIVESTRIDEDDATA structure.
3764 * PrimitiveType: The primitive type to draw
3765 * VertexType: The FVF description of the vertices to draw (for the stride??)
3766 * D3DDrawPrimStrideData: A D3DDRAWPRIMITIVESTRIDEDDATA structure describing
3767 * the vertex data locations
3768 * VertexCount: The number of vertices to draw
3772 * D3D_OK, because it's a stub
3773 * (DDERR_INVALIDPARAMS if D3DDrawPrimStrideData is NULL)
3774 * (For details, see IWineD3DDevice::DrawPrimitiveStrided)
3776 *****************************************************************************/
3778 IDirect3DDeviceImpl_7_DrawPrimitiveStrided(IDirect3DDevice7
*iface
,
3779 D3DPRIMITIVETYPE PrimitiveType
,
3781 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
,
3785 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
3786 WineDirect3DVertexStridedData WineD3DStrided
;
3790 TRACE("iface %p, primitive_type %#x, FVF %#x, strided_data %p, vertex_count %u, flags %#x.\n",
3791 iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Flags
);
3793 memset(&WineD3DStrided
, 0, sizeof(WineD3DStrided
));
3794 /* Get the strided data right. the wined3d structure is a bit bigger
3795 * Watch out: The contents of the strided data are determined by the fvf,
3796 * not by the members set in D3DDrawPrimStrideData. So it's valid
3797 * to have diffuse.lpvData set to 0xdeadbeef if the diffuse flag is
3798 * not set in the fvf.
3800 if(VertexType
& D3DFVF_POSITION_MASK
)
3802 WineD3DStrided
.position
.format
= WINED3DFMT_R32G32B32_FLOAT
;
3803 WineD3DStrided
.position
.lpData
= D3DDrawPrimStrideData
->position
.lpvData
;
3804 WineD3DStrided
.position
.dwStride
= D3DDrawPrimStrideData
->position
.dwStride
;
3805 if (VertexType
& D3DFVF_XYZRHW
)
3807 WineD3DStrided
.position
.format
= WINED3DFMT_R32G32B32A32_FLOAT
;
3808 WineD3DStrided
.position_transformed
= TRUE
;
3810 WineD3DStrided
.position_transformed
= FALSE
;
3813 if(VertexType
& D3DFVF_NORMAL
)
3815 WineD3DStrided
.normal
.format
= WINED3DFMT_R32G32B32_FLOAT
;
3816 WineD3DStrided
.normal
.lpData
= D3DDrawPrimStrideData
->normal
.lpvData
;
3817 WineD3DStrided
.normal
.dwStride
= D3DDrawPrimStrideData
->normal
.dwStride
;
3820 if(VertexType
& D3DFVF_DIFFUSE
)
3822 WineD3DStrided
.diffuse
.format
= WINED3DFMT_B8G8R8A8_UNORM
;
3823 WineD3DStrided
.diffuse
.lpData
= D3DDrawPrimStrideData
->diffuse
.lpvData
;
3824 WineD3DStrided
.diffuse
.dwStride
= D3DDrawPrimStrideData
->diffuse
.dwStride
;
3827 if(VertexType
& D3DFVF_SPECULAR
)
3829 WineD3DStrided
.specular
.format
= WINED3DFMT_B8G8R8A8_UNORM
;
3830 WineD3DStrided
.specular
.lpData
= D3DDrawPrimStrideData
->specular
.lpvData
;
3831 WineD3DStrided
.specular
.dwStride
= D3DDrawPrimStrideData
->specular
.dwStride
;
3834 for( i
= 0; i
< GET_TEXCOUNT_FROM_FVF(VertexType
); i
++)
3836 switch(GET_TEXCOORD_SIZE_FROM_FVF(VertexType
, i
))
3838 case 1: WineD3DStrided
.texCoords
[i
].format
= WINED3DFMT_R32_FLOAT
; break;
3839 case 2: WineD3DStrided
.texCoords
[i
].format
= WINED3DFMT_R32G32_FLOAT
; break;
3840 case 3: WineD3DStrided
.texCoords
[i
].format
= WINED3DFMT_R32G32B32_FLOAT
; break;
3841 case 4: WineD3DStrided
.texCoords
[i
].format
= WINED3DFMT_R32G32B32A32_FLOAT
; break;
3842 default: ERR("Unexpected texture coordinate size %d\n",
3843 GET_TEXCOORD_SIZE_FROM_FVF(VertexType
, i
));
3845 WineD3DStrided
.texCoords
[i
].lpData
= D3DDrawPrimStrideData
->textureCoords
[i
].lpvData
;
3846 WineD3DStrided
.texCoords
[i
].dwStride
= D3DDrawPrimStrideData
->textureCoords
[i
].dwStride
;
3849 /* WineD3D doesn't need the FVF here */
3850 EnterCriticalSection(&ddraw_cs
);
3851 wined3d_device_set_primitive_type(This
->wined3d_device
, PrimitiveType
);
3852 hr
= wined3d_device_draw_primitive_strided(This
->wined3d_device
, VertexCount
, &WineD3DStrided
);
3853 LeaveCriticalSection(&ddraw_cs
);
3857 static HRESULT WINAPI
3858 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUSetup(IDirect3DDevice7
*iface
,
3859 D3DPRIMITIVETYPE PrimitiveType
,
3861 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
,
3865 return IDirect3DDeviceImpl_7_DrawPrimitiveStrided(iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Flags
);
3868 static HRESULT WINAPI
3869 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUPreserve(IDirect3DDevice7
*iface
,
3870 D3DPRIMITIVETYPE PrimitiveType
,
3872 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
,
3879 old_fpucw
= d3d_fpu_setup();
3880 hr
= IDirect3DDeviceImpl_7_DrawPrimitiveStrided(iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Flags
);
3881 set_fpu_control_word(old_fpucw
);
3886 static HRESULT WINAPI
IDirect3DDeviceImpl_3_DrawPrimitiveStrided(IDirect3DDevice3
*iface
,
3887 D3DPRIMITIVETYPE PrimitiveType
, DWORD VertexType
,
3888 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
, DWORD VertexCount
, DWORD Flags
)
3890 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
3892 TRACE("iface %p, primitive_type %#x, FVF %#x, strided_data %p, vertex_count %u, flags %#x.\n",
3893 iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Flags
);
3895 return IDirect3DDevice7_DrawPrimitiveStrided(&This
->IDirect3DDevice7_iface
,
3896 PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Flags
);
3899 /*****************************************************************************
3900 * IDirect3DDevice7::DrawIndexedPrimitiveStrided
3902 * Draws primitives specified by strided data locations based on indices
3910 * D3D_OK, because it's a stub
3911 * (DDERR_INVALIDPARAMS if D3DDrawPrimStrideData is NULL)
3912 * (DDERR_INVALIDPARAMS if Indices is NULL)
3913 * (For more details, see IWineD3DDevice::DrawIndexedPrimitiveStrided)
3915 *****************************************************************************/
3917 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided(IDirect3DDevice7
*iface
,
3918 D3DPRIMITIVETYPE PrimitiveType
,
3920 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
,
3926 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
3927 WineDirect3DVertexStridedData WineD3DStrided
;
3931 TRACE("iface %p, primitive_type %#x, FVF %#x, strided_data %p, vertex_count %u, indices %p, index_count %u, flags %#x.\n",
3932 iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Indices
, IndexCount
, Flags
);
3934 memset(&WineD3DStrided
, 0, sizeof(WineD3DStrided
));
3935 /* Get the strided data right. the wined3d structure is a bit bigger
3936 * Watch out: The contents of the strided data are determined by the fvf,
3937 * not by the members set in D3DDrawPrimStrideData. So it's valid
3938 * to have diffuse.lpvData set to 0xdeadbeef if the diffuse flag is
3939 * not set in the fvf.
3941 if(VertexType
& D3DFVF_POSITION_MASK
)
3943 WineD3DStrided
.position
.format
= WINED3DFMT_R32G32B32_FLOAT
;
3944 WineD3DStrided
.position
.lpData
= D3DDrawPrimStrideData
->position
.lpvData
;
3945 WineD3DStrided
.position
.dwStride
= D3DDrawPrimStrideData
->position
.dwStride
;
3946 if (VertexType
& D3DFVF_XYZRHW
)
3948 WineD3DStrided
.position
.format
= WINED3DFMT_R32G32B32A32_FLOAT
;
3949 WineD3DStrided
.position_transformed
= TRUE
;
3951 WineD3DStrided
.position_transformed
= FALSE
;
3954 if(VertexType
& D3DFVF_NORMAL
)
3956 WineD3DStrided
.normal
.format
= WINED3DFMT_R32G32B32_FLOAT
;
3957 WineD3DStrided
.normal
.lpData
= D3DDrawPrimStrideData
->normal
.lpvData
;
3958 WineD3DStrided
.normal
.dwStride
= D3DDrawPrimStrideData
->normal
.dwStride
;
3961 if(VertexType
& D3DFVF_DIFFUSE
)
3963 WineD3DStrided
.diffuse
.format
= WINED3DFMT_B8G8R8A8_UNORM
;
3964 WineD3DStrided
.diffuse
.lpData
= D3DDrawPrimStrideData
->diffuse
.lpvData
;
3965 WineD3DStrided
.diffuse
.dwStride
= D3DDrawPrimStrideData
->diffuse
.dwStride
;
3968 if(VertexType
& D3DFVF_SPECULAR
)
3970 WineD3DStrided
.specular
.format
= WINED3DFMT_B8G8R8A8_UNORM
;
3971 WineD3DStrided
.specular
.lpData
= D3DDrawPrimStrideData
->specular
.lpvData
;
3972 WineD3DStrided
.specular
.dwStride
= D3DDrawPrimStrideData
->specular
.dwStride
;
3975 for( i
= 0; i
< GET_TEXCOUNT_FROM_FVF(VertexType
); i
++)
3977 switch(GET_TEXCOORD_SIZE_FROM_FVF(VertexType
, i
))
3979 case 1: WineD3DStrided
.texCoords
[i
].format
= WINED3DFMT_R32_FLOAT
; break;
3980 case 2: WineD3DStrided
.texCoords
[i
].format
= WINED3DFMT_R32G32_FLOAT
; break;
3981 case 3: WineD3DStrided
.texCoords
[i
].format
= WINED3DFMT_R32G32B32_FLOAT
; break;
3982 case 4: WineD3DStrided
.texCoords
[i
].format
= WINED3DFMT_R32G32B32A32_FLOAT
; break;
3983 default: ERR("Unexpected texture coordinate size %d\n",
3984 GET_TEXCOORD_SIZE_FROM_FVF(VertexType
, i
));
3986 WineD3DStrided
.texCoords
[i
].lpData
= D3DDrawPrimStrideData
->textureCoords
[i
].lpvData
;
3987 WineD3DStrided
.texCoords
[i
].dwStride
= D3DDrawPrimStrideData
->textureCoords
[i
].dwStride
;
3990 /* WineD3D doesn't need the FVF here */
3991 EnterCriticalSection(&ddraw_cs
);
3992 wined3d_device_set_primitive_type(This
->wined3d_device
, PrimitiveType
);
3993 hr
= wined3d_device_draw_indexed_primitive_strided(This
->wined3d_device
,
3994 IndexCount
, &WineD3DStrided
, VertexCount
, Indices
, WINED3DFMT_R16_UINT
);
3995 LeaveCriticalSection(&ddraw_cs
);
3999 static HRESULT WINAPI
4000 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUSetup(IDirect3DDevice7
*iface
,
4001 D3DPRIMITIVETYPE PrimitiveType
,
4003 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
,
4009 return IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided(iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Indices
, IndexCount
, Flags
);
4012 static HRESULT WINAPI
4013 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUPreserve(IDirect3DDevice7
*iface
,
4014 D3DPRIMITIVETYPE PrimitiveType
,
4016 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
,
4025 old_fpucw
= d3d_fpu_setup();
4026 hr
= IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided(iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Indices
, IndexCount
, Flags
);
4027 set_fpu_control_word(old_fpucw
);
4032 static HRESULT WINAPI
IDirect3DDeviceImpl_3_DrawIndexedPrimitiveStrided(IDirect3DDevice3
*iface
,
4033 D3DPRIMITIVETYPE PrimitiveType
, DWORD VertexType
,
4034 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
, DWORD VertexCount
, WORD
*Indices
,
4035 DWORD IndexCount
, DWORD Flags
)
4037 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
4039 TRACE("iface %p, primitive_type %#x, FVF %#x, strided_data %p, vertex_count %u, indices %p, index_count %u, flags %#x.\n",
4040 iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Indices
, IndexCount
, Flags
);
4042 return IDirect3DDevice7_DrawIndexedPrimitiveStrided(&This
->IDirect3DDevice7_iface
,
4043 PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Indices
, IndexCount
, Flags
);
4046 /*****************************************************************************
4047 * IDirect3DDevice7::DrawPrimitiveVB
4049 * Draws primitives from a vertex buffer to the screen.
4054 * PrimitiveType: Type of primitive to be rendered.
4055 * D3DVertexBuf: Source Vertex Buffer
4056 * StartVertex: Index of the first vertex from the buffer to be rendered
4057 * NumVertices: Number of vertices to be rendered
4058 * Flags: Can be D3DDP_WAIT to wait until rendering has finished
4062 * DDERR_INVALIDPARAMS if D3DVertexBuf is NULL
4064 *****************************************************************************/
4066 IDirect3DDeviceImpl_7_DrawPrimitiveVB(IDirect3DDevice7
*iface
,
4067 D3DPRIMITIVETYPE PrimitiveType
,
4068 IDirect3DVertexBuffer7
*D3DVertexBuf
,
4073 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
4074 IDirect3DVertexBufferImpl
*vb
= unsafe_impl_from_IDirect3DVertexBuffer7(D3DVertexBuf
);
4078 TRACE("iface %p, primitive_type %#x, vb %p, start_vertex %u, vertex_count %u, flags %#x.\n",
4079 iface
, PrimitiveType
, D3DVertexBuf
, StartVertex
, NumVertices
, Flags
);
4084 ERR("(%p) No Vertex buffer specified\n", This
);
4085 return DDERR_INVALIDPARAMS
;
4087 stride
= get_flexible_vertex_size(vb
->fvf
);
4089 EnterCriticalSection(&ddraw_cs
);
4090 hr
= wined3d_device_set_vertex_declaration(This
->wined3d_device
, vb
->wineD3DVertexDeclaration
);
4093 ERR(" (%p) Setting the FVF failed, hr = %x!\n", This
, hr
);
4094 LeaveCriticalSection(&ddraw_cs
);
4098 /* Set the vertex stream source */
4099 hr
= wined3d_device_set_stream_source(This
->wined3d_device
, 0, vb
->wineD3DVertexBuffer
, 0, stride
);
4102 ERR("(%p) IDirect3DDevice::SetStreamSource failed with hr = %08x\n", This
, hr
);
4103 LeaveCriticalSection(&ddraw_cs
);
4107 /* Now draw the primitives */
4108 wined3d_device_set_primitive_type(This
->wined3d_device
, PrimitiveType
);
4109 hr
= wined3d_device_draw_primitive(This
->wined3d_device
, StartVertex
, NumVertices
);
4110 LeaveCriticalSection(&ddraw_cs
);
4114 static HRESULT WINAPI
4115 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUSetup(IDirect3DDevice7
*iface
,
4116 D3DPRIMITIVETYPE PrimitiveType
,
4117 IDirect3DVertexBuffer7
*D3DVertexBuf
,
4122 return IDirect3DDeviceImpl_7_DrawPrimitiveVB(iface
, PrimitiveType
, D3DVertexBuf
, StartVertex
, NumVertices
, Flags
);
4125 static HRESULT WINAPI
4126 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUPreserve(IDirect3DDevice7
*iface
,
4127 D3DPRIMITIVETYPE PrimitiveType
,
4128 IDirect3DVertexBuffer7
*D3DVertexBuf
,
4136 old_fpucw
= d3d_fpu_setup();
4137 hr
= IDirect3DDeviceImpl_7_DrawPrimitiveVB(iface
, PrimitiveType
, D3DVertexBuf
, StartVertex
, NumVertices
, Flags
);
4138 set_fpu_control_word(old_fpucw
);
4143 static HRESULT WINAPI
IDirect3DDeviceImpl_3_DrawPrimitiveVB(IDirect3DDevice3
*iface
,
4144 D3DPRIMITIVETYPE PrimitiveType
, IDirect3DVertexBuffer
*D3DVertexBuf
, DWORD StartVertex
,
4145 DWORD NumVertices
, DWORD Flags
)
4147 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
4148 IDirect3DVertexBufferImpl
*vb
= unsafe_impl_from_IDirect3DVertexBuffer(D3DVertexBuf
);
4150 TRACE("iface %p, primitive_type %#x, vb %p, start_vertex %u, vertex_count %u, flags %#x.\n",
4151 iface
, PrimitiveType
, D3DVertexBuf
, StartVertex
, NumVertices
, Flags
);
4153 return IDirect3DDevice7_DrawPrimitiveVB(&This
->IDirect3DDevice7_iface
,
4154 PrimitiveType
, &vb
->IDirect3DVertexBuffer7_iface
, StartVertex
, NumVertices
, Flags
);
4158 /*****************************************************************************
4159 * IDirect3DDevice7::DrawIndexedPrimitiveVB
4161 * Draws primitives from a vertex buffer to the screen
4164 * PrimitiveType: Type of primitive to be rendered.
4165 * D3DVertexBuf: Source Vertex Buffer
4166 * StartVertex: Index of the first vertex from the buffer to be rendered
4167 * NumVertices: Number of vertices to be rendered
4168 * Indices: Array of DWORDs used to index into the Vertices
4169 * IndexCount: Number of indices in Indices
4170 * Flags: Can be D3DDP_WAIT to wait until rendering has finished
4174 *****************************************************************************/
4176 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB(IDirect3DDevice7
*iface
,
4177 D3DPRIMITIVETYPE PrimitiveType
,
4178 IDirect3DVertexBuffer7
*D3DVertexBuf
,
4185 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
4186 IDirect3DVertexBufferImpl
*vb
= unsafe_impl_from_IDirect3DVertexBuffer7(D3DVertexBuf
);
4187 DWORD stride
= get_flexible_vertex_size(vb
->fvf
);
4188 struct wined3d_resource
*wined3d_resource
;
4189 struct wined3d_resource_desc desc
;
4190 WORD
*LockedIndices
;
4193 TRACE("iface %p, primitive_type %#x, vb %p, start_vertex %u, vertex_count %u, indices %p, index_count %u, flags %#x.\n",
4194 iface
, PrimitiveType
, D3DVertexBuf
, StartVertex
, NumVertices
, Indices
, IndexCount
, Flags
);
4197 * 1) Upload the Indices to the index buffer
4198 * 2) Set the index source
4199 * 3) Set the Vertex Buffer as the Stream source
4200 * 4) Call IWineD3DDevice::DrawIndexedPrimitive
4203 EnterCriticalSection(&ddraw_cs
);
4205 hr
= wined3d_device_set_vertex_declaration(This
->wined3d_device
, vb
->wineD3DVertexDeclaration
);
4208 ERR(" (%p) Setting the FVF failed, hr = %x!\n", This
, hr
);
4209 LeaveCriticalSection(&ddraw_cs
);
4213 /* check that the buffer is large enough to hold the indices,
4214 * reallocate if necessary. */
4215 wined3d_resource
= wined3d_buffer_get_resource(This
->indexbuffer
);
4216 wined3d_resource_get_desc(wined3d_resource
, &desc
);
4217 if (desc
.size
< IndexCount
* sizeof(WORD
))
4219 UINT size
= max(desc
.size
* 2, IndexCount
* sizeof(WORD
));
4220 struct wined3d_buffer
*buffer
;
4222 TRACE("Growing index buffer to %u bytes\n", size
);
4224 hr
= wined3d_buffer_create_ib(This
->wined3d_device
, size
, WINED3DUSAGE_DYNAMIC
/* Usage */,
4225 WINED3DPOOL_DEFAULT
, NULL
, &ddraw_null_wined3d_parent_ops
, &buffer
);
4228 ERR("(%p) IWineD3DDevice::CreateIndexBuffer failed with hr = %08x\n", This
, hr
);
4229 LeaveCriticalSection(&ddraw_cs
);
4233 wined3d_buffer_decref(This
->indexbuffer
);
4234 This
->indexbuffer
= buffer
;
4237 /* Copy the index stream into the index buffer. A new IWineD3DDevice
4238 * method could be created which takes an user pointer containing the
4239 * indices or a SetData-Method for the index buffer, which overrides the
4240 * index buffer data with our pointer. */
4241 hr
= wined3d_buffer_map(This
->indexbuffer
, 0, IndexCount
* sizeof(WORD
),
4242 (BYTE
**)&LockedIndices
, 0);
4245 ERR("Failed to map buffer, hr %#x.\n", hr
);
4246 LeaveCriticalSection(&ddraw_cs
);
4249 memcpy(LockedIndices
, Indices
, IndexCount
* sizeof(WORD
));
4250 wined3d_buffer_unmap(This
->indexbuffer
);
4252 /* Set the index stream */
4253 wined3d_device_set_base_vertex_index(This
->wined3d_device
, StartVertex
);
4254 hr
= wined3d_device_set_index_buffer(This
->wined3d_device
, This
->indexbuffer
, WINED3DFMT_R16_UINT
);
4256 /* Set the vertex stream source */
4257 hr
= wined3d_device_set_stream_source(This
->wined3d_device
, 0, vb
->wineD3DVertexBuffer
, 0, stride
);
4260 ERR("(%p) IDirect3DDevice::SetStreamSource failed with hr = %08x\n", This
, hr
);
4261 LeaveCriticalSection(&ddraw_cs
);
4266 wined3d_device_set_primitive_type(This
->wined3d_device
, PrimitiveType
);
4267 hr
= wined3d_device_draw_indexed_primitive(This
->wined3d_device
, 0, IndexCount
);
4269 LeaveCriticalSection(&ddraw_cs
);
4273 static HRESULT WINAPI
4274 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUSetup(IDirect3DDevice7
*iface
,
4275 D3DPRIMITIVETYPE PrimitiveType
,
4276 IDirect3DVertexBuffer7
*D3DVertexBuf
,
4283 return IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB(iface
, PrimitiveType
, D3DVertexBuf
, StartVertex
, NumVertices
, Indices
, IndexCount
, Flags
);
4286 static HRESULT WINAPI
4287 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUPreserve(IDirect3DDevice7
*iface
,
4288 D3DPRIMITIVETYPE PrimitiveType
,
4289 IDirect3DVertexBuffer7
*D3DVertexBuf
,
4299 old_fpucw
= d3d_fpu_setup();
4300 hr
= IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB(iface
, PrimitiveType
, D3DVertexBuf
, StartVertex
, NumVertices
, Indices
, IndexCount
, Flags
);
4301 set_fpu_control_word(old_fpucw
);
4306 static HRESULT WINAPI
IDirect3DDeviceImpl_3_DrawIndexedPrimitiveVB(IDirect3DDevice3
*iface
,
4307 D3DPRIMITIVETYPE PrimitiveType
, IDirect3DVertexBuffer
*D3DVertexBuf
, WORD
*Indices
,
4308 DWORD IndexCount
, DWORD Flags
)
4310 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
4311 IDirect3DVertexBufferImpl
*vb
= unsafe_impl_from_IDirect3DVertexBuffer(D3DVertexBuf
);
4313 TRACE("iface %p, primitive_type %#x, vb %p, indices %p, index_count %u, flags %#x.\n",
4314 iface
, PrimitiveType
, D3DVertexBuf
, Indices
, IndexCount
, Flags
);
4316 return IDirect3DDevice7_DrawIndexedPrimitiveVB(&This
->IDirect3DDevice7_iface
,
4317 PrimitiveType
, &vb
->IDirect3DVertexBuffer7_iface
, 0, IndexCount
, Indices
, IndexCount
,
4321 /*****************************************************************************
4322 * IDirect3DDevice7::ComputeSphereVisibility
4324 * Calculates the visibility of spheres in the current viewport. The spheres
4325 * are passed in the Centers and Radii arrays, the results are passed back
4326 * in the ReturnValues array. Return values are either completely visible,
4327 * partially visible or completely invisible.
4328 * The return value consist of a combination of D3DCLIP_* flags, or it's
4329 * 0 if the sphere is completely visible(according to the SDK, not checked)
4334 * Centers: Array containing the sphere centers
4335 * Radii: Array containing the sphere radii
4336 * NumSpheres: The number of centers and radii in the arrays
4338 * ReturnValues: Array to write the results to
4342 * (DDERR_INVALIDPARAMS if Centers, Radii or ReturnValues are NULL)
4343 * (D3DERR_INVALIDMATRIX if the combined world, view and proj matrix
4346 *****************************************************************************/
4348 static DWORD
in_plane(UINT plane
, D3DVECTOR normal
, D3DVALUE origin_plane
, D3DVECTOR center
, D3DVALUE radius
)
4350 float distance
, norm
;
4352 norm
= sqrt( normal
.u1
.x
* normal
.u1
.x
+ normal
.u2
.y
* normal
.u2
.y
+ normal
.u3
.z
* normal
.u3
.z
);
4353 distance
= ( origin_plane
+ normal
.u1
.x
* center
.u1
.x
+ normal
.u2
.y
* center
.u2
.y
+ normal
.u3
.z
* center
.u3
.z
) / norm
;
4355 if ( fabs( distance
) < radius
) return D3DSTATUS_CLIPUNIONLEFT
<< plane
;
4356 if ( distance
< -radius
) return (D3DSTATUS_CLIPUNIONLEFT
| D3DSTATUS_CLIPINTERSECTIONLEFT
) << plane
;
4360 static HRESULT WINAPI
4361 IDirect3DDeviceImpl_7_ComputeSphereVisibility(IDirect3DDevice7
*iface
,
4366 DWORD
*ReturnValues
)
4369 D3DVALUE origin_plane
[6];
4374 TRACE("iface %p, centers %p, radii %p, sphere_count %u, flags %#x, return_values %p.\n",
4375 iface
, Centers
, Radii
, NumSpheres
, Flags
, ReturnValues
);
4377 hr
= IDirect3DDeviceImpl_7_GetTransform(iface
, D3DTRANSFORMSTATE_WORLD
, &m
);
4378 if ( hr
!= DD_OK
) return DDERR_INVALIDPARAMS
;
4379 hr
= IDirect3DDeviceImpl_7_GetTransform(iface
, D3DTRANSFORMSTATE_VIEW
, &temp
);
4380 if ( hr
!= DD_OK
) return DDERR_INVALIDPARAMS
;
4381 multiply_matrix(&m
, &temp
, &m
);
4383 hr
= IDirect3DDeviceImpl_7_GetTransform(iface
, D3DTRANSFORMSTATE_PROJECTION
, &temp
);
4384 if ( hr
!= DD_OK
) return DDERR_INVALIDPARAMS
;
4385 multiply_matrix(&m
, &temp
, &m
);
4388 vec
[0].u1
.x
= m
._14
+ m
._11
;
4389 vec
[0].u2
.y
= m
._24
+ m
._21
;
4390 vec
[0].u3
.z
= m
._34
+ m
._31
;
4391 origin_plane
[0] = m
._44
+ m
._41
;
4394 vec
[1].u1
.x
= m
._14
- m
._11
;
4395 vec
[1].u2
.y
= m
._24
- m
._21
;
4396 vec
[1].u3
.z
= m
._34
- m
._31
;
4397 origin_plane
[1] = m
._44
- m
._41
;
4400 vec
[2].u1
.x
= m
._14
- m
._12
;
4401 vec
[2].u2
.y
= m
._24
- m
._22
;
4402 vec
[2].u3
.z
= m
._34
- m
._32
;
4403 origin_plane
[2] = m
._44
- m
._42
;
4406 vec
[3].u1
.x
= m
._14
+ m
._12
;
4407 vec
[3].u2
.y
= m
._24
+ m
._22
;
4408 vec
[3].u3
.z
= m
._34
+ m
._32
;
4409 origin_plane
[3] = m
._44
+ m
._42
;
4412 vec
[4].u1
.x
= m
._13
;
4413 vec
[4].u2
.y
= m
._23
;
4414 vec
[4].u3
.z
= m
._33
;
4415 origin_plane
[4] = m
._43
;
4418 vec
[5].u1
.x
= m
._14
- m
._13
;
4419 vec
[5].u2
.y
= m
._24
- m
._23
;
4420 vec
[5].u3
.z
= m
._34
- m
._33
;
4421 origin_plane
[5] = m
._44
- m
._43
;
4423 for(i
=0; i
<NumSpheres
; i
++)
4425 ReturnValues
[i
] = 0;
4426 for(j
=0; j
<6; j
++) ReturnValues
[i
] |= in_plane(j
, vec
[j
], origin_plane
[j
], Centers
[i
], Radii
[i
]);
4432 static HRESULT WINAPI
IDirect3DDeviceImpl_3_ComputeSphereVisibility(IDirect3DDevice3
*iface
,
4433 D3DVECTOR
*Centers
, D3DVALUE
*Radii
, DWORD NumSpheres
, DWORD Flags
, DWORD
*ReturnValues
)
4435 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
4437 TRACE("iface %p, centers %p, radii %p, sphere_count %u, flags %#x, return_values %p.\n",
4438 iface
, Centers
, Radii
, NumSpheres
, Flags
, ReturnValues
);
4440 return IDirect3DDevice7_ComputeSphereVisibility(&This
->IDirect3DDevice7_iface
,
4441 Centers
, Radii
, NumSpheres
, Flags
, ReturnValues
);
4444 /*****************************************************************************
4445 * IDirect3DDevice7::GetTexture
4447 * Returns the texture interface handle assigned to a texture stage.
4448 * The returned texture is AddRefed. This is taken from old ddraw,
4449 * not checked in Windows.
4454 * Stage: Texture stage to read the texture from
4455 * Texture: Address to store the interface pointer at
4459 * DDERR_INVALIDPARAMS if Texture is NULL
4460 * For details, see IWineD3DDevice::GetTexture
4462 *****************************************************************************/
4464 IDirect3DDeviceImpl_7_GetTexture(IDirect3DDevice7
*iface
,
4466 IDirectDrawSurface7
**Texture
)
4468 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
4469 struct wined3d_texture
*wined3d_texture
;
4472 TRACE("iface %p, stage %u, texture %p.\n", iface
, Stage
, Texture
);
4476 TRACE("Texture == NULL, failing with DDERR_INVALIDPARAMS\n");
4477 return DDERR_INVALIDPARAMS
;
4480 EnterCriticalSection(&ddraw_cs
);
4481 hr
= wined3d_device_get_texture(This
->wined3d_device
, Stage
, &wined3d_texture
);
4482 if (FAILED(hr
) || !wined3d_texture
)
4485 LeaveCriticalSection(&ddraw_cs
);
4489 *Texture
= wined3d_texture_get_parent(wined3d_texture
);
4490 IDirectDrawSurface7_AddRef(*Texture
);
4491 wined3d_texture_decref(wined3d_texture
);
4492 LeaveCriticalSection(&ddraw_cs
);
4496 static HRESULT WINAPI
4497 IDirect3DDeviceImpl_7_GetTexture_FPUSetup(IDirect3DDevice7
*iface
,
4499 IDirectDrawSurface7
**Texture
)
4501 return IDirect3DDeviceImpl_7_GetTexture(iface
, Stage
, Texture
);
4504 static HRESULT WINAPI
4505 IDirect3DDeviceImpl_7_GetTexture_FPUPreserve(IDirect3DDevice7
*iface
,
4507 IDirectDrawSurface7
**Texture
)
4512 old_fpucw
= d3d_fpu_setup();
4513 hr
= IDirect3DDeviceImpl_7_GetTexture(iface
, Stage
, Texture
);
4514 set_fpu_control_word(old_fpucw
);
4519 static HRESULT WINAPI
IDirect3DDeviceImpl_3_GetTexture(IDirect3DDevice3
*iface
, DWORD Stage
,
4520 IDirect3DTexture2
**Texture2
)
4522 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
4524 IDirectDrawSurface7
*ret_val
;
4525 IDirectDrawSurfaceImpl
*ret_val_impl
;
4527 TRACE("iface %p, stage %u, texture %p.\n", iface
, Stage
, Texture2
);
4529 ret
= IDirect3DDevice7_GetTexture(&This
->IDirect3DDevice7_iface
, Stage
, &ret_val
);
4531 ret_val_impl
= unsafe_impl_from_IDirectDrawSurface7(ret_val
);
4532 *Texture2
= ret_val_impl
? &ret_val_impl
->IDirect3DTexture2_iface
: NULL
;
4534 TRACE("Returning texture %p.\n", *Texture2
);
4539 /*****************************************************************************
4540 * IDirect3DDevice7::SetTexture
4542 * Assigns a texture to a texture stage. Is the texture AddRef-ed?
4547 * Stage: The stage to assign the texture to
4548 * Texture: Interface pointer to the texture surface
4552 * For details, see IWineD3DDevice::SetTexture
4554 *****************************************************************************/
4556 IDirect3DDeviceImpl_7_SetTexture(IDirect3DDevice7
*iface
,
4558 IDirectDrawSurface7
*Texture
)
4560 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
4561 IDirectDrawSurfaceImpl
*surf
= unsafe_impl_from_IDirectDrawSurface7(Texture
);
4564 TRACE("iface %p, stage %u, texture %p.\n", iface
, Stage
, Texture
);
4566 /* Texture may be NULL here */
4567 EnterCriticalSection(&ddraw_cs
);
4568 hr
= wined3d_device_set_texture(This
->wined3d_device
,
4569 Stage
, surf
? surf
->wined3d_texture
: NULL
);
4570 LeaveCriticalSection(&ddraw_cs
);
4574 static HRESULT WINAPI
4575 IDirect3DDeviceImpl_7_SetTexture_FPUSetup(IDirect3DDevice7
*iface
,
4577 IDirectDrawSurface7
*Texture
)
4579 return IDirect3DDeviceImpl_7_SetTexture(iface
, Stage
, Texture
);
4582 static HRESULT WINAPI
4583 IDirect3DDeviceImpl_7_SetTexture_FPUPreserve(IDirect3DDevice7
*iface
,
4585 IDirectDrawSurface7
*Texture
)
4590 old_fpucw
= d3d_fpu_setup();
4591 hr
= IDirect3DDeviceImpl_7_SetTexture(iface
, Stage
, Texture
);
4592 set_fpu_control_word(old_fpucw
);
4597 static HRESULT WINAPI
4598 IDirect3DDeviceImpl_3_SetTexture(IDirect3DDevice3
*iface
,
4600 IDirect3DTexture2
*Texture2
)
4602 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
4603 IDirectDrawSurfaceImpl
*tex
= unsafe_impl_from_IDirect3DTexture2(Texture2
);
4607 TRACE("iface %p, stage %u, texture %p.\n", iface
, Stage
, Texture2
);
4609 EnterCriticalSection(&ddraw_cs
);
4611 if (This
->legacyTextureBlending
)
4612 IDirect3DDevice3_GetRenderState(iface
, D3DRENDERSTATE_TEXTUREMAPBLEND
, &texmapblend
);
4614 hr
= IDirect3DDevice7_SetTexture(&This
->IDirect3DDevice7_iface
, Stage
, &tex
->IDirectDrawSurface7_iface
);
4616 if (This
->legacyTextureBlending
&& texmapblend
== D3DTBLEND_MODULATE
)
4618 /* This fixup is required by the way D3DTBLEND_MODULATE maps to texture stage states.
4619 See IDirect3DDeviceImpl_3_SetRenderState for details. */
4620 struct wined3d_texture
*tex
= NULL
;
4621 BOOL tex_alpha
= FALSE
;
4622 DDPIXELFORMAT ddfmt
;
4625 result
= wined3d_device_get_texture(This
->wined3d_device
, 0, &tex
);
4626 if (result
== WINED3D_OK
&& tex
)
4628 struct wined3d_resource
*sub_resource
;
4630 if ((sub_resource
= wined3d_texture_get_sub_resource(tex
, 0)))
4632 struct wined3d_resource_desc desc
;
4634 wined3d_resource_get_desc(sub_resource
, &desc
);
4635 ddfmt
.dwSize
= sizeof(ddfmt
);
4636 PixelFormat_WineD3DtoDD(&ddfmt
, desc
.format
);
4637 if (ddfmt
.u5
.dwRGBAlphaBitMask
) tex_alpha
= TRUE
;
4640 wined3d_texture_decref(tex
);
4643 /* Arg 1/2 are already set to WINED3DTA_TEXTURE/WINED3DTA_CURRENT in case of D3DTBLEND_MODULATE */
4645 wined3d_device_set_texture_stage_state(This
->wined3d_device
, 0, WINED3DTSS_ALPHAOP
, WINED3DTOP_SELECTARG1
);
4647 wined3d_device_set_texture_stage_state(This
->wined3d_device
, 0, WINED3DTSS_ALPHAOP
, WINED3DTOP_SELECTARG2
);
4650 LeaveCriticalSection(&ddraw_cs
);
4655 static const struct tss_lookup
4662 {FALSE
, WINED3DTSS_FORCE_DWORD
}, /* 0, unused */
4663 {FALSE
, WINED3DTSS_COLOROP
}, /* 1, D3DTSS_COLOROP */
4664 {FALSE
, WINED3DTSS_COLORARG1
}, /* 2, D3DTSS_COLORARG1 */
4665 {FALSE
, WINED3DTSS_COLORARG2
}, /* 3, D3DTSS_COLORARG2 */
4666 {FALSE
, WINED3DTSS_ALPHAOP
}, /* 4, D3DTSS_ALPHAOP */
4667 {FALSE
, WINED3DTSS_ALPHAARG1
}, /* 5, D3DTSS_ALPHAARG1 */
4668 {FALSE
, WINED3DTSS_ALPHAARG2
}, /* 6, D3DTSS_ALPHAARG2 */
4669 {FALSE
, WINED3DTSS_BUMPENVMAT00
}, /* 7, D3DTSS_BUMPENVMAT00 */
4670 {FALSE
, WINED3DTSS_BUMPENVMAT01
}, /* 8, D3DTSS_BUMPENVMAT01 */
4671 {FALSE
, WINED3DTSS_BUMPENVMAT10
}, /* 9, D3DTSS_BUMPENVMAT10 */
4672 {FALSE
, WINED3DTSS_BUMPENVMAT11
}, /* 10, D3DTSS_BUMPENVMAT11 */
4673 {FALSE
, WINED3DTSS_TEXCOORDINDEX
}, /* 11, D3DTSS_TEXCOORDINDEX */
4674 {TRUE
, WINED3DSAMP_ADDRESSU
}, /* 12, D3DTSS_ADDRESS */
4675 {TRUE
, WINED3DSAMP_ADDRESSU
}, /* 13, D3DTSS_ADDRESSU */
4676 {TRUE
, WINED3DSAMP_ADDRESSV
}, /* 14, D3DTSS_ADDRESSV */
4677 {TRUE
, WINED3DSAMP_BORDERCOLOR
}, /* 15, D3DTSS_BORDERCOLOR */
4678 {TRUE
, WINED3DSAMP_MAGFILTER
}, /* 16, D3DTSS_MAGFILTER */
4679 {TRUE
, WINED3DSAMP_MINFILTER
}, /* 17, D3DTSS_MINFILTER */
4680 {TRUE
, WINED3DSAMP_MIPFILTER
}, /* 18, D3DTSS_MIPFILTER */
4681 {TRUE
, WINED3DSAMP_MIPMAPLODBIAS
}, /* 19, D3DTSS_MIPMAPLODBIAS */
4682 {TRUE
, WINED3DSAMP_MAXMIPLEVEL
}, /* 20, D3DTSS_MAXMIPLEVEL */
4683 {TRUE
, WINED3DSAMP_MAXANISOTROPY
}, /* 21, D3DTSS_MAXANISOTROPY */
4684 {FALSE
, WINED3DTSS_BUMPENVLSCALE
}, /* 22, D3DTSS_BUMPENVLSCALE */
4685 {FALSE
, WINED3DTSS_BUMPENVLOFFSET
}, /* 23, D3DTSS_BUMPENVLOFFSET */
4686 {FALSE
, WINED3DTSS_TEXTURETRANSFORMFLAGS
}, /* 24, D3DTSS_TEXTURETRANSFORMFLAGS */
4689 /*****************************************************************************
4690 * IDirect3DDevice7::GetTextureStageState
4692 * Retrieves a state from a texture stage.
4697 * Stage: The stage to retrieve the state from
4698 * TexStageStateType: The state type to retrieve
4699 * State: Address to store the state's value at
4703 * DDERR_INVALIDPARAMS if State is NULL
4704 * For details, see IWineD3DDevice::GetTextureStageState
4706 *****************************************************************************/
4708 IDirect3DDeviceImpl_7_GetTextureStageState(IDirect3DDevice7
*iface
,
4710 D3DTEXTURESTAGESTATETYPE TexStageStateType
,
4713 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
4715 const struct tss_lookup
*l
;
4717 TRACE("iface %p, stage %u, state %#x, value %p.\n",
4718 iface
, Stage
, TexStageStateType
, State
);
4721 return DDERR_INVALIDPARAMS
;
4723 if (TexStageStateType
> D3DTSS_TEXTURETRANSFORMFLAGS
)
4725 WARN("Invalid TexStageStateType %#x passed.\n", TexStageStateType
);
4729 l
= &tss_lookup
[TexStageStateType
];
4731 EnterCriticalSection(&ddraw_cs
);
4733 if (l
->sampler_state
)
4735 hr
= wined3d_device_get_sampler_state(This
->wined3d_device
, Stage
, l
->state
, State
);
4737 switch(TexStageStateType
)
4739 /* Mipfilter is a sampler state with different values */
4740 case D3DTSS_MIPFILTER
:
4744 case WINED3DTEXF_NONE
: *State
= D3DTFP_NONE
; break;
4745 case WINED3DTEXF_POINT
: *State
= D3DTFP_POINT
; break;
4746 case WINED3DTEXF_LINEAR
: *State
= D3DTFP_LINEAR
; break;
4748 ERR("Unexpected mipfilter value %#x\n", *State
);
4749 *State
= D3DTFP_NONE
;
4755 /* Magfilter has slightly different values */
4756 case D3DTSS_MAGFILTER
:
4760 case WINED3DTEXF_POINT
: *State
= D3DTFG_POINT
; break;
4761 case WINED3DTEXF_LINEAR
: *State
= D3DTFG_LINEAR
; break;
4762 case WINED3DTEXF_ANISOTROPIC
: *State
= D3DTFG_ANISOTROPIC
; break;
4763 case WINED3DTEXF_FLATCUBIC
: *State
= D3DTFG_FLATCUBIC
; break;
4764 case WINED3DTEXF_GAUSSIANCUBIC
: *State
= D3DTFG_GAUSSIANCUBIC
; break;
4766 ERR("Unexpected wined3d mag filter value %#x\n", *State
);
4767 *State
= D3DTFG_POINT
;
4779 hr
= wined3d_device_get_texture_stage_state(This
->wined3d_device
, Stage
, l
->state
, State
);
4782 LeaveCriticalSection(&ddraw_cs
);
4786 static HRESULT WINAPI
4787 IDirect3DDeviceImpl_7_GetTextureStageState_FPUSetup(IDirect3DDevice7
*iface
,
4789 D3DTEXTURESTAGESTATETYPE TexStageStateType
,
4792 return IDirect3DDeviceImpl_7_GetTextureStageState(iface
, Stage
, TexStageStateType
, State
);
4795 static HRESULT WINAPI
4796 IDirect3DDeviceImpl_7_GetTextureStageState_FPUPreserve(IDirect3DDevice7
*iface
,
4798 D3DTEXTURESTAGESTATETYPE TexStageStateType
,
4804 old_fpucw
= d3d_fpu_setup();
4805 hr
= IDirect3DDeviceImpl_7_GetTextureStageState(iface
, Stage
, TexStageStateType
, State
);
4806 set_fpu_control_word(old_fpucw
);
4811 static HRESULT WINAPI
IDirect3DDeviceImpl_3_GetTextureStageState(IDirect3DDevice3
*iface
,
4812 DWORD Stage
, D3DTEXTURESTAGESTATETYPE TexStageStateType
, DWORD
*State
)
4814 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
4816 TRACE("iface %p, stage %u, state %#x, value %p.\n",
4817 iface
, Stage
, TexStageStateType
, State
);
4819 return IDirect3DDevice7_GetTextureStageState(&This
->IDirect3DDevice7_iface
,
4820 Stage
, TexStageStateType
, State
);
4823 /*****************************************************************************
4824 * IDirect3DDevice7::SetTextureStageState
4826 * Sets a texture stage state. Some stage types need to be handled specially,
4827 * because they do not exist in WineD3D and were moved to another place
4832 * Stage: The stage to modify
4833 * TexStageStateType: The state to change
4834 * State: The new value for the state
4838 * For details, see IWineD3DDevice::SetTextureStageState
4840 *****************************************************************************/
4842 IDirect3DDeviceImpl_7_SetTextureStageState(IDirect3DDevice7
*iface
,
4844 D3DTEXTURESTAGESTATETYPE TexStageStateType
,
4847 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
4848 const struct tss_lookup
*l
;
4851 TRACE("iface %p, stage %u, state %#x, value %#x.\n",
4852 iface
, Stage
, TexStageStateType
, State
);
4854 if (TexStageStateType
> D3DTSS_TEXTURETRANSFORMFLAGS
)
4856 WARN("Invalid TexStageStateType %#x passed.\n", TexStageStateType
);
4860 l
= &tss_lookup
[TexStageStateType
];
4862 EnterCriticalSection(&ddraw_cs
);
4864 if (l
->sampler_state
)
4866 switch(TexStageStateType
)
4868 /* Mipfilter is a sampler state with different values */
4869 case D3DTSS_MIPFILTER
:
4873 case D3DTFP_NONE
: State
= WINED3DTEXF_NONE
; break;
4874 case D3DTFP_POINT
: State
= WINED3DTEXF_POINT
; break;
4875 case 0: /* Unchecked */
4876 case D3DTFP_LINEAR
: State
= WINED3DTEXF_LINEAR
; break;
4878 ERR("Unexpected mipfilter value %d\n", State
);
4879 State
= WINED3DTEXF_NONE
;
4885 /* Magfilter has slightly different values */
4886 case D3DTSS_MAGFILTER
:
4890 case D3DTFG_POINT
: State
= WINED3DTEXF_POINT
; break;
4891 case D3DTFG_LINEAR
: State
= WINED3DTEXF_LINEAR
; break;
4892 case D3DTFG_FLATCUBIC
: State
= WINED3DTEXF_FLATCUBIC
; break;
4893 case D3DTFG_GAUSSIANCUBIC
: State
= WINED3DTEXF_GAUSSIANCUBIC
; break;
4894 case D3DTFG_ANISOTROPIC
: State
= WINED3DTEXF_ANISOTROPIC
; break;
4896 ERR("Unexpected d3d7 mag filter type %d\n", State
);
4897 State
= WINED3DTEXF_POINT
;
4903 case D3DTSS_ADDRESS
:
4904 wined3d_device_set_sampler_state(This
->wined3d_device
, Stage
, WINED3DSAMP_ADDRESSV
, State
);
4911 hr
= wined3d_device_set_sampler_state(This
->wined3d_device
, Stage
, l
->state
, State
);
4915 hr
= wined3d_device_set_texture_stage_state(This
->wined3d_device
, Stage
, l
->state
, State
);
4918 LeaveCriticalSection(&ddraw_cs
);
4922 static HRESULT WINAPI
4923 IDirect3DDeviceImpl_7_SetTextureStageState_FPUSetup(IDirect3DDevice7
*iface
,
4925 D3DTEXTURESTAGESTATETYPE TexStageStateType
,
4928 return IDirect3DDeviceImpl_7_SetTextureStageState(iface
, Stage
, TexStageStateType
, State
);
4931 static HRESULT WINAPI
4932 IDirect3DDeviceImpl_7_SetTextureStageState_FPUPreserve(IDirect3DDevice7
*iface
,
4934 D3DTEXTURESTAGESTATETYPE TexStageStateType
,
4940 old_fpucw
= d3d_fpu_setup();
4941 hr
= IDirect3DDeviceImpl_7_SetTextureStageState(iface
, Stage
, TexStageStateType
, State
);
4942 set_fpu_control_word(old_fpucw
);
4947 static HRESULT WINAPI
IDirect3DDeviceImpl_3_SetTextureStageState(IDirect3DDevice3
*iface
,
4948 DWORD Stage
, D3DTEXTURESTAGESTATETYPE TexStageStateType
, DWORD State
)
4950 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
4952 TRACE("iface %p, stage %u, state %#x, value %#x.\n",
4953 iface
, Stage
, TexStageStateType
, State
);
4955 return IDirect3DDevice7_SetTextureStageState(&This
->IDirect3DDevice7_iface
,
4956 Stage
, TexStageStateType
, State
);
4959 /*****************************************************************************
4960 * IDirect3DDevice7::ValidateDevice
4962 * SDK: "Reports the device's ability to render the currently set
4963 * texture-blending operations in a single pass". Whatever that means
4969 * NumPasses: Address to write the number of necessary passes for the
4970 * desired effect to.
4974 * See IWineD3DDevice::ValidateDevice for more details
4976 *****************************************************************************/
4978 IDirect3DDeviceImpl_7_ValidateDevice(IDirect3DDevice7
*iface
,
4981 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
4984 TRACE("iface %p, pass_count %p.\n", iface
, NumPasses
);
4986 EnterCriticalSection(&ddraw_cs
);
4987 hr
= wined3d_device_validate_device(This
->wined3d_device
, NumPasses
);
4988 LeaveCriticalSection(&ddraw_cs
);
4992 static HRESULT WINAPI
4993 IDirect3DDeviceImpl_7_ValidateDevice_FPUSetup(IDirect3DDevice7
*iface
,
4996 return IDirect3DDeviceImpl_7_ValidateDevice(iface
, NumPasses
);
4999 static HRESULT WINAPI
5000 IDirect3DDeviceImpl_7_ValidateDevice_FPUPreserve(IDirect3DDevice7
*iface
,
5006 old_fpucw
= d3d_fpu_setup();
5007 hr
= IDirect3DDeviceImpl_7_ValidateDevice(iface
, NumPasses
);
5008 set_fpu_control_word(old_fpucw
);
5013 static HRESULT WINAPI
IDirect3DDeviceImpl_3_ValidateDevice(IDirect3DDevice3
*iface
, DWORD
*Passes
)
5015 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
5017 TRACE("iface %p, pass_count %p.\n", iface
, Passes
);
5019 return IDirect3DDevice7_ValidateDevice(&This
->IDirect3DDevice7_iface
, Passes
);
5022 /*****************************************************************************
5023 * IDirect3DDevice7::Clear
5025 * Fills the render target, the z buffer and the stencil buffer with a
5026 * clear color / value
5031 * Count: Number of rectangles in Rects must be 0 if Rects is NULL
5032 * Rects: Rectangles to clear. If NULL, the whole surface is cleared
5033 * Flags: Some flags, as usual
5034 * Color: Clear color for the render target
5035 * Z: Clear value for the Z buffer
5036 * Stencil: Clear value to store in each stencil buffer entry
5040 * For details, see IWineD3DDevice::Clear
5042 *****************************************************************************/
5044 IDirect3DDeviceImpl_7_Clear(IDirect3DDevice7
*iface
,
5052 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
5055 TRACE("iface %p, count %u, rects %p, flags %#x, color 0x%08x, z %.8e, stencil %#x.\n",
5056 iface
, Count
, Rects
, Flags
, Color
, Z
, Stencil
);
5058 EnterCriticalSection(&ddraw_cs
);
5059 hr
= wined3d_device_clear(This
->wined3d_device
, Count
, (RECT
*)Rects
, Flags
, Color
, Z
, Stencil
);
5060 LeaveCriticalSection(&ddraw_cs
);
5064 static HRESULT WINAPI
5065 IDirect3DDeviceImpl_7_Clear_FPUSetup(IDirect3DDevice7
*iface
,
5073 return IDirect3DDeviceImpl_7_Clear(iface
, Count
, Rects
, Flags
, Color
, Z
, Stencil
);
5076 static HRESULT WINAPI
5077 IDirect3DDeviceImpl_7_Clear_FPUPreserve(IDirect3DDevice7
*iface
,
5088 old_fpucw
= d3d_fpu_setup();
5089 hr
= IDirect3DDeviceImpl_7_Clear(iface
, Count
, Rects
, Flags
, Color
, Z
, Stencil
);
5090 set_fpu_control_word(old_fpucw
);
5095 /*****************************************************************************
5096 * IDirect3DDevice7::SetViewport
5098 * Sets the current viewport.
5100 * Version 7 only, but IDirect3DViewport uses this call for older
5104 * Data: The new viewport to set
5108 * DDERR_INVALIDPARAMS if Data is NULL
5109 * For more details, see IWineDDDevice::SetViewport
5111 *****************************************************************************/
5113 IDirect3DDeviceImpl_7_SetViewport(IDirect3DDevice7
*iface
,
5116 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
5119 TRACE("iface %p, viewport %p.\n", iface
, Data
);
5122 return DDERR_INVALIDPARAMS
;
5124 /* Note: D3DVIEWPORT7 is compatible with WINED3DVIEWPORT */
5125 EnterCriticalSection(&ddraw_cs
);
5126 hr
= wined3d_device_set_viewport(This
->wined3d_device
, (WINED3DVIEWPORT
*)Data
);
5127 LeaveCriticalSection(&ddraw_cs
);
5131 static HRESULT WINAPI
5132 IDirect3DDeviceImpl_7_SetViewport_FPUSetup(IDirect3DDevice7
*iface
,
5135 return IDirect3DDeviceImpl_7_SetViewport(iface
, Data
);
5138 static HRESULT WINAPI
5139 IDirect3DDeviceImpl_7_SetViewport_FPUPreserve(IDirect3DDevice7
*iface
,
5145 old_fpucw
= d3d_fpu_setup();
5146 hr
= IDirect3DDeviceImpl_7_SetViewport(iface
, Data
);
5147 set_fpu_control_word(old_fpucw
);
5152 /*****************************************************************************
5153 * IDirect3DDevice::GetViewport
5155 * Returns the current viewport
5160 * Data: D3D7Viewport structure to write the viewport information to
5164 * DDERR_INVALIDPARAMS if Data is NULL
5165 * For more details, see IWineD3DDevice::GetViewport
5167 *****************************************************************************/
5169 IDirect3DDeviceImpl_7_GetViewport(IDirect3DDevice7
*iface
,
5172 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
5175 TRACE("iface %p, viewport %p.\n", iface
, Data
);
5178 return DDERR_INVALIDPARAMS
;
5180 /* Note: D3DVIEWPORT7 is compatible with WINED3DVIEWPORT */
5181 EnterCriticalSection(&ddraw_cs
);
5182 hr
= wined3d_device_get_viewport(This
->wined3d_device
, (WINED3DVIEWPORT
*)Data
);
5184 LeaveCriticalSection(&ddraw_cs
);
5185 return hr_ddraw_from_wined3d(hr
);
5188 static HRESULT WINAPI
5189 IDirect3DDeviceImpl_7_GetViewport_FPUSetup(IDirect3DDevice7
*iface
,
5192 return IDirect3DDeviceImpl_7_GetViewport(iface
, Data
);
5195 static HRESULT WINAPI
5196 IDirect3DDeviceImpl_7_GetViewport_FPUPreserve(IDirect3DDevice7
*iface
,
5202 old_fpucw
= d3d_fpu_setup();
5203 hr
= IDirect3DDeviceImpl_7_GetViewport(iface
, Data
);
5204 set_fpu_control_word(old_fpucw
);
5209 /*****************************************************************************
5210 * IDirect3DDevice7::SetMaterial
5217 * Mat: The material to set
5221 * DDERR_INVALIDPARAMS if Mat is NULL.
5222 * For more details, see IWineD3DDevice::SetMaterial
5224 *****************************************************************************/
5226 IDirect3DDeviceImpl_7_SetMaterial(IDirect3DDevice7
*iface
,
5229 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
5232 TRACE("iface %p, material %p.\n", iface
, Mat
);
5234 if (!Mat
) return DDERR_INVALIDPARAMS
;
5235 /* Note: D3DMATERIAL7 is compatible with WINED3DMATERIAL */
5236 EnterCriticalSection(&ddraw_cs
);
5237 hr
= wined3d_device_set_material(This
->wined3d_device
, (WINED3DMATERIAL
*)Mat
);
5238 LeaveCriticalSection(&ddraw_cs
);
5239 return hr_ddraw_from_wined3d(hr
);
5242 static HRESULT WINAPI
5243 IDirect3DDeviceImpl_7_SetMaterial_FPUSetup(IDirect3DDevice7
*iface
,
5246 return IDirect3DDeviceImpl_7_SetMaterial(iface
, Mat
);
5249 static HRESULT WINAPI
5250 IDirect3DDeviceImpl_7_SetMaterial_FPUPreserve(IDirect3DDevice7
*iface
,
5256 old_fpucw
= d3d_fpu_setup();
5257 hr
= IDirect3DDeviceImpl_7_SetMaterial(iface
, Mat
);
5258 set_fpu_control_word(old_fpucw
);
5263 /*****************************************************************************
5264 * IDirect3DDevice7::GetMaterial
5266 * Returns the current material
5271 * Mat: D3DMATERIAL7 structure to write the material parameters to
5275 * DDERR_INVALIDPARAMS if Mat is NULL
5276 * For more details, see IWineD3DDevice::GetMaterial
5278 *****************************************************************************/
5280 IDirect3DDeviceImpl_7_GetMaterial(IDirect3DDevice7
*iface
,
5283 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
5286 TRACE("iface %p, material %p.\n", iface
, Mat
);
5288 EnterCriticalSection(&ddraw_cs
);
5289 /* Note: D3DMATERIAL7 is compatible with WINED3DMATERIAL */
5290 hr
= wined3d_device_get_material(This
->wined3d_device
, (WINED3DMATERIAL
*)Mat
);
5291 LeaveCriticalSection(&ddraw_cs
);
5292 return hr_ddraw_from_wined3d(hr
);
5295 static HRESULT WINAPI
5296 IDirect3DDeviceImpl_7_GetMaterial_FPUSetup(IDirect3DDevice7
*iface
,
5299 return IDirect3DDeviceImpl_7_GetMaterial(iface
, Mat
);
5302 static HRESULT WINAPI
5303 IDirect3DDeviceImpl_7_GetMaterial_FPUPreserve(IDirect3DDevice7
*iface
,
5309 old_fpucw
= d3d_fpu_setup();
5310 hr
= IDirect3DDeviceImpl_7_GetMaterial(iface
, Mat
);
5311 set_fpu_control_word(old_fpucw
);
5316 /*****************************************************************************
5317 * IDirect3DDevice7::SetLight
5319 * Assigns a light to a light index, but doesn't activate it yet.
5321 * Version 7, IDirect3DLight uses this method for older versions
5324 * LightIndex: The index of the new light
5325 * Light: A D3DLIGHT7 structure describing the light
5329 * For more details, see IWineD3DDevice::SetLight
5331 *****************************************************************************/
5333 IDirect3DDeviceImpl_7_SetLight(IDirect3DDevice7
*iface
,
5337 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
5340 TRACE("iface %p, light_idx %u, light %p.\n", iface
, LightIndex
, Light
);
5342 EnterCriticalSection(&ddraw_cs
);
5343 /* Note: D3DLIGHT7 is compatible with WINED3DLIGHT */
5344 hr
= wined3d_device_set_light(This
->wined3d_device
, LightIndex
, (WINED3DLIGHT
*)Light
);
5345 LeaveCriticalSection(&ddraw_cs
);
5346 return hr_ddraw_from_wined3d(hr
);
5349 static HRESULT WINAPI
5350 IDirect3DDeviceImpl_7_SetLight_FPUSetup(IDirect3DDevice7
*iface
,
5354 return IDirect3DDeviceImpl_7_SetLight(iface
, LightIndex
, Light
);
5357 static HRESULT WINAPI
5358 IDirect3DDeviceImpl_7_SetLight_FPUPreserve(IDirect3DDevice7
*iface
,
5365 old_fpucw
= d3d_fpu_setup();
5366 hr
= IDirect3DDeviceImpl_7_SetLight(iface
, LightIndex
, Light
);
5367 set_fpu_control_word(old_fpucw
);
5372 /*****************************************************************************
5373 * IDirect3DDevice7::GetLight
5375 * Returns the light assigned to a light index
5378 * Light: Structure to write the light information to
5382 * DDERR_INVALIDPARAMS if Light is NULL
5383 * For details, see IWineD3DDevice::GetLight
5385 *****************************************************************************/
5387 IDirect3DDeviceImpl_7_GetLight(IDirect3DDevice7
*iface
,
5391 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
5394 TRACE("iface %p, light_idx %u, light %p.\n", iface
, LightIndex
, Light
);
5396 EnterCriticalSection(&ddraw_cs
);
5397 /* Note: D3DLIGHT7 is compatible with WINED3DLIGHT */
5398 rc
= wined3d_device_get_light(This
->wined3d_device
, LightIndex
, (WINED3DLIGHT
*)Light
);
5400 /* Translate the result. WineD3D returns other values than D3D7 */
5401 LeaveCriticalSection(&ddraw_cs
);
5402 return hr_ddraw_from_wined3d(rc
);
5405 static HRESULT WINAPI
5406 IDirect3DDeviceImpl_7_GetLight_FPUSetup(IDirect3DDevice7
*iface
,
5410 return IDirect3DDeviceImpl_7_GetLight(iface
, LightIndex
, Light
);
5413 static HRESULT WINAPI
5414 IDirect3DDeviceImpl_7_GetLight_FPUPreserve(IDirect3DDevice7
*iface
,
5421 old_fpucw
= d3d_fpu_setup();
5422 hr
= IDirect3DDeviceImpl_7_GetLight(iface
, LightIndex
, Light
);
5423 set_fpu_control_word(old_fpucw
);
5428 /*****************************************************************************
5429 * IDirect3DDevice7::BeginStateBlock
5431 * Begins recording to a stateblock
5437 * For details see IWineD3DDevice::BeginStateBlock
5439 *****************************************************************************/
5441 IDirect3DDeviceImpl_7_BeginStateBlock(IDirect3DDevice7
*iface
)
5443 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
5446 TRACE("iface %p.\n", iface
);
5448 EnterCriticalSection(&ddraw_cs
);
5449 hr
= wined3d_device_begin_stateblock(This
->wined3d_device
);
5450 LeaveCriticalSection(&ddraw_cs
);
5451 return hr_ddraw_from_wined3d(hr
);
5454 static HRESULT WINAPI
5455 IDirect3DDeviceImpl_7_BeginStateBlock_FPUSetup(IDirect3DDevice7
*iface
)
5457 return IDirect3DDeviceImpl_7_BeginStateBlock(iface
);
5460 static HRESULT WINAPI
5461 IDirect3DDeviceImpl_7_BeginStateBlock_FPUPreserve(IDirect3DDevice7
*iface
)
5466 old_fpucw
= d3d_fpu_setup();
5467 hr
= IDirect3DDeviceImpl_7_BeginStateBlock(iface
);
5468 set_fpu_control_word(old_fpucw
);
5473 /*****************************************************************************
5474 * IDirect3DDevice7::EndStateBlock
5476 * Stops recording to a state block and returns the created stateblock
5482 * BlockHandle: Address to store the stateblock's handle to
5486 * DDERR_INVALIDPARAMS if BlockHandle is NULL
5487 * See IWineD3DDevice::EndStateBlock for more details
5489 *****************************************************************************/
5491 IDirect3DDeviceImpl_7_EndStateBlock(IDirect3DDevice7
*iface
,
5494 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
5495 struct wined3d_stateblock
*wined3d_sb
;
5499 TRACE("iface %p, stateblock %p.\n", iface
, BlockHandle
);
5503 WARN("BlockHandle == NULL, returning DDERR_INVALIDPARAMS\n");
5504 return DDERR_INVALIDPARAMS
;
5507 EnterCriticalSection(&ddraw_cs
);
5509 hr
= wined3d_device_end_stateblock(This
->wined3d_device
, &wined3d_sb
);
5512 WARN("Failed to end stateblock, hr %#x.\n", hr
);
5513 LeaveCriticalSection(&ddraw_cs
);
5515 return hr_ddraw_from_wined3d(hr
);
5518 h
= ddraw_allocate_handle(&This
->handle_table
, wined3d_sb
, DDRAW_HANDLE_STATEBLOCK
);
5519 if (h
== DDRAW_INVALID_HANDLE
)
5521 ERR("Failed to allocate a stateblock handle.\n");
5522 wined3d_stateblock_decref(wined3d_sb
);
5523 LeaveCriticalSection(&ddraw_cs
);
5525 return DDERR_OUTOFMEMORY
;
5528 LeaveCriticalSection(&ddraw_cs
);
5529 *BlockHandle
= h
+ 1;
5531 return hr_ddraw_from_wined3d(hr
);
5534 static HRESULT WINAPI
5535 IDirect3DDeviceImpl_7_EndStateBlock_FPUSetup(IDirect3DDevice7
*iface
,
5538 return IDirect3DDeviceImpl_7_EndStateBlock(iface
, BlockHandle
);
5541 static HRESULT WINAPI
5542 IDirect3DDeviceImpl_7_EndStateBlock_FPUPreserve(IDirect3DDevice7
*iface
,
5548 old_fpucw
= d3d_fpu_setup();
5549 hr
= IDirect3DDeviceImpl_7_EndStateBlock(iface
, BlockHandle
);
5550 set_fpu_control_word(old_fpucw
);
5555 /*****************************************************************************
5556 * IDirect3DDevice7::PreLoad
5558 * Allows the app to signal that a texture will be used soon, to allow
5559 * the Direct3DDevice to load it to the video card in the meantime.
5564 * Texture: The texture to preload
5568 * DDERR_INVALIDPARAMS if Texture is NULL
5569 * See IWineD3DSurface::PreLoad for details
5571 *****************************************************************************/
5573 IDirect3DDeviceImpl_7_PreLoad(IDirect3DDevice7
*iface
,
5574 IDirectDrawSurface7
*Texture
)
5576 IDirectDrawSurfaceImpl
*surf
= unsafe_impl_from_IDirectDrawSurface7(Texture
);
5578 TRACE("iface %p, texture %p.\n", iface
, Texture
);
5581 return DDERR_INVALIDPARAMS
;
5583 EnterCriticalSection(&ddraw_cs
);
5584 wined3d_surface_preload(surf
->wined3d_surface
);
5585 LeaveCriticalSection(&ddraw_cs
);
5589 static HRESULT WINAPI
5590 IDirect3DDeviceImpl_7_PreLoad_FPUSetup(IDirect3DDevice7
*iface
,
5591 IDirectDrawSurface7
*Texture
)
5593 return IDirect3DDeviceImpl_7_PreLoad(iface
, Texture
);
5596 static HRESULT WINAPI
5597 IDirect3DDeviceImpl_7_PreLoad_FPUPreserve(IDirect3DDevice7
*iface
,
5598 IDirectDrawSurface7
*Texture
)
5603 old_fpucw
= d3d_fpu_setup();
5604 hr
= IDirect3DDeviceImpl_7_PreLoad(iface
, Texture
);
5605 set_fpu_control_word(old_fpucw
);
5610 /*****************************************************************************
5611 * IDirect3DDevice7::ApplyStateBlock
5613 * Activates the state stored in a state block handle.
5616 * BlockHandle: The stateblock handle to activate
5620 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is NULL
5622 *****************************************************************************/
5624 IDirect3DDeviceImpl_7_ApplyStateBlock(IDirect3DDevice7
*iface
,
5627 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
5628 struct wined3d_stateblock
*wined3d_sb
;
5631 TRACE("iface %p, stateblock %#x.\n", iface
, BlockHandle
);
5633 EnterCriticalSection(&ddraw_cs
);
5635 wined3d_sb
= ddraw_get_object(&This
->handle_table
, BlockHandle
- 1, DDRAW_HANDLE_STATEBLOCK
);
5638 WARN("Invalid stateblock handle.\n");
5639 LeaveCriticalSection(&ddraw_cs
);
5640 return D3DERR_INVALIDSTATEBLOCK
;
5643 hr
= wined3d_stateblock_apply(wined3d_sb
);
5644 LeaveCriticalSection(&ddraw_cs
);
5646 return hr_ddraw_from_wined3d(hr
);
5649 static HRESULT WINAPI
5650 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUSetup(IDirect3DDevice7
*iface
,
5653 return IDirect3DDeviceImpl_7_ApplyStateBlock(iface
, BlockHandle
);
5656 static HRESULT WINAPI
5657 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUPreserve(IDirect3DDevice7
*iface
,
5663 old_fpucw
= d3d_fpu_setup();
5664 hr
= IDirect3DDeviceImpl_7_ApplyStateBlock(iface
, BlockHandle
);
5665 set_fpu_control_word(old_fpucw
);
5670 /*****************************************************************************
5671 * IDirect3DDevice7::CaptureStateBlock
5673 * Updates a stateblock's values to the values currently set for the device
5678 * BlockHandle: Stateblock to update
5682 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is NULL
5683 * See IWineD3DDevice::CaptureStateBlock for more details
5685 *****************************************************************************/
5687 IDirect3DDeviceImpl_7_CaptureStateBlock(IDirect3DDevice7
*iface
,
5690 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
5691 struct wined3d_stateblock
*wined3d_sb
;
5694 TRACE("iface %p, stateblock %#x.\n", iface
, BlockHandle
);
5696 EnterCriticalSection(&ddraw_cs
);
5698 wined3d_sb
= ddraw_get_object(&This
->handle_table
, BlockHandle
- 1, DDRAW_HANDLE_STATEBLOCK
);
5701 WARN("Invalid stateblock handle.\n");
5702 LeaveCriticalSection(&ddraw_cs
);
5703 return D3DERR_INVALIDSTATEBLOCK
;
5706 hr
= wined3d_stateblock_capture(wined3d_sb
);
5707 LeaveCriticalSection(&ddraw_cs
);
5708 return hr_ddraw_from_wined3d(hr
);
5711 static HRESULT WINAPI
5712 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUSetup(IDirect3DDevice7
*iface
,
5715 return IDirect3DDeviceImpl_7_CaptureStateBlock(iface
, BlockHandle
);
5718 static HRESULT WINAPI
5719 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUPreserve(IDirect3DDevice7
*iface
,
5725 old_fpucw
= d3d_fpu_setup();
5726 hr
= IDirect3DDeviceImpl_7_CaptureStateBlock(iface
, BlockHandle
);
5727 set_fpu_control_word(old_fpucw
);
5732 /*****************************************************************************
5733 * IDirect3DDevice7::DeleteStateBlock
5735 * Deletes a stateblock handle. This means releasing the WineD3DStateBlock
5740 * BlockHandle: Stateblock handle to delete
5744 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is 0
5746 *****************************************************************************/
5748 IDirect3DDeviceImpl_7_DeleteStateBlock(IDirect3DDevice7
*iface
,
5751 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
5752 struct wined3d_stateblock
*wined3d_sb
;
5755 TRACE("iface %p, stateblock %#x.\n", iface
, BlockHandle
);
5757 EnterCriticalSection(&ddraw_cs
);
5759 wined3d_sb
= ddraw_free_handle(&This
->handle_table
, BlockHandle
- 1, DDRAW_HANDLE_STATEBLOCK
);
5762 WARN("Invalid stateblock handle.\n");
5763 LeaveCriticalSection(&ddraw_cs
);
5764 return D3DERR_INVALIDSTATEBLOCK
;
5767 if ((ref
= wined3d_stateblock_decref(wined3d_sb
)))
5769 ERR("Something is still holding stateblock %p (refcount %u).\n", wined3d_sb
, ref
);
5772 LeaveCriticalSection(&ddraw_cs
);
5776 static HRESULT WINAPI
5777 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUSetup(IDirect3DDevice7
*iface
,
5780 return IDirect3DDeviceImpl_7_DeleteStateBlock(iface
, BlockHandle
);
5783 static HRESULT WINAPI
5784 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUPreserve(IDirect3DDevice7
*iface
,
5790 old_fpucw
= d3d_fpu_setup();
5791 hr
= IDirect3DDeviceImpl_7_DeleteStateBlock(iface
, BlockHandle
);
5792 set_fpu_control_word(old_fpucw
);
5797 /*****************************************************************************
5798 * IDirect3DDevice7::CreateStateBlock
5800 * Creates a new state block handle.
5805 * Type: The state block type
5806 * BlockHandle: Address to write the created handle to
5810 * DDERR_INVALIDPARAMS if BlockHandle is NULL
5812 *****************************************************************************/
5814 IDirect3DDeviceImpl_7_CreateStateBlock(IDirect3DDevice7
*iface
,
5815 D3DSTATEBLOCKTYPE Type
,
5818 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
5819 struct wined3d_stateblock
*wined3d_sb
;
5823 TRACE("iface %p, type %#x, stateblock %p.\n", iface
, Type
, BlockHandle
);
5827 WARN("BlockHandle == NULL, returning DDERR_INVALIDPARAMS\n");
5828 return DDERR_INVALIDPARAMS
;
5830 if(Type
!= D3DSBT_ALL
&& Type
!= D3DSBT_PIXELSTATE
&&
5831 Type
!= D3DSBT_VERTEXSTATE
) {
5832 WARN("Unexpected stateblock type, returning DDERR_INVALIDPARAMS\n");
5833 return DDERR_INVALIDPARAMS
;
5836 EnterCriticalSection(&ddraw_cs
);
5838 /* The D3DSTATEBLOCKTYPE enum is fine here. */
5839 hr
= wined3d_stateblock_create(This
->wined3d_device
, Type
, &wined3d_sb
);
5842 WARN("Failed to create stateblock, hr %#x.\n", hr
);
5843 LeaveCriticalSection(&ddraw_cs
);
5844 return hr_ddraw_from_wined3d(hr
);
5847 h
= ddraw_allocate_handle(&This
->handle_table
, wined3d_sb
, DDRAW_HANDLE_STATEBLOCK
);
5848 if (h
== DDRAW_INVALID_HANDLE
)
5850 ERR("Failed to allocate stateblock handle.\n");
5851 wined3d_stateblock_decref(wined3d_sb
);
5852 LeaveCriticalSection(&ddraw_cs
);
5853 return DDERR_OUTOFMEMORY
;
5856 *BlockHandle
= h
+ 1;
5857 LeaveCriticalSection(&ddraw_cs
);
5859 return hr_ddraw_from_wined3d(hr
);
5862 static HRESULT WINAPI
5863 IDirect3DDeviceImpl_7_CreateStateBlock_FPUSetup(IDirect3DDevice7
*iface
,
5864 D3DSTATEBLOCKTYPE Type
,
5867 return IDirect3DDeviceImpl_7_CreateStateBlock(iface
, Type
, BlockHandle
);
5870 static HRESULT WINAPI
5871 IDirect3DDeviceImpl_7_CreateStateBlock_FPUPreserve(IDirect3DDevice7
*iface
,
5872 D3DSTATEBLOCKTYPE Type
,
5878 old_fpucw
= d3d_fpu_setup();
5879 hr
=IDirect3DDeviceImpl_7_CreateStateBlock(iface
, Type
, BlockHandle
);
5880 set_fpu_control_word(old_fpucw
);
5885 /* Helper function for IDirect3DDeviceImpl_7_Load. */
5886 static BOOL
is_mip_level_subset(IDirectDrawSurfaceImpl
*dest
,
5887 IDirectDrawSurfaceImpl
*src
)
5889 IDirectDrawSurfaceImpl
*src_level
, *dest_level
;
5890 IDirectDrawSurface7
*temp
;
5891 DDSURFACEDESC2 ddsd
;
5892 BOOL levelFound
; /* at least one suitable sublevel in dest found */
5894 /* To satisfy "destination is mip level subset of source" criteria (regular texture counts as 1 level),
5895 * 1) there must be at least one mip level in destination that matched dimensions of some mip level in source and
5896 * 2) there must be no destination levels that don't match any levels in source. Otherwise it's INVALIDPARAMS.
5903 for (;src_level
&& dest_level
;)
5905 if (src_level
->surface_desc
.dwWidth
== dest_level
->surface_desc
.dwWidth
&&
5906 src_level
->surface_desc
.dwHeight
== dest_level
->surface_desc
.dwHeight
)
5910 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
5911 ddsd
.ddsCaps
.dwCaps2
= DDSCAPS2_MIPMAPSUBLEVEL
;
5912 IDirectDrawSurface7_GetAttachedSurface(&dest_level
->IDirectDrawSurface7_iface
, &ddsd
.ddsCaps
, &temp
);
5914 if (dest_level
!= dest
) IDirectDrawSurface7_Release(&dest_level
->IDirectDrawSurface7_iface
);
5916 dest_level
= unsafe_impl_from_IDirectDrawSurface7(temp
);
5919 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
5920 ddsd
.ddsCaps
.dwCaps2
= DDSCAPS2_MIPMAPSUBLEVEL
;
5921 IDirectDrawSurface7_GetAttachedSurface(&src_level
->IDirectDrawSurface7_iface
, &ddsd
.ddsCaps
, &temp
);
5923 if (src_level
!= src
) IDirectDrawSurface7_Release(&src_level
->IDirectDrawSurface7_iface
);
5925 src_level
= unsafe_impl_from_IDirectDrawSurface7(temp
);
5928 if (src_level
&& src_level
!= src
) IDirectDrawSurface7_Release(&src_level
->IDirectDrawSurface7_iface
);
5929 if (dest_level
&& dest_level
!= dest
) IDirectDrawSurface7_Release(&dest_level
->IDirectDrawSurface7_iface
);
5931 return !dest_level
&& levelFound
;
5934 /* Helper function for IDirect3DDeviceImpl_7_Load. */
5935 static void copy_mipmap_chain(IDirect3DDeviceImpl
*device
,
5936 IDirectDrawSurfaceImpl
*dest
,
5937 IDirectDrawSurfaceImpl
*src
,
5938 const POINT
*DestPoint
,
5939 const RECT
*SrcRect
)
5941 IDirectDrawSurfaceImpl
*src_level
, *dest_level
;
5942 IDirectDrawSurface7
*temp
;
5943 DDSURFACEDESC2 ddsd
;
5947 IDirectDrawPalette
*pal
= NULL
, *pal_src
= NULL
;
5951 /* Copy palette, if possible. */
5952 IDirectDrawSurface7_GetPalette(&src
->IDirectDrawSurface7_iface
, &pal_src
);
5953 IDirectDrawSurface7_GetPalette(&dest
->IDirectDrawSurface7_iface
, &pal
);
5955 if (pal_src
!= NULL
&& pal
!= NULL
)
5957 PALETTEENTRY palent
[256];
5959 IDirectDrawPalette_GetEntries(pal_src
, 0, 0, 256, palent
);
5960 IDirectDrawPalette_SetEntries(pal
, 0, 0, 256, palent
);
5963 if (pal
) IDirectDrawPalette_Release(pal
);
5964 if (pal_src
) IDirectDrawPalette_Release(pal_src
);
5966 /* Copy colorkeys, if present. */
5967 for (ckeyflag
= DDCKEY_DESTBLT
; ckeyflag
<= DDCKEY_SRCOVERLAY
; ckeyflag
<<= 1)
5969 hr
= IDirectDrawSurface7_GetColorKey(&src
->IDirectDrawSurface7_iface
, ckeyflag
, &ddckey
);
5973 IDirectDrawSurface7_SetColorKey(&dest
->IDirectDrawSurface7_iface
, ckeyflag
, &ddckey
);
5981 src_rect
= *SrcRect
;
5983 for (;src_level
&& dest_level
;)
5985 if (src_level
->surface_desc
.dwWidth
== dest_level
->surface_desc
.dwWidth
&&
5986 src_level
->surface_desc
.dwHeight
== dest_level
->surface_desc
.dwHeight
)
5988 UINT src_w
= src_rect
.right
- src_rect
.left
;
5989 UINT src_h
= src_rect
.bottom
- src_rect
.top
;
5990 RECT dst_rect
= {point
.x
, point
.y
, point
.x
+ src_w
, point
.y
+ src_h
};
5992 if (FAILED(hr
= wined3d_surface_blt(dest_level
->wined3d_surface
, &dst_rect
,
5993 src_level
->wined3d_surface
, &src_rect
, 0, NULL
, WINED3DTEXF_POINT
)))
5994 ERR("Blit failed, hr %#x.\n", hr
);
5996 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
5997 ddsd
.ddsCaps
.dwCaps2
= DDSCAPS2_MIPMAPSUBLEVEL
;
5998 IDirectDrawSurface7_GetAttachedSurface(&dest_level
->IDirectDrawSurface7_iface
, &ddsd
.ddsCaps
, &temp
);
6000 if (dest_level
!= dest
) IDirectDrawSurface7_Release(&dest_level
->IDirectDrawSurface7_iface
);
6002 dest_level
= unsafe_impl_from_IDirectDrawSurface7(temp
);
6005 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
6006 ddsd
.ddsCaps
.dwCaps2
= DDSCAPS2_MIPMAPSUBLEVEL
;
6007 IDirectDrawSurface7_GetAttachedSurface(&src_level
->IDirectDrawSurface7_iface
, &ddsd
.ddsCaps
, &temp
);
6009 if (src_level
!= src
) IDirectDrawSurface7_Release(&src_level
->IDirectDrawSurface7_iface
);
6011 src_level
= unsafe_impl_from_IDirectDrawSurface7(temp
);
6018 src_rect
.right
= (src_rect
.right
+ 1) / 2;
6019 src_rect
.bottom
= (src_rect
.bottom
+ 1) / 2;
6022 if (src_level
&& src_level
!= src
) IDirectDrawSurface7_Release(&src_level
->IDirectDrawSurface7_iface
);
6023 if (dest_level
&& dest_level
!= dest
) IDirectDrawSurface7_Release(&dest_level
->IDirectDrawSurface7_iface
);
6026 /*****************************************************************************
6027 * IDirect3DDevice7::Load
6029 * Loads a rectangular area from the source into the destination texture.
6030 * It can also copy the source to the faces of a cubic environment map
6035 * DestTex: Destination texture
6036 * DestPoint: Point in the destination where the source image should be
6038 * SrcTex: Source texture
6039 * SrcRect: Source rectangle
6040 * Flags: Cubemap faces to load (DDSCAPS2_CUBEMAP_ALLFACES, DDSCAPS2_CUBEMAP_POSITIVEX,
6041 * DDSCAPS2_CUBEMAP_NEGATIVEX, DDSCAPS2_CUBEMAP_POSITIVEY, DDSCAPS2_CUBEMAP_NEGATIVEY,
6042 * DDSCAPS2_CUBEMAP_POSITIVEZ, DDSCAPS2_CUBEMAP_NEGATIVEZ)
6046 * DDERR_INVALIDPARAMS if DestTex or SrcTex are NULL, broken coordinates or anything unexpected.
6049 *****************************************************************************/
6052 IDirect3DDeviceImpl_7_Load(IDirect3DDevice7
*iface
,
6053 IDirectDrawSurface7
*DestTex
,
6055 IDirectDrawSurface7
*SrcTex
,
6059 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
6060 IDirectDrawSurfaceImpl
*dest
= unsafe_impl_from_IDirectDrawSurface7(DestTex
);
6061 IDirectDrawSurfaceImpl
*src
= unsafe_impl_from_IDirectDrawSurface7(SrcTex
);
6065 TRACE("iface %p, dst_texture %p, dst_pos %s, src_texture %p, src_rect %s, flags %#x.\n",
6066 iface
, DestTex
, wine_dbgstr_point(DestPoint
), SrcTex
, wine_dbgstr_rect(SrcRect
), Flags
);
6068 if( (!src
) || (!dest
) )
6069 return DDERR_INVALIDPARAMS
;
6071 EnterCriticalSection(&ddraw_cs
);
6073 if (SrcRect
) srcrect
= *SrcRect
;
6076 srcrect
.left
= srcrect
.top
= 0;
6077 srcrect
.right
= src
->surface_desc
.dwWidth
;
6078 srcrect
.bottom
= src
->surface_desc
.dwHeight
;
6081 if (DestPoint
) destpoint
= *DestPoint
;
6084 destpoint
.x
= destpoint
.y
= 0;
6086 /* Check bad dimensions. DestPoint is validated against src, not dest, because
6087 * destination can be a subset of mip levels, in which case actual coordinates used
6088 * for it may be divided. If any dimension of dest is larger than source, it can't be
6089 * mip level subset, so an error can be returned early.
6091 if (srcrect
.left
>= srcrect
.right
|| srcrect
.top
>= srcrect
.bottom
||
6092 srcrect
.right
> src
->surface_desc
.dwWidth
||
6093 srcrect
.bottom
> src
->surface_desc
.dwHeight
||
6094 destpoint
.x
+ srcrect
.right
- srcrect
.left
> src
->surface_desc
.dwWidth
||
6095 destpoint
.y
+ srcrect
.bottom
- srcrect
.top
> src
->surface_desc
.dwHeight
||
6096 dest
->surface_desc
.dwWidth
> src
->surface_desc
.dwWidth
||
6097 dest
->surface_desc
.dwHeight
> src
->surface_desc
.dwHeight
)
6099 LeaveCriticalSection(&ddraw_cs
);
6100 return DDERR_INVALIDPARAMS
;
6103 /* Must be top level surfaces. */
6104 if (src
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_MIPMAPSUBLEVEL
||
6105 dest
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_MIPMAPSUBLEVEL
)
6107 LeaveCriticalSection(&ddraw_cs
);
6108 return DDERR_INVALIDPARAMS
;
6111 if (src
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_CUBEMAP
)
6113 DWORD src_face_flag
, dest_face_flag
;
6114 IDirectDrawSurfaceImpl
*src_face
, *dest_face
;
6115 IDirectDrawSurface7
*temp
;
6116 DDSURFACEDESC2 ddsd
;
6119 if (!(dest
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_CUBEMAP
))
6121 LeaveCriticalSection(&ddraw_cs
);
6122 return DDERR_INVALIDPARAMS
;
6125 /* Iterate through cube faces 2 times. First time is just to check INVALIDPARAMS conditions, second
6126 * time it's actual surface loading. */
6127 for (i
= 0; i
< 2; i
++)
6132 for (;dest_face
&& src_face
;)
6134 src_face_flag
= src_face
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_CUBEMAP_ALLFACES
;
6135 dest_face_flag
= dest_face
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_CUBEMAP_ALLFACES
;
6137 if (src_face_flag
== dest_face_flag
)
6141 /* Destination mip levels must be subset of source mip levels. */
6142 if (!is_mip_level_subset(dest_face
, src_face
))
6144 LeaveCriticalSection(&ddraw_cs
);
6145 return DDERR_INVALIDPARAMS
;
6148 else if (Flags
& dest_face_flag
)
6150 copy_mipmap_chain(This
, dest_face
, src_face
, &destpoint
, &srcrect
);
6153 if (src_face_flag
< DDSCAPS2_CUBEMAP_NEGATIVEZ
)
6155 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
6156 ddsd
.ddsCaps
.dwCaps2
= DDSCAPS2_CUBEMAP
| (src_face_flag
<< 1);
6157 IDirectDrawSurface7_GetAttachedSurface(&src
->IDirectDrawSurface7_iface
, &ddsd
.ddsCaps
, &temp
);
6159 if (src_face
!= src
) IDirectDrawSurface7_Release(&src_face
->IDirectDrawSurface7_iface
);
6161 src_face
= unsafe_impl_from_IDirectDrawSurface7(temp
);
6165 if (src_face
!= src
) IDirectDrawSurface7_Release(&src_face
->IDirectDrawSurface7_iface
);
6171 if (dest_face_flag
< DDSCAPS2_CUBEMAP_NEGATIVEZ
)
6173 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
6174 ddsd
.ddsCaps
.dwCaps2
= DDSCAPS2_CUBEMAP
| (dest_face_flag
<< 1);
6175 IDirectDrawSurface7_GetAttachedSurface(&dest
->IDirectDrawSurface7_iface
, &ddsd
.ddsCaps
, &temp
);
6177 if (dest_face
!= dest
) IDirectDrawSurface7_Release(&dest_face
->IDirectDrawSurface7_iface
);
6179 dest_face
= unsafe_impl_from_IDirectDrawSurface7(temp
);
6183 if (dest_face
!= dest
) IDirectDrawSurface7_Release(&dest_face
->IDirectDrawSurface7_iface
);
6191 /* Native returns error if src faces are not subset of dest faces. */
6194 LeaveCriticalSection(&ddraw_cs
);
6195 return DDERR_INVALIDPARAMS
;
6200 LeaveCriticalSection(&ddraw_cs
);
6203 else if (dest
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_CUBEMAP
)
6205 LeaveCriticalSection(&ddraw_cs
);
6206 return DDERR_INVALIDPARAMS
;
6209 /* Handle non cube map textures. */
6211 /* Destination mip levels must be subset of source mip levels. */
6212 if (!is_mip_level_subset(dest
, src
))
6214 LeaveCriticalSection(&ddraw_cs
);
6215 return DDERR_INVALIDPARAMS
;
6218 copy_mipmap_chain(This
, dest
, src
, &destpoint
, &srcrect
);
6220 LeaveCriticalSection(&ddraw_cs
);
6224 static HRESULT WINAPI
6225 IDirect3DDeviceImpl_7_Load_FPUSetup(IDirect3DDevice7
*iface
,
6226 IDirectDrawSurface7
*DestTex
,
6228 IDirectDrawSurface7
*SrcTex
,
6232 return IDirect3DDeviceImpl_7_Load(iface
, DestTex
, DestPoint
, SrcTex
, SrcRect
, Flags
);
6235 static HRESULT WINAPI
6236 IDirect3DDeviceImpl_7_Load_FPUPreserve(IDirect3DDevice7
*iface
,
6237 IDirectDrawSurface7
*DestTex
,
6239 IDirectDrawSurface7
*SrcTex
,
6246 old_fpucw
= d3d_fpu_setup();
6247 hr
= IDirect3DDeviceImpl_7_Load(iface
, DestTex
, DestPoint
, SrcTex
, SrcRect
, Flags
);
6248 set_fpu_control_word(old_fpucw
);
6253 /*****************************************************************************
6254 * IDirect3DDevice7::LightEnable
6256 * Enables or disables a light
6258 * Version 7, IDirect3DLight uses this method too.
6261 * LightIndex: The index of the light to enable / disable
6262 * Enable: Enable or disable the light
6266 * For more details, see IWineD3DDevice::SetLightEnable
6268 *****************************************************************************/
6270 IDirect3DDeviceImpl_7_LightEnable(IDirect3DDevice7
*iface
,
6274 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
6277 TRACE("iface %p, light_idx %u, enabled %#x.\n", iface
, LightIndex
, Enable
);
6279 EnterCriticalSection(&ddraw_cs
);
6280 hr
= wined3d_device_set_light_enable(This
->wined3d_device
, LightIndex
, Enable
);
6281 LeaveCriticalSection(&ddraw_cs
);
6282 return hr_ddraw_from_wined3d(hr
);
6285 static HRESULT WINAPI
6286 IDirect3DDeviceImpl_7_LightEnable_FPUSetup(IDirect3DDevice7
*iface
,
6290 return IDirect3DDeviceImpl_7_LightEnable(iface
, LightIndex
, Enable
);
6293 static HRESULT WINAPI
6294 IDirect3DDeviceImpl_7_LightEnable_FPUPreserve(IDirect3DDevice7
*iface
,
6301 old_fpucw
= d3d_fpu_setup();
6302 hr
= IDirect3DDeviceImpl_7_LightEnable(iface
, LightIndex
, Enable
);
6303 set_fpu_control_word(old_fpucw
);
6308 /*****************************************************************************
6309 * IDirect3DDevice7::GetLightEnable
6311 * Retrieves if the light with the given index is enabled or not
6316 * LightIndex: Index of desired light
6317 * Enable: Pointer to a BOOL which contains the result
6321 * DDERR_INVALIDPARAMS if Enable is NULL
6322 * See IWineD3DDevice::GetLightEnable for more details
6324 *****************************************************************************/
6326 IDirect3DDeviceImpl_7_GetLightEnable(IDirect3DDevice7
*iface
,
6330 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
6333 TRACE("iface %p, light_idx %u, enabled %p.\n", iface
, LightIndex
, Enable
);
6336 return DDERR_INVALIDPARAMS
;
6338 EnterCriticalSection(&ddraw_cs
);
6339 hr
= wined3d_device_get_light_enable(This
->wined3d_device
, LightIndex
, Enable
);
6340 LeaveCriticalSection(&ddraw_cs
);
6341 return hr_ddraw_from_wined3d(hr
);
6344 static HRESULT WINAPI
6345 IDirect3DDeviceImpl_7_GetLightEnable_FPUSetup(IDirect3DDevice7
*iface
,
6349 return IDirect3DDeviceImpl_7_GetLightEnable(iface
, LightIndex
, Enable
);
6352 static HRESULT WINAPI
6353 IDirect3DDeviceImpl_7_GetLightEnable_FPUPreserve(IDirect3DDevice7
*iface
,
6360 old_fpucw
= d3d_fpu_setup();
6361 hr
= IDirect3DDeviceImpl_7_GetLightEnable(iface
, LightIndex
, Enable
);
6362 set_fpu_control_word(old_fpucw
);
6367 /*****************************************************************************
6368 * IDirect3DDevice7::SetClipPlane
6370 * Sets custom clipping plane
6375 * Index: The index of the clipping plane
6376 * PlaneEquation: An equation defining the clipping plane
6380 * DDERR_INVALIDPARAMS if PlaneEquation is NULL
6381 * See IWineD3DDevice::SetClipPlane for more details
6383 *****************************************************************************/
6385 IDirect3DDeviceImpl_7_SetClipPlane(IDirect3DDevice7
*iface
,
6387 D3DVALUE
* PlaneEquation
)
6389 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
6392 TRACE("iface %p, idx %u, plane %p.\n", iface
, Index
, PlaneEquation
);
6395 return DDERR_INVALIDPARAMS
;
6397 EnterCriticalSection(&ddraw_cs
);
6398 hr
= wined3d_device_set_clip_plane(This
->wined3d_device
, Index
, PlaneEquation
);
6399 LeaveCriticalSection(&ddraw_cs
);
6403 static HRESULT WINAPI
6404 IDirect3DDeviceImpl_7_SetClipPlane_FPUSetup(IDirect3DDevice7
*iface
,
6406 D3DVALUE
* PlaneEquation
)
6408 return IDirect3DDeviceImpl_7_SetClipPlane(iface
, Index
, PlaneEquation
);
6411 static HRESULT WINAPI
6412 IDirect3DDeviceImpl_7_SetClipPlane_FPUPreserve(IDirect3DDevice7
*iface
,
6414 D3DVALUE
* PlaneEquation
)
6419 old_fpucw
= d3d_fpu_setup();
6420 hr
= IDirect3DDeviceImpl_7_SetClipPlane(iface
, Index
, PlaneEquation
);
6421 set_fpu_control_word(old_fpucw
);
6426 /*****************************************************************************
6427 * IDirect3DDevice7::GetClipPlane
6429 * Returns the clipping plane with a specific index
6432 * Index: The index of the desired plane
6433 * PlaneEquation: Address to store the plane equation to
6437 * DDERR_INVALIDPARAMS if PlaneEquation is NULL
6438 * See IWineD3DDevice::GetClipPlane for more details
6440 *****************************************************************************/
6442 IDirect3DDeviceImpl_7_GetClipPlane(IDirect3DDevice7
*iface
,
6444 D3DVALUE
* PlaneEquation
)
6446 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
6449 TRACE("iface %p, idx %u, plane %p.\n", iface
, Index
, PlaneEquation
);
6452 return DDERR_INVALIDPARAMS
;
6454 EnterCriticalSection(&ddraw_cs
);
6455 hr
= wined3d_device_get_clip_plane(This
->wined3d_device
, Index
, PlaneEquation
);
6456 LeaveCriticalSection(&ddraw_cs
);
6460 static HRESULT WINAPI
6461 IDirect3DDeviceImpl_7_GetClipPlane_FPUSetup(IDirect3DDevice7
*iface
,
6463 D3DVALUE
* PlaneEquation
)
6465 return IDirect3DDeviceImpl_7_GetClipPlane(iface
, Index
, PlaneEquation
);
6468 static HRESULT WINAPI
6469 IDirect3DDeviceImpl_7_GetClipPlane_FPUPreserve(IDirect3DDevice7
*iface
,
6471 D3DVALUE
* PlaneEquation
)
6476 old_fpucw
= d3d_fpu_setup();
6477 hr
= IDirect3DDeviceImpl_7_GetClipPlane(iface
, Index
, PlaneEquation
);
6478 set_fpu_control_word(old_fpucw
);
6483 /*****************************************************************************
6484 * IDirect3DDevice7::GetInfo
6486 * Retrieves some information about the device. The DirectX sdk says that
6487 * this version returns S_FALSE for all retail builds of DirectX, that's what
6488 * this implementation does.
6491 * DevInfoID: Information type requested
6492 * DevInfoStruct: Pointer to a structure to store the info to
6493 * Size: Size of the structure
6496 * S_FALSE, because it's a non-debug driver
6498 *****************************************************************************/
6499 static HRESULT WINAPI
6500 IDirect3DDeviceImpl_7_GetInfo(IDirect3DDevice7
*iface
,
6502 void *DevInfoStruct
,
6505 TRACE("iface %p, info_id %#x, info %p, info_size %u.\n",
6506 iface
, DevInfoID
, DevInfoStruct
, Size
);
6508 if (TRACE_ON(ddraw
))
6510 TRACE(" info requested : ");
6513 case D3DDEVINFOID_TEXTUREMANAGER
: TRACE("D3DDEVINFOID_TEXTUREMANAGER\n"); break;
6514 case D3DDEVINFOID_D3DTEXTUREMANAGER
: TRACE("D3DDEVINFOID_D3DTEXTUREMANAGER\n"); break;
6515 case D3DDEVINFOID_TEXTURING
: TRACE("D3DDEVINFOID_TEXTURING\n"); break;
6516 default: ERR(" invalid flag !!!\n"); return DDERR_INVALIDPARAMS
;
6520 return S_FALSE
; /* According to MSDN, this is valid for a non-debug driver */
6523 /* For performance optimization, devices created in FPUSETUP and FPUPRESERVE modes
6524 * have separate vtables. Simple functions where this doesn't matter like GetDirect3D
6525 * are not duplicated.
6527 * Device created with DDSCL_FPUSETUP (d3d7 default) - device methods assume that FPU
6528 * has already been setup for optimal d3d operation.
6530 * Device created with DDSCL_FPUPRESERVE - resets and restores FPU mode when necessary in
6531 * d3d calls (FPU may be in a mode non-suitable for d3d when the app calls d3d). Required
6532 * by Sacrifice (game). */
6533 static const struct IDirect3DDevice7Vtbl d3d_device7_fpu_setup_vtbl
=
6535 /*** IUnknown Methods ***/
6536 IDirect3DDeviceImpl_7_QueryInterface
,
6537 IDirect3DDeviceImpl_7_AddRef
,
6538 IDirect3DDeviceImpl_7_Release
,
6539 /*** IDirect3DDevice7 ***/
6540 IDirect3DDeviceImpl_7_GetCaps_FPUSetup
,
6541 IDirect3DDeviceImpl_7_EnumTextureFormats_FPUSetup
,
6542 IDirect3DDeviceImpl_7_BeginScene_FPUSetup
,
6543 IDirect3DDeviceImpl_7_EndScene_FPUSetup
,
6544 IDirect3DDeviceImpl_7_GetDirect3D
,
6545 IDirect3DDeviceImpl_7_SetRenderTarget_FPUSetup
,
6546 IDirect3DDeviceImpl_7_GetRenderTarget
,
6547 IDirect3DDeviceImpl_7_Clear_FPUSetup
,
6548 IDirect3DDeviceImpl_7_SetTransform_FPUSetup
,
6549 IDirect3DDeviceImpl_7_GetTransform_FPUSetup
,
6550 IDirect3DDeviceImpl_7_SetViewport_FPUSetup
,
6551 IDirect3DDeviceImpl_7_MultiplyTransform_FPUSetup
,
6552 IDirect3DDeviceImpl_7_GetViewport_FPUSetup
,
6553 IDirect3DDeviceImpl_7_SetMaterial_FPUSetup
,
6554 IDirect3DDeviceImpl_7_GetMaterial_FPUSetup
,
6555 IDirect3DDeviceImpl_7_SetLight_FPUSetup
,
6556 IDirect3DDeviceImpl_7_GetLight_FPUSetup
,
6557 IDirect3DDeviceImpl_7_SetRenderState_FPUSetup
,
6558 IDirect3DDeviceImpl_7_GetRenderState_FPUSetup
,
6559 IDirect3DDeviceImpl_7_BeginStateBlock_FPUSetup
,
6560 IDirect3DDeviceImpl_7_EndStateBlock_FPUSetup
,
6561 IDirect3DDeviceImpl_7_PreLoad_FPUSetup
,
6562 IDirect3DDeviceImpl_7_DrawPrimitive_FPUSetup
,
6563 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUSetup
,
6564 IDirect3DDeviceImpl_7_SetClipStatus
,
6565 IDirect3DDeviceImpl_7_GetClipStatus
,
6566 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUSetup
,
6567 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUSetup
,
6568 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUSetup
,
6569 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUSetup
,
6570 IDirect3DDeviceImpl_7_ComputeSphereVisibility
,
6571 IDirect3DDeviceImpl_7_GetTexture_FPUSetup
,
6572 IDirect3DDeviceImpl_7_SetTexture_FPUSetup
,
6573 IDirect3DDeviceImpl_7_GetTextureStageState_FPUSetup
,
6574 IDirect3DDeviceImpl_7_SetTextureStageState_FPUSetup
,
6575 IDirect3DDeviceImpl_7_ValidateDevice_FPUSetup
,
6576 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUSetup
,
6577 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUSetup
,
6578 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUSetup
,
6579 IDirect3DDeviceImpl_7_CreateStateBlock_FPUSetup
,
6580 IDirect3DDeviceImpl_7_Load_FPUSetup
,
6581 IDirect3DDeviceImpl_7_LightEnable_FPUSetup
,
6582 IDirect3DDeviceImpl_7_GetLightEnable_FPUSetup
,
6583 IDirect3DDeviceImpl_7_SetClipPlane_FPUSetup
,
6584 IDirect3DDeviceImpl_7_GetClipPlane_FPUSetup
,
6585 IDirect3DDeviceImpl_7_GetInfo
6588 static const struct IDirect3DDevice7Vtbl d3d_device7_fpu_preserve_vtbl
=
6590 /*** IUnknown Methods ***/
6591 IDirect3DDeviceImpl_7_QueryInterface
,
6592 IDirect3DDeviceImpl_7_AddRef
,
6593 IDirect3DDeviceImpl_7_Release
,
6594 /*** IDirect3DDevice7 ***/
6595 IDirect3DDeviceImpl_7_GetCaps_FPUPreserve
,
6596 IDirect3DDeviceImpl_7_EnumTextureFormats_FPUPreserve
,
6597 IDirect3DDeviceImpl_7_BeginScene_FPUPreserve
,
6598 IDirect3DDeviceImpl_7_EndScene_FPUPreserve
,
6599 IDirect3DDeviceImpl_7_GetDirect3D
,
6600 IDirect3DDeviceImpl_7_SetRenderTarget_FPUPreserve
,
6601 IDirect3DDeviceImpl_7_GetRenderTarget
,
6602 IDirect3DDeviceImpl_7_Clear_FPUPreserve
,
6603 IDirect3DDeviceImpl_7_SetTransform_FPUPreserve
,
6604 IDirect3DDeviceImpl_7_GetTransform_FPUPreserve
,
6605 IDirect3DDeviceImpl_7_SetViewport_FPUPreserve
,
6606 IDirect3DDeviceImpl_7_MultiplyTransform_FPUPreserve
,
6607 IDirect3DDeviceImpl_7_GetViewport_FPUPreserve
,
6608 IDirect3DDeviceImpl_7_SetMaterial_FPUPreserve
,
6609 IDirect3DDeviceImpl_7_GetMaterial_FPUPreserve
,
6610 IDirect3DDeviceImpl_7_SetLight_FPUPreserve
,
6611 IDirect3DDeviceImpl_7_GetLight_FPUPreserve
,
6612 IDirect3DDeviceImpl_7_SetRenderState_FPUPreserve
,
6613 IDirect3DDeviceImpl_7_GetRenderState_FPUPreserve
,
6614 IDirect3DDeviceImpl_7_BeginStateBlock_FPUPreserve
,
6615 IDirect3DDeviceImpl_7_EndStateBlock_FPUPreserve
,
6616 IDirect3DDeviceImpl_7_PreLoad_FPUPreserve
,
6617 IDirect3DDeviceImpl_7_DrawPrimitive_FPUPreserve
,
6618 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUPreserve
,
6619 IDirect3DDeviceImpl_7_SetClipStatus
,
6620 IDirect3DDeviceImpl_7_GetClipStatus
,
6621 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUPreserve
,
6622 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUPreserve
,
6623 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUPreserve
,
6624 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUPreserve
,
6625 IDirect3DDeviceImpl_7_ComputeSphereVisibility
,
6626 IDirect3DDeviceImpl_7_GetTexture_FPUPreserve
,
6627 IDirect3DDeviceImpl_7_SetTexture_FPUPreserve
,
6628 IDirect3DDeviceImpl_7_GetTextureStageState_FPUPreserve
,
6629 IDirect3DDeviceImpl_7_SetTextureStageState_FPUPreserve
,
6630 IDirect3DDeviceImpl_7_ValidateDevice_FPUPreserve
,
6631 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUPreserve
,
6632 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUPreserve
,
6633 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUPreserve
,
6634 IDirect3DDeviceImpl_7_CreateStateBlock_FPUPreserve
,
6635 IDirect3DDeviceImpl_7_Load_FPUPreserve
,
6636 IDirect3DDeviceImpl_7_LightEnable_FPUPreserve
,
6637 IDirect3DDeviceImpl_7_GetLightEnable_FPUPreserve
,
6638 IDirect3DDeviceImpl_7_SetClipPlane_FPUPreserve
,
6639 IDirect3DDeviceImpl_7_GetClipPlane_FPUPreserve
,
6640 IDirect3DDeviceImpl_7_GetInfo
6643 static const struct IDirect3DDevice3Vtbl d3d_device3_vtbl
=
6645 /*** IUnknown Methods ***/
6646 IDirect3DDeviceImpl_3_QueryInterface
,
6647 IDirect3DDeviceImpl_3_AddRef
,
6648 IDirect3DDeviceImpl_3_Release
,
6649 /*** IDirect3DDevice3 ***/
6650 IDirect3DDeviceImpl_3_GetCaps
,
6651 IDirect3DDeviceImpl_3_GetStats
,
6652 IDirect3DDeviceImpl_3_AddViewport
,
6653 IDirect3DDeviceImpl_3_DeleteViewport
,
6654 IDirect3DDeviceImpl_3_NextViewport
,
6655 IDirect3DDeviceImpl_3_EnumTextureFormats
,
6656 IDirect3DDeviceImpl_3_BeginScene
,
6657 IDirect3DDeviceImpl_3_EndScene
,
6658 IDirect3DDeviceImpl_3_GetDirect3D
,
6659 IDirect3DDeviceImpl_3_SetCurrentViewport
,
6660 IDirect3DDeviceImpl_3_GetCurrentViewport
,
6661 IDirect3DDeviceImpl_3_SetRenderTarget
,
6662 IDirect3DDeviceImpl_3_GetRenderTarget
,
6663 IDirect3DDeviceImpl_3_Begin
,
6664 IDirect3DDeviceImpl_3_BeginIndexed
,
6665 IDirect3DDeviceImpl_3_Vertex
,
6666 IDirect3DDeviceImpl_3_Index
,
6667 IDirect3DDeviceImpl_3_End
,
6668 IDirect3DDeviceImpl_3_GetRenderState
,
6669 IDirect3DDeviceImpl_3_SetRenderState
,
6670 IDirect3DDeviceImpl_3_GetLightState
,
6671 IDirect3DDeviceImpl_3_SetLightState
,
6672 IDirect3DDeviceImpl_3_SetTransform
,
6673 IDirect3DDeviceImpl_3_GetTransform
,
6674 IDirect3DDeviceImpl_3_MultiplyTransform
,
6675 IDirect3DDeviceImpl_3_DrawPrimitive
,
6676 IDirect3DDeviceImpl_3_DrawIndexedPrimitive
,
6677 IDirect3DDeviceImpl_3_SetClipStatus
,
6678 IDirect3DDeviceImpl_3_GetClipStatus
,
6679 IDirect3DDeviceImpl_3_DrawPrimitiveStrided
,
6680 IDirect3DDeviceImpl_3_DrawIndexedPrimitiveStrided
,
6681 IDirect3DDeviceImpl_3_DrawPrimitiveVB
,
6682 IDirect3DDeviceImpl_3_DrawIndexedPrimitiveVB
,
6683 IDirect3DDeviceImpl_3_ComputeSphereVisibility
,
6684 IDirect3DDeviceImpl_3_GetTexture
,
6685 IDirect3DDeviceImpl_3_SetTexture
,
6686 IDirect3DDeviceImpl_3_GetTextureStageState
,
6687 IDirect3DDeviceImpl_3_SetTextureStageState
,
6688 IDirect3DDeviceImpl_3_ValidateDevice
6691 static const struct IDirect3DDevice2Vtbl d3d_device2_vtbl
=
6693 /*** IUnknown Methods ***/
6694 IDirect3DDeviceImpl_2_QueryInterface
,
6695 IDirect3DDeviceImpl_2_AddRef
,
6696 IDirect3DDeviceImpl_2_Release
,
6697 /*** IDirect3DDevice2 ***/
6698 IDirect3DDeviceImpl_2_GetCaps
,
6699 IDirect3DDeviceImpl_2_SwapTextureHandles
,
6700 IDirect3DDeviceImpl_2_GetStats
,
6701 IDirect3DDeviceImpl_2_AddViewport
,
6702 IDirect3DDeviceImpl_2_DeleteViewport
,
6703 IDirect3DDeviceImpl_2_NextViewport
,
6704 IDirect3DDeviceImpl_2_EnumTextureFormats
,
6705 IDirect3DDeviceImpl_2_BeginScene
,
6706 IDirect3DDeviceImpl_2_EndScene
,
6707 IDirect3DDeviceImpl_2_GetDirect3D
,
6708 IDirect3DDeviceImpl_2_SetCurrentViewport
,
6709 IDirect3DDeviceImpl_2_GetCurrentViewport
,
6710 IDirect3DDeviceImpl_2_SetRenderTarget
,
6711 IDirect3DDeviceImpl_2_GetRenderTarget
,
6712 IDirect3DDeviceImpl_2_Begin
,
6713 IDirect3DDeviceImpl_2_BeginIndexed
,
6714 IDirect3DDeviceImpl_2_Vertex
,
6715 IDirect3DDeviceImpl_2_Index
,
6716 IDirect3DDeviceImpl_2_End
,
6717 IDirect3DDeviceImpl_2_GetRenderState
,
6718 IDirect3DDeviceImpl_2_SetRenderState
,
6719 IDirect3DDeviceImpl_2_GetLightState
,
6720 IDirect3DDeviceImpl_2_SetLightState
,
6721 IDirect3DDeviceImpl_2_SetTransform
,
6722 IDirect3DDeviceImpl_2_GetTransform
,
6723 IDirect3DDeviceImpl_2_MultiplyTransform
,
6724 IDirect3DDeviceImpl_2_DrawPrimitive
,
6725 IDirect3DDeviceImpl_2_DrawIndexedPrimitive
,
6726 IDirect3DDeviceImpl_2_SetClipStatus
,
6727 IDirect3DDeviceImpl_2_GetClipStatus
6730 static const struct IDirect3DDeviceVtbl d3d_device1_vtbl
=
6732 /*** IUnknown Methods ***/
6733 IDirect3DDeviceImpl_1_QueryInterface
,
6734 IDirect3DDeviceImpl_1_AddRef
,
6735 IDirect3DDeviceImpl_1_Release
,
6736 /*** IDirect3DDevice1 ***/
6737 IDirect3DDeviceImpl_1_Initialize
,
6738 IDirect3DDeviceImpl_1_GetCaps
,
6739 IDirect3DDeviceImpl_1_SwapTextureHandles
,
6740 IDirect3DDeviceImpl_1_CreateExecuteBuffer
,
6741 IDirect3DDeviceImpl_1_GetStats
,
6742 IDirect3DDeviceImpl_1_Execute
,
6743 IDirect3DDeviceImpl_1_AddViewport
,
6744 IDirect3DDeviceImpl_1_DeleteViewport
,
6745 IDirect3DDeviceImpl_1_NextViewport
,
6746 IDirect3DDeviceImpl_1_Pick
,
6747 IDirect3DDeviceImpl_1_GetPickRecords
,
6748 IDirect3DDeviceImpl_1_EnumTextureFormats
,
6749 IDirect3DDeviceImpl_1_CreateMatrix
,
6750 IDirect3DDeviceImpl_1_SetMatrix
,
6751 IDirect3DDeviceImpl_1_GetMatrix
,
6752 IDirect3DDeviceImpl_1_DeleteMatrix
,
6753 IDirect3DDeviceImpl_1_BeginScene
,
6754 IDirect3DDeviceImpl_1_EndScene
,
6755 IDirect3DDeviceImpl_1_GetDirect3D
6758 IDirect3DDeviceImpl
*unsafe_impl_from_IDirect3DDevice7(IDirect3DDevice7
*iface
)
6760 if (!iface
) return NULL
;
6761 assert((iface
->lpVtbl
== &d3d_device7_fpu_preserve_vtbl
) || (iface
->lpVtbl
== &d3d_device7_fpu_setup_vtbl
));
6762 return CONTAINING_RECORD(iface
, IDirect3DDeviceImpl
, IDirect3DDevice7_iface
);
6765 IDirect3DDeviceImpl
*unsafe_impl_from_IDirect3DDevice3(IDirect3DDevice3
*iface
)
6767 if (!iface
) return NULL
;
6768 assert(iface
->lpVtbl
== &d3d_device3_vtbl
);
6769 return CONTAINING_RECORD(iface
, IDirect3DDeviceImpl
, IDirect3DDevice3_iface
);
6772 IDirect3DDeviceImpl
*unsafe_impl_from_IDirect3DDevice2(IDirect3DDevice2
*iface
)
6774 if (!iface
) return NULL
;
6775 assert(iface
->lpVtbl
== &d3d_device2_vtbl
);
6776 return CONTAINING_RECORD(iface
, IDirect3DDeviceImpl
, IDirect3DDevice2_iface
);
6779 IDirect3DDeviceImpl
*unsafe_impl_from_IDirect3DDevice(IDirect3DDevice
*iface
)
6781 if (!iface
) return NULL
;
6782 assert(iface
->lpVtbl
== &d3d_device1_vtbl
);
6783 return CONTAINING_RECORD(iface
, IDirect3DDeviceImpl
, IDirect3DDevice_iface
);
6786 /*****************************************************************************
6787 * IDirect3DDeviceImpl_UpdateDepthStencil
6789 * Checks the current render target for attached depth stencils and sets the
6790 * WineD3D depth stencil accordingly.
6793 * The depth stencil state to set if creating the device
6795 *****************************************************************************/
6797 IDirect3DDeviceImpl_UpdateDepthStencil(IDirect3DDeviceImpl
*This
)
6799 IDirectDrawSurface7
*depthStencil
= NULL
;
6800 IDirectDrawSurfaceImpl
*dsi
;
6801 static DDSCAPS2 depthcaps
= { DDSCAPS_ZBUFFER
, 0, 0, 0 };
6803 IDirectDrawSurface7_GetAttachedSurface(&This
->target
->IDirectDrawSurface7_iface
, &depthcaps
, &depthStencil
);
6806 TRACE("Setting wined3d depth stencil to NULL\n");
6807 wined3d_device_set_depth_stencil(This
->wined3d_device
, NULL
);
6808 return WINED3DZB_FALSE
;
6811 dsi
= impl_from_IDirectDrawSurface7(depthStencil
);
6812 TRACE("Setting wined3d depth stencil to %p (wined3d %p)\n", dsi
, dsi
->wined3d_surface
);
6813 wined3d_device_set_depth_stencil(This
->wined3d_device
, dsi
->wined3d_surface
);
6815 IDirectDrawSurface7_Release(depthStencil
);
6816 return WINED3DZB_TRUE
;
6819 HRESULT
d3d_device_init(IDirect3DDeviceImpl
*device
, IDirectDrawImpl
*ddraw
, IDirectDrawSurfaceImpl
*target
)
6823 if (ddraw
->cooperative_level
& DDSCL_FPUPRESERVE
)
6824 device
->IDirect3DDevice7_iface
.lpVtbl
= &d3d_device7_fpu_preserve_vtbl
;
6826 device
->IDirect3DDevice7_iface
.lpVtbl
= &d3d_device7_fpu_setup_vtbl
;
6828 device
->IDirect3DDevice3_iface
.lpVtbl
= &d3d_device3_vtbl
;
6829 device
->IDirect3DDevice2_iface
.lpVtbl
= &d3d_device2_vtbl
;
6830 device
->IDirect3DDevice_iface
.lpVtbl
= &d3d_device1_vtbl
;
6832 device
->ddraw
= ddraw
;
6833 device
->target
= target
;
6834 list_init(&device
->viewport_list
);
6836 if (!ddraw_handle_table_init(&device
->handle_table
, 64))
6838 ERR("Failed to initialize handle table.\n");
6839 return DDERR_OUTOFMEMORY
;
6842 device
->legacyTextureBlending
= FALSE
;
6844 /* Create an index buffer, it's needed for indexed drawing */
6845 hr
= wined3d_buffer_create_ib(ddraw
->wined3d_device
, 0x40000 /* Length. Don't know how long it should be */,
6846 WINED3DUSAGE_DYNAMIC
/* Usage */, WINED3DPOOL_DEFAULT
, NULL
,
6847 &ddraw_null_wined3d_parent_ops
, &device
->indexbuffer
);
6850 ERR("Failed to create an index buffer, hr %#x.\n", hr
);
6851 ddraw_handle_table_destroy(&device
->handle_table
);
6855 /* This is for convenience. */
6856 device
->wined3d_device
= ddraw
->wined3d_device
;
6857 wined3d_device_incref(ddraw
->wined3d_device
);
6859 /* Render to the back buffer */
6860 hr
= wined3d_device_set_render_target(ddraw
->wined3d_device
, 0, target
->wined3d_surface
, TRUE
);
6863 ERR("Failed to set render target, hr %#x.\n", hr
);
6864 wined3d_buffer_decref(device
->indexbuffer
);
6865 ddraw_handle_table_destroy(&device
->handle_table
);
6869 /* FIXME: This is broken. The target AddRef() makes some sense, because
6870 * we store a pointer during initialization, but then that's also where
6871 * the AddRef() should be. We don't store ddraw->d3d_target anywhere. */
6872 /* AddRef the render target. Also AddRef the render target from ddraw,
6873 * because if it is released before the app releases the D3D device, the
6874 * D3D capabilities of wined3d will be uninitialized, which has bad effects.
6876 * In most cases, those surfaces are the same anyway, but this will simply
6877 * add another ref which is released when the device is destroyed. */
6878 IDirectDrawSurface7_AddRef(&target
->IDirectDrawSurface7_iface
);
6879 IDirectDrawSurface7_AddRef(&ddraw
->d3d_target
->IDirectDrawSurface7_iface
);
6881 ddraw
->d3ddevice
= device
;
6883 wined3d_device_set_render_state(ddraw
->wined3d_device
, WINED3DRS_ZENABLE
,
6884 IDirect3DDeviceImpl_UpdateDepthStencil(device
));