2 * Copyright (c) 1998-2004 Lionel Ulmer
3 * Copyright (c) 2002-2005 Christian Costa
4 * Copyright (c) 2006 Stefan Dösinger
5 * Copyright (c) 2008 Alexander Dorofeyev
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 * IDirect3DDevice implementation, version 1, 2, 3 and 7. Rendering is relayed
22 * to WineD3D, some minimal DirectDraw specific management is handled here.
23 * The Direct3DDevice is NOT the parent of the WineD3DDevice, because d3d
24 * is initialized when DirectDraw creates the primary surface.
25 * Some type management is necessary, because some D3D types changed between
31 #include "wine/port.h"
33 #include "ddraw_private.h"
35 WINE_DEFAULT_DEBUG_CHANNEL(ddraw
);
38 const GUID IID_D3DDEVICE_WineD3D
= {
42 { 0xb7,0x98,0xc6,0x8a,0x77,0x2d,0x72,0x2a }
45 static inline void set_fpu_control_word(WORD fpucw
)
47 #if defined(__i386__) && defined(__GNUC__)
48 __asm__
volatile ("fldcw %0" : : "m" (fpucw
));
49 #elif defined(__i386__) && defined(_MSC_VER)
54 static inline WORD
d3d_fpu_setup(void)
58 #if defined(__i386__) && defined(__GNUC__)
59 __asm__
volatile ("fnstcw %0" : "=m" (oldcw
));
60 #elif defined(__i386__) && defined(_MSC_VER)
63 static BOOL warned
= FALSE
;
66 FIXME("FPUPRESERVE not implemented for this platform / compiler\n");
72 set_fpu_control_word(0x37f);
77 /*****************************************************************************
78 * IUnknown Methods. Common for Version 1, 2, 3 and 7
79 *****************************************************************************/
81 /*****************************************************************************
82 * IDirect3DDevice7::QueryInterface
84 * Used to query other interfaces from a Direct3DDevice interface.
85 * It can return interface pointers to all Direct3DDevice versions as well
86 * as IDirectDraw and IDirect3D. For a link to QueryInterface
87 * rules see ddraw.c, IDirectDraw7::QueryInterface
89 * Exists in Version 1, 2, 3 and 7
92 * refiid: Interface ID queried for
93 * obj: Used to return the interface pointer
96 * D3D_OK or E_NOINTERFACE
98 *****************************************************************************/
100 IDirect3DDeviceImpl_7_QueryInterface(IDirect3DDevice7
*iface
,
104 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
106 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(refiid
), obj
);
108 /* According to COM docs, if the QueryInterface fails, obj should be set to NULL */
112 return DDERR_INVALIDPARAMS
;
114 if ( IsEqualGUID( &IID_IUnknown
, refiid
) )
119 /* Check DirectDraw Interfaces. */
120 else if( IsEqualGUID( &IID_IDirectDraw7
, refiid
) )
122 *obj
= &This
->ddraw
->IDirectDraw7_iface
;
123 TRACE("(%p) Returning IDirectDraw7 interface at %p\n", This
, *obj
);
125 else if ( IsEqualGUID( &IID_IDirectDraw4
, refiid
) )
127 *obj
= &This
->ddraw
->IDirectDraw4_iface
;
128 TRACE("(%p) Returning IDirectDraw4 interface at %p\n", This
, *obj
);
130 else if ( IsEqualGUID( &IID_IDirectDraw2
, refiid
) )
132 *obj
= &This
->ddraw
->IDirectDraw2_iface
;
133 TRACE("(%p) Returning IDirectDraw2 interface at %p\n", This
, *obj
);
135 else if( IsEqualGUID( &IID_IDirectDraw
, refiid
) )
137 *obj
= &This
->ddraw
->IDirectDraw_iface
;
138 TRACE("(%p) Returning IDirectDraw interface at %p\n", This
, *obj
);
142 else if ( IsEqualGUID( &IID_IDirect3D
, refiid
) )
144 *obj
= &This
->ddraw
->IDirect3D_iface
;
145 TRACE("(%p) Returning IDirect3D interface at %p\n", This
, *obj
);
147 else if ( IsEqualGUID( &IID_IDirect3D2
, refiid
) )
149 *obj
= &This
->ddraw
->IDirect3D2_iface
;
150 TRACE("(%p) Returning IDirect3D2 interface at %p\n", This
, *obj
);
152 else if ( IsEqualGUID( &IID_IDirect3D3
, refiid
) )
154 *obj
= &This
->ddraw
->IDirect3D3_iface
;
155 TRACE("(%p) Returning IDirect3D3 interface at %p\n", This
, *obj
);
157 else if ( IsEqualGUID( &IID_IDirect3D7
, refiid
) )
159 *obj
= &This
->ddraw
->IDirect3D7_iface
;
160 TRACE("(%p) Returning IDirect3D7 interface at %p\n", This
, *obj
);
164 else if ( IsEqualGUID( &IID_IDirect3DDevice
, refiid
) )
166 *obj
= &This
->IDirect3DDevice_iface
;
167 TRACE("(%p) Returning IDirect3DDevice interface at %p\n", This
, *obj
);
169 else if ( IsEqualGUID( &IID_IDirect3DDevice2
, refiid
) ) {
170 *obj
= &This
->IDirect3DDevice2_iface
;
171 TRACE("(%p) Returning IDirect3DDevice2 interface at %p\n", This
, *obj
);
173 else if ( IsEqualGUID( &IID_IDirect3DDevice3
, refiid
) ) {
174 *obj
= &This
->IDirect3DDevice3_iface
;
175 TRACE("(%p) Returning IDirect3DDevice3 interface at %p\n", This
, *obj
);
177 else if ( IsEqualGUID( &IID_IDirect3DDevice7
, refiid
) ) {
179 TRACE("(%p) Returning IDirect3DDevice7 interface at %p\n", This
, *obj
);
182 /* Unknown interface */
185 ERR("(%p)->(%s, %p): No interface found\n", This
, debugstr_guid(refiid
), obj
);
186 return E_NOINTERFACE
;
189 /* AddRef the returned interface */
190 IUnknown_AddRef( (IUnknown
*) *obj
);
194 static HRESULT WINAPI
IDirect3DDeviceImpl_3_QueryInterface(IDirect3DDevice3
*iface
, REFIID riid
,
197 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
198 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), obj
);
200 return IDirect3DDevice7_QueryInterface(&This
->IDirect3DDevice7_iface
, riid
, obj
);
203 static HRESULT WINAPI
IDirect3DDeviceImpl_2_QueryInterface(IDirect3DDevice2
*iface
, REFIID riid
,
206 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
207 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), obj
);
209 return IDirect3DDevice7_QueryInterface(&This
->IDirect3DDevice7_iface
, riid
, obj
);
212 static HRESULT WINAPI
IDirect3DDeviceImpl_1_QueryInterface(IDirect3DDevice
*iface
, REFIID riid
,
215 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
216 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), obp
);
218 return IDirect3DDevice7_QueryInterface(&This
->IDirect3DDevice7_iface
, riid
, obp
);
221 /*****************************************************************************
222 * IDirect3DDevice7::AddRef
224 * Increases the refcount....
225 * The most exciting Method, definitely
227 * Exists in Version 1, 2, 3 and 7
232 *****************************************************************************/
234 IDirect3DDeviceImpl_7_AddRef(IDirect3DDevice7
*iface
)
236 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
237 ULONG ref
= InterlockedIncrement(&This
->ref
);
239 TRACE("%p increasing refcount to %u.\n", This
, ref
);
244 static ULONG WINAPI
IDirect3DDeviceImpl_3_AddRef(IDirect3DDevice3
*iface
)
246 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
247 TRACE("iface %p.\n", iface
);
249 return IDirect3DDevice7_AddRef(&This
->IDirect3DDevice7_iface
);
252 static ULONG WINAPI
IDirect3DDeviceImpl_2_AddRef(IDirect3DDevice2
*iface
)
254 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
255 TRACE("iface %p.\n", iface
);
257 return IDirect3DDevice7_AddRef(&This
->IDirect3DDevice7_iface
);
260 static ULONG WINAPI
IDirect3DDeviceImpl_1_AddRef(IDirect3DDevice
*iface
)
262 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
263 TRACE("iface %p.\n", iface
);
265 return IDirect3DDevice7_AddRef(&This
->IDirect3DDevice7_iface
);
268 /*****************************************************************************
269 * IDirect3DDevice7::Release
271 * Decreases the refcount of the interface
272 * When the refcount is reduced to 0, the object is destroyed.
274 * Exists in Version 1, 2, 3 and 7
279 *****************************************************************************/
281 IDirect3DDeviceImpl_7_Release(IDirect3DDevice7
*iface
)
283 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
284 ULONG ref
= InterlockedDecrement(&This
->ref
);
286 TRACE("%p decreasing refcount to %u.\n", This
, ref
);
288 /* This method doesn't destroy the WineD3DDevice, because it's still in use for
289 * 2D rendering. IDirectDrawSurface7::Release will destroy the WineD3DDevice
290 * when the render target is released
296 wined3d_mutex_lock();
298 /* There is no need to unset any resources here, wined3d will take
299 * care of that on Uninit3D(). */
301 /* Free the index buffer. */
302 wined3d_buffer_decref(This
->indexbuffer
);
304 /* Set the device up to render to the front buffer since the back
305 * buffer will vanish soon. */
306 wined3d_device_set_render_target(This
->wined3d_device
, 0,
307 This
->ddraw
->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 wined3d_mutex_unlock();
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 wined3d_mutex_lock();
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 wined3d_mutex_unlock();
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 wined3d_mutex_lock();
734 hr
= d3d_execute_buffer_execute(buffer
, This
, Direct3DViewportImpl
);
735 wined3d_mutex_unlock();
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 wined3d_mutex_lock();
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 wined3d_mutex_unlock();
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 wined3d_mutex_lock();
826 if (vp
->active_device
!= This
)
828 WARN("Viewport %p active device is %p.\n", vp
, vp
->active_device
);
829 wined3d_mutex_unlock();
830 return DDERR_INVALIDPARAMS
;
833 vp
->active_device
= NULL
;
834 list_remove(&vp
->entry
);
836 wined3d_mutex_unlock();
841 static HRESULT WINAPI
IDirect3DDeviceImpl_2_DeleteViewport(IDirect3DDevice2
*iface
,
842 IDirect3DViewport2
*Direct3DViewport2
)
844 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
845 IDirect3DViewportImpl
*vp
= unsafe_impl_from_IDirect3DViewport2(Direct3DViewport2
);
847 TRACE("iface %p, viewport %p.\n", iface
, Direct3DViewport2
);
849 return IDirect3DDevice3_DeleteViewport(&This
->IDirect3DDevice3_iface
, &vp
->IDirect3DViewport3_iface
);
852 static HRESULT WINAPI
IDirect3DDeviceImpl_1_DeleteViewport(IDirect3DDevice
*iface
,
853 IDirect3DViewport
*Direct3DViewport
)
855 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
856 IDirect3DViewportImpl
*vp
= unsafe_impl_from_IDirect3DViewport(Direct3DViewport
);
858 TRACE("iface %p, viewport %p.\n", iface
, Direct3DViewport
);
860 return IDirect3DDevice3_DeleteViewport(&This
->IDirect3DDevice3_iface
, &vp
->IDirect3DViewport3_iface
);
863 /*****************************************************************************
864 * IDirect3DDevice3::NextViewport
866 * Returns a viewport from the viewport list, depending on the
867 * passed viewport and the flags.
869 * Exists in Version 1, 2 and 3. Note that all Viewport interface versions
873 * Viewport: Viewport to use for beginning the search
874 * Flags: D3DNEXT_NEXT, D3DNEXT_HEAD or D3DNEXT_TAIL
878 * DDERR_INVALIDPARAMS if the flags were wrong, or Viewport was NULL
880 *****************************************************************************/
881 static HRESULT WINAPI
882 IDirect3DDeviceImpl_3_NextViewport(IDirect3DDevice3
*iface
,
883 IDirect3DViewport3
*Viewport3
,
884 IDirect3DViewport3
**lplpDirect3DViewport3
,
887 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
888 IDirect3DViewportImpl
*vp
= unsafe_impl_from_IDirect3DViewport3(Viewport3
);
889 IDirect3DViewportImpl
*next
;
892 TRACE("iface %p, viewport %p, next %p, flags %#x.\n",
893 iface
, Viewport3
, lplpDirect3DViewport3
, Flags
);
897 *lplpDirect3DViewport3
= NULL
;
898 return DDERR_INVALIDPARAMS
;
902 wined3d_mutex_lock();
906 entry
= list_next(&This
->viewport_list
, &vp
->entry
);
910 entry
= list_head(&This
->viewport_list
);
914 entry
= list_tail(&This
->viewport_list
);
918 WARN("Invalid flags %#x.\n", Flags
);
919 *lplpDirect3DViewport3
= NULL
;
920 wined3d_mutex_unlock();
921 return DDERR_INVALIDPARAMS
;
926 next
= LIST_ENTRY(entry
, IDirect3DViewportImpl
, entry
);
927 *lplpDirect3DViewport3
= &next
->IDirect3DViewport3_iface
;
930 *lplpDirect3DViewport3
= NULL
;
932 wined3d_mutex_unlock();
937 static HRESULT WINAPI
IDirect3DDeviceImpl_2_NextViewport(IDirect3DDevice2
*iface
,
938 IDirect3DViewport2
*Viewport2
, IDirect3DViewport2
**lplpDirect3DViewport2
, DWORD Flags
)
940 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
941 IDirect3DViewportImpl
*vp
= unsafe_impl_from_IDirect3DViewport2(Viewport2
);
942 IDirect3DViewport3
*res
;
945 TRACE("iface %p, viewport %p, next %p, flags %#x.\n",
946 iface
, Viewport2
, lplpDirect3DViewport2
, Flags
);
948 hr
= IDirect3DDevice3_NextViewport(&This
->IDirect3DDevice3_iface
,
949 &vp
->IDirect3DViewport3_iface
, &res
, Flags
);
950 *lplpDirect3DViewport2
= (IDirect3DViewport2
*)res
;
954 static HRESULT WINAPI
IDirect3DDeviceImpl_1_NextViewport(IDirect3DDevice
*iface
,
955 IDirect3DViewport
*Viewport
, IDirect3DViewport
**lplpDirect3DViewport
, DWORD Flags
)
957 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
958 IDirect3DViewportImpl
*vp
= unsafe_impl_from_IDirect3DViewport(Viewport
);
959 IDirect3DViewport3
*res
;
962 TRACE("iface %p, viewport %p, next %p, flags %#x.\n",
963 iface
, Viewport
, lplpDirect3DViewport
, Flags
);
965 hr
= IDirect3DDevice3_NextViewport(&This
->IDirect3DDevice3_iface
,
966 &vp
->IDirect3DViewport3_iface
, &res
, Flags
);
967 *lplpDirect3DViewport
= (IDirect3DViewport
*)res
;
971 /*****************************************************************************
972 * IDirect3DDevice::Pick
974 * Executes an execute buffer without performing rendering. Instead, a
975 * list of primitives that intersect with (x1,y1) of the passed rectangle
976 * is created. IDirect3DDevice::GetPickRecords can be used to retrieve
982 * ExecuteBuffer: Buffer to execute
983 * Viewport: Viewport to use for execution
984 * Flags: None are defined, according to the SDK
985 * Rect: Specifies the coordinates to be picked. Only x1 and y2 are used,
986 * x2 and y2 are ignored.
989 * D3D_OK because it's a stub
991 *****************************************************************************/
992 static HRESULT WINAPI
993 IDirect3DDeviceImpl_1_Pick(IDirect3DDevice
*iface
,
994 IDirect3DExecuteBuffer
*ExecuteBuffer
,
995 IDirect3DViewport
*Viewport
,
999 FIXME("iface %p, buffer %p, viewport %p, flags %#x, rect %s stub!\n",
1000 iface
, ExecuteBuffer
, Viewport
, Flags
, wine_dbgstr_rect((RECT
*)Rect
));
1005 /*****************************************************************************
1006 * IDirect3DDevice::GetPickRecords
1008 * Retrieves the pick records generated by IDirect3DDevice::GetPickRecords
1013 * Count: Pointer to a DWORD containing the numbers of pick records to
1015 * D3DPickRec: Address to store the resulting D3DPICKRECORD array.
1018 * D3D_OK, because it's a stub
1020 *****************************************************************************/
1021 static HRESULT WINAPI
1022 IDirect3DDeviceImpl_1_GetPickRecords(IDirect3DDevice
*iface
,
1024 D3DPICKRECORD
*D3DPickRec
)
1026 FIXME("iface %p, count %p, records %p stub!\n", iface
, Count
, D3DPickRec
);
1031 /*****************************************************************************
1032 * IDirect3DDevice7::EnumTextureformats
1034 * Enumerates the supported texture formats. It has a list of all possible
1035 * formats and calls IWineD3D::CheckDeviceFormat for each format to see if
1036 * WineD3D supports it. If so, then it is passed to the app.
1038 * This is for Version 7 and 3, older versions have a different
1039 * callback function and their own implementation
1042 * Callback: Callback to call for each enumerated format
1043 * Arg: Argument to pass to the callback
1047 * DDERR_INVALIDPARAMS if Callback == NULL
1049 *****************************************************************************/
1051 IDirect3DDeviceImpl_7_EnumTextureFormats(IDirect3DDevice7
*iface
,
1052 LPD3DENUMPIXELFORMATSCALLBACK Callback
,
1055 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
1057 WINED3DDISPLAYMODE mode
;
1060 static const enum wined3d_format_id FormatList
[] =
1063 WINED3DFMT_B8G8R8A8_UNORM
,
1064 WINED3DFMT_B8G8R8X8_UNORM
,
1066 WINED3DFMT_B8G8R8_UNORM
,
1068 WINED3DFMT_B5G5R5A1_UNORM
,
1069 WINED3DFMT_B4G4R4A4_UNORM
,
1070 WINED3DFMT_B5G6R5_UNORM
,
1071 WINED3DFMT_B5G5R5X1_UNORM
,
1073 WINED3DFMT_B2G3R3_UNORM
,
1081 static const enum wined3d_format_id BumpFormatList
[] =
1083 WINED3DFMT_R8G8_SNORM
,
1084 WINED3DFMT_R5G5_SNORM_L6_UNORM
,
1085 WINED3DFMT_R8G8_SNORM_L8X8_UNORM
,
1086 WINED3DFMT_R16G16_SNORM
,
1087 WINED3DFMT_R10G11B11_SNORM
,
1088 WINED3DFMT_R10G10B10_SNORM_A2_UNORM
1091 TRACE("iface %p, callback %p, context %p.\n", iface
, Callback
, Arg
);
1094 return DDERR_INVALIDPARAMS
;
1096 wined3d_mutex_lock();
1098 memset(&mode
, 0, sizeof(mode
));
1099 hr
= wined3d_device_get_display_mode(This
->ddraw
->wined3d_device
, 0, &mode
);
1102 wined3d_mutex_unlock();
1103 WARN("Cannot get the current adapter format\n");
1107 for (i
= 0; i
< sizeof(FormatList
) / sizeof(*FormatList
); ++i
)
1109 hr
= wined3d_check_device_format(This
->ddraw
->wineD3D
, WINED3DADAPTER_DEFAULT
, WINED3DDEVTYPE_HAL
,
1110 mode
.Format
, 0, WINED3DRTYPE_TEXTURE
, FormatList
[i
], SURFACE_OPENGL
);
1113 DDPIXELFORMAT pformat
;
1115 memset(&pformat
, 0, sizeof(pformat
));
1116 pformat
.dwSize
= sizeof(pformat
);
1117 PixelFormat_WineD3DtoDD(&pformat
, FormatList
[i
]);
1119 TRACE("Enumerating WineD3DFormat %d\n", FormatList
[i
]);
1120 hr
= Callback(&pformat
, Arg
);
1121 if(hr
!= DDENUMRET_OK
)
1123 TRACE("Format enumeration cancelled by application\n");
1124 wined3d_mutex_unlock();
1130 for (i
= 0; i
< sizeof(BumpFormatList
) / sizeof(*BumpFormatList
); ++i
)
1132 hr
= wined3d_check_device_format(This
->ddraw
->wineD3D
, WINED3DADAPTER_DEFAULT
,
1133 WINED3DDEVTYPE_HAL
, mode
.Format
, WINED3DUSAGE_QUERY_LEGACYBUMPMAP
,
1134 WINED3DRTYPE_TEXTURE
, BumpFormatList
[i
], SURFACE_OPENGL
);
1137 DDPIXELFORMAT pformat
;
1139 memset(&pformat
, 0, sizeof(pformat
));
1140 pformat
.dwSize
= sizeof(pformat
);
1141 PixelFormat_WineD3DtoDD(&pformat
, BumpFormatList
[i
]);
1143 TRACE("Enumerating WineD3DFormat %d\n", BumpFormatList
[i
]);
1144 hr
= Callback(&pformat
, Arg
);
1145 if(hr
!= DDENUMRET_OK
)
1147 TRACE("Format enumeration cancelled by application\n");
1148 wined3d_mutex_unlock();
1153 TRACE("End of enumeration\n");
1154 wined3d_mutex_unlock();
1159 static HRESULT WINAPI
1160 IDirect3DDeviceImpl_7_EnumTextureFormats_FPUSetup(IDirect3DDevice7
*iface
,
1161 LPD3DENUMPIXELFORMATSCALLBACK Callback
,
1164 return IDirect3DDeviceImpl_7_EnumTextureFormats(iface
, Callback
, Arg
);
1167 static HRESULT WINAPI
1168 IDirect3DDeviceImpl_7_EnumTextureFormats_FPUPreserve(IDirect3DDevice7
*iface
,
1169 LPD3DENUMPIXELFORMATSCALLBACK Callback
,
1175 old_fpucw
= d3d_fpu_setup();
1176 hr
= IDirect3DDeviceImpl_7_EnumTextureFormats(iface
, Callback
, Arg
);
1177 set_fpu_control_word(old_fpucw
);
1182 static HRESULT WINAPI
IDirect3DDeviceImpl_3_EnumTextureFormats(IDirect3DDevice3
*iface
,
1183 LPD3DENUMPIXELFORMATSCALLBACK Callback
, void *Arg
)
1185 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
1187 TRACE("iface %p, callback %p, context %p.\n", iface
, Callback
, Arg
);
1189 return IDirect3DDevice7_EnumTextureFormats(&This
->IDirect3DDevice7_iface
, Callback
, Arg
);
1192 /*****************************************************************************
1193 * IDirect3DDevice2::EnumTextureformats
1195 * EnumTextureFormats for Version 1 and 2, see
1196 * IDirect3DDevice7::EnumTexureFormats for a more detailed description.
1198 * This version has a different callback and does not enumerate FourCC
1201 *****************************************************************************/
1202 static HRESULT WINAPI
1203 IDirect3DDeviceImpl_2_EnumTextureFormats(IDirect3DDevice2
*iface
,
1204 LPD3DENUMTEXTUREFORMATSCALLBACK Callback
,
1207 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
1210 WINED3DDISPLAYMODE mode
;
1212 static const enum wined3d_format_id FormatList
[] =
1215 WINED3DFMT_B8G8R8A8_UNORM
,
1216 WINED3DFMT_B8G8R8X8_UNORM
,
1218 WINED3DFMT_B8G8R8_UNORM
,
1220 WINED3DFMT_B5G5R5A1_UNORM
,
1221 WINED3DFMT_B4G4R4A4_UNORM
,
1222 WINED3DFMT_B5G6R5_UNORM
,
1223 WINED3DFMT_B5G5R5X1_UNORM
,
1225 WINED3DFMT_B2G3R3_UNORM
,
1227 /* FOURCC codes - Not in this version*/
1230 TRACE("iface %p, callback %p, context %p.\n", iface
, Callback
, Arg
);
1233 return DDERR_INVALIDPARAMS
;
1235 wined3d_mutex_lock();
1237 memset(&mode
, 0, sizeof(mode
));
1238 hr
= wined3d_device_get_display_mode(This
->ddraw
->wined3d_device
, 0, &mode
);
1241 wined3d_mutex_unlock();
1242 WARN("Cannot get the current adapter format\n");
1246 for (i
= 0; i
< sizeof(FormatList
) / sizeof(*FormatList
); ++i
)
1248 hr
= wined3d_check_device_format(This
->ddraw
->wineD3D
, 0, WINED3DDEVTYPE_HAL
,
1249 mode
.Format
, 0, WINED3DRTYPE_TEXTURE
, FormatList
[i
], SURFACE_OPENGL
);
1252 DDSURFACEDESC sdesc
;
1254 memset(&sdesc
, 0, sizeof(sdesc
));
1255 sdesc
.dwSize
= sizeof(sdesc
);
1256 sdesc
.dwFlags
= DDSD_PIXELFORMAT
| DDSD_CAPS
;
1257 sdesc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
1258 sdesc
.ddpfPixelFormat
.dwSize
= sizeof(sdesc
.ddpfPixelFormat
);
1259 PixelFormat_WineD3DtoDD(&sdesc
.ddpfPixelFormat
, FormatList
[i
]);
1261 TRACE("Enumerating WineD3DFormat %d\n", FormatList
[i
]);
1262 hr
= Callback(&sdesc
, Arg
);
1263 if(hr
!= DDENUMRET_OK
)
1265 TRACE("Format enumeration cancelled by application\n");
1266 wined3d_mutex_unlock();
1271 TRACE("End of enumeration\n");
1272 wined3d_mutex_unlock();
1277 static HRESULT WINAPI
IDirect3DDeviceImpl_1_EnumTextureFormats(IDirect3DDevice
*iface
,
1278 LPD3DENUMTEXTUREFORMATSCALLBACK Callback
, void *Arg
)
1280 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
1282 TRACE("iface %p, callback %p, context %p.\n", iface
, Callback
, Arg
);
1284 return IDirect3DDevice2_EnumTextureFormats(&This
->IDirect3DDevice2_iface
, Callback
, Arg
);
1287 /*****************************************************************************
1288 * IDirect3DDevice::CreateMatrix
1290 * Creates a matrix handle. A handle is created and memory for a D3DMATRIX is
1291 * allocated for the handle.
1296 * D3DMatHandle: Address to return the handle at
1300 * DDERR_INVALIDPARAMS if D3DMatHandle = NULL
1302 *****************************************************************************/
1303 static HRESULT WINAPI
1304 IDirect3DDeviceImpl_1_CreateMatrix(IDirect3DDevice
*iface
, D3DMATRIXHANDLE
*D3DMatHandle
)
1306 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
1310 TRACE("iface %p, matrix_handle %p.\n", iface
, D3DMatHandle
);
1313 return DDERR_INVALIDPARAMS
;
1315 Matrix
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(D3DMATRIX
));
1318 ERR("Out of memory when allocating a D3DMATRIX\n");
1319 return DDERR_OUTOFMEMORY
;
1322 wined3d_mutex_lock();
1324 h
= ddraw_allocate_handle(&This
->handle_table
, Matrix
, DDRAW_HANDLE_MATRIX
);
1325 if (h
== DDRAW_INVALID_HANDLE
)
1327 ERR("Failed to allocate a matrix handle.\n");
1328 HeapFree(GetProcessHeap(), 0, Matrix
);
1329 wined3d_mutex_unlock();
1330 return DDERR_OUTOFMEMORY
;
1333 *D3DMatHandle
= h
+ 1;
1335 TRACE(" returning matrix handle %d\n", *D3DMatHandle
);
1337 wined3d_mutex_unlock();
1342 /*****************************************************************************
1343 * IDirect3DDevice::SetMatrix
1345 * Sets a matrix for a matrix handle. The matrix is copied into the memory
1346 * allocated for the handle
1351 * D3DMatHandle: Handle to set the matrix to
1352 * D3DMatrix: Matrix to set
1356 * DDERR_INVALIDPARAMS if the handle of the matrix is invalid or the matrix
1359 *****************************************************************************/
1360 static HRESULT WINAPI
1361 IDirect3DDeviceImpl_1_SetMatrix(IDirect3DDevice
*iface
,
1362 D3DMATRIXHANDLE D3DMatHandle
,
1363 D3DMATRIX
*D3DMatrix
)
1365 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
1368 TRACE("iface %p, matrix_handle %#x, matrix %p.\n", iface
, D3DMatHandle
, D3DMatrix
);
1370 if (!D3DMatrix
) return DDERR_INVALIDPARAMS
;
1372 wined3d_mutex_lock();
1374 m
= ddraw_get_object(&This
->handle_table
, D3DMatHandle
- 1, DDRAW_HANDLE_MATRIX
);
1377 WARN("Invalid matrix handle.\n");
1378 wined3d_mutex_unlock();
1379 return DDERR_INVALIDPARAMS
;
1382 if (TRACE_ON(ddraw
))
1383 dump_D3DMATRIX(D3DMatrix
);
1387 if (D3DMatHandle
== This
->world
)
1388 wined3d_device_set_transform(This
->wined3d_device
, WINED3DTS_WORLDMATRIX(0), (WINED3DMATRIX
*)D3DMatrix
);
1390 if (D3DMatHandle
== This
->view
)
1391 wined3d_device_set_transform(This
->wined3d_device
, WINED3DTS_VIEW
, (WINED3DMATRIX
*)D3DMatrix
);
1393 if (D3DMatHandle
== This
->proj
)
1394 wined3d_device_set_transform(This
->wined3d_device
, WINED3DTS_PROJECTION
, (WINED3DMATRIX
*)D3DMatrix
);
1396 wined3d_mutex_unlock();
1401 /*****************************************************************************
1402 * IDirect3DDevice::GetMatrix
1404 * Returns the content of a D3DMATRIX handle
1409 * D3DMatHandle: Matrix handle to read the content from
1410 * D3DMatrix: Address to store the content at
1414 * DDERR_INVALIDPARAMS if D3DMatHandle is invalid or D3DMatrix is NULL
1416 *****************************************************************************/
1417 static HRESULT WINAPI
1418 IDirect3DDeviceImpl_1_GetMatrix(IDirect3DDevice
*iface
,
1419 D3DMATRIXHANDLE D3DMatHandle
,
1420 D3DMATRIX
*D3DMatrix
)
1422 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
1425 TRACE("iface %p, matrix_handle %#x, matrix %p.\n", iface
, D3DMatHandle
, D3DMatrix
);
1427 if (!D3DMatrix
) return DDERR_INVALIDPARAMS
;
1429 wined3d_mutex_lock();
1431 m
= ddraw_get_object(&This
->handle_table
, D3DMatHandle
- 1, DDRAW_HANDLE_MATRIX
);
1434 WARN("Invalid matrix handle.\n");
1435 wined3d_mutex_unlock();
1436 return DDERR_INVALIDPARAMS
;
1441 wined3d_mutex_unlock();
1446 /*****************************************************************************
1447 * IDirect3DDevice::DeleteMatrix
1449 * Destroys a Matrix handle. Frees the memory and unsets the handle data
1454 * D3DMatHandle: Handle to destroy
1458 * DDERR_INVALIDPARAMS if D3DMatHandle is invalid
1460 *****************************************************************************/
1461 static HRESULT WINAPI
1462 IDirect3DDeviceImpl_1_DeleteMatrix(IDirect3DDevice
*iface
,
1463 D3DMATRIXHANDLE D3DMatHandle
)
1465 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
1468 TRACE("iface %p, matrix_handle %#x.\n", iface
, D3DMatHandle
);
1470 wined3d_mutex_lock();
1472 m
= ddraw_free_handle(&This
->handle_table
, D3DMatHandle
- 1, DDRAW_HANDLE_MATRIX
);
1475 WARN("Invalid matrix handle.\n");
1476 wined3d_mutex_unlock();
1477 return DDERR_INVALIDPARAMS
;
1480 wined3d_mutex_unlock();
1482 HeapFree(GetProcessHeap(), 0, m
);
1487 /*****************************************************************************
1488 * IDirect3DDevice7::BeginScene
1490 * This method must be called before any rendering is performed.
1491 * IDirect3DDevice::EndScene has to be called after the scene is complete
1493 * Version 1, 2, 3 and 7
1496 * D3D_OK on success, for details see IWineD3DDevice::BeginScene
1497 * D3DERR_SCENE_IN_SCENE if WineD3D returns an error(Only in case of an already
1500 *****************************************************************************/
1502 IDirect3DDeviceImpl_7_BeginScene(IDirect3DDevice7
*iface
)
1504 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
1507 TRACE("iface %p.\n", iface
);
1509 wined3d_mutex_lock();
1510 hr
= wined3d_device_begin_scene(This
->wined3d_device
);
1511 wined3d_mutex_unlock();
1513 if(hr
== WINED3D_OK
) return D3D_OK
;
1514 else return D3DERR_SCENE_IN_SCENE
; /* TODO: Other possible causes of failure */
1517 static HRESULT WINAPI
1518 IDirect3DDeviceImpl_7_BeginScene_FPUSetup(IDirect3DDevice7
*iface
)
1520 return IDirect3DDeviceImpl_7_BeginScene(iface
);
1523 static HRESULT WINAPI
1524 IDirect3DDeviceImpl_7_BeginScene_FPUPreserve(IDirect3DDevice7
*iface
)
1529 old_fpucw
= d3d_fpu_setup();
1530 hr
= IDirect3DDeviceImpl_7_BeginScene(iface
);
1531 set_fpu_control_word(old_fpucw
);
1536 static HRESULT WINAPI
IDirect3DDeviceImpl_3_BeginScene(IDirect3DDevice3
*iface
)
1538 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
1539 TRACE("iface %p.\n", iface
);
1541 return IDirect3DDevice7_BeginScene(&This
->IDirect3DDevice7_iface
);
1544 static HRESULT WINAPI
IDirect3DDeviceImpl_2_BeginScene(IDirect3DDevice2
*iface
)
1546 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
1547 TRACE("iface %p.\n", iface
);
1549 return IDirect3DDevice7_BeginScene(&This
->IDirect3DDevice7_iface
);
1552 static HRESULT WINAPI
IDirect3DDeviceImpl_1_BeginScene(IDirect3DDevice
*iface
)
1554 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
1555 TRACE("iface %p.\n", iface
);
1557 return IDirect3DDevice7_BeginScene(&This
->IDirect3DDevice7_iface
);
1560 /*****************************************************************************
1561 * IDirect3DDevice7::EndScene
1563 * Ends a scene that has been begun with IDirect3DDevice7::BeginScene.
1564 * This method must be called after rendering is finished.
1566 * Version 1, 2, 3 and 7
1569 * D3D_OK on success, for details see IWineD3DDevice::EndScene
1570 * D3DERR_SCENE_NOT_IN_SCENE is returned if WineD3D returns an error. It does
1571 * that only if the scene was already ended.
1573 *****************************************************************************/
1575 IDirect3DDeviceImpl_7_EndScene(IDirect3DDevice7
*iface
)
1577 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
1580 TRACE("iface %p.\n", iface
);
1582 wined3d_mutex_lock();
1583 hr
= wined3d_device_end_scene(This
->wined3d_device
);
1584 wined3d_mutex_unlock();
1586 if(hr
== WINED3D_OK
) return D3D_OK
;
1587 else return D3DERR_SCENE_NOT_IN_SCENE
;
1590 static HRESULT WINAPI DECLSPEC_HOTPATCH
1591 IDirect3DDeviceImpl_7_EndScene_FPUSetup(IDirect3DDevice7
*iface
)
1593 return IDirect3DDeviceImpl_7_EndScene(iface
);
1596 static HRESULT WINAPI DECLSPEC_HOTPATCH
1597 IDirect3DDeviceImpl_7_EndScene_FPUPreserve(IDirect3DDevice7
*iface
)
1602 old_fpucw
= d3d_fpu_setup();
1603 hr
= IDirect3DDeviceImpl_7_EndScene(iface
);
1604 set_fpu_control_word(old_fpucw
);
1609 static HRESULT WINAPI DECLSPEC_HOTPATCH
IDirect3DDeviceImpl_3_EndScene(IDirect3DDevice3
*iface
)
1611 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
1612 TRACE("iface %p.\n", iface
);
1614 return IDirect3DDevice7_EndScene(&This
->IDirect3DDevice7_iface
);
1617 static HRESULT WINAPI DECLSPEC_HOTPATCH
IDirect3DDeviceImpl_2_EndScene(IDirect3DDevice2
*iface
)
1619 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
1620 TRACE("iface %p.\n", iface
);
1622 return IDirect3DDevice7_EndScene(&This
->IDirect3DDevice7_iface
);
1625 static HRESULT WINAPI DECLSPEC_HOTPATCH
IDirect3DDeviceImpl_1_EndScene(IDirect3DDevice
*iface
)
1627 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
1628 TRACE("iface %p.\n", iface
);
1630 return IDirect3DDevice7_EndScene(&This
->IDirect3DDevice7_iface
);
1633 /*****************************************************************************
1634 * IDirect3DDevice7::GetDirect3D
1636 * Returns the IDirect3D(= interface to the DirectDraw object) used to create
1640 * Direct3D7: Address to store the interface pointer at
1644 * DDERR_INVALIDPARAMS if Direct3D7 == NULL
1646 *****************************************************************************/
1647 static HRESULT WINAPI
1648 IDirect3DDeviceImpl_7_GetDirect3D(IDirect3DDevice7
*iface
,
1649 IDirect3D7
**Direct3D7
)
1651 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
1653 TRACE("iface %p, d3d %p.\n", iface
, Direct3D7
);
1656 return DDERR_INVALIDPARAMS
;
1658 *Direct3D7
= &This
->ddraw
->IDirect3D7_iface
;
1659 IDirect3D7_AddRef(*Direct3D7
);
1661 TRACE(" returning interface %p\n", *Direct3D7
);
1665 static HRESULT WINAPI
IDirect3DDeviceImpl_3_GetDirect3D(IDirect3DDevice3
*iface
,
1666 IDirect3D3
**Direct3D3
)
1668 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
1670 TRACE("iface %p, d3d %p.\n", iface
, Direct3D3
);
1673 return DDERR_INVALIDPARAMS
;
1675 IDirect3D3_AddRef(&This
->ddraw
->IDirect3D3_iface
);
1676 *Direct3D3
= &This
->ddraw
->IDirect3D3_iface
;
1677 TRACE(" returning interface %p\n", *Direct3D3
);
1681 static HRESULT WINAPI
IDirect3DDeviceImpl_2_GetDirect3D(IDirect3DDevice2
*iface
,
1682 IDirect3D2
**Direct3D2
)
1684 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
1686 TRACE("iface %p, d3d %p.\n", iface
, Direct3D2
);
1689 return DDERR_INVALIDPARAMS
;
1691 IDirect3D2_AddRef(&This
->ddraw
->IDirect3D2_iface
);
1692 *Direct3D2
= &This
->ddraw
->IDirect3D2_iface
;
1693 TRACE(" returning interface %p\n", *Direct3D2
);
1697 static HRESULT WINAPI
IDirect3DDeviceImpl_1_GetDirect3D(IDirect3DDevice
*iface
,
1698 IDirect3D
**Direct3D
)
1700 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
1702 TRACE("iface %p, d3d %p.\n", iface
, Direct3D
);
1705 return DDERR_INVALIDPARAMS
;
1707 IDirect3D_AddRef(&This
->ddraw
->IDirect3D_iface
);
1708 *Direct3D
= &This
->ddraw
->IDirect3D_iface
;
1709 TRACE(" returning interface %p\n", *Direct3D
);
1713 /*****************************************************************************
1714 * IDirect3DDevice3::SetCurrentViewport
1716 * Sets a Direct3DViewport as the current viewport.
1717 * For the thunks note that all viewport interface versions are equal
1720 * Direct3DViewport3: The viewport to set
1726 * (Is a NULL viewport valid?)
1728 *****************************************************************************/
1729 static HRESULT WINAPI
1730 IDirect3DDeviceImpl_3_SetCurrentViewport(IDirect3DDevice3
*iface
,
1731 IDirect3DViewport3
*Direct3DViewport3
)
1733 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
1734 IDirect3DViewportImpl
*vp
= unsafe_impl_from_IDirect3DViewport3(Direct3DViewport3
);
1736 TRACE("iface %p, viewport %p.\n", iface
, Direct3DViewport3
);
1738 wined3d_mutex_lock();
1739 /* Do nothing if the specified viewport is the same as the current one */
1740 if (This
->current_viewport
== vp
)
1742 wined3d_mutex_unlock();
1746 if (vp
->active_device
!= This
)
1748 WARN("Viewport %p active device is %p.\n", vp
, vp
->active_device
);
1749 wined3d_mutex_unlock();
1750 return DDERR_INVALIDPARAMS
;
1753 /* Release previous viewport and AddRef the new one */
1754 if (This
->current_viewport
)
1756 TRACE("ViewportImpl is at %p, interface is at %p\n", This
->current_viewport
,
1757 &This
->current_viewport
->IDirect3DViewport3_iface
);
1758 IDirect3DViewport3_Release(&This
->current_viewport
->IDirect3DViewport3_iface
);
1760 IDirect3DViewport3_AddRef(Direct3DViewport3
);
1762 /* Set this viewport as the current viewport */
1763 This
->current_viewport
= vp
;
1765 /* Activate this viewport */
1766 viewport_activate(This
->current_viewport
, FALSE
);
1768 wined3d_mutex_unlock();
1773 static HRESULT WINAPI
IDirect3DDeviceImpl_2_SetCurrentViewport(IDirect3DDevice2
*iface
,
1774 IDirect3DViewport2
*Direct3DViewport2
)
1776 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
1777 IDirect3DViewportImpl
*vp
= unsafe_impl_from_IDirect3DViewport2(Direct3DViewport2
);
1779 TRACE("iface %p, viewport %p.\n", iface
, Direct3DViewport2
);
1781 return IDirect3DDevice3_SetCurrentViewport(&This
->IDirect3DDevice3_iface
,
1782 &vp
->IDirect3DViewport3_iface
);
1785 /*****************************************************************************
1786 * IDirect3DDevice3::GetCurrentViewport
1788 * Returns the currently active viewport.
1793 * Direct3DViewport3: Address to return the interface pointer at
1797 * DDERR_INVALIDPARAMS if Direct3DViewport == NULL
1799 *****************************************************************************/
1800 static HRESULT WINAPI
1801 IDirect3DDeviceImpl_3_GetCurrentViewport(IDirect3DDevice3
*iface
,
1802 IDirect3DViewport3
**Direct3DViewport3
)
1804 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
1806 TRACE("iface %p, viewport %p.\n", iface
, Direct3DViewport3
);
1808 if(!Direct3DViewport3
)
1809 return DDERR_INVALIDPARAMS
;
1811 wined3d_mutex_lock();
1812 *Direct3DViewport3
= &This
->current_viewport
->IDirect3DViewport3_iface
;
1814 /* AddRef the returned viewport */
1815 if(*Direct3DViewport3
) IDirect3DViewport3_AddRef(*Direct3DViewport3
);
1817 TRACE(" returning interface %p\n", *Direct3DViewport3
);
1819 wined3d_mutex_unlock();
1824 static HRESULT WINAPI
IDirect3DDeviceImpl_2_GetCurrentViewport(IDirect3DDevice2
*iface
,
1825 IDirect3DViewport2
**Direct3DViewport2
)
1827 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
1830 TRACE("iface %p, viewport %p.\n", iface
, Direct3DViewport2
);
1832 hr
= IDirect3DDevice3_GetCurrentViewport(&This
->IDirect3DDevice3_iface
,
1833 (IDirect3DViewport3
**)Direct3DViewport2
);
1834 if(hr
!= D3D_OK
) return hr
;
1838 /*****************************************************************************
1839 * IDirect3DDevice7::SetRenderTarget
1841 * Sets the render target for the Direct3DDevice.
1842 * For the thunks note that IDirectDrawSurface7 == IDirectDrawSurface4 and
1843 * IDirectDrawSurface3 == IDirectDrawSurface
1845 * Version 2, 3 and 7
1848 * NewTarget: Pointer to an IDirectDrawSurface7 interface to set as the new
1853 * D3D_OK on success, for details see IWineD3DDevice::SetRenderTarget
1855 *****************************************************************************/
1856 static HRESULT
d3d_device_set_render_target(IDirect3DDeviceImpl
*This
, IDirectDrawSurfaceImpl
*Target
)
1860 wined3d_mutex_lock();
1862 if(This
->target
== Target
)
1864 TRACE("No-op SetRenderTarget operation, not doing anything\n");
1865 wined3d_mutex_unlock();
1868 This
->target
= Target
;
1869 hr
= wined3d_device_set_render_target(This
->wined3d_device
, 0,
1870 Target
? Target
->wined3d_surface
: NULL
, FALSE
);
1873 wined3d_mutex_unlock();
1876 IDirect3DDeviceImpl_UpdateDepthStencil(This
);
1878 wined3d_mutex_unlock();
1884 IDirect3DDeviceImpl_7_SetRenderTarget(IDirect3DDevice7
*iface
,
1885 IDirectDrawSurface7
*NewTarget
,
1888 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
1889 IDirectDrawSurfaceImpl
*Target
= unsafe_impl_from_IDirectDrawSurface7(NewTarget
);
1891 TRACE("iface %p, target %p, flags %#x.\n", iface
, NewTarget
, Flags
);
1892 /* Flags: Not used */
1894 IDirectDrawSurface7_AddRef(NewTarget
);
1895 IDirectDrawSurface7_Release(&This
->target
->IDirectDrawSurface7_iface
);
1896 return d3d_device_set_render_target(This
, Target
);
1899 static HRESULT WINAPI
1900 IDirect3DDeviceImpl_7_SetRenderTarget_FPUSetup(IDirect3DDevice7
*iface
,
1901 IDirectDrawSurface7
*NewTarget
,
1904 return IDirect3DDeviceImpl_7_SetRenderTarget(iface
, NewTarget
, Flags
);
1907 static HRESULT WINAPI
1908 IDirect3DDeviceImpl_7_SetRenderTarget_FPUPreserve(IDirect3DDevice7
*iface
,
1909 IDirectDrawSurface7
*NewTarget
,
1915 old_fpucw
= d3d_fpu_setup();
1916 hr
= IDirect3DDeviceImpl_7_SetRenderTarget(iface
, NewTarget
, Flags
);
1917 set_fpu_control_word(old_fpucw
);
1922 static HRESULT WINAPI
IDirect3DDeviceImpl_3_SetRenderTarget(IDirect3DDevice3
*iface
,
1923 IDirectDrawSurface4
*NewRenderTarget
, DWORD Flags
)
1925 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
1926 IDirectDrawSurfaceImpl
*Target
= unsafe_impl_from_IDirectDrawSurface4(NewRenderTarget
);
1928 TRACE("iface %p, target %p, flags %#x.\n", iface
, NewRenderTarget
, Flags
);
1930 IDirectDrawSurface4_AddRef(NewRenderTarget
);
1931 IDirectDrawSurface4_Release(&This
->target
->IDirectDrawSurface4_iface
);
1932 return d3d_device_set_render_target(This
, Target
);
1935 static HRESULT WINAPI
IDirect3DDeviceImpl_2_SetRenderTarget(IDirect3DDevice2
*iface
,
1936 IDirectDrawSurface
*NewRenderTarget
, DWORD Flags
)
1938 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
1939 IDirectDrawSurfaceImpl
*Target
= unsafe_impl_from_IDirectDrawSurface(NewRenderTarget
);
1941 TRACE("iface %p, target %p, flags %#x.\n", iface
, NewRenderTarget
, Flags
);
1943 IDirectDrawSurface_AddRef(NewRenderTarget
);
1944 IDirectDrawSurface_Release(&This
->target
->IDirectDrawSurface_iface
);
1945 return d3d_device_set_render_target(This
, Target
);
1948 /*****************************************************************************
1949 * IDirect3DDevice7::GetRenderTarget
1951 * Returns the current render target.
1952 * This is handled locally, because the WineD3D render target's parent
1955 * Version 2, 3 and 7
1958 * RenderTarget: Address to store the surface interface pointer
1962 * DDERR_INVALIDPARAMS if RenderTarget == NULL
1964 *****************************************************************************/
1965 static HRESULT WINAPI
1966 IDirect3DDeviceImpl_7_GetRenderTarget(IDirect3DDevice7
*iface
,
1967 IDirectDrawSurface7
**RenderTarget
)
1969 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
1971 TRACE("iface %p, target %p.\n", iface
, RenderTarget
);
1974 return DDERR_INVALIDPARAMS
;
1976 wined3d_mutex_lock();
1977 *RenderTarget
= &This
->target
->IDirectDrawSurface7_iface
;
1978 IDirectDrawSurface7_AddRef(*RenderTarget
);
1979 wined3d_mutex_unlock();
1984 static HRESULT WINAPI
IDirect3DDeviceImpl_3_GetRenderTarget(IDirect3DDevice3
*iface
,
1985 IDirectDrawSurface4
**RenderTarget
)
1987 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
1988 IDirectDrawSurface7
*RenderTarget7
;
1989 IDirectDrawSurfaceImpl
*RenderTargetImpl
;
1992 TRACE("iface %p, target %p.\n", iface
, RenderTarget
);
1995 return DDERR_INVALIDPARAMS
;
1997 hr
= IDirect3DDevice7_GetRenderTarget(&This
->IDirect3DDevice7_iface
, &RenderTarget7
);
1998 if(hr
!= D3D_OK
) return hr
;
1999 RenderTargetImpl
= impl_from_IDirectDrawSurface7(RenderTarget7
);
2000 *RenderTarget
= &RenderTargetImpl
->IDirectDrawSurface4_iface
;
2001 IDirectDrawSurface4_AddRef(*RenderTarget
);
2002 IDirectDrawSurface7_Release(RenderTarget7
);
2006 static HRESULT WINAPI
IDirect3DDeviceImpl_2_GetRenderTarget(IDirect3DDevice2
*iface
,
2007 IDirectDrawSurface
**RenderTarget
)
2009 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
2010 IDirectDrawSurface7
*RenderTarget7
;
2011 IDirectDrawSurfaceImpl
*RenderTargetImpl
;
2014 TRACE("iface %p, target %p.\n", iface
, RenderTarget
);
2017 return DDERR_INVALIDPARAMS
;
2019 hr
= IDirect3DDevice7_GetRenderTarget(&This
->IDirect3DDevice7_iface
, &RenderTarget7
);
2020 if(hr
!= D3D_OK
) return hr
;
2021 RenderTargetImpl
= impl_from_IDirectDrawSurface7(RenderTarget7
);
2022 *RenderTarget
= &RenderTargetImpl
->IDirectDrawSurface_iface
;
2023 IDirectDrawSurface_AddRef(*RenderTarget
);
2024 IDirectDrawSurface7_Release(RenderTarget7
);
2028 /*****************************************************************************
2029 * IDirect3DDevice3::Begin
2031 * Begins a description block of vertices. This is similar to glBegin()
2032 * and glEnd(). After a call to IDirect3DDevice3::End, the vertices
2033 * described with IDirect3DDevice::Vertex are drawn.
2038 * PrimitiveType: The type of primitives to draw
2039 * VertexTypeDesc: A flexible vertex format description of the vertices
2040 * Flags: Some flags..
2045 *****************************************************************************/
2046 static HRESULT WINAPI
2047 IDirect3DDeviceImpl_3_Begin(IDirect3DDevice3
*iface
,
2048 D3DPRIMITIVETYPE PrimitiveType
,
2049 DWORD VertexTypeDesc
,
2052 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
2054 TRACE("iface %p, primitive_type %#x, FVF %#x, flags %#x.\n",
2055 iface
, PrimitiveType
, VertexTypeDesc
, Flags
);
2057 wined3d_mutex_lock();
2058 This
->primitive_type
= PrimitiveType
;
2059 This
->vertex_type
= VertexTypeDesc
;
2060 This
->render_flags
= Flags
;
2061 This
->vertex_size
= get_flexible_vertex_size(This
->vertex_type
);
2062 This
->nb_vertices
= 0;
2063 wined3d_mutex_unlock();
2068 static HRESULT WINAPI
IDirect3DDeviceImpl_2_Begin(IDirect3DDevice2
*iface
, D3DPRIMITIVETYPE d3dpt
,
2069 D3DVERTEXTYPE dwVertexTypeDesc
, DWORD dwFlags
)
2072 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
2074 TRACE("iface %p, primitive_type %#x, vertex_type %#x, flags %#x.\n",
2075 iface
, d3dpt
, dwVertexTypeDesc
, dwFlags
);
2077 switch(dwVertexTypeDesc
)
2079 case D3DVT_VERTEX
: FVF
= D3DFVF_VERTEX
; break;
2080 case D3DVT_LVERTEX
: FVF
= D3DFVF_LVERTEX
; break;
2081 case D3DVT_TLVERTEX
: FVF
= D3DFVF_TLVERTEX
; break;
2083 ERR("Unexpected vertex type %d\n", dwVertexTypeDesc
);
2084 return DDERR_INVALIDPARAMS
; /* Should never happen */
2087 return IDirect3DDevice3_Begin(&This
->IDirect3DDevice3_iface
, d3dpt
, FVF
, dwFlags
);
2090 /*****************************************************************************
2091 * IDirect3DDevice3::BeginIndexed
2093 * Draws primitives based on vertices in a vertex array which are specified
2099 * PrimitiveType: Primitive type to draw
2100 * VertexType: A FVF description of the vertex format
2101 * Vertices: pointer to an array containing the vertices
2102 * NumVertices: The number of vertices in the vertex array
2103 * Flags: Some flags ...
2106 * D3D_OK, because it's a stub
2108 *****************************************************************************/
2109 static HRESULT WINAPI
2110 IDirect3DDeviceImpl_3_BeginIndexed(IDirect3DDevice3
*iface
,
2111 D3DPRIMITIVETYPE PrimitiveType
,
2117 FIXME("iface %p, primitive_type %#x, FVF %#x, vertices %p, vertex_count %u, flags %#x stub!\n",
2118 iface
, PrimitiveType
, VertexType
, Vertices
, NumVertices
, Flags
);
2124 static HRESULT WINAPI
IDirect3DDeviceImpl_2_BeginIndexed(IDirect3DDevice2
*iface
,
2125 D3DPRIMITIVETYPE d3dptPrimitiveType
, D3DVERTEXTYPE d3dvtVertexType
,
2126 void *lpvVertices
, DWORD dwNumVertices
, DWORD dwFlags
)
2129 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
2131 TRACE("iface %p, primitive_type %#x, vertex_type %#x, vertices %p, vertex_count %u, flags %#x stub!\n",
2132 iface
, d3dptPrimitiveType
, d3dvtVertexType
, lpvVertices
, dwNumVertices
, dwFlags
);
2134 switch(d3dvtVertexType
)
2136 case D3DVT_VERTEX
: FVF
= D3DFVF_VERTEX
; break;
2137 case D3DVT_LVERTEX
: FVF
= D3DFVF_LVERTEX
; break;
2138 case D3DVT_TLVERTEX
: FVF
= D3DFVF_TLVERTEX
; break;
2140 ERR("Unexpected vertex type %d\n", d3dvtVertexType
);
2141 return DDERR_INVALIDPARAMS
; /* Should never happen */
2144 return IDirect3DDevice3_BeginIndexed(&This
->IDirect3DDevice3_iface
,
2145 d3dptPrimitiveType
, FVF
, lpvVertices
, dwNumVertices
, dwFlags
);
2148 /*****************************************************************************
2149 * IDirect3DDevice3::Vertex
2151 * Draws a vertex as described by IDirect3DDevice3::Begin. It places all
2152 * drawn vertices in a vertex buffer. If the buffer is too small, its
2153 * size is increased.
2158 * Vertex: Pointer to the vertex
2161 * D3D_OK, on success
2162 * DDERR_INVALIDPARAMS if Vertex is NULL
2164 *****************************************************************************/
2165 static HRESULT WINAPI
2166 IDirect3DDeviceImpl_3_Vertex(IDirect3DDevice3
*iface
,
2169 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
2171 TRACE("iface %p, vertex %p.\n", iface
, Vertex
);
2174 return DDERR_INVALIDPARAMS
;
2176 wined3d_mutex_lock();
2177 if ((This
->nb_vertices
+1)*This
->vertex_size
> This
->buffer_size
)
2180 This
->buffer_size
= This
->buffer_size
? This
->buffer_size
* 2 : This
->vertex_size
* 3;
2181 old_buffer
= This
->vertex_buffer
;
2182 This
->vertex_buffer
= HeapAlloc(GetProcessHeap(), 0, This
->buffer_size
);
2185 CopyMemory(This
->vertex_buffer
, old_buffer
, This
->nb_vertices
* This
->vertex_size
);
2186 HeapFree(GetProcessHeap(), 0, old_buffer
);
2190 CopyMemory(This
->vertex_buffer
+ This
->nb_vertices
++ * This
->vertex_size
, Vertex
, This
->vertex_size
);
2191 wined3d_mutex_unlock();
2196 static HRESULT WINAPI
IDirect3DDeviceImpl_2_Vertex(IDirect3DDevice2
*iface
, void *lpVertexType
)
2198 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
2200 TRACE("iface %p, vertex %p.\n", iface
, lpVertexType
);
2202 return IDirect3DDevice3_Vertex(&This
->IDirect3DDevice3_iface
, lpVertexType
);
2205 /*****************************************************************************
2206 * IDirect3DDevice3::Index
2208 * Specifies an index to a vertex to be drawn. The vertex array has to
2209 * be specified with BeginIndexed first.
2212 * VertexIndex: The index of the vertex to draw
2215 * D3D_OK because it's a stub
2217 *****************************************************************************/
2218 static HRESULT WINAPI
2219 IDirect3DDeviceImpl_3_Index(IDirect3DDevice3
*iface
,
2222 FIXME("iface %p, index %#x stub!\n", iface
, VertexIndex
);
2227 static HRESULT WINAPI
IDirect3DDeviceImpl_2_Index(IDirect3DDevice2
*iface
, WORD wVertexIndex
)
2229 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
2231 TRACE("iface %p, index %#x.\n", iface
, wVertexIndex
);
2233 return IDirect3DDevice3_Index(&This
->IDirect3DDevice3_iface
, wVertexIndex
);
2236 /*****************************************************************************
2237 * IDirect3DDevice3::End
2239 * Ends a draw begun with IDirect3DDevice3::Begin or
2240 * IDirect3DDevice::BeginIndexed. The vertices specified with
2241 * IDirect3DDevice::Vertex or IDirect3DDevice::Index are drawn using
2242 * the IDirect3DDevice7::DrawPrimitive method. So far only
2243 * non-indexed mode is supported
2248 * Flags: Some flags, as usual. Don't know which are defined
2251 * The return value of IDirect3DDevice7::DrawPrimitive
2253 *****************************************************************************/
2254 static HRESULT WINAPI
2255 IDirect3DDeviceImpl_3_End(IDirect3DDevice3
*iface
,
2258 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
2260 TRACE("iface %p, flags %#x.\n", iface
, Flags
);
2262 return IDirect3DDevice7_DrawPrimitive(&This
->IDirect3DDevice7_iface
, This
->primitive_type
,
2263 This
->vertex_type
, This
->vertex_buffer
, This
->nb_vertices
, This
->render_flags
);
2266 static HRESULT WINAPI
IDirect3DDeviceImpl_2_End(IDirect3DDevice2
*iface
, DWORD dwFlags
)
2268 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
2270 TRACE("iface %p, flags %#x.\n", iface
, dwFlags
);
2272 return IDirect3DDevice3_End(&This
->IDirect3DDevice3_iface
, dwFlags
);
2275 /*****************************************************************************
2276 * IDirect3DDevice7::GetRenderState
2278 * Returns the value of a render state. The possible render states are
2279 * defined in include/d3dtypes.h
2281 * Version 2, 3 and 7
2284 * RenderStateType: Render state to return the current setting of
2285 * Value: Address to store the value at
2288 * D3D_OK on success, for details see IWineD3DDevice::GetRenderState
2289 * DDERR_INVALIDPARAMS if Value == NULL
2291 *****************************************************************************/
2292 static HRESULT
IDirect3DDeviceImpl_7_GetRenderState(IDirect3DDevice7
*iface
,
2293 D3DRENDERSTATETYPE RenderStateType
, DWORD
*Value
)
2295 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
2298 TRACE("iface %p, state %#x, value %p.\n", iface
, RenderStateType
, Value
);
2301 return DDERR_INVALIDPARAMS
;
2303 wined3d_mutex_lock();
2304 switch(RenderStateType
)
2306 case D3DRENDERSTATE_TEXTUREMAG
:
2308 WINED3DTEXTUREFILTERTYPE tex_mag
;
2310 hr
= wined3d_device_get_sampler_state(This
->wined3d_device
, 0, WINED3DSAMP_MAGFILTER
, &tex_mag
);
2314 case WINED3DTEXF_POINT
:
2315 *Value
= D3DFILTER_NEAREST
;
2317 case WINED3DTEXF_LINEAR
:
2318 *Value
= D3DFILTER_LINEAR
;
2321 ERR("Unhandled texture mag %d !\n",tex_mag
);
2327 case D3DRENDERSTATE_TEXTUREMIN
:
2329 WINED3DTEXTUREFILTERTYPE tex_min
;
2330 WINED3DTEXTUREFILTERTYPE tex_mip
;
2332 hr
= wined3d_device_get_sampler_state(This
->wined3d_device
,
2333 0, WINED3DSAMP_MINFILTER
, &tex_min
);
2336 wined3d_mutex_unlock();
2339 hr
= wined3d_device_get_sampler_state(This
->wined3d_device
,
2340 0, WINED3DSAMP_MIPFILTER
, &tex_mip
);
2344 case WINED3DTEXF_POINT
:
2347 case WINED3DTEXF_NONE
:
2348 *Value
= D3DFILTER_NEAREST
;
2350 case WINED3DTEXF_POINT
:
2351 *Value
= D3DFILTER_MIPNEAREST
;
2353 case WINED3DTEXF_LINEAR
:
2354 *Value
= D3DFILTER_LINEARMIPNEAREST
;
2357 ERR("Unhandled mip filter %#x.\n", tex_mip
);
2358 *Value
= D3DFILTER_NEAREST
;
2362 case WINED3DTEXF_LINEAR
:
2365 case WINED3DTEXF_NONE
:
2366 *Value
= D3DFILTER_LINEAR
;
2368 case WINED3DTEXF_POINT
:
2369 *Value
= D3DFILTER_MIPLINEAR
;
2371 case WINED3DTEXF_LINEAR
:
2372 *Value
= D3DFILTER_LINEARMIPLINEAR
;
2375 ERR("Unhandled mip filter %#x.\n", tex_mip
);
2376 *Value
= D3DFILTER_LINEAR
;
2381 ERR("Unhandled texture min filter %#x.\n",tex_min
);
2382 *Value
= D3DFILTER_NEAREST
;
2388 case D3DRENDERSTATE_TEXTUREADDRESS
:
2389 case D3DRENDERSTATE_TEXTUREADDRESSU
:
2390 hr
= wined3d_device_get_sampler_state(This
->wined3d_device
,
2391 0, WINED3DSAMP_ADDRESSU
, Value
);
2393 case D3DRENDERSTATE_TEXTUREADDRESSV
:
2394 hr
= wined3d_device_get_sampler_state(This
->wined3d_device
,
2395 0, WINED3DSAMP_ADDRESSV
, Value
);
2398 case D3DRENDERSTATE_BORDERCOLOR
:
2399 FIXME("Unhandled render state D3DRENDERSTATE_BORDERCOLOR.\n");
2403 case D3DRENDERSTATE_TEXTUREHANDLE
:
2404 case D3DRENDERSTATE_TEXTUREMAPBLEND
:
2405 WARN("Render state %#x is invalid in d3d7.\n", RenderStateType
);
2406 hr
= DDERR_INVALIDPARAMS
;
2409 case D3DRENDERSTATE_ZBIAS
:
2410 hr
= wined3d_device_get_render_state(This
->wined3d_device
, WINED3DRS_DEPTHBIAS
, Value
);
2414 if (RenderStateType
>= D3DRENDERSTATE_STIPPLEPATTERN00
2415 && RenderStateType
<= D3DRENDERSTATE_STIPPLEPATTERN31
)
2417 FIXME("Unhandled stipple pattern render state (%#x).\n",
2422 hr
= wined3d_device_get_render_state(This
->wined3d_device
, RenderStateType
, Value
);
2424 wined3d_mutex_unlock();
2429 static HRESULT WINAPI
2430 IDirect3DDeviceImpl_7_GetRenderState_FPUSetup(IDirect3DDevice7
*iface
,
2431 D3DRENDERSTATETYPE RenderStateType
,
2434 return IDirect3DDeviceImpl_7_GetRenderState(iface
, RenderStateType
, Value
);
2437 static HRESULT WINAPI
2438 IDirect3DDeviceImpl_7_GetRenderState_FPUPreserve(IDirect3DDevice7
*iface
,
2439 D3DRENDERSTATETYPE RenderStateType
,
2445 old_fpucw
= d3d_fpu_setup();
2446 hr
= IDirect3DDeviceImpl_7_GetRenderState(iface
, RenderStateType
, Value
);
2447 set_fpu_control_word(old_fpucw
);
2452 static HRESULT WINAPI
2453 IDirect3DDeviceImpl_3_GetRenderState(IDirect3DDevice3
*iface
,
2454 D3DRENDERSTATETYPE dwRenderStateType
,
2455 DWORD
*lpdwRenderState
)
2457 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
2460 TRACE("iface %p, state %#x, value %p.\n", iface
, dwRenderStateType
, lpdwRenderState
);
2462 switch(dwRenderStateType
)
2464 case D3DRENDERSTATE_TEXTUREHANDLE
:
2466 /* This state is wrapped to SetTexture in SetRenderState, so
2467 * it has to be wrapped to GetTexture here. */
2468 struct wined3d_texture
*tex
= NULL
;
2469 *lpdwRenderState
= 0;
2471 wined3d_mutex_lock();
2472 hr
= wined3d_device_get_texture(This
->wined3d_device
, 0, &tex
);
2473 if (SUCCEEDED(hr
) && tex
)
2475 /* The parent of the texture is the IDirectDrawSurface7
2476 * interface of the ddraw surface. */
2477 IDirectDrawSurfaceImpl
*parent
= wined3d_texture_get_parent(tex
);
2478 if (parent
) *lpdwRenderState
= parent
->Handle
;
2479 wined3d_texture_decref(tex
);
2481 wined3d_mutex_unlock();
2486 case D3DRENDERSTATE_TEXTUREMAPBLEND
:
2488 /* D3DRENDERSTATE_TEXTUREMAPBLEND is mapped to texture state stages in SetRenderState; reverse
2489 the mapping to get the value. */
2490 DWORD colorop
, colorarg1
, colorarg2
;
2491 DWORD alphaop
, alphaarg1
, alphaarg2
;
2493 wined3d_mutex_lock();
2495 This
->legacyTextureBlending
= TRUE
;
2497 wined3d_device_get_texture_stage_state(This
->wined3d_device
, 0, WINED3DTSS_COLOROP
, &colorop
);
2498 wined3d_device_get_texture_stage_state(This
->wined3d_device
, 0, WINED3DTSS_COLORARG1
, &colorarg1
);
2499 wined3d_device_get_texture_stage_state(This
->wined3d_device
, 0, WINED3DTSS_COLORARG2
, &colorarg2
);
2500 wined3d_device_get_texture_stage_state(This
->wined3d_device
, 0, WINED3DTSS_ALPHAOP
, &alphaop
);
2501 wined3d_device_get_texture_stage_state(This
->wined3d_device
, 0, WINED3DTSS_ALPHAARG1
, &alphaarg1
);
2502 wined3d_device_get_texture_stage_state(This
->wined3d_device
, 0, WINED3DTSS_ALPHAARG2
, &alphaarg2
);
2504 if (colorop
== WINED3DTOP_SELECTARG1
&& colorarg1
== WINED3DTA_TEXTURE
&&
2505 alphaop
== WINED3DTOP_SELECTARG1
&& alphaarg1
== WINED3DTA_TEXTURE
)
2507 *lpdwRenderState
= D3DTBLEND_DECAL
;
2509 else if (colorop
== WINED3DTOP_SELECTARG1
&& colorarg1
== WINED3DTA_TEXTURE
&&
2510 alphaop
== WINED3DTOP_MODULATE
&& alphaarg1
== WINED3DTA_TEXTURE
&& alphaarg2
== WINED3DTA_CURRENT
)
2512 *lpdwRenderState
= D3DTBLEND_DECALALPHA
;
2514 else if (colorop
== WINED3DTOP_MODULATE
&& colorarg1
== WINED3DTA_TEXTURE
&& colorarg2
== WINED3DTA_CURRENT
&&
2515 alphaop
== WINED3DTOP_MODULATE
&& alphaarg1
== WINED3DTA_TEXTURE
&& alphaarg2
== WINED3DTA_CURRENT
)
2517 *lpdwRenderState
= D3DTBLEND_MODULATEALPHA
;
2521 struct wined3d_texture
*tex
= NULL
;
2523 BOOL tex_alpha
= FALSE
;
2524 DDPIXELFORMAT ddfmt
;
2526 hr
= wined3d_device_get_texture(This
->wined3d_device
, 0, &tex
);
2528 if(hr
== WINED3D_OK
&& tex
)
2530 struct wined3d_resource
*sub_resource
;
2532 if ((sub_resource
= wined3d_texture_get_sub_resource(tex
, 0)))
2534 struct wined3d_resource_desc desc
;
2536 wined3d_resource_get_desc(sub_resource
, &desc
);
2537 ddfmt
.dwSize
= sizeof(ddfmt
);
2538 PixelFormat_WineD3DtoDD(&ddfmt
, desc
.format
);
2539 if (ddfmt
.u5
.dwRGBAlphaBitMask
) tex_alpha
= TRUE
;
2542 wined3d_texture_decref(tex
);
2545 if (!(colorop
== WINED3DTOP_MODULATE
&& colorarg1
== WINED3DTA_TEXTURE
&& colorarg2
== WINED3DTA_CURRENT
&&
2546 alphaop
== (tex_alpha
? WINED3DTOP_SELECTARG1
: WINED3DTOP_SELECTARG2
) &&
2547 alphaarg1
== WINED3DTA_TEXTURE
&& alphaarg2
== WINED3DTA_CURRENT
))
2549 ERR("Unexpected texture stage state setup, returning D3DTBLEND_MODULATE - likely erroneous\n");
2552 *lpdwRenderState
= D3DTBLEND_MODULATE
;
2555 wined3d_mutex_unlock();
2561 return IDirect3DDevice7_GetRenderState(&This
->IDirect3DDevice7_iface
, dwRenderStateType
, lpdwRenderState
);
2565 static HRESULT WINAPI
IDirect3DDeviceImpl_2_GetRenderState(IDirect3DDevice2
*iface
,
2566 D3DRENDERSTATETYPE dwRenderStateType
, DWORD
*lpdwRenderState
)
2568 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
2570 TRACE("iface %p, state %#x, value %p.\n", iface
, dwRenderStateType
, lpdwRenderState
);
2572 return IDirect3DDevice3_GetRenderState(&This
->IDirect3DDevice3_iface
,
2573 dwRenderStateType
, lpdwRenderState
);
2576 /*****************************************************************************
2577 * IDirect3DDevice7::SetRenderState
2579 * Sets a render state. The possible render states are defined in
2580 * include/d3dtypes.h
2582 * Version 2, 3 and 7
2585 * RenderStateType: State to set
2586 * Value: Value to assign to that state
2589 * D3D_OK on success,
2590 * for details see IWineD3DDevice::SetRenderState
2592 *****************************************************************************/
2594 IDirect3DDeviceImpl_7_SetRenderState(IDirect3DDevice7
*iface
,
2595 D3DRENDERSTATETYPE RenderStateType
,
2598 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
2601 TRACE("iface %p, state %#x, value %#x.\n", iface
, RenderStateType
, Value
);
2603 wined3d_mutex_lock();
2604 /* Some render states need special care */
2605 switch(RenderStateType
)
2608 * The ddraw texture filter mapping works like this:
2609 * D3DFILTER_NEAREST Point min/mag, no mip
2610 * D3DFILTER_MIPNEAREST Point min/mag, point mip
2611 * D3DFILTER_LINEARMIPNEAREST: Point min/mag, linear mip
2613 * D3DFILTER_LINEAR Linear min/mag, no mip
2614 * D3DFILTER_MIPLINEAR Linear min/mag, point mip
2615 * D3DFILTER_LINEARMIPLINEAR Linear min/mag, linear mip
2617 * This is the opposite of the GL naming convention,
2618 * D3DFILTER_LINEARMIPNEAREST corresponds to GL_NEAREST_MIPMAP_LINEAR.
2620 case D3DRENDERSTATE_TEXTUREMAG
:
2622 WINED3DTEXTUREFILTERTYPE tex_mag
;
2626 case D3DFILTER_NEAREST
:
2627 case D3DFILTER_MIPNEAREST
:
2628 case D3DFILTER_LINEARMIPNEAREST
:
2629 tex_mag
= WINED3DTEXF_POINT
;
2631 case D3DFILTER_LINEAR
:
2632 case D3DFILTER_MIPLINEAR
:
2633 case D3DFILTER_LINEARMIPLINEAR
:
2634 tex_mag
= WINED3DTEXF_LINEAR
;
2637 tex_mag
= WINED3DTEXF_POINT
;
2638 ERR("Unhandled texture mag %d !\n",Value
);
2642 hr
= wined3d_device_set_sampler_state(This
->wined3d_device
, 0, WINED3DSAMP_MAGFILTER
, tex_mag
);
2646 case D3DRENDERSTATE_TEXTUREMIN
:
2648 WINED3DTEXTUREFILTERTYPE tex_min
;
2649 WINED3DTEXTUREFILTERTYPE tex_mip
;
2651 switch ((D3DTEXTUREFILTER
) Value
)
2653 case D3DFILTER_NEAREST
:
2654 tex_min
= WINED3DTEXF_POINT
;
2655 tex_mip
= WINED3DTEXF_NONE
;
2657 case D3DFILTER_LINEAR
:
2658 tex_min
= WINED3DTEXF_LINEAR
;
2659 tex_mip
= WINED3DTEXF_NONE
;
2661 case D3DFILTER_MIPNEAREST
:
2662 tex_min
= WINED3DTEXF_POINT
;
2663 tex_mip
= WINED3DTEXF_POINT
;
2665 case D3DFILTER_MIPLINEAR
:
2666 tex_min
= WINED3DTEXF_LINEAR
;
2667 tex_mip
= WINED3DTEXF_POINT
;
2669 case D3DFILTER_LINEARMIPNEAREST
:
2670 tex_min
= WINED3DTEXF_POINT
;
2671 tex_mip
= WINED3DTEXF_LINEAR
;
2673 case D3DFILTER_LINEARMIPLINEAR
:
2674 tex_min
= WINED3DTEXF_LINEAR
;
2675 tex_mip
= WINED3DTEXF_LINEAR
;
2679 ERR("Unhandled texture min %d !\n",Value
);
2680 tex_min
= WINED3DTEXF_POINT
;
2681 tex_mip
= WINED3DTEXF_NONE
;
2685 wined3d_device_set_sampler_state(This
->wined3d_device
,
2686 0, WINED3DSAMP_MIPFILTER
, tex_mip
);
2687 hr
= wined3d_device_set_sampler_state(This
->wined3d_device
,
2688 0, WINED3DSAMP_MINFILTER
, tex_min
);
2692 case D3DRENDERSTATE_TEXTUREADDRESS
:
2693 wined3d_device_set_sampler_state(This
->wined3d_device
,
2694 0, WINED3DSAMP_ADDRESSV
, Value
);
2696 case D3DRENDERSTATE_TEXTUREADDRESSU
:
2697 hr
= wined3d_device_set_sampler_state(This
->wined3d_device
,
2698 0, WINED3DSAMP_ADDRESSU
, Value
);
2700 case D3DRENDERSTATE_TEXTUREADDRESSV
:
2701 hr
= wined3d_device_set_sampler_state(This
->wined3d_device
,
2702 0, WINED3DSAMP_ADDRESSV
, Value
);
2705 case D3DRENDERSTATE_BORDERCOLOR
:
2706 /* This should probably just forward to the corresponding sampler
2707 * state. Needs tests. */
2708 FIXME("Unhandled render state D3DRENDERSTATE_BORDERCOLOR.\n");
2712 case D3DRENDERSTATE_TEXTUREHANDLE
:
2713 case D3DRENDERSTATE_TEXTUREMAPBLEND
:
2714 WARN("Render state %#x is invalid in d3d7.\n", RenderStateType
);
2715 hr
= DDERR_INVALIDPARAMS
;
2718 case D3DRENDERSTATE_ZBIAS
:
2719 hr
= wined3d_device_set_render_state(This
->wined3d_device
, WINED3DRS_DEPTHBIAS
, Value
);
2723 if (RenderStateType
>= D3DRENDERSTATE_STIPPLEPATTERN00
2724 && RenderStateType
<= D3DRENDERSTATE_STIPPLEPATTERN31
)
2726 FIXME("Unhandled stipple pattern render state (%#x).\n",
2732 hr
= wined3d_device_set_render_state(This
->wined3d_device
, RenderStateType
, Value
);
2735 wined3d_mutex_unlock();
2740 static HRESULT WINAPI
2741 IDirect3DDeviceImpl_7_SetRenderState_FPUSetup(IDirect3DDevice7
*iface
,
2742 D3DRENDERSTATETYPE RenderStateType
,
2745 return IDirect3DDeviceImpl_7_SetRenderState(iface
, RenderStateType
, Value
);
2748 static HRESULT WINAPI
2749 IDirect3DDeviceImpl_7_SetRenderState_FPUPreserve(IDirect3DDevice7
*iface
,
2750 D3DRENDERSTATETYPE RenderStateType
,
2756 old_fpucw
= d3d_fpu_setup();
2757 hr
= IDirect3DDeviceImpl_7_SetRenderState(iface
, RenderStateType
, Value
);
2758 set_fpu_control_word(old_fpucw
);
2763 static HRESULT WINAPI
2764 IDirect3DDeviceImpl_3_SetRenderState(IDirect3DDevice3
*iface
,
2765 D3DRENDERSTATETYPE RenderStateType
,
2768 /* Note about D3DRENDERSTATE_TEXTUREMAPBLEND implementation: most of values
2769 for this state can be directly mapped to texture stage colorop and alphaop, but
2770 D3DTBLEND_MODULATE is tricky: it uses alpha from texture when available and alpha
2771 from diffuse otherwise. So changing the texture must be monitored in SetTexture to modify
2772 alphaarg when needed.
2774 Aliens vs Predator 1 depends on accurate D3DTBLEND_MODULATE emulation
2776 Legacy texture blending (TEXTUREMAPBLEND) and texture stage states: directx6 docs state that
2777 TEXTUREMAPBLEND is deprecated, yet can still be used. Games must not use both or results
2778 are undefined. D3DTBLEND_MODULATE mode in particular is dependent on texture pixel format and
2779 requires fixup of stage 0 texture states when texture changes, but this fixup can interfere
2780 with games not using this deprecated state. So a flag 'legacyTextureBlending' has to be kept
2781 in device - TRUE if the app is using TEXTUREMAPBLEND.
2783 Tests show that setting TEXTUREMAPBLEND on native doesn't seem to change values returned by
2784 GetTextureStageState and vice versa. Not so on Wine, but it is 'undefined' anyway so, probably, ok,
2785 unless some broken game will be found that cares. */
2788 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
2790 TRACE("iface %p, state %#x, value %#x.\n", iface
, RenderStateType
, Value
);
2792 wined3d_mutex_lock();
2794 switch(RenderStateType
)
2796 case D3DRENDERSTATE_TEXTUREHANDLE
:
2798 IDirectDrawSurfaceImpl
*surf
;
2802 hr
= wined3d_device_set_texture(This
->wined3d_device
, 0, NULL
);
2806 surf
= ddraw_get_object(&This
->handle_table
, Value
- 1, DDRAW_HANDLE_SURFACE
);
2809 WARN("Invalid texture handle.\n");
2810 hr
= DDERR_INVALIDPARAMS
;
2814 hr
= IDirect3DDevice3_SetTexture(iface
, 0, &surf
->IDirect3DTexture2_iface
);
2818 case D3DRENDERSTATE_TEXTUREMAPBLEND
:
2820 This
->legacyTextureBlending
= TRUE
;
2822 switch ( (D3DTEXTUREBLEND
) Value
)
2824 case D3DTBLEND_MODULATE
:
2826 struct wined3d_texture
*tex
= NULL
;
2827 BOOL tex_alpha
= FALSE
;
2828 DDPIXELFORMAT ddfmt
;
2830 hr
= wined3d_device_get_texture(This
->wined3d_device
, 0, &tex
);
2832 if(hr
== WINED3D_OK
&& tex
)
2834 struct wined3d_resource
*sub_resource
;
2836 if ((sub_resource
= wined3d_texture_get_sub_resource(tex
, 0)))
2838 struct wined3d_resource_desc desc
;
2840 wined3d_resource_get_desc(sub_resource
, &desc
);
2841 ddfmt
.dwSize
= sizeof(ddfmt
);
2842 PixelFormat_WineD3DtoDD(&ddfmt
, desc
.format
);
2843 if (ddfmt
.u5
.dwRGBAlphaBitMask
) tex_alpha
= TRUE
;
2846 wined3d_texture_decref(tex
);
2850 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2851 0, WINED3DTSS_ALPHAOP
, WINED3DTOP_SELECTARG1
);
2853 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2854 0, WINED3DTSS_ALPHAOP
, WINED3DTOP_SELECTARG2
);
2855 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2856 0, WINED3DTSS_ALPHAARG1
, WINED3DTA_TEXTURE
);
2857 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2858 0, WINED3DTSS_ALPHAARG2
, WINED3DTA_CURRENT
);
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_COLOROP
, WINED3DTOP_MODULATE
);
2869 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2870 0, WINED3DTSS_COLOROP
, WINED3DTOP_ADD
);
2871 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2872 0, WINED3DTSS_COLORARG1
, WINED3DTA_TEXTURE
);
2873 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2874 0, WINED3DTSS_COLORARG2
, WINED3DTA_CURRENT
);
2875 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2876 0, WINED3DTSS_ALPHAOP
, WINED3DTOP_SELECTARG2
);
2877 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2878 0, WINED3DTSS_ALPHAARG2
, WINED3DTA_CURRENT
);
2881 case D3DTBLEND_MODULATEALPHA
:
2882 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2883 0, WINED3DTSS_COLORARG1
, WINED3DTA_TEXTURE
);
2884 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2885 0, WINED3DTSS_ALPHAARG1
, WINED3DTA_TEXTURE
);
2886 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2887 0, WINED3DTSS_COLORARG2
, WINED3DTA_CURRENT
);
2888 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2889 0, WINED3DTSS_ALPHAARG2
, WINED3DTA_CURRENT
);
2890 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2891 0, WINED3DTSS_COLOROP
, WINED3DTOP_MODULATE
);
2892 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2893 0, WINED3DTSS_ALPHAOP
, WINED3DTOP_MODULATE
);
2896 case D3DTBLEND_COPY
:
2897 case D3DTBLEND_DECAL
:
2898 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2899 0, WINED3DTSS_COLORARG1
, WINED3DTA_TEXTURE
);
2900 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2901 0, WINED3DTSS_ALPHAARG1
, WINED3DTA_TEXTURE
);
2902 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2903 0, WINED3DTSS_COLOROP
, WINED3DTOP_SELECTARG1
);
2904 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2905 0, WINED3DTSS_ALPHAOP
, WINED3DTOP_SELECTARG1
);
2908 case D3DTBLEND_DECALALPHA
:
2909 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2910 0, WINED3DTSS_COLOROP
, WINED3DTOP_BLENDTEXTUREALPHA
);
2911 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2912 0, WINED3DTSS_COLORARG1
, WINED3DTA_TEXTURE
);
2913 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2914 0, WINED3DTSS_COLORARG2
, WINED3DTA_CURRENT
);
2915 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2916 0, WINED3DTSS_ALPHAOP
, WINED3DTOP_SELECTARG2
);
2917 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2918 0, WINED3DTSS_ALPHAARG2
, WINED3DTA_CURRENT
);
2922 ERR("Unhandled texture environment %d !\n",Value
);
2930 hr
= IDirect3DDevice7_SetRenderState(&This
->IDirect3DDevice7_iface
, RenderStateType
, Value
);
2933 wined3d_mutex_unlock();
2938 static HRESULT WINAPI
IDirect3DDeviceImpl_2_SetRenderState(IDirect3DDevice2
*iface
,
2939 D3DRENDERSTATETYPE RenderStateType
, DWORD Value
)
2941 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
2943 TRACE("iface %p, state %#x, value %#x.\n", iface
, RenderStateType
, Value
);
2945 return IDirect3DDevice3_SetRenderState(&This
->IDirect3DDevice3_iface
, RenderStateType
, Value
);
2948 /*****************************************************************************
2949 * Direct3DDevice3::SetLightState
2951 * Sets a light state for Direct3DDevice3 and Direct3DDevice2. The
2952 * light states are forwarded to Direct3DDevice7 render states
2957 * LightStateType: The light state to change
2958 * Value: The value to assign to that light state
2962 * DDERR_INVALIDPARAMS if the parameters were incorrect
2963 * Also check IDirect3DDevice7::SetRenderState
2965 *****************************************************************************/
2966 static HRESULT WINAPI
2967 IDirect3DDeviceImpl_3_SetLightState(IDirect3DDevice3
*iface
,
2968 D3DLIGHTSTATETYPE LightStateType
,
2971 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
2974 TRACE("iface %p, state %#x, value %#x.\n", iface
, LightStateType
, Value
);
2976 if (!LightStateType
|| (LightStateType
> D3DLIGHTSTATE_COLORVERTEX
))
2978 TRACE("Unexpected Light State Type\n");
2979 return DDERR_INVALIDPARAMS
;
2982 wined3d_mutex_lock();
2983 if (LightStateType
== D3DLIGHTSTATE_MATERIAL
/* 1 */)
2985 IDirect3DMaterialImpl
*m
= ddraw_get_object(&This
->handle_table
, Value
- 1, DDRAW_HANDLE_MATERIAL
);
2988 WARN("Invalid material handle.\n");
2989 wined3d_mutex_unlock();
2990 return DDERR_INVALIDPARAMS
;
2993 TRACE(" activating material %p.\n", m
);
2994 material_activate(m
);
2996 This
->material
= Value
;
2998 else if (LightStateType
== D3DLIGHTSTATE_COLORMODEL
/* 3 */)
3003 ERR("DDCOLOR_MONO should not happen!\n");
3006 /* We are already in this mode */
3007 TRACE("Setting color model to RGB (no-op).\n");
3010 ERR("Unknown color model!\n");
3011 wined3d_mutex_unlock();
3012 return DDERR_INVALIDPARAMS
;
3017 D3DRENDERSTATETYPE rs
;
3018 switch (LightStateType
)
3020 case D3DLIGHTSTATE_AMBIENT
: /* 2 */
3021 rs
= D3DRENDERSTATE_AMBIENT
;
3023 case D3DLIGHTSTATE_FOGMODE
: /* 4 */
3024 rs
= D3DRENDERSTATE_FOGVERTEXMODE
;
3026 case D3DLIGHTSTATE_FOGSTART
: /* 5 */
3027 rs
= D3DRENDERSTATE_FOGSTART
;
3029 case D3DLIGHTSTATE_FOGEND
: /* 6 */
3030 rs
= D3DRENDERSTATE_FOGEND
;
3032 case D3DLIGHTSTATE_FOGDENSITY
: /* 7 */
3033 rs
= D3DRENDERSTATE_FOGDENSITY
;
3035 case D3DLIGHTSTATE_COLORVERTEX
: /* 8 */
3036 rs
= D3DRENDERSTATE_COLORVERTEX
;
3039 ERR("Unknown D3DLIGHTSTATETYPE %d.\n", LightStateType
);
3040 wined3d_mutex_unlock();
3041 return DDERR_INVALIDPARAMS
;
3044 hr
= IDirect3DDevice7_SetRenderState(&This
->IDirect3DDevice7_iface
, rs
, Value
);
3045 wined3d_mutex_unlock();
3048 wined3d_mutex_unlock();
3053 static HRESULT WINAPI
IDirect3DDeviceImpl_2_SetLightState(IDirect3DDevice2
*iface
,
3054 D3DLIGHTSTATETYPE LightStateType
, DWORD Value
)
3056 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
3058 TRACE("iface %p, state %#x, value %#x.\n", iface
, LightStateType
, Value
);
3060 return IDirect3DDevice3_SetLightState(&This
->IDirect3DDevice3_iface
, LightStateType
, Value
);
3063 /*****************************************************************************
3064 * IDirect3DDevice3::GetLightState
3066 * Returns the current setting of a light state. The state is read from
3067 * the Direct3DDevice7 render state.
3072 * LightStateType: The light state to return
3073 * Value: The address to store the light state setting at
3077 * DDDERR_INVALIDPARAMS if the parameters were incorrect
3078 * Also see IDirect3DDevice7::GetRenderState
3080 *****************************************************************************/
3081 static HRESULT WINAPI
3082 IDirect3DDeviceImpl_3_GetLightState(IDirect3DDevice3
*iface
,
3083 D3DLIGHTSTATETYPE LightStateType
,
3086 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
3089 TRACE("iface %p, state %#x, value %p.\n", iface
, LightStateType
, Value
);
3091 if (!LightStateType
|| (LightStateType
> D3DLIGHTSTATE_COLORVERTEX
))
3093 TRACE("Unexpected Light State Type\n");
3094 return DDERR_INVALIDPARAMS
;
3098 return DDERR_INVALIDPARAMS
;
3100 wined3d_mutex_lock();
3101 if (LightStateType
== D3DLIGHTSTATE_MATERIAL
/* 1 */)
3103 *Value
= This
->material
;
3105 else if (LightStateType
== D3DLIGHTSTATE_COLORMODEL
/* 3 */)
3107 *Value
= D3DCOLOR_RGB
;
3111 D3DRENDERSTATETYPE rs
;
3112 switch (LightStateType
)
3114 case D3DLIGHTSTATE_AMBIENT
: /* 2 */
3115 rs
= D3DRENDERSTATE_AMBIENT
;
3117 case D3DLIGHTSTATE_FOGMODE
: /* 4 */
3118 rs
= D3DRENDERSTATE_FOGVERTEXMODE
;
3120 case D3DLIGHTSTATE_FOGSTART
: /* 5 */
3121 rs
= D3DRENDERSTATE_FOGSTART
;
3123 case D3DLIGHTSTATE_FOGEND
: /* 6 */
3124 rs
= D3DRENDERSTATE_FOGEND
;
3126 case D3DLIGHTSTATE_FOGDENSITY
: /* 7 */
3127 rs
= D3DRENDERSTATE_FOGDENSITY
;
3129 case D3DLIGHTSTATE_COLORVERTEX
: /* 8 */
3130 rs
= D3DRENDERSTATE_COLORVERTEX
;
3133 ERR("Unknown D3DLIGHTSTATETYPE %d.\n", LightStateType
);
3134 wined3d_mutex_unlock();
3135 return DDERR_INVALIDPARAMS
;
3138 hr
= IDirect3DDevice7_GetRenderState(&This
->IDirect3DDevice7_iface
, rs
, Value
);
3139 wined3d_mutex_unlock();
3142 wined3d_mutex_unlock();
3147 static HRESULT WINAPI
IDirect3DDeviceImpl_2_GetLightState(IDirect3DDevice2
*iface
,
3148 D3DLIGHTSTATETYPE LightStateType
, DWORD
*Value
)
3150 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
3152 TRACE("iface %p, state %#x, value %p.\n", iface
, LightStateType
, Value
);
3154 return IDirect3DDevice3_GetLightState(&This
->IDirect3DDevice3_iface
, LightStateType
, Value
);
3157 /*****************************************************************************
3158 * IDirect3DDevice7::SetTransform
3160 * Assigns a D3DMATRIX to a transform type. The transform types are defined
3161 * in include/d3dtypes.h.
3162 * The D3DTRANSFORMSTATE_WORLD (=1) is translated to D3DTS_WORLDMATRIX(0)
3163 * (=255) for wined3d, because the 1 transform state was removed in d3d8
3164 * and WineD3D already understands the replacement D3DTS_WORLDMATRIX(0)
3166 * Version 2, 3 and 7
3169 * TransformStateType: transform state to set
3170 * Matrix: Matrix to assign to the state
3174 * DDERR_INVALIDPARAMS if Matrix == NULL
3175 * For details see IWineD3DDevice::SetTransform
3177 *****************************************************************************/
3179 IDirect3DDeviceImpl_7_SetTransform(IDirect3DDevice7
*iface
,
3180 D3DTRANSFORMSTATETYPE TransformStateType
,
3183 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
3184 D3DTRANSFORMSTATETYPE type
;
3187 TRACE("iface %p, state %#x, matrix %p.\n", iface
, TransformStateType
, Matrix
);
3189 switch(TransformStateType
)
3191 case D3DTRANSFORMSTATE_WORLD
: type
= WINED3DTS_WORLDMATRIX(0); break;
3192 case D3DTRANSFORMSTATE_WORLD1
: type
= WINED3DTS_WORLDMATRIX(1); break;
3193 case D3DTRANSFORMSTATE_WORLD2
: type
= WINED3DTS_WORLDMATRIX(2); break;
3194 case D3DTRANSFORMSTATE_WORLD3
: type
= WINED3DTS_WORLDMATRIX(3); break;
3195 default: type
= TransformStateType
;
3199 return DDERR_INVALIDPARAMS
;
3201 /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
3202 wined3d_mutex_lock();
3203 hr
= wined3d_device_set_transform(This
->wined3d_device
, type
, (WINED3DMATRIX
*)Matrix
);
3204 wined3d_mutex_unlock();
3209 static HRESULT WINAPI
3210 IDirect3DDeviceImpl_7_SetTransform_FPUSetup(IDirect3DDevice7
*iface
,
3211 D3DTRANSFORMSTATETYPE TransformStateType
,
3214 return IDirect3DDeviceImpl_7_SetTransform(iface
, TransformStateType
, Matrix
);
3217 static HRESULT WINAPI
3218 IDirect3DDeviceImpl_7_SetTransform_FPUPreserve(IDirect3DDevice7
*iface
,
3219 D3DTRANSFORMSTATETYPE TransformStateType
,
3225 old_fpucw
= d3d_fpu_setup();
3226 hr
= IDirect3DDeviceImpl_7_SetTransform(iface
, TransformStateType
, Matrix
);
3227 set_fpu_control_word(old_fpucw
);
3232 static HRESULT WINAPI
IDirect3DDeviceImpl_3_SetTransform(IDirect3DDevice3
*iface
,
3233 D3DTRANSFORMSTATETYPE TransformStateType
, D3DMATRIX
*D3DMatrix
)
3235 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
3237 TRACE("iface %p, state %#x, matrix %p.\n", iface
, TransformStateType
, D3DMatrix
);
3239 return IDirect3DDevice7_SetTransform(&This
->IDirect3DDevice7_iface
, TransformStateType
, D3DMatrix
);
3242 static HRESULT WINAPI
IDirect3DDeviceImpl_2_SetTransform(IDirect3DDevice2
*iface
,
3243 D3DTRANSFORMSTATETYPE TransformStateType
, D3DMATRIX
*D3DMatrix
)
3245 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
3247 TRACE("iface %p, state %#x, matrix %p.\n", iface
, TransformStateType
, D3DMatrix
);
3249 return IDirect3DDevice7_SetTransform(&This
->IDirect3DDevice7_iface
, TransformStateType
, D3DMatrix
);
3252 /*****************************************************************************
3253 * IDirect3DDevice7::GetTransform
3255 * Returns the matrix assigned to a transform state
3256 * D3DTRANSFORMSTATE_WORLD is translated to D3DTS_WORLDMATRIX(0), see
3260 * TransformStateType: State to read the matrix from
3261 * Matrix: Address to store the matrix at
3265 * DDERR_INVALIDPARAMS if Matrix == NULL
3266 * For details, see IWineD3DDevice::GetTransform
3268 *****************************************************************************/
3270 IDirect3DDeviceImpl_7_GetTransform(IDirect3DDevice7
*iface
,
3271 D3DTRANSFORMSTATETYPE TransformStateType
,
3274 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
3275 D3DTRANSFORMSTATETYPE type
;
3278 TRACE("iface %p, state %#x, matrix %p.\n", iface
, TransformStateType
, Matrix
);
3280 switch(TransformStateType
)
3282 case D3DTRANSFORMSTATE_WORLD
: type
= WINED3DTS_WORLDMATRIX(0); break;
3283 case D3DTRANSFORMSTATE_WORLD1
: type
= WINED3DTS_WORLDMATRIX(1); break;
3284 case D3DTRANSFORMSTATE_WORLD2
: type
= WINED3DTS_WORLDMATRIX(2); break;
3285 case D3DTRANSFORMSTATE_WORLD3
: type
= WINED3DTS_WORLDMATRIX(3); break;
3286 default: type
= TransformStateType
;
3290 return DDERR_INVALIDPARAMS
;
3292 /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
3293 wined3d_mutex_lock();
3294 hr
= wined3d_device_get_transform(This
->wined3d_device
, type
, (WINED3DMATRIX
*)Matrix
);
3295 wined3d_mutex_unlock();
3300 static HRESULT WINAPI
3301 IDirect3DDeviceImpl_7_GetTransform_FPUSetup(IDirect3DDevice7
*iface
,
3302 D3DTRANSFORMSTATETYPE TransformStateType
,
3305 return IDirect3DDeviceImpl_7_GetTransform(iface
, TransformStateType
, Matrix
);
3308 static HRESULT WINAPI
3309 IDirect3DDeviceImpl_7_GetTransform_FPUPreserve(IDirect3DDevice7
*iface
,
3310 D3DTRANSFORMSTATETYPE TransformStateType
,
3316 old_fpucw
= d3d_fpu_setup();
3317 hr
= IDirect3DDeviceImpl_7_GetTransform(iface
, TransformStateType
, Matrix
);
3318 set_fpu_control_word(old_fpucw
);
3323 static HRESULT WINAPI
IDirect3DDeviceImpl_3_GetTransform(IDirect3DDevice3
*iface
,
3324 D3DTRANSFORMSTATETYPE TransformStateType
, D3DMATRIX
*D3DMatrix
)
3326 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
3328 TRACE("iface %p, state %#x, matrix %p.\n", iface
, TransformStateType
, D3DMatrix
);
3330 return IDirect3DDevice7_GetTransform(&This
->IDirect3DDevice7_iface
, TransformStateType
, D3DMatrix
);
3333 static HRESULT WINAPI
IDirect3DDeviceImpl_2_GetTransform(IDirect3DDevice2
*iface
,
3334 D3DTRANSFORMSTATETYPE TransformStateType
, D3DMATRIX
*D3DMatrix
)
3336 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
3338 TRACE("iface %p, state %#x, matrix %p.\n", iface
, TransformStateType
, D3DMatrix
);
3340 return IDirect3DDevice7_GetTransform(&This
->IDirect3DDevice7_iface
, TransformStateType
, D3DMatrix
);
3343 /*****************************************************************************
3344 * IDirect3DDevice7::MultiplyTransform
3346 * Multiplies the already-set transform matrix of a transform state
3347 * with another matrix. For the world matrix, see SetTransform
3349 * Version 2, 3 and 7
3352 * TransformStateType: Transform state to multiply
3353 * D3DMatrix Matrix to multiply with.
3357 * DDERR_INVALIDPARAMS if D3DMatrix is NULL
3358 * For details, see IWineD3DDevice::MultiplyTransform
3360 *****************************************************************************/
3362 IDirect3DDeviceImpl_7_MultiplyTransform(IDirect3DDevice7
*iface
,
3363 D3DTRANSFORMSTATETYPE TransformStateType
,
3364 D3DMATRIX
*D3DMatrix
)
3366 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
3368 D3DTRANSFORMSTATETYPE type
;
3370 TRACE("iface %p, state %#x, matrix %p.\n", iface
, TransformStateType
, D3DMatrix
);
3372 switch(TransformStateType
)
3374 case D3DTRANSFORMSTATE_WORLD
: type
= WINED3DTS_WORLDMATRIX(0); break;
3375 case D3DTRANSFORMSTATE_WORLD1
: type
= WINED3DTS_WORLDMATRIX(1); break;
3376 case D3DTRANSFORMSTATE_WORLD2
: type
= WINED3DTS_WORLDMATRIX(2); break;
3377 case D3DTRANSFORMSTATE_WORLD3
: type
= WINED3DTS_WORLDMATRIX(3); break;
3378 default: type
= TransformStateType
;
3381 /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
3382 wined3d_mutex_lock();
3383 hr
= wined3d_device_multiply_transform(This
->wined3d_device
,
3384 type
, (WINED3DMATRIX
*)D3DMatrix
);
3385 wined3d_mutex_unlock();
3390 static HRESULT WINAPI
3391 IDirect3DDeviceImpl_7_MultiplyTransform_FPUSetup(IDirect3DDevice7
*iface
,
3392 D3DTRANSFORMSTATETYPE TransformStateType
,
3393 D3DMATRIX
*D3DMatrix
)
3395 return IDirect3DDeviceImpl_7_MultiplyTransform(iface
, TransformStateType
, D3DMatrix
);
3398 static HRESULT WINAPI
3399 IDirect3DDeviceImpl_7_MultiplyTransform_FPUPreserve(IDirect3DDevice7
*iface
,
3400 D3DTRANSFORMSTATETYPE TransformStateType
,
3401 D3DMATRIX
*D3DMatrix
)
3406 old_fpucw
= d3d_fpu_setup();
3407 hr
= IDirect3DDeviceImpl_7_MultiplyTransform(iface
, TransformStateType
, D3DMatrix
);
3408 set_fpu_control_word(old_fpucw
);
3413 static HRESULT WINAPI
IDirect3DDeviceImpl_3_MultiplyTransform(IDirect3DDevice3
*iface
,
3414 D3DTRANSFORMSTATETYPE TransformStateType
, D3DMATRIX
*D3DMatrix
)
3416 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
3418 TRACE("iface %p, state %#x, matrix %p.\n", iface
, TransformStateType
, D3DMatrix
);
3420 return IDirect3DDevice7_MultiplyTransform(&This
->IDirect3DDevice7_iface
, TransformStateType
, D3DMatrix
);
3423 static HRESULT WINAPI
IDirect3DDeviceImpl_2_MultiplyTransform(IDirect3DDevice2
*iface
,
3424 D3DTRANSFORMSTATETYPE TransformStateType
, D3DMATRIX
*D3DMatrix
)
3426 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
3428 TRACE("iface %p, state %#x, matrix %p.\n", iface
, TransformStateType
, D3DMatrix
);
3430 return IDirect3DDevice7_MultiplyTransform(&This
->IDirect3DDevice7_iface
, TransformStateType
, D3DMatrix
);
3433 /*****************************************************************************
3434 * IDirect3DDevice7::DrawPrimitive
3436 * Draws primitives based on vertices in an application-provided pointer
3438 * Version 2, 3 and 7. The IDirect3DDevice2 thunk converts the fixed vertex type into
3439 * an FVF format for D3D7
3442 * PrimitiveType: The type of the primitives to draw
3443 * Vertex type: Flexible vertex format vertex description
3444 * Vertices: Pointer to the vertex array
3445 * VertexCount: The number of vertices to draw
3446 * Flags: As usual a few flags
3450 * DDERR_INVALIDPARAMS if Vertices is NULL
3451 * For details, see IWineD3DDevice::DrawPrimitiveUP
3453 *****************************************************************************/
3455 IDirect3DDeviceImpl_7_DrawPrimitive(IDirect3DDevice7
*iface
,
3456 D3DPRIMITIVETYPE PrimitiveType
,
3462 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
3466 TRACE("iface %p, primitive_type %#x, FVF %#x, vertices %p, vertex_count %u, flags %#x.\n",
3467 iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Flags
);
3470 return DDERR_INVALIDPARAMS
;
3472 /* Get the stride */
3473 stride
= get_flexible_vertex_size(VertexType
);
3476 wined3d_mutex_lock();
3477 hr
= wined3d_device_set_vertex_declaration(This
->wined3d_device
, ddraw_find_decl(This
->ddraw
, VertexType
));
3480 wined3d_mutex_unlock();
3484 /* This method translates to the user pointer draw of WineD3D */
3485 wined3d_device_set_primitive_type(This
->wined3d_device
, PrimitiveType
);
3486 hr
= wined3d_device_draw_primitive_up(This
->wined3d_device
, VertexCount
, Vertices
, stride
);
3487 wined3d_mutex_unlock();
3492 static HRESULT WINAPI
3493 IDirect3DDeviceImpl_7_DrawPrimitive_FPUSetup(IDirect3DDevice7
*iface
,
3494 D3DPRIMITIVETYPE PrimitiveType
,
3500 return IDirect3DDeviceImpl_7_DrawPrimitive(iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Flags
);
3503 static HRESULT WINAPI
3504 IDirect3DDeviceImpl_7_DrawPrimitive_FPUPreserve(IDirect3DDevice7
*iface
,
3505 D3DPRIMITIVETYPE PrimitiveType
,
3514 old_fpucw
= d3d_fpu_setup();
3515 hr
= IDirect3DDeviceImpl_7_DrawPrimitive(iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Flags
);
3516 set_fpu_control_word(old_fpucw
);
3521 static HRESULT WINAPI
IDirect3DDeviceImpl_3_DrawPrimitive(IDirect3DDevice3
*iface
,
3522 D3DPRIMITIVETYPE PrimitiveType
, DWORD VertexType
, void *Vertices
, DWORD VertexCount
,
3525 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
3526 TRACE("iface %p, primitive_type %#x, FVF %#x, vertices %p, vertex_count %u, flags %#x.\n",
3527 iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Flags
);
3529 return IDirect3DDevice7_DrawPrimitive(&This
->IDirect3DDevice7_iface
,
3530 PrimitiveType
, VertexType
, Vertices
, VertexCount
, Flags
);
3533 static HRESULT WINAPI
IDirect3DDeviceImpl_2_DrawPrimitive(IDirect3DDevice2
*iface
,
3534 D3DPRIMITIVETYPE PrimitiveType
, D3DVERTEXTYPE VertexType
, void *Vertices
,
3535 DWORD VertexCount
, DWORD Flags
)
3537 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
3540 TRACE("iface %p, primitive_type %#x, vertex_type %#x, vertices %p, vertex_count %u, flags %#x.\n",
3541 iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Flags
);
3545 case D3DVT_VERTEX
: FVF
= D3DFVF_VERTEX
; break;
3546 case D3DVT_LVERTEX
: FVF
= D3DFVF_LVERTEX
; break;
3547 case D3DVT_TLVERTEX
: FVF
= D3DFVF_TLVERTEX
; break;
3549 ERR("Unexpected vertex type %d\n", VertexType
);
3550 return DDERR_INVALIDPARAMS
; /* Should never happen */
3553 return IDirect3DDevice7_DrawPrimitive(&This
->IDirect3DDevice7_iface
,
3554 PrimitiveType
, FVF
, Vertices
, VertexCount
, Flags
);
3557 /*****************************************************************************
3558 * IDirect3DDevice7::DrawIndexedPrimitive
3560 * Draws vertices from an application-provided pointer, based on the index
3561 * numbers in a WORD array.
3563 * Version 2, 3 and 7. The version 7 thunk translates the vertex type into
3564 * an FVF format for D3D7
3567 * PrimitiveType: The primitive type to draw
3568 * VertexType: The FVF vertex description
3569 * Vertices: Pointer to the vertex array
3571 * Indices: Pointer to the index array
3572 * IndexCount: Number of indices = Number of vertices to draw
3573 * Flags: As usual, some flags
3577 * DDERR_INVALIDPARAMS if Vertices or Indices is NULL
3578 * For details, see IWineD3DDevice::DrawIndexedPrimitiveUP
3580 *****************************************************************************/
3582 IDirect3DDeviceImpl_7_DrawIndexedPrimitive(IDirect3DDevice7
*iface
,
3583 D3DPRIMITIVETYPE PrimitiveType
,
3591 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
3594 TRACE("iface %p, primitive_type %#x, FVF %#x, vertices %p, vertex_count %u, indices %p, index_count %u, flags %#x.\n",
3595 iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Indices
, IndexCount
, Flags
);
3597 /* Set the D3DDevice's FVF */
3598 wined3d_mutex_lock();
3599 hr
= wined3d_device_set_vertex_declaration(This
->wined3d_device
, ddraw_find_decl(This
->ddraw
, VertexType
));
3602 ERR(" (%p) Setting the FVF failed, hr = %x!\n", This
, hr
);
3603 wined3d_mutex_unlock();
3607 wined3d_device_set_primitive_type(This
->wined3d_device
, PrimitiveType
);
3608 hr
= wined3d_device_draw_indexed_primitive_up(This
->wined3d_device
, IndexCount
, Indices
,
3609 WINED3DFMT_R16_UINT
, Vertices
, get_flexible_vertex_size(VertexType
));
3610 wined3d_mutex_unlock();
3615 static HRESULT WINAPI
3616 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUSetup(IDirect3DDevice7
*iface
,
3617 D3DPRIMITIVETYPE PrimitiveType
,
3625 return IDirect3DDeviceImpl_7_DrawIndexedPrimitive(iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Indices
, IndexCount
, Flags
);
3628 static HRESULT WINAPI
3629 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUPreserve(IDirect3DDevice7
*iface
,
3630 D3DPRIMITIVETYPE PrimitiveType
,
3641 old_fpucw
= d3d_fpu_setup();
3642 hr
= IDirect3DDeviceImpl_7_DrawIndexedPrimitive(iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Indices
, IndexCount
, Flags
);
3643 set_fpu_control_word(old_fpucw
);
3648 static HRESULT WINAPI
IDirect3DDeviceImpl_3_DrawIndexedPrimitive(IDirect3DDevice3
*iface
,
3649 D3DPRIMITIVETYPE PrimitiveType
, DWORD VertexType
, void *Vertices
, DWORD VertexCount
,
3650 WORD
*Indices
, DWORD IndexCount
, DWORD Flags
)
3652 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
3653 TRACE("iface %p, primitive_type %#x, FVF %#x, vertices %p, vertex_count %u, indices %p, index_count %u, flags %#x.\n",
3654 iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Indices
, IndexCount
, Flags
);
3656 return IDirect3DDevice7_DrawIndexedPrimitive(&This
->IDirect3DDevice7_iface
,
3657 PrimitiveType
, VertexType
, Vertices
, VertexCount
, Indices
, IndexCount
, Flags
);
3660 static HRESULT WINAPI
IDirect3DDeviceImpl_2_DrawIndexedPrimitive(IDirect3DDevice2
*iface
,
3661 D3DPRIMITIVETYPE PrimitiveType
, D3DVERTEXTYPE VertexType
, void *Vertices
,
3662 DWORD VertexCount
, WORD
*Indices
, DWORD IndexCount
, DWORD Flags
)
3664 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
3667 TRACE("iface %p, primitive_type %#x, vertex_type %#x, vertices %p, vertex_count %u, indices %p, index_count %u, flags %#x.\n",
3668 iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Indices
, IndexCount
, Flags
);
3672 case D3DVT_VERTEX
: FVF
= D3DFVF_VERTEX
; break;
3673 case D3DVT_LVERTEX
: FVF
= D3DFVF_LVERTEX
; break;
3674 case D3DVT_TLVERTEX
: FVF
= D3DFVF_TLVERTEX
; break;
3676 ERR("Unexpected vertex type %d\n", VertexType
);
3677 return DDERR_INVALIDPARAMS
; /* Should never happen */
3680 return IDirect3DDevice7_DrawIndexedPrimitive(&This
->IDirect3DDevice7_iface
,
3681 PrimitiveType
, FVF
, Vertices
, VertexCount
, Indices
, IndexCount
, Flags
);
3684 /*****************************************************************************
3685 * IDirect3DDevice7::SetClipStatus
3687 * Sets the clip status. This defines things as clipping conditions and
3688 * the extents of the clipping region.
3690 * Version 2, 3 and 7
3696 * D3D_OK because it's a stub
3697 * (DDERR_INVALIDPARAMS if ClipStatus == NULL)
3699 *****************************************************************************/
3700 static HRESULT WINAPI
3701 IDirect3DDeviceImpl_7_SetClipStatus(IDirect3DDevice7
*iface
,
3702 D3DCLIPSTATUS
*ClipStatus
)
3704 FIXME("iface %p, clip_status %p stub!\n", iface
, ClipStatus
);
3706 /* D3DCLIPSTATUS and WINED3DCLIPSTATUS are different. I don't know how to convert them
3707 * Perhaps this needs a new data type and an additional IWineD3DDevice method
3709 /* return IWineD3DDevice_SetClipStatus(This->wineD3DDevice, ClipStatus);*/
3713 static HRESULT WINAPI
IDirect3DDeviceImpl_3_SetClipStatus(IDirect3DDevice3
*iface
,
3714 D3DCLIPSTATUS
*ClipStatus
)
3716 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
3717 TRACE("iface %p, clip_status %p.\n", iface
, ClipStatus
);
3719 return IDirect3DDevice7_SetClipStatus(&This
->IDirect3DDevice7_iface
, ClipStatus
);
3722 static HRESULT WINAPI
IDirect3DDeviceImpl_2_SetClipStatus(IDirect3DDevice2
*iface
,
3723 D3DCLIPSTATUS
*ClipStatus
)
3725 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
3726 TRACE("iface %p, clip_status %p.\n", iface
, ClipStatus
);
3728 return IDirect3DDevice7_SetClipStatus(&This
->IDirect3DDevice7_iface
, ClipStatus
);
3731 /*****************************************************************************
3732 * IDirect3DDevice7::GetClipStatus
3734 * Returns the clip status
3737 * ClipStatus: Address to write the clip status to
3740 * D3D_OK because it's a stub
3742 *****************************************************************************/
3743 static HRESULT WINAPI
3744 IDirect3DDeviceImpl_7_GetClipStatus(IDirect3DDevice7
*iface
,
3745 D3DCLIPSTATUS
*ClipStatus
)
3747 FIXME("iface %p, clip_status %p stub!\n", iface
, ClipStatus
);
3749 /* D3DCLIPSTATUS and WINED3DCLIPSTATUS are different. I don't know how to convert them */
3750 /* return IWineD3DDevice_GetClipStatus(This->wineD3DDevice, ClipStatus);*/
3754 static HRESULT WINAPI
IDirect3DDeviceImpl_3_GetClipStatus(IDirect3DDevice3
*iface
,
3755 D3DCLIPSTATUS
*ClipStatus
)
3757 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
3758 TRACE("iface %p, clip_status %p.\n", iface
, ClipStatus
);
3760 return IDirect3DDevice7_GetClipStatus(&This
->IDirect3DDevice7_iface
, ClipStatus
);
3763 static HRESULT WINAPI
IDirect3DDeviceImpl_2_GetClipStatus(IDirect3DDevice2
*iface
,
3764 D3DCLIPSTATUS
*ClipStatus
)
3766 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
3767 TRACE("iface %p, clip_status %p.\n", iface
, ClipStatus
);
3769 return IDirect3DDevice7_GetClipStatus(&This
->IDirect3DDevice7_iface
, ClipStatus
);
3772 /*****************************************************************************
3773 * IDirect3DDevice::DrawPrimitiveStrided
3775 * Draws vertices described by a D3DDRAWPRIMITIVESTRIDEDDATA structure.
3780 * PrimitiveType: The primitive type to draw
3781 * VertexType: The FVF description of the vertices to draw (for the stride??)
3782 * D3DDrawPrimStrideData: A D3DDRAWPRIMITIVESTRIDEDDATA structure describing
3783 * the vertex data locations
3784 * VertexCount: The number of vertices to draw
3788 * D3D_OK, because it's a stub
3789 * (DDERR_INVALIDPARAMS if D3DDrawPrimStrideData is NULL)
3790 * (For details, see IWineD3DDevice::DrawPrimitiveStrided)
3792 *****************************************************************************/
3794 IDirect3DDeviceImpl_7_DrawPrimitiveStrided(IDirect3DDevice7
*iface
,
3795 D3DPRIMITIVETYPE PrimitiveType
,
3797 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
,
3801 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
3802 WineDirect3DVertexStridedData WineD3DStrided
;
3806 TRACE("iface %p, primitive_type %#x, FVF %#x, strided_data %p, vertex_count %u, flags %#x.\n",
3807 iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Flags
);
3809 memset(&WineD3DStrided
, 0, sizeof(WineD3DStrided
));
3810 /* Get the strided data right. the wined3d structure is a bit bigger
3811 * Watch out: The contents of the strided data are determined by the fvf,
3812 * not by the members set in D3DDrawPrimStrideData. So it's valid
3813 * to have diffuse.lpvData set to 0xdeadbeef if the diffuse flag is
3814 * not set in the fvf.
3816 if(VertexType
& D3DFVF_POSITION_MASK
)
3818 WineD3DStrided
.position
.format
= WINED3DFMT_R32G32B32_FLOAT
;
3819 WineD3DStrided
.position
.lpData
= D3DDrawPrimStrideData
->position
.lpvData
;
3820 WineD3DStrided
.position
.dwStride
= D3DDrawPrimStrideData
->position
.dwStride
;
3821 if (VertexType
& D3DFVF_XYZRHW
)
3823 WineD3DStrided
.position
.format
= WINED3DFMT_R32G32B32A32_FLOAT
;
3824 WineD3DStrided
.position_transformed
= TRUE
;
3826 WineD3DStrided
.position_transformed
= FALSE
;
3829 if(VertexType
& D3DFVF_NORMAL
)
3831 WineD3DStrided
.normal
.format
= WINED3DFMT_R32G32B32_FLOAT
;
3832 WineD3DStrided
.normal
.lpData
= D3DDrawPrimStrideData
->normal
.lpvData
;
3833 WineD3DStrided
.normal
.dwStride
= D3DDrawPrimStrideData
->normal
.dwStride
;
3836 if(VertexType
& D3DFVF_DIFFUSE
)
3838 WineD3DStrided
.diffuse
.format
= WINED3DFMT_B8G8R8A8_UNORM
;
3839 WineD3DStrided
.diffuse
.lpData
= D3DDrawPrimStrideData
->diffuse
.lpvData
;
3840 WineD3DStrided
.diffuse
.dwStride
= D3DDrawPrimStrideData
->diffuse
.dwStride
;
3843 if(VertexType
& D3DFVF_SPECULAR
)
3845 WineD3DStrided
.specular
.format
= WINED3DFMT_B8G8R8A8_UNORM
;
3846 WineD3DStrided
.specular
.lpData
= D3DDrawPrimStrideData
->specular
.lpvData
;
3847 WineD3DStrided
.specular
.dwStride
= D3DDrawPrimStrideData
->specular
.dwStride
;
3850 for( i
= 0; i
< GET_TEXCOUNT_FROM_FVF(VertexType
); i
++)
3852 switch(GET_TEXCOORD_SIZE_FROM_FVF(VertexType
, i
))
3854 case 1: WineD3DStrided
.texCoords
[i
].format
= WINED3DFMT_R32_FLOAT
; break;
3855 case 2: WineD3DStrided
.texCoords
[i
].format
= WINED3DFMT_R32G32_FLOAT
; break;
3856 case 3: WineD3DStrided
.texCoords
[i
].format
= WINED3DFMT_R32G32B32_FLOAT
; break;
3857 case 4: WineD3DStrided
.texCoords
[i
].format
= WINED3DFMT_R32G32B32A32_FLOAT
; break;
3858 default: ERR("Unexpected texture coordinate size %d\n",
3859 GET_TEXCOORD_SIZE_FROM_FVF(VertexType
, i
));
3861 WineD3DStrided
.texCoords
[i
].lpData
= D3DDrawPrimStrideData
->textureCoords
[i
].lpvData
;
3862 WineD3DStrided
.texCoords
[i
].dwStride
= D3DDrawPrimStrideData
->textureCoords
[i
].dwStride
;
3865 /* WineD3D doesn't need the FVF here */
3866 wined3d_mutex_lock();
3867 wined3d_device_set_primitive_type(This
->wined3d_device
, PrimitiveType
);
3868 hr
= wined3d_device_draw_primitive_strided(This
->wined3d_device
, VertexCount
, &WineD3DStrided
);
3869 wined3d_mutex_unlock();
3874 static HRESULT WINAPI
3875 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUSetup(IDirect3DDevice7
*iface
,
3876 D3DPRIMITIVETYPE PrimitiveType
,
3878 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
,
3882 return IDirect3DDeviceImpl_7_DrawPrimitiveStrided(iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Flags
);
3885 static HRESULT WINAPI
3886 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUPreserve(IDirect3DDevice7
*iface
,
3887 D3DPRIMITIVETYPE PrimitiveType
,
3889 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
,
3896 old_fpucw
= d3d_fpu_setup();
3897 hr
= IDirect3DDeviceImpl_7_DrawPrimitiveStrided(iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Flags
);
3898 set_fpu_control_word(old_fpucw
);
3903 static HRESULT WINAPI
IDirect3DDeviceImpl_3_DrawPrimitiveStrided(IDirect3DDevice3
*iface
,
3904 D3DPRIMITIVETYPE PrimitiveType
, DWORD VertexType
,
3905 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
, DWORD VertexCount
, DWORD Flags
)
3907 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
3909 TRACE("iface %p, primitive_type %#x, FVF %#x, strided_data %p, vertex_count %u, flags %#x.\n",
3910 iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Flags
);
3912 return IDirect3DDevice7_DrawPrimitiveStrided(&This
->IDirect3DDevice7_iface
,
3913 PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Flags
);
3916 /*****************************************************************************
3917 * IDirect3DDevice7::DrawIndexedPrimitiveStrided
3919 * Draws primitives specified by strided data locations based on indices
3927 * D3D_OK, because it's a stub
3928 * (DDERR_INVALIDPARAMS if D3DDrawPrimStrideData is NULL)
3929 * (DDERR_INVALIDPARAMS if Indices is NULL)
3930 * (For more details, see IWineD3DDevice::DrawIndexedPrimitiveStrided)
3932 *****************************************************************************/
3934 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided(IDirect3DDevice7
*iface
,
3935 D3DPRIMITIVETYPE PrimitiveType
,
3937 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
,
3943 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
3944 WineDirect3DVertexStridedData WineD3DStrided
;
3948 TRACE("iface %p, primitive_type %#x, FVF %#x, strided_data %p, vertex_count %u, indices %p, index_count %u, flags %#x.\n",
3949 iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Indices
, IndexCount
, Flags
);
3951 memset(&WineD3DStrided
, 0, sizeof(WineD3DStrided
));
3952 /* Get the strided data right. the wined3d structure is a bit bigger
3953 * Watch out: The contents of the strided data are determined by the fvf,
3954 * not by the members set in D3DDrawPrimStrideData. So it's valid
3955 * to have diffuse.lpvData set to 0xdeadbeef if the diffuse flag is
3956 * not set in the fvf.
3958 if(VertexType
& D3DFVF_POSITION_MASK
)
3960 WineD3DStrided
.position
.format
= WINED3DFMT_R32G32B32_FLOAT
;
3961 WineD3DStrided
.position
.lpData
= D3DDrawPrimStrideData
->position
.lpvData
;
3962 WineD3DStrided
.position
.dwStride
= D3DDrawPrimStrideData
->position
.dwStride
;
3963 if (VertexType
& D3DFVF_XYZRHW
)
3965 WineD3DStrided
.position
.format
= WINED3DFMT_R32G32B32A32_FLOAT
;
3966 WineD3DStrided
.position_transformed
= TRUE
;
3968 WineD3DStrided
.position_transformed
= FALSE
;
3971 if(VertexType
& D3DFVF_NORMAL
)
3973 WineD3DStrided
.normal
.format
= WINED3DFMT_R32G32B32_FLOAT
;
3974 WineD3DStrided
.normal
.lpData
= D3DDrawPrimStrideData
->normal
.lpvData
;
3975 WineD3DStrided
.normal
.dwStride
= D3DDrawPrimStrideData
->normal
.dwStride
;
3978 if(VertexType
& D3DFVF_DIFFUSE
)
3980 WineD3DStrided
.diffuse
.format
= WINED3DFMT_B8G8R8A8_UNORM
;
3981 WineD3DStrided
.diffuse
.lpData
= D3DDrawPrimStrideData
->diffuse
.lpvData
;
3982 WineD3DStrided
.diffuse
.dwStride
= D3DDrawPrimStrideData
->diffuse
.dwStride
;
3985 if(VertexType
& D3DFVF_SPECULAR
)
3987 WineD3DStrided
.specular
.format
= WINED3DFMT_B8G8R8A8_UNORM
;
3988 WineD3DStrided
.specular
.lpData
= D3DDrawPrimStrideData
->specular
.lpvData
;
3989 WineD3DStrided
.specular
.dwStride
= D3DDrawPrimStrideData
->specular
.dwStride
;
3992 for( i
= 0; i
< GET_TEXCOUNT_FROM_FVF(VertexType
); i
++)
3994 switch(GET_TEXCOORD_SIZE_FROM_FVF(VertexType
, i
))
3996 case 1: WineD3DStrided
.texCoords
[i
].format
= WINED3DFMT_R32_FLOAT
; break;
3997 case 2: WineD3DStrided
.texCoords
[i
].format
= WINED3DFMT_R32G32_FLOAT
; break;
3998 case 3: WineD3DStrided
.texCoords
[i
].format
= WINED3DFMT_R32G32B32_FLOAT
; break;
3999 case 4: WineD3DStrided
.texCoords
[i
].format
= WINED3DFMT_R32G32B32A32_FLOAT
; break;
4000 default: ERR("Unexpected texture coordinate size %d\n",
4001 GET_TEXCOORD_SIZE_FROM_FVF(VertexType
, i
));
4003 WineD3DStrided
.texCoords
[i
].lpData
= D3DDrawPrimStrideData
->textureCoords
[i
].lpvData
;
4004 WineD3DStrided
.texCoords
[i
].dwStride
= D3DDrawPrimStrideData
->textureCoords
[i
].dwStride
;
4007 /* WineD3D doesn't need the FVF here */
4008 wined3d_mutex_lock();
4009 wined3d_device_set_primitive_type(This
->wined3d_device
, PrimitiveType
);
4010 hr
= wined3d_device_draw_indexed_primitive_strided(This
->wined3d_device
,
4011 IndexCount
, &WineD3DStrided
, VertexCount
, Indices
, WINED3DFMT_R16_UINT
);
4012 wined3d_mutex_unlock();
4017 static HRESULT WINAPI
4018 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUSetup(IDirect3DDevice7
*iface
,
4019 D3DPRIMITIVETYPE PrimitiveType
,
4021 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
,
4027 return IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided(iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Indices
, IndexCount
, Flags
);
4030 static HRESULT WINAPI
4031 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUPreserve(IDirect3DDevice7
*iface
,
4032 D3DPRIMITIVETYPE PrimitiveType
,
4034 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
,
4043 old_fpucw
= d3d_fpu_setup();
4044 hr
= IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided(iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Indices
, IndexCount
, Flags
);
4045 set_fpu_control_word(old_fpucw
);
4050 static HRESULT WINAPI
IDirect3DDeviceImpl_3_DrawIndexedPrimitiveStrided(IDirect3DDevice3
*iface
,
4051 D3DPRIMITIVETYPE PrimitiveType
, DWORD VertexType
,
4052 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
, DWORD VertexCount
, WORD
*Indices
,
4053 DWORD IndexCount
, DWORD Flags
)
4055 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
4057 TRACE("iface %p, primitive_type %#x, FVF %#x, strided_data %p, vertex_count %u, indices %p, index_count %u, flags %#x.\n",
4058 iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Indices
, IndexCount
, Flags
);
4060 return IDirect3DDevice7_DrawIndexedPrimitiveStrided(&This
->IDirect3DDevice7_iface
,
4061 PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Indices
, IndexCount
, Flags
);
4064 /*****************************************************************************
4065 * IDirect3DDevice7::DrawPrimitiveVB
4067 * Draws primitives from a vertex buffer to the screen.
4072 * PrimitiveType: Type of primitive to be rendered.
4073 * D3DVertexBuf: Source Vertex Buffer
4074 * StartVertex: Index of the first vertex from the buffer to be rendered
4075 * NumVertices: Number of vertices to be rendered
4076 * Flags: Can be D3DDP_WAIT to wait until rendering has finished
4080 * DDERR_INVALIDPARAMS if D3DVertexBuf is NULL
4082 *****************************************************************************/
4084 IDirect3DDeviceImpl_7_DrawPrimitiveVB(IDirect3DDevice7
*iface
,
4085 D3DPRIMITIVETYPE PrimitiveType
,
4086 IDirect3DVertexBuffer7
*D3DVertexBuf
,
4091 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
4092 IDirect3DVertexBufferImpl
*vb
= unsafe_impl_from_IDirect3DVertexBuffer7(D3DVertexBuf
);
4096 TRACE("iface %p, primitive_type %#x, vb %p, start_vertex %u, vertex_count %u, flags %#x.\n",
4097 iface
, PrimitiveType
, D3DVertexBuf
, StartVertex
, NumVertices
, Flags
);
4102 ERR("(%p) No Vertex buffer specified\n", This
);
4103 return DDERR_INVALIDPARAMS
;
4105 stride
= get_flexible_vertex_size(vb
->fvf
);
4107 wined3d_mutex_lock();
4108 hr
= wined3d_device_set_vertex_declaration(This
->wined3d_device
, vb
->wineD3DVertexDeclaration
);
4111 ERR(" (%p) Setting the FVF failed, hr = %x!\n", This
, hr
);
4112 wined3d_mutex_unlock();
4116 /* Set the vertex stream source */
4117 hr
= wined3d_device_set_stream_source(This
->wined3d_device
, 0, vb
->wineD3DVertexBuffer
, 0, stride
);
4120 ERR("(%p) IDirect3DDevice::SetStreamSource failed with hr = %08x\n", This
, hr
);
4121 wined3d_mutex_unlock();
4125 /* Now draw the primitives */
4126 wined3d_device_set_primitive_type(This
->wined3d_device
, PrimitiveType
);
4127 hr
= wined3d_device_draw_primitive(This
->wined3d_device
, StartVertex
, NumVertices
);
4128 wined3d_mutex_unlock();
4133 static HRESULT WINAPI
4134 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUSetup(IDirect3DDevice7
*iface
,
4135 D3DPRIMITIVETYPE PrimitiveType
,
4136 IDirect3DVertexBuffer7
*D3DVertexBuf
,
4141 return IDirect3DDeviceImpl_7_DrawPrimitiveVB(iface
, PrimitiveType
, D3DVertexBuf
, StartVertex
, NumVertices
, Flags
);
4144 static HRESULT WINAPI
4145 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUPreserve(IDirect3DDevice7
*iface
,
4146 D3DPRIMITIVETYPE PrimitiveType
,
4147 IDirect3DVertexBuffer7
*D3DVertexBuf
,
4155 old_fpucw
= d3d_fpu_setup();
4156 hr
= IDirect3DDeviceImpl_7_DrawPrimitiveVB(iface
, PrimitiveType
, D3DVertexBuf
, StartVertex
, NumVertices
, Flags
);
4157 set_fpu_control_word(old_fpucw
);
4162 static HRESULT WINAPI
IDirect3DDeviceImpl_3_DrawPrimitiveVB(IDirect3DDevice3
*iface
,
4163 D3DPRIMITIVETYPE PrimitiveType
, IDirect3DVertexBuffer
*D3DVertexBuf
, DWORD StartVertex
,
4164 DWORD NumVertices
, DWORD Flags
)
4166 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
4167 IDirect3DVertexBufferImpl
*vb
= unsafe_impl_from_IDirect3DVertexBuffer(D3DVertexBuf
);
4169 TRACE("iface %p, primitive_type %#x, vb %p, start_vertex %u, vertex_count %u, flags %#x.\n",
4170 iface
, PrimitiveType
, D3DVertexBuf
, StartVertex
, NumVertices
, Flags
);
4172 return IDirect3DDevice7_DrawPrimitiveVB(&This
->IDirect3DDevice7_iface
,
4173 PrimitiveType
, &vb
->IDirect3DVertexBuffer7_iface
, StartVertex
, NumVertices
, Flags
);
4177 /*****************************************************************************
4178 * IDirect3DDevice7::DrawIndexedPrimitiveVB
4180 * Draws primitives from a vertex buffer to the screen
4183 * PrimitiveType: Type of primitive to be rendered.
4184 * D3DVertexBuf: Source Vertex Buffer
4185 * StartVertex: Index of the first vertex from the buffer to be rendered
4186 * NumVertices: Number of vertices to be rendered
4187 * Indices: Array of DWORDs used to index into the Vertices
4188 * IndexCount: Number of indices in Indices
4189 * Flags: Can be D3DDP_WAIT to wait until rendering has finished
4193 *****************************************************************************/
4195 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB(IDirect3DDevice7
*iface
,
4196 D3DPRIMITIVETYPE PrimitiveType
,
4197 IDirect3DVertexBuffer7
*D3DVertexBuf
,
4204 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
4205 IDirect3DVertexBufferImpl
*vb
= unsafe_impl_from_IDirect3DVertexBuffer7(D3DVertexBuf
);
4206 DWORD stride
= get_flexible_vertex_size(vb
->fvf
);
4207 struct wined3d_resource
*wined3d_resource
;
4208 struct wined3d_resource_desc desc
;
4209 WORD
*LockedIndices
;
4212 TRACE("iface %p, primitive_type %#x, vb %p, start_vertex %u, vertex_count %u, indices %p, index_count %u, flags %#x.\n",
4213 iface
, PrimitiveType
, D3DVertexBuf
, StartVertex
, NumVertices
, Indices
, IndexCount
, Flags
);
4216 * 1) Upload the Indices to the index buffer
4217 * 2) Set the index source
4218 * 3) Set the Vertex Buffer as the Stream source
4219 * 4) Call IWineD3DDevice::DrawIndexedPrimitive
4222 wined3d_mutex_lock();
4224 hr
= wined3d_device_set_vertex_declaration(This
->wined3d_device
, vb
->wineD3DVertexDeclaration
);
4227 ERR(" (%p) Setting the FVF failed, hr = %x!\n", This
, hr
);
4228 wined3d_mutex_unlock();
4232 /* check that the buffer is large enough to hold the indices,
4233 * reallocate if necessary. */
4234 wined3d_resource
= wined3d_buffer_get_resource(This
->indexbuffer
);
4235 wined3d_resource_get_desc(wined3d_resource
, &desc
);
4236 if (desc
.size
< IndexCount
* sizeof(WORD
))
4238 UINT size
= max(desc
.size
* 2, IndexCount
* sizeof(WORD
));
4239 struct wined3d_buffer
*buffer
;
4241 TRACE("Growing index buffer to %u bytes\n", size
);
4243 hr
= wined3d_buffer_create_ib(This
->wined3d_device
, size
, WINED3DUSAGE_DYNAMIC
/* Usage */,
4244 WINED3DPOOL_DEFAULT
, NULL
, &ddraw_null_wined3d_parent_ops
, &buffer
);
4247 ERR("(%p) IWineD3DDevice::CreateIndexBuffer failed with hr = %08x\n", This
, hr
);
4248 wined3d_mutex_unlock();
4252 wined3d_buffer_decref(This
->indexbuffer
);
4253 This
->indexbuffer
= buffer
;
4256 /* Copy the index stream into the index buffer. A new IWineD3DDevice
4257 * method could be created which takes an user pointer containing the
4258 * indices or a SetData-Method for the index buffer, which overrides the
4259 * index buffer data with our pointer. */
4260 hr
= wined3d_buffer_map(This
->indexbuffer
, 0, IndexCount
* sizeof(WORD
),
4261 (BYTE
**)&LockedIndices
, 0);
4264 ERR("Failed to map buffer, hr %#x.\n", hr
);
4265 wined3d_mutex_unlock();
4268 memcpy(LockedIndices
, Indices
, IndexCount
* sizeof(WORD
));
4269 wined3d_buffer_unmap(This
->indexbuffer
);
4271 /* Set the index stream */
4272 wined3d_device_set_base_vertex_index(This
->wined3d_device
, StartVertex
);
4273 hr
= wined3d_device_set_index_buffer(This
->wined3d_device
, This
->indexbuffer
, WINED3DFMT_R16_UINT
);
4275 /* Set the vertex stream source */
4276 hr
= wined3d_device_set_stream_source(This
->wined3d_device
, 0, vb
->wineD3DVertexBuffer
, 0, stride
);
4279 ERR("(%p) IDirect3DDevice::SetStreamSource failed with hr = %08x\n", This
, hr
);
4280 wined3d_mutex_unlock();
4285 wined3d_device_set_primitive_type(This
->wined3d_device
, PrimitiveType
);
4286 hr
= wined3d_device_draw_indexed_primitive(This
->wined3d_device
, 0, IndexCount
);
4288 wined3d_mutex_unlock();
4293 static HRESULT WINAPI
4294 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUSetup(IDirect3DDevice7
*iface
,
4295 D3DPRIMITIVETYPE PrimitiveType
,
4296 IDirect3DVertexBuffer7
*D3DVertexBuf
,
4303 return IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB(iface
, PrimitiveType
, D3DVertexBuf
, StartVertex
, NumVertices
, Indices
, IndexCount
, Flags
);
4306 static HRESULT WINAPI
4307 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUPreserve(IDirect3DDevice7
*iface
,
4308 D3DPRIMITIVETYPE PrimitiveType
,
4309 IDirect3DVertexBuffer7
*D3DVertexBuf
,
4319 old_fpucw
= d3d_fpu_setup();
4320 hr
= IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB(iface
, PrimitiveType
, D3DVertexBuf
, StartVertex
, NumVertices
, Indices
, IndexCount
, Flags
);
4321 set_fpu_control_word(old_fpucw
);
4326 static HRESULT WINAPI
IDirect3DDeviceImpl_3_DrawIndexedPrimitiveVB(IDirect3DDevice3
*iface
,
4327 D3DPRIMITIVETYPE PrimitiveType
, IDirect3DVertexBuffer
*D3DVertexBuf
, WORD
*Indices
,
4328 DWORD IndexCount
, DWORD Flags
)
4330 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
4331 IDirect3DVertexBufferImpl
*vb
= unsafe_impl_from_IDirect3DVertexBuffer(D3DVertexBuf
);
4333 TRACE("iface %p, primitive_type %#x, vb %p, indices %p, index_count %u, flags %#x.\n",
4334 iface
, PrimitiveType
, D3DVertexBuf
, Indices
, IndexCount
, Flags
);
4336 return IDirect3DDevice7_DrawIndexedPrimitiveVB(&This
->IDirect3DDevice7_iface
,
4337 PrimitiveType
, &vb
->IDirect3DVertexBuffer7_iface
, 0, IndexCount
, Indices
, IndexCount
,
4341 /*****************************************************************************
4342 * IDirect3DDevice7::ComputeSphereVisibility
4344 * Calculates the visibility of spheres in the current viewport. The spheres
4345 * are passed in the Centers and Radii arrays, the results are passed back
4346 * in the ReturnValues array. Return values are either completely visible,
4347 * partially visible or completely invisible.
4348 * The return value consist of a combination of D3DCLIP_* flags, or it's
4349 * 0 if the sphere is completely visible(according to the SDK, not checked)
4354 * Centers: Array containing the sphere centers
4355 * Radii: Array containing the sphere radii
4356 * NumSpheres: The number of centers and radii in the arrays
4358 * ReturnValues: Array to write the results to
4362 * (DDERR_INVALIDPARAMS if Centers, Radii or ReturnValues are NULL)
4363 * (D3DERR_INVALIDMATRIX if the combined world, view and proj matrix
4366 *****************************************************************************/
4368 static DWORD
in_plane(UINT plane
, D3DVECTOR normal
, D3DVALUE origin_plane
, D3DVECTOR center
, D3DVALUE radius
)
4370 float distance
, norm
;
4372 norm
= sqrt( normal
.u1
.x
* normal
.u1
.x
+ normal
.u2
.y
* normal
.u2
.y
+ normal
.u3
.z
* normal
.u3
.z
);
4373 distance
= ( origin_plane
+ normal
.u1
.x
* center
.u1
.x
+ normal
.u2
.y
* center
.u2
.y
+ normal
.u3
.z
* center
.u3
.z
) / norm
;
4375 if ( fabs( distance
) < radius
) return D3DSTATUS_CLIPUNIONLEFT
<< plane
;
4376 if ( distance
< -radius
) return (D3DSTATUS_CLIPUNIONLEFT
| D3DSTATUS_CLIPINTERSECTIONLEFT
) << plane
;
4380 static HRESULT WINAPI
4381 IDirect3DDeviceImpl_7_ComputeSphereVisibility(IDirect3DDevice7
*iface
,
4386 DWORD
*ReturnValues
)
4389 D3DVALUE origin_plane
[6];
4394 TRACE("iface %p, centers %p, radii %p, sphere_count %u, flags %#x, return_values %p.\n",
4395 iface
, Centers
, Radii
, NumSpheres
, Flags
, ReturnValues
);
4397 hr
= IDirect3DDeviceImpl_7_GetTransform(iface
, D3DTRANSFORMSTATE_WORLD
, &m
);
4398 if ( hr
!= DD_OK
) return DDERR_INVALIDPARAMS
;
4399 hr
= IDirect3DDeviceImpl_7_GetTransform(iface
, D3DTRANSFORMSTATE_VIEW
, &temp
);
4400 if ( hr
!= DD_OK
) return DDERR_INVALIDPARAMS
;
4401 multiply_matrix(&m
, &temp
, &m
);
4403 hr
= IDirect3DDeviceImpl_7_GetTransform(iface
, D3DTRANSFORMSTATE_PROJECTION
, &temp
);
4404 if ( hr
!= DD_OK
) return DDERR_INVALIDPARAMS
;
4405 multiply_matrix(&m
, &temp
, &m
);
4408 vec
[0].u1
.x
= m
._14
+ m
._11
;
4409 vec
[0].u2
.y
= m
._24
+ m
._21
;
4410 vec
[0].u3
.z
= m
._34
+ m
._31
;
4411 origin_plane
[0] = m
._44
+ m
._41
;
4414 vec
[1].u1
.x
= m
._14
- m
._11
;
4415 vec
[1].u2
.y
= m
._24
- m
._21
;
4416 vec
[1].u3
.z
= m
._34
- m
._31
;
4417 origin_plane
[1] = m
._44
- m
._41
;
4420 vec
[2].u1
.x
= m
._14
- m
._12
;
4421 vec
[2].u2
.y
= m
._24
- m
._22
;
4422 vec
[2].u3
.z
= m
._34
- m
._32
;
4423 origin_plane
[2] = m
._44
- m
._42
;
4426 vec
[3].u1
.x
= m
._14
+ m
._12
;
4427 vec
[3].u2
.y
= m
._24
+ m
._22
;
4428 vec
[3].u3
.z
= m
._34
+ m
._32
;
4429 origin_plane
[3] = m
._44
+ m
._42
;
4432 vec
[4].u1
.x
= m
._13
;
4433 vec
[4].u2
.y
= m
._23
;
4434 vec
[4].u3
.z
= m
._33
;
4435 origin_plane
[4] = m
._43
;
4438 vec
[5].u1
.x
= m
._14
- m
._13
;
4439 vec
[5].u2
.y
= m
._24
- m
._23
;
4440 vec
[5].u3
.z
= m
._34
- m
._33
;
4441 origin_plane
[5] = m
._44
- m
._43
;
4443 for(i
=0; i
<NumSpheres
; i
++)
4445 ReturnValues
[i
] = 0;
4446 for(j
=0; j
<6; j
++) ReturnValues
[i
] |= in_plane(j
, vec
[j
], origin_plane
[j
], Centers
[i
], Radii
[i
]);
4452 static HRESULT WINAPI
IDirect3DDeviceImpl_3_ComputeSphereVisibility(IDirect3DDevice3
*iface
,
4453 D3DVECTOR
*Centers
, D3DVALUE
*Radii
, DWORD NumSpheres
, DWORD Flags
, DWORD
*ReturnValues
)
4455 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
4457 TRACE("iface %p, centers %p, radii %p, sphere_count %u, flags %#x, return_values %p.\n",
4458 iface
, Centers
, Radii
, NumSpheres
, Flags
, ReturnValues
);
4460 return IDirect3DDevice7_ComputeSphereVisibility(&This
->IDirect3DDevice7_iface
,
4461 Centers
, Radii
, NumSpheres
, Flags
, ReturnValues
);
4464 /*****************************************************************************
4465 * IDirect3DDevice7::GetTexture
4467 * Returns the texture interface handle assigned to a texture stage.
4468 * The returned texture is AddRefed. This is taken from old ddraw,
4469 * not checked in Windows.
4474 * Stage: Texture stage to read the texture from
4475 * Texture: Address to store the interface pointer at
4479 * DDERR_INVALIDPARAMS if Texture is NULL
4480 * For details, see IWineD3DDevice::GetTexture
4482 *****************************************************************************/
4484 IDirect3DDeviceImpl_7_GetTexture(IDirect3DDevice7
*iface
,
4486 IDirectDrawSurface7
**Texture
)
4488 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
4489 struct wined3d_texture
*wined3d_texture
;
4492 TRACE("iface %p, stage %u, texture %p.\n", iface
, Stage
, Texture
);
4496 TRACE("Texture == NULL, failing with DDERR_INVALIDPARAMS\n");
4497 return DDERR_INVALIDPARAMS
;
4500 wined3d_mutex_lock();
4501 hr
= wined3d_device_get_texture(This
->wined3d_device
, Stage
, &wined3d_texture
);
4502 if (FAILED(hr
) || !wined3d_texture
)
4505 wined3d_mutex_unlock();
4509 *Texture
= wined3d_texture_get_parent(wined3d_texture
);
4510 IDirectDrawSurface7_AddRef(*Texture
);
4511 wined3d_texture_decref(wined3d_texture
);
4512 wined3d_mutex_unlock();
4517 static HRESULT WINAPI
4518 IDirect3DDeviceImpl_7_GetTexture_FPUSetup(IDirect3DDevice7
*iface
,
4520 IDirectDrawSurface7
**Texture
)
4522 return IDirect3DDeviceImpl_7_GetTexture(iface
, Stage
, Texture
);
4525 static HRESULT WINAPI
4526 IDirect3DDeviceImpl_7_GetTexture_FPUPreserve(IDirect3DDevice7
*iface
,
4528 IDirectDrawSurface7
**Texture
)
4533 old_fpucw
= d3d_fpu_setup();
4534 hr
= IDirect3DDeviceImpl_7_GetTexture(iface
, Stage
, Texture
);
4535 set_fpu_control_word(old_fpucw
);
4540 static HRESULT WINAPI
IDirect3DDeviceImpl_3_GetTexture(IDirect3DDevice3
*iface
, DWORD Stage
,
4541 IDirect3DTexture2
**Texture2
)
4543 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
4545 IDirectDrawSurface7
*ret_val
;
4546 IDirectDrawSurfaceImpl
*ret_val_impl
;
4548 TRACE("iface %p, stage %u, texture %p.\n", iface
, Stage
, Texture2
);
4550 ret
= IDirect3DDevice7_GetTexture(&This
->IDirect3DDevice7_iface
, Stage
, &ret_val
);
4552 ret_val_impl
= unsafe_impl_from_IDirectDrawSurface7(ret_val
);
4553 *Texture2
= ret_val_impl
? &ret_val_impl
->IDirect3DTexture2_iface
: NULL
;
4555 TRACE("Returning texture %p.\n", *Texture2
);
4560 /*****************************************************************************
4561 * IDirect3DDevice7::SetTexture
4563 * Assigns a texture to a texture stage. Is the texture AddRef-ed?
4568 * Stage: The stage to assign the texture to
4569 * Texture: Interface pointer to the texture surface
4573 * For details, see IWineD3DDevice::SetTexture
4575 *****************************************************************************/
4577 IDirect3DDeviceImpl_7_SetTexture(IDirect3DDevice7
*iface
,
4579 IDirectDrawSurface7
*Texture
)
4581 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
4582 IDirectDrawSurfaceImpl
*surf
= unsafe_impl_from_IDirectDrawSurface7(Texture
);
4585 TRACE("iface %p, stage %u, texture %p.\n", iface
, Stage
, Texture
);
4587 /* Texture may be NULL here */
4588 wined3d_mutex_lock();
4589 hr
= wined3d_device_set_texture(This
->wined3d_device
,
4590 Stage
, surf
? surf
->wined3d_texture
: NULL
);
4591 wined3d_mutex_unlock();
4596 static HRESULT WINAPI
4597 IDirect3DDeviceImpl_7_SetTexture_FPUSetup(IDirect3DDevice7
*iface
,
4599 IDirectDrawSurface7
*Texture
)
4601 return IDirect3DDeviceImpl_7_SetTexture(iface
, Stage
, Texture
);
4604 static HRESULT WINAPI
4605 IDirect3DDeviceImpl_7_SetTexture_FPUPreserve(IDirect3DDevice7
*iface
,
4607 IDirectDrawSurface7
*Texture
)
4612 old_fpucw
= d3d_fpu_setup();
4613 hr
= IDirect3DDeviceImpl_7_SetTexture(iface
, Stage
, Texture
);
4614 set_fpu_control_word(old_fpucw
);
4619 static HRESULT WINAPI
4620 IDirect3DDeviceImpl_3_SetTexture(IDirect3DDevice3
*iface
,
4622 IDirect3DTexture2
*Texture2
)
4624 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
4625 IDirectDrawSurfaceImpl
*tex
= unsafe_impl_from_IDirect3DTexture2(Texture2
);
4629 TRACE("iface %p, stage %u, texture %p.\n", iface
, Stage
, Texture2
);
4631 wined3d_mutex_lock();
4633 if (This
->legacyTextureBlending
)
4634 IDirect3DDevice3_GetRenderState(iface
, D3DRENDERSTATE_TEXTUREMAPBLEND
, &texmapblend
);
4636 hr
= IDirect3DDevice7_SetTexture(&This
->IDirect3DDevice7_iface
, Stage
, &tex
->IDirectDrawSurface7_iface
);
4638 if (This
->legacyTextureBlending
&& texmapblend
== D3DTBLEND_MODULATE
)
4640 /* This fixup is required by the way D3DTBLEND_MODULATE maps to texture stage states.
4641 See IDirect3DDeviceImpl_3_SetRenderState for details. */
4642 struct wined3d_texture
*tex
= NULL
;
4643 BOOL tex_alpha
= FALSE
;
4644 DDPIXELFORMAT ddfmt
;
4647 result
= wined3d_device_get_texture(This
->wined3d_device
, 0, &tex
);
4648 if (result
== WINED3D_OK
&& tex
)
4650 struct wined3d_resource
*sub_resource
;
4652 if ((sub_resource
= wined3d_texture_get_sub_resource(tex
, 0)))
4654 struct wined3d_resource_desc desc
;
4656 wined3d_resource_get_desc(sub_resource
, &desc
);
4657 ddfmt
.dwSize
= sizeof(ddfmt
);
4658 PixelFormat_WineD3DtoDD(&ddfmt
, desc
.format
);
4659 if (ddfmt
.u5
.dwRGBAlphaBitMask
) tex_alpha
= TRUE
;
4662 wined3d_texture_decref(tex
);
4665 /* Arg 1/2 are already set to WINED3DTA_TEXTURE/WINED3DTA_CURRENT in case of D3DTBLEND_MODULATE */
4667 wined3d_device_set_texture_stage_state(This
->wined3d_device
, 0, WINED3DTSS_ALPHAOP
, WINED3DTOP_SELECTARG1
);
4669 wined3d_device_set_texture_stage_state(This
->wined3d_device
, 0, WINED3DTSS_ALPHAOP
, WINED3DTOP_SELECTARG2
);
4672 wined3d_mutex_unlock();
4677 static const struct tss_lookup
4684 {FALSE
, WINED3DTSS_FORCE_DWORD
}, /* 0, unused */
4685 {FALSE
, WINED3DTSS_COLOROP
}, /* 1, D3DTSS_COLOROP */
4686 {FALSE
, WINED3DTSS_COLORARG1
}, /* 2, D3DTSS_COLORARG1 */
4687 {FALSE
, WINED3DTSS_COLORARG2
}, /* 3, D3DTSS_COLORARG2 */
4688 {FALSE
, WINED3DTSS_ALPHAOP
}, /* 4, D3DTSS_ALPHAOP */
4689 {FALSE
, WINED3DTSS_ALPHAARG1
}, /* 5, D3DTSS_ALPHAARG1 */
4690 {FALSE
, WINED3DTSS_ALPHAARG2
}, /* 6, D3DTSS_ALPHAARG2 */
4691 {FALSE
, WINED3DTSS_BUMPENVMAT00
}, /* 7, D3DTSS_BUMPENVMAT00 */
4692 {FALSE
, WINED3DTSS_BUMPENVMAT01
}, /* 8, D3DTSS_BUMPENVMAT01 */
4693 {FALSE
, WINED3DTSS_BUMPENVMAT10
}, /* 9, D3DTSS_BUMPENVMAT10 */
4694 {FALSE
, WINED3DTSS_BUMPENVMAT11
}, /* 10, D3DTSS_BUMPENVMAT11 */
4695 {FALSE
, WINED3DTSS_TEXCOORDINDEX
}, /* 11, D3DTSS_TEXCOORDINDEX */
4696 {TRUE
, WINED3DSAMP_ADDRESSU
}, /* 12, D3DTSS_ADDRESS */
4697 {TRUE
, WINED3DSAMP_ADDRESSU
}, /* 13, D3DTSS_ADDRESSU */
4698 {TRUE
, WINED3DSAMP_ADDRESSV
}, /* 14, D3DTSS_ADDRESSV */
4699 {TRUE
, WINED3DSAMP_BORDERCOLOR
}, /* 15, D3DTSS_BORDERCOLOR */
4700 {TRUE
, WINED3DSAMP_MAGFILTER
}, /* 16, D3DTSS_MAGFILTER */
4701 {TRUE
, WINED3DSAMP_MINFILTER
}, /* 17, D3DTSS_MINFILTER */
4702 {TRUE
, WINED3DSAMP_MIPFILTER
}, /* 18, D3DTSS_MIPFILTER */
4703 {TRUE
, WINED3DSAMP_MIPMAPLODBIAS
}, /* 19, D3DTSS_MIPMAPLODBIAS */
4704 {TRUE
, WINED3DSAMP_MAXMIPLEVEL
}, /* 20, D3DTSS_MAXMIPLEVEL */
4705 {TRUE
, WINED3DSAMP_MAXANISOTROPY
}, /* 21, D3DTSS_MAXANISOTROPY */
4706 {FALSE
, WINED3DTSS_BUMPENVLSCALE
}, /* 22, D3DTSS_BUMPENVLSCALE */
4707 {FALSE
, WINED3DTSS_BUMPENVLOFFSET
}, /* 23, D3DTSS_BUMPENVLOFFSET */
4708 {FALSE
, WINED3DTSS_TEXTURETRANSFORMFLAGS
}, /* 24, D3DTSS_TEXTURETRANSFORMFLAGS */
4711 /*****************************************************************************
4712 * IDirect3DDevice7::GetTextureStageState
4714 * Retrieves a state from a texture stage.
4719 * Stage: The stage to retrieve the state from
4720 * TexStageStateType: The state type to retrieve
4721 * State: Address to store the state's value at
4725 * DDERR_INVALIDPARAMS if State is NULL
4726 * For details, see IWineD3DDevice::GetTextureStageState
4728 *****************************************************************************/
4730 IDirect3DDeviceImpl_7_GetTextureStageState(IDirect3DDevice7
*iface
,
4732 D3DTEXTURESTAGESTATETYPE TexStageStateType
,
4735 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
4737 const struct tss_lookup
*l
;
4739 TRACE("iface %p, stage %u, state %#x, value %p.\n",
4740 iface
, Stage
, TexStageStateType
, State
);
4743 return DDERR_INVALIDPARAMS
;
4745 if (TexStageStateType
> D3DTSS_TEXTURETRANSFORMFLAGS
)
4747 WARN("Invalid TexStageStateType %#x passed.\n", TexStageStateType
);
4751 l
= &tss_lookup
[TexStageStateType
];
4753 wined3d_mutex_lock();
4755 if (l
->sampler_state
)
4757 hr
= wined3d_device_get_sampler_state(This
->wined3d_device
, Stage
, l
->state
, State
);
4759 switch(TexStageStateType
)
4761 /* Mipfilter is a sampler state with different values */
4762 case D3DTSS_MIPFILTER
:
4766 case WINED3DTEXF_NONE
: *State
= D3DTFP_NONE
; break;
4767 case WINED3DTEXF_POINT
: *State
= D3DTFP_POINT
; break;
4768 case WINED3DTEXF_LINEAR
: *State
= D3DTFP_LINEAR
; break;
4770 ERR("Unexpected mipfilter value %#x\n", *State
);
4771 *State
= D3DTFP_NONE
;
4777 /* Magfilter has slightly different values */
4778 case D3DTSS_MAGFILTER
:
4782 case WINED3DTEXF_POINT
: *State
= D3DTFG_POINT
; break;
4783 case WINED3DTEXF_LINEAR
: *State
= D3DTFG_LINEAR
; break;
4784 case WINED3DTEXF_ANISOTROPIC
: *State
= D3DTFG_ANISOTROPIC
; break;
4785 case WINED3DTEXF_FLATCUBIC
: *State
= D3DTFG_FLATCUBIC
; break;
4786 case WINED3DTEXF_GAUSSIANCUBIC
: *State
= D3DTFG_GAUSSIANCUBIC
; break;
4788 ERR("Unexpected wined3d mag filter value %#x\n", *State
);
4789 *State
= D3DTFG_POINT
;
4801 hr
= wined3d_device_get_texture_stage_state(This
->wined3d_device
, Stage
, l
->state
, State
);
4804 wined3d_mutex_unlock();
4809 static HRESULT WINAPI
4810 IDirect3DDeviceImpl_7_GetTextureStageState_FPUSetup(IDirect3DDevice7
*iface
,
4812 D3DTEXTURESTAGESTATETYPE TexStageStateType
,
4815 return IDirect3DDeviceImpl_7_GetTextureStageState(iface
, Stage
, TexStageStateType
, State
);
4818 static HRESULT WINAPI
4819 IDirect3DDeviceImpl_7_GetTextureStageState_FPUPreserve(IDirect3DDevice7
*iface
,
4821 D3DTEXTURESTAGESTATETYPE TexStageStateType
,
4827 old_fpucw
= d3d_fpu_setup();
4828 hr
= IDirect3DDeviceImpl_7_GetTextureStageState(iface
, Stage
, TexStageStateType
, State
);
4829 set_fpu_control_word(old_fpucw
);
4834 static HRESULT WINAPI
IDirect3DDeviceImpl_3_GetTextureStageState(IDirect3DDevice3
*iface
,
4835 DWORD Stage
, D3DTEXTURESTAGESTATETYPE TexStageStateType
, DWORD
*State
)
4837 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
4839 TRACE("iface %p, stage %u, state %#x, value %p.\n",
4840 iface
, Stage
, TexStageStateType
, State
);
4842 return IDirect3DDevice7_GetTextureStageState(&This
->IDirect3DDevice7_iface
,
4843 Stage
, TexStageStateType
, State
);
4846 /*****************************************************************************
4847 * IDirect3DDevice7::SetTextureStageState
4849 * Sets a texture stage state. Some stage types need to be handled specially,
4850 * because they do not exist in WineD3D and were moved to another place
4855 * Stage: The stage to modify
4856 * TexStageStateType: The state to change
4857 * State: The new value for the state
4861 * For details, see IWineD3DDevice::SetTextureStageState
4863 *****************************************************************************/
4865 IDirect3DDeviceImpl_7_SetTextureStageState(IDirect3DDevice7
*iface
,
4867 D3DTEXTURESTAGESTATETYPE TexStageStateType
,
4870 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
4871 const struct tss_lookup
*l
;
4874 TRACE("iface %p, stage %u, state %#x, value %#x.\n",
4875 iface
, Stage
, TexStageStateType
, State
);
4877 if (TexStageStateType
> D3DTSS_TEXTURETRANSFORMFLAGS
)
4879 WARN("Invalid TexStageStateType %#x passed.\n", TexStageStateType
);
4883 l
= &tss_lookup
[TexStageStateType
];
4885 wined3d_mutex_lock();
4887 if (l
->sampler_state
)
4889 switch(TexStageStateType
)
4891 /* Mipfilter is a sampler state with different values */
4892 case D3DTSS_MIPFILTER
:
4896 case D3DTFP_NONE
: State
= WINED3DTEXF_NONE
; break;
4897 case D3DTFP_POINT
: State
= WINED3DTEXF_POINT
; break;
4898 case 0: /* Unchecked */
4899 case D3DTFP_LINEAR
: State
= WINED3DTEXF_LINEAR
; break;
4901 ERR("Unexpected mipfilter value %d\n", State
);
4902 State
= WINED3DTEXF_NONE
;
4908 /* Magfilter has slightly different values */
4909 case D3DTSS_MAGFILTER
:
4913 case D3DTFG_POINT
: State
= WINED3DTEXF_POINT
; break;
4914 case D3DTFG_LINEAR
: State
= WINED3DTEXF_LINEAR
; break;
4915 case D3DTFG_FLATCUBIC
: State
= WINED3DTEXF_FLATCUBIC
; break;
4916 case D3DTFG_GAUSSIANCUBIC
: State
= WINED3DTEXF_GAUSSIANCUBIC
; break;
4917 case D3DTFG_ANISOTROPIC
: State
= WINED3DTEXF_ANISOTROPIC
; break;
4919 ERR("Unexpected d3d7 mag filter type %d\n", State
);
4920 State
= WINED3DTEXF_POINT
;
4926 case D3DTSS_ADDRESS
:
4927 wined3d_device_set_sampler_state(This
->wined3d_device
, Stage
, WINED3DSAMP_ADDRESSV
, State
);
4934 hr
= wined3d_device_set_sampler_state(This
->wined3d_device
, Stage
, l
->state
, State
);
4938 hr
= wined3d_device_set_texture_stage_state(This
->wined3d_device
, Stage
, l
->state
, State
);
4941 wined3d_mutex_unlock();
4946 static HRESULT WINAPI
4947 IDirect3DDeviceImpl_7_SetTextureStageState_FPUSetup(IDirect3DDevice7
*iface
,
4949 D3DTEXTURESTAGESTATETYPE TexStageStateType
,
4952 return IDirect3DDeviceImpl_7_SetTextureStageState(iface
, Stage
, TexStageStateType
, State
);
4955 static HRESULT WINAPI
4956 IDirect3DDeviceImpl_7_SetTextureStageState_FPUPreserve(IDirect3DDevice7
*iface
,
4958 D3DTEXTURESTAGESTATETYPE TexStageStateType
,
4964 old_fpucw
= d3d_fpu_setup();
4965 hr
= IDirect3DDeviceImpl_7_SetTextureStageState(iface
, Stage
, TexStageStateType
, State
);
4966 set_fpu_control_word(old_fpucw
);
4971 static HRESULT WINAPI
IDirect3DDeviceImpl_3_SetTextureStageState(IDirect3DDevice3
*iface
,
4972 DWORD Stage
, D3DTEXTURESTAGESTATETYPE TexStageStateType
, DWORD State
)
4974 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
4976 TRACE("iface %p, stage %u, state %#x, value %#x.\n",
4977 iface
, Stage
, TexStageStateType
, State
);
4979 return IDirect3DDevice7_SetTextureStageState(&This
->IDirect3DDevice7_iface
,
4980 Stage
, TexStageStateType
, State
);
4983 /*****************************************************************************
4984 * IDirect3DDevice7::ValidateDevice
4986 * SDK: "Reports the device's ability to render the currently set
4987 * texture-blending operations in a single pass". Whatever that means
4993 * NumPasses: Address to write the number of necessary passes for the
4994 * desired effect to.
4998 * See IWineD3DDevice::ValidateDevice for more details
5000 *****************************************************************************/
5002 IDirect3DDeviceImpl_7_ValidateDevice(IDirect3DDevice7
*iface
,
5005 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
5008 TRACE("iface %p, pass_count %p.\n", iface
, NumPasses
);
5010 wined3d_mutex_lock();
5011 hr
= wined3d_device_validate_device(This
->wined3d_device
, NumPasses
);
5012 wined3d_mutex_unlock();
5017 static HRESULT WINAPI
5018 IDirect3DDeviceImpl_7_ValidateDevice_FPUSetup(IDirect3DDevice7
*iface
,
5021 return IDirect3DDeviceImpl_7_ValidateDevice(iface
, NumPasses
);
5024 static HRESULT WINAPI
5025 IDirect3DDeviceImpl_7_ValidateDevice_FPUPreserve(IDirect3DDevice7
*iface
,
5031 old_fpucw
= d3d_fpu_setup();
5032 hr
= IDirect3DDeviceImpl_7_ValidateDevice(iface
, NumPasses
);
5033 set_fpu_control_word(old_fpucw
);
5038 static HRESULT WINAPI
IDirect3DDeviceImpl_3_ValidateDevice(IDirect3DDevice3
*iface
, DWORD
*Passes
)
5040 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
5042 TRACE("iface %p, pass_count %p.\n", iface
, Passes
);
5044 return IDirect3DDevice7_ValidateDevice(&This
->IDirect3DDevice7_iface
, Passes
);
5047 /*****************************************************************************
5048 * IDirect3DDevice7::Clear
5050 * Fills the render target, the z buffer and the stencil buffer with a
5051 * clear color / value
5056 * Count: Number of rectangles in Rects must be 0 if Rects is NULL
5057 * Rects: Rectangles to clear. If NULL, the whole surface is cleared
5058 * Flags: Some flags, as usual
5059 * Color: Clear color for the render target
5060 * Z: Clear value for the Z buffer
5061 * Stencil: Clear value to store in each stencil buffer entry
5065 * For details, see IWineD3DDevice::Clear
5067 *****************************************************************************/
5068 static HRESULT
IDirect3DDeviceImpl_7_Clear(IDirect3DDevice7
*iface
, DWORD count
,
5069 D3DRECT
*rects
, DWORD flags
, D3DCOLOR color
, D3DVALUE z
, DWORD stencil
)
5071 const struct wined3d_color c
=
5073 ((color
>> 16) & 0xff) / 255.0f
,
5074 ((color
>> 8) & 0xff) / 255.0f
,
5075 (color
& 0xff) / 255.0f
,
5076 ((color
>> 24) & 0xff) / 255.0f
,
5078 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
5081 TRACE("iface %p, count %u, rects %p, flags %#x, color 0x%08x, z %.8e, stencil %#x.\n",
5082 iface
, count
, rects
, flags
, color
, z
, stencil
);
5084 wined3d_mutex_lock();
5085 hr
= wined3d_device_clear(This
->wined3d_device
, count
, (RECT
*)rects
, flags
, &c
, z
, stencil
);
5086 wined3d_mutex_unlock();
5091 static HRESULT WINAPI
5092 IDirect3DDeviceImpl_7_Clear_FPUSetup(IDirect3DDevice7
*iface
,
5100 return IDirect3DDeviceImpl_7_Clear(iface
, Count
, Rects
, Flags
, Color
, Z
, Stencil
);
5103 static HRESULT WINAPI
5104 IDirect3DDeviceImpl_7_Clear_FPUPreserve(IDirect3DDevice7
*iface
,
5115 old_fpucw
= d3d_fpu_setup();
5116 hr
= IDirect3DDeviceImpl_7_Clear(iface
, Count
, Rects
, Flags
, Color
, Z
, Stencil
);
5117 set_fpu_control_word(old_fpucw
);
5122 /*****************************************************************************
5123 * IDirect3DDevice7::SetViewport
5125 * Sets the current viewport.
5127 * Version 7 only, but IDirect3DViewport uses this call for older
5131 * Data: The new viewport to set
5135 * DDERR_INVALIDPARAMS if Data is NULL
5136 * For more details, see IWineDDDevice::SetViewport
5138 *****************************************************************************/
5140 IDirect3DDeviceImpl_7_SetViewport(IDirect3DDevice7
*iface
,
5143 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
5146 TRACE("iface %p, viewport %p.\n", iface
, Data
);
5149 return DDERR_INVALIDPARAMS
;
5151 /* Note: D3DVIEWPORT7 is compatible with WINED3DVIEWPORT */
5152 wined3d_mutex_lock();
5153 hr
= wined3d_device_set_viewport(This
->wined3d_device
, (WINED3DVIEWPORT
*)Data
);
5154 wined3d_mutex_unlock();
5159 static HRESULT WINAPI
5160 IDirect3DDeviceImpl_7_SetViewport_FPUSetup(IDirect3DDevice7
*iface
,
5163 return IDirect3DDeviceImpl_7_SetViewport(iface
, Data
);
5166 static HRESULT WINAPI
5167 IDirect3DDeviceImpl_7_SetViewport_FPUPreserve(IDirect3DDevice7
*iface
,
5173 old_fpucw
= d3d_fpu_setup();
5174 hr
= IDirect3DDeviceImpl_7_SetViewport(iface
, Data
);
5175 set_fpu_control_word(old_fpucw
);
5180 /*****************************************************************************
5181 * IDirect3DDevice::GetViewport
5183 * Returns the current viewport
5188 * Data: D3D7Viewport structure to write the viewport information to
5192 * DDERR_INVALIDPARAMS if Data is NULL
5193 * For more details, see IWineD3DDevice::GetViewport
5195 *****************************************************************************/
5197 IDirect3DDeviceImpl_7_GetViewport(IDirect3DDevice7
*iface
,
5200 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
5203 TRACE("iface %p, viewport %p.\n", iface
, Data
);
5206 return DDERR_INVALIDPARAMS
;
5208 /* Note: D3DVIEWPORT7 is compatible with WINED3DVIEWPORT */
5209 wined3d_mutex_lock();
5210 hr
= wined3d_device_get_viewport(This
->wined3d_device
, (WINED3DVIEWPORT
*)Data
);
5211 wined3d_mutex_unlock();
5213 return hr_ddraw_from_wined3d(hr
);
5216 static HRESULT WINAPI
5217 IDirect3DDeviceImpl_7_GetViewport_FPUSetup(IDirect3DDevice7
*iface
,
5220 return IDirect3DDeviceImpl_7_GetViewport(iface
, Data
);
5223 static HRESULT WINAPI
5224 IDirect3DDeviceImpl_7_GetViewport_FPUPreserve(IDirect3DDevice7
*iface
,
5230 old_fpucw
= d3d_fpu_setup();
5231 hr
= IDirect3DDeviceImpl_7_GetViewport(iface
, Data
);
5232 set_fpu_control_word(old_fpucw
);
5237 /*****************************************************************************
5238 * IDirect3DDevice7::SetMaterial
5245 * Mat: The material to set
5249 * DDERR_INVALIDPARAMS if Mat is NULL.
5250 * For more details, see IWineD3DDevice::SetMaterial
5252 *****************************************************************************/
5254 IDirect3DDeviceImpl_7_SetMaterial(IDirect3DDevice7
*iface
,
5257 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
5260 TRACE("iface %p, material %p.\n", iface
, Mat
);
5262 if (!Mat
) return DDERR_INVALIDPARAMS
;
5264 wined3d_mutex_lock();
5265 /* Note: D3DMATERIAL7 is compatible with WINED3DMATERIAL */
5266 hr
= wined3d_device_set_material(This
->wined3d_device
, (WINED3DMATERIAL
*)Mat
);
5267 wined3d_mutex_unlock();
5269 return hr_ddraw_from_wined3d(hr
);
5272 static HRESULT WINAPI
5273 IDirect3DDeviceImpl_7_SetMaterial_FPUSetup(IDirect3DDevice7
*iface
,
5276 return IDirect3DDeviceImpl_7_SetMaterial(iface
, Mat
);
5279 static HRESULT WINAPI
5280 IDirect3DDeviceImpl_7_SetMaterial_FPUPreserve(IDirect3DDevice7
*iface
,
5286 old_fpucw
= d3d_fpu_setup();
5287 hr
= IDirect3DDeviceImpl_7_SetMaterial(iface
, Mat
);
5288 set_fpu_control_word(old_fpucw
);
5293 /*****************************************************************************
5294 * IDirect3DDevice7::GetMaterial
5296 * Returns the current material
5301 * Mat: D3DMATERIAL7 structure to write the material parameters to
5305 * DDERR_INVALIDPARAMS if Mat is NULL
5306 * For more details, see IWineD3DDevice::GetMaterial
5308 *****************************************************************************/
5310 IDirect3DDeviceImpl_7_GetMaterial(IDirect3DDevice7
*iface
,
5313 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
5316 TRACE("iface %p, material %p.\n", iface
, Mat
);
5318 wined3d_mutex_lock();
5319 /* Note: D3DMATERIAL7 is compatible with WINED3DMATERIAL */
5320 hr
= wined3d_device_get_material(This
->wined3d_device
, (WINED3DMATERIAL
*)Mat
);
5321 wined3d_mutex_unlock();
5323 return hr_ddraw_from_wined3d(hr
);
5326 static HRESULT WINAPI
5327 IDirect3DDeviceImpl_7_GetMaterial_FPUSetup(IDirect3DDevice7
*iface
,
5330 return IDirect3DDeviceImpl_7_GetMaterial(iface
, Mat
);
5333 static HRESULT WINAPI
5334 IDirect3DDeviceImpl_7_GetMaterial_FPUPreserve(IDirect3DDevice7
*iface
,
5340 old_fpucw
= d3d_fpu_setup();
5341 hr
= IDirect3DDeviceImpl_7_GetMaterial(iface
, Mat
);
5342 set_fpu_control_word(old_fpucw
);
5347 /*****************************************************************************
5348 * IDirect3DDevice7::SetLight
5350 * Assigns a light to a light index, but doesn't activate it yet.
5352 * Version 7, IDirect3DLight uses this method for older versions
5355 * LightIndex: The index of the new light
5356 * Light: A D3DLIGHT7 structure describing the light
5360 * For more details, see IWineD3DDevice::SetLight
5362 *****************************************************************************/
5364 IDirect3DDeviceImpl_7_SetLight(IDirect3DDevice7
*iface
,
5368 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
5371 TRACE("iface %p, light_idx %u, light %p.\n", iface
, LightIndex
, Light
);
5373 wined3d_mutex_lock();
5374 /* Note: D3DLIGHT7 is compatible with WINED3DLIGHT */
5375 hr
= wined3d_device_set_light(This
->wined3d_device
, LightIndex
, (WINED3DLIGHT
*)Light
);
5376 wined3d_mutex_unlock();
5378 return hr_ddraw_from_wined3d(hr
);
5381 static HRESULT WINAPI
5382 IDirect3DDeviceImpl_7_SetLight_FPUSetup(IDirect3DDevice7
*iface
,
5386 return IDirect3DDeviceImpl_7_SetLight(iface
, LightIndex
, Light
);
5389 static HRESULT WINAPI
5390 IDirect3DDeviceImpl_7_SetLight_FPUPreserve(IDirect3DDevice7
*iface
,
5397 old_fpucw
= d3d_fpu_setup();
5398 hr
= IDirect3DDeviceImpl_7_SetLight(iface
, LightIndex
, Light
);
5399 set_fpu_control_word(old_fpucw
);
5404 /*****************************************************************************
5405 * IDirect3DDevice7::GetLight
5407 * Returns the light assigned to a light index
5410 * Light: Structure to write the light information to
5414 * DDERR_INVALIDPARAMS if Light is NULL
5415 * For details, see IWineD3DDevice::GetLight
5417 *****************************************************************************/
5419 IDirect3DDeviceImpl_7_GetLight(IDirect3DDevice7
*iface
,
5423 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
5426 TRACE("iface %p, light_idx %u, light %p.\n", iface
, LightIndex
, Light
);
5428 wined3d_mutex_lock();
5429 /* Note: D3DLIGHT7 is compatible with WINED3DLIGHT */
5430 rc
= wined3d_device_get_light(This
->wined3d_device
, LightIndex
, (WINED3DLIGHT
*)Light
);
5431 wined3d_mutex_unlock();
5433 /* Translate the result. WineD3D returns other values than D3D7 */
5434 return hr_ddraw_from_wined3d(rc
);
5437 static HRESULT WINAPI
5438 IDirect3DDeviceImpl_7_GetLight_FPUSetup(IDirect3DDevice7
*iface
,
5442 return IDirect3DDeviceImpl_7_GetLight(iface
, LightIndex
, Light
);
5445 static HRESULT WINAPI
5446 IDirect3DDeviceImpl_7_GetLight_FPUPreserve(IDirect3DDevice7
*iface
,
5453 old_fpucw
= d3d_fpu_setup();
5454 hr
= IDirect3DDeviceImpl_7_GetLight(iface
, LightIndex
, Light
);
5455 set_fpu_control_word(old_fpucw
);
5460 /*****************************************************************************
5461 * IDirect3DDevice7::BeginStateBlock
5463 * Begins recording to a stateblock
5469 * For details see IWineD3DDevice::BeginStateBlock
5471 *****************************************************************************/
5473 IDirect3DDeviceImpl_7_BeginStateBlock(IDirect3DDevice7
*iface
)
5475 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
5478 TRACE("iface %p.\n", iface
);
5480 wined3d_mutex_lock();
5481 hr
= wined3d_device_begin_stateblock(This
->wined3d_device
);
5482 wined3d_mutex_unlock();
5484 return hr_ddraw_from_wined3d(hr
);
5487 static HRESULT WINAPI
5488 IDirect3DDeviceImpl_7_BeginStateBlock_FPUSetup(IDirect3DDevice7
*iface
)
5490 return IDirect3DDeviceImpl_7_BeginStateBlock(iface
);
5493 static HRESULT WINAPI
5494 IDirect3DDeviceImpl_7_BeginStateBlock_FPUPreserve(IDirect3DDevice7
*iface
)
5499 old_fpucw
= d3d_fpu_setup();
5500 hr
= IDirect3DDeviceImpl_7_BeginStateBlock(iface
);
5501 set_fpu_control_word(old_fpucw
);
5506 /*****************************************************************************
5507 * IDirect3DDevice7::EndStateBlock
5509 * Stops recording to a state block and returns the created stateblock
5515 * BlockHandle: Address to store the stateblock's handle to
5519 * DDERR_INVALIDPARAMS if BlockHandle is NULL
5520 * See IWineD3DDevice::EndStateBlock for more details
5522 *****************************************************************************/
5524 IDirect3DDeviceImpl_7_EndStateBlock(IDirect3DDevice7
*iface
,
5527 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
5528 struct wined3d_stateblock
*wined3d_sb
;
5532 TRACE("iface %p, stateblock %p.\n", iface
, BlockHandle
);
5536 WARN("BlockHandle == NULL, returning DDERR_INVALIDPARAMS\n");
5537 return DDERR_INVALIDPARAMS
;
5540 wined3d_mutex_lock();
5542 hr
= wined3d_device_end_stateblock(This
->wined3d_device
, &wined3d_sb
);
5545 WARN("Failed to end stateblock, hr %#x.\n", hr
);
5546 wined3d_mutex_unlock();
5548 return hr_ddraw_from_wined3d(hr
);
5551 h
= ddraw_allocate_handle(&This
->handle_table
, wined3d_sb
, DDRAW_HANDLE_STATEBLOCK
);
5552 if (h
== DDRAW_INVALID_HANDLE
)
5554 ERR("Failed to allocate a stateblock handle.\n");
5555 wined3d_stateblock_decref(wined3d_sb
);
5556 wined3d_mutex_unlock();
5558 return DDERR_OUTOFMEMORY
;
5561 wined3d_mutex_unlock();
5562 *BlockHandle
= h
+ 1;
5564 return hr_ddraw_from_wined3d(hr
);
5567 static HRESULT WINAPI
5568 IDirect3DDeviceImpl_7_EndStateBlock_FPUSetup(IDirect3DDevice7
*iface
,
5571 return IDirect3DDeviceImpl_7_EndStateBlock(iface
, BlockHandle
);
5574 static HRESULT WINAPI
5575 IDirect3DDeviceImpl_7_EndStateBlock_FPUPreserve(IDirect3DDevice7
*iface
,
5581 old_fpucw
= d3d_fpu_setup();
5582 hr
= IDirect3DDeviceImpl_7_EndStateBlock(iface
, BlockHandle
);
5583 set_fpu_control_word(old_fpucw
);
5588 /*****************************************************************************
5589 * IDirect3DDevice7::PreLoad
5591 * Allows the app to signal that a texture will be used soon, to allow
5592 * the Direct3DDevice to load it to the video card in the meantime.
5597 * Texture: The texture to preload
5601 * DDERR_INVALIDPARAMS if Texture is NULL
5602 * See IWineD3DSurface::PreLoad for details
5604 *****************************************************************************/
5606 IDirect3DDeviceImpl_7_PreLoad(IDirect3DDevice7
*iface
,
5607 IDirectDrawSurface7
*Texture
)
5609 IDirectDrawSurfaceImpl
*surf
= unsafe_impl_from_IDirectDrawSurface7(Texture
);
5611 TRACE("iface %p, texture %p.\n", iface
, Texture
);
5614 return DDERR_INVALIDPARAMS
;
5616 wined3d_mutex_lock();
5617 wined3d_surface_preload(surf
->wined3d_surface
);
5618 wined3d_mutex_unlock();
5623 static HRESULT WINAPI
5624 IDirect3DDeviceImpl_7_PreLoad_FPUSetup(IDirect3DDevice7
*iface
,
5625 IDirectDrawSurface7
*Texture
)
5627 return IDirect3DDeviceImpl_7_PreLoad(iface
, Texture
);
5630 static HRESULT WINAPI
5631 IDirect3DDeviceImpl_7_PreLoad_FPUPreserve(IDirect3DDevice7
*iface
,
5632 IDirectDrawSurface7
*Texture
)
5637 old_fpucw
= d3d_fpu_setup();
5638 hr
= IDirect3DDeviceImpl_7_PreLoad(iface
, Texture
);
5639 set_fpu_control_word(old_fpucw
);
5644 /*****************************************************************************
5645 * IDirect3DDevice7::ApplyStateBlock
5647 * Activates the state stored in a state block handle.
5650 * BlockHandle: The stateblock handle to activate
5654 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is NULL
5656 *****************************************************************************/
5658 IDirect3DDeviceImpl_7_ApplyStateBlock(IDirect3DDevice7
*iface
,
5661 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
5662 struct wined3d_stateblock
*wined3d_sb
;
5665 TRACE("iface %p, stateblock %#x.\n", iface
, BlockHandle
);
5667 wined3d_mutex_lock();
5668 wined3d_sb
= ddraw_get_object(&This
->handle_table
, BlockHandle
- 1, DDRAW_HANDLE_STATEBLOCK
);
5671 WARN("Invalid stateblock handle.\n");
5672 wined3d_mutex_unlock();
5673 return D3DERR_INVALIDSTATEBLOCK
;
5676 hr
= wined3d_stateblock_apply(wined3d_sb
);
5677 wined3d_mutex_unlock();
5679 return hr_ddraw_from_wined3d(hr
);
5682 static HRESULT WINAPI
5683 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUSetup(IDirect3DDevice7
*iface
,
5686 return IDirect3DDeviceImpl_7_ApplyStateBlock(iface
, BlockHandle
);
5689 static HRESULT WINAPI
5690 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUPreserve(IDirect3DDevice7
*iface
,
5696 old_fpucw
= d3d_fpu_setup();
5697 hr
= IDirect3DDeviceImpl_7_ApplyStateBlock(iface
, BlockHandle
);
5698 set_fpu_control_word(old_fpucw
);
5703 /*****************************************************************************
5704 * IDirect3DDevice7::CaptureStateBlock
5706 * Updates a stateblock's values to the values currently set for the device
5711 * BlockHandle: Stateblock to update
5715 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is NULL
5716 * See IWineD3DDevice::CaptureStateBlock for more details
5718 *****************************************************************************/
5720 IDirect3DDeviceImpl_7_CaptureStateBlock(IDirect3DDevice7
*iface
,
5723 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
5724 struct wined3d_stateblock
*wined3d_sb
;
5727 TRACE("iface %p, stateblock %#x.\n", iface
, BlockHandle
);
5729 wined3d_mutex_lock();
5730 wined3d_sb
= ddraw_get_object(&This
->handle_table
, BlockHandle
- 1, DDRAW_HANDLE_STATEBLOCK
);
5733 WARN("Invalid stateblock handle.\n");
5734 wined3d_mutex_unlock();
5735 return D3DERR_INVALIDSTATEBLOCK
;
5738 hr
= wined3d_stateblock_capture(wined3d_sb
);
5739 wined3d_mutex_unlock();
5741 return hr_ddraw_from_wined3d(hr
);
5744 static HRESULT WINAPI
5745 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUSetup(IDirect3DDevice7
*iface
,
5748 return IDirect3DDeviceImpl_7_CaptureStateBlock(iface
, BlockHandle
);
5751 static HRESULT WINAPI
5752 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUPreserve(IDirect3DDevice7
*iface
,
5758 old_fpucw
= d3d_fpu_setup();
5759 hr
= IDirect3DDeviceImpl_7_CaptureStateBlock(iface
, BlockHandle
);
5760 set_fpu_control_word(old_fpucw
);
5765 /*****************************************************************************
5766 * IDirect3DDevice7::DeleteStateBlock
5768 * Deletes a stateblock handle. This means releasing the WineD3DStateBlock
5773 * BlockHandle: Stateblock handle to delete
5777 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is 0
5779 *****************************************************************************/
5781 IDirect3DDeviceImpl_7_DeleteStateBlock(IDirect3DDevice7
*iface
,
5784 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
5785 struct wined3d_stateblock
*wined3d_sb
;
5788 TRACE("iface %p, stateblock %#x.\n", iface
, BlockHandle
);
5790 wined3d_mutex_lock();
5792 wined3d_sb
= ddraw_free_handle(&This
->handle_table
, BlockHandle
- 1, DDRAW_HANDLE_STATEBLOCK
);
5795 WARN("Invalid stateblock handle.\n");
5796 wined3d_mutex_unlock();
5797 return D3DERR_INVALIDSTATEBLOCK
;
5800 if ((ref
= wined3d_stateblock_decref(wined3d_sb
)))
5802 ERR("Something is still holding stateblock %p (refcount %u).\n", wined3d_sb
, ref
);
5805 wined3d_mutex_unlock();
5810 static HRESULT WINAPI
5811 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUSetup(IDirect3DDevice7
*iface
,
5814 return IDirect3DDeviceImpl_7_DeleteStateBlock(iface
, BlockHandle
);
5817 static HRESULT WINAPI
5818 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUPreserve(IDirect3DDevice7
*iface
,
5824 old_fpucw
= d3d_fpu_setup();
5825 hr
= IDirect3DDeviceImpl_7_DeleteStateBlock(iface
, BlockHandle
);
5826 set_fpu_control_word(old_fpucw
);
5831 /*****************************************************************************
5832 * IDirect3DDevice7::CreateStateBlock
5834 * Creates a new state block handle.
5839 * Type: The state block type
5840 * BlockHandle: Address to write the created handle to
5844 * DDERR_INVALIDPARAMS if BlockHandle is NULL
5846 *****************************************************************************/
5848 IDirect3DDeviceImpl_7_CreateStateBlock(IDirect3DDevice7
*iface
,
5849 D3DSTATEBLOCKTYPE Type
,
5852 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
5853 struct wined3d_stateblock
*wined3d_sb
;
5857 TRACE("iface %p, type %#x, stateblock %p.\n", iface
, Type
, BlockHandle
);
5861 WARN("BlockHandle == NULL, returning DDERR_INVALIDPARAMS\n");
5862 return DDERR_INVALIDPARAMS
;
5864 if(Type
!= D3DSBT_ALL
&& Type
!= D3DSBT_PIXELSTATE
&&
5865 Type
!= D3DSBT_VERTEXSTATE
) {
5866 WARN("Unexpected stateblock type, returning DDERR_INVALIDPARAMS\n");
5867 return DDERR_INVALIDPARAMS
;
5870 wined3d_mutex_lock();
5872 /* The D3DSTATEBLOCKTYPE enum is fine here. */
5873 hr
= wined3d_stateblock_create(This
->wined3d_device
, Type
, &wined3d_sb
);
5876 WARN("Failed to create stateblock, hr %#x.\n", hr
);
5877 wined3d_mutex_unlock();
5878 return hr_ddraw_from_wined3d(hr
);
5881 h
= ddraw_allocate_handle(&This
->handle_table
, wined3d_sb
, DDRAW_HANDLE_STATEBLOCK
);
5882 if (h
== DDRAW_INVALID_HANDLE
)
5884 ERR("Failed to allocate stateblock handle.\n");
5885 wined3d_stateblock_decref(wined3d_sb
);
5886 wined3d_mutex_unlock();
5887 return DDERR_OUTOFMEMORY
;
5890 *BlockHandle
= h
+ 1;
5891 wined3d_mutex_unlock();
5893 return hr_ddraw_from_wined3d(hr
);
5896 static HRESULT WINAPI
5897 IDirect3DDeviceImpl_7_CreateStateBlock_FPUSetup(IDirect3DDevice7
*iface
,
5898 D3DSTATEBLOCKTYPE Type
,
5901 return IDirect3DDeviceImpl_7_CreateStateBlock(iface
, Type
, BlockHandle
);
5904 static HRESULT WINAPI
5905 IDirect3DDeviceImpl_7_CreateStateBlock_FPUPreserve(IDirect3DDevice7
*iface
,
5906 D3DSTATEBLOCKTYPE Type
,
5912 old_fpucw
= d3d_fpu_setup();
5913 hr
=IDirect3DDeviceImpl_7_CreateStateBlock(iface
, Type
, BlockHandle
);
5914 set_fpu_control_word(old_fpucw
);
5919 /* Helper function for IDirect3DDeviceImpl_7_Load. */
5920 static BOOL
is_mip_level_subset(IDirectDrawSurfaceImpl
*dest
,
5921 IDirectDrawSurfaceImpl
*src
)
5923 IDirectDrawSurfaceImpl
*src_level
, *dest_level
;
5924 IDirectDrawSurface7
*temp
;
5925 DDSURFACEDESC2 ddsd
;
5926 BOOL levelFound
; /* at least one suitable sublevel in dest found */
5928 /* To satisfy "destination is mip level subset of source" criteria (regular texture counts as 1 level),
5929 * 1) there must be at least one mip level in destination that matched dimensions of some mip level in source and
5930 * 2) there must be no destination levels that don't match any levels in source. Otherwise it's INVALIDPARAMS.
5937 for (;src_level
&& dest_level
;)
5939 if (src_level
->surface_desc
.dwWidth
== dest_level
->surface_desc
.dwWidth
&&
5940 src_level
->surface_desc
.dwHeight
== dest_level
->surface_desc
.dwHeight
)
5944 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
5945 ddsd
.ddsCaps
.dwCaps2
= DDSCAPS2_MIPMAPSUBLEVEL
;
5946 IDirectDrawSurface7_GetAttachedSurface(&dest_level
->IDirectDrawSurface7_iface
, &ddsd
.ddsCaps
, &temp
);
5948 if (dest_level
!= dest
) IDirectDrawSurface7_Release(&dest_level
->IDirectDrawSurface7_iface
);
5950 dest_level
= unsafe_impl_from_IDirectDrawSurface7(temp
);
5953 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
5954 ddsd
.ddsCaps
.dwCaps2
= DDSCAPS2_MIPMAPSUBLEVEL
;
5955 IDirectDrawSurface7_GetAttachedSurface(&src_level
->IDirectDrawSurface7_iface
, &ddsd
.ddsCaps
, &temp
);
5957 if (src_level
!= src
) IDirectDrawSurface7_Release(&src_level
->IDirectDrawSurface7_iface
);
5959 src_level
= unsafe_impl_from_IDirectDrawSurface7(temp
);
5962 if (src_level
&& src_level
!= src
) IDirectDrawSurface7_Release(&src_level
->IDirectDrawSurface7_iface
);
5963 if (dest_level
&& dest_level
!= dest
) IDirectDrawSurface7_Release(&dest_level
->IDirectDrawSurface7_iface
);
5965 return !dest_level
&& levelFound
;
5968 /* Helper function for IDirect3DDeviceImpl_7_Load. */
5969 static void copy_mipmap_chain(IDirect3DDeviceImpl
*device
,
5970 IDirectDrawSurfaceImpl
*dest
,
5971 IDirectDrawSurfaceImpl
*src
,
5972 const POINT
*DestPoint
,
5973 const RECT
*SrcRect
)
5975 IDirectDrawSurfaceImpl
*src_level
, *dest_level
;
5976 IDirectDrawSurface7
*temp
;
5977 DDSURFACEDESC2 ddsd
;
5981 IDirectDrawPalette
*pal
= NULL
, *pal_src
= NULL
;
5985 /* Copy palette, if possible. */
5986 IDirectDrawSurface7_GetPalette(&src
->IDirectDrawSurface7_iface
, &pal_src
);
5987 IDirectDrawSurface7_GetPalette(&dest
->IDirectDrawSurface7_iface
, &pal
);
5989 if (pal_src
!= NULL
&& pal
!= NULL
)
5991 PALETTEENTRY palent
[256];
5993 IDirectDrawPalette_GetEntries(pal_src
, 0, 0, 256, palent
);
5994 IDirectDrawPalette_SetEntries(pal
, 0, 0, 256, palent
);
5997 if (pal
) IDirectDrawPalette_Release(pal
);
5998 if (pal_src
) IDirectDrawPalette_Release(pal_src
);
6000 /* Copy colorkeys, if present. */
6001 for (ckeyflag
= DDCKEY_DESTBLT
; ckeyflag
<= DDCKEY_SRCOVERLAY
; ckeyflag
<<= 1)
6003 hr
= IDirectDrawSurface7_GetColorKey(&src
->IDirectDrawSurface7_iface
, ckeyflag
, &ddckey
);
6007 IDirectDrawSurface7_SetColorKey(&dest
->IDirectDrawSurface7_iface
, ckeyflag
, &ddckey
);
6015 src_rect
= *SrcRect
;
6017 for (;src_level
&& dest_level
;)
6019 if (src_level
->surface_desc
.dwWidth
== dest_level
->surface_desc
.dwWidth
&&
6020 src_level
->surface_desc
.dwHeight
== dest_level
->surface_desc
.dwHeight
)
6022 UINT src_w
= src_rect
.right
- src_rect
.left
;
6023 UINT src_h
= src_rect
.bottom
- src_rect
.top
;
6024 RECT dst_rect
= {point
.x
, point
.y
, point
.x
+ src_w
, point
.y
+ src_h
};
6026 if (FAILED(hr
= wined3d_surface_blt(dest_level
->wined3d_surface
, &dst_rect
,
6027 src_level
->wined3d_surface
, &src_rect
, 0, NULL
, WINED3DTEXF_POINT
)))
6028 ERR("Blit failed, hr %#x.\n", hr
);
6030 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
6031 ddsd
.ddsCaps
.dwCaps2
= DDSCAPS2_MIPMAPSUBLEVEL
;
6032 IDirectDrawSurface7_GetAttachedSurface(&dest_level
->IDirectDrawSurface7_iface
, &ddsd
.ddsCaps
, &temp
);
6034 if (dest_level
!= dest
) IDirectDrawSurface7_Release(&dest_level
->IDirectDrawSurface7_iface
);
6036 dest_level
= unsafe_impl_from_IDirectDrawSurface7(temp
);
6039 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
6040 ddsd
.ddsCaps
.dwCaps2
= DDSCAPS2_MIPMAPSUBLEVEL
;
6041 IDirectDrawSurface7_GetAttachedSurface(&src_level
->IDirectDrawSurface7_iface
, &ddsd
.ddsCaps
, &temp
);
6043 if (src_level
!= src
) IDirectDrawSurface7_Release(&src_level
->IDirectDrawSurface7_iface
);
6045 src_level
= unsafe_impl_from_IDirectDrawSurface7(temp
);
6052 src_rect
.right
= (src_rect
.right
+ 1) / 2;
6053 src_rect
.bottom
= (src_rect
.bottom
+ 1) / 2;
6056 if (src_level
&& src_level
!= src
) IDirectDrawSurface7_Release(&src_level
->IDirectDrawSurface7_iface
);
6057 if (dest_level
&& dest_level
!= dest
) IDirectDrawSurface7_Release(&dest_level
->IDirectDrawSurface7_iface
);
6060 /*****************************************************************************
6061 * IDirect3DDevice7::Load
6063 * Loads a rectangular area from the source into the destination texture.
6064 * It can also copy the source to the faces of a cubic environment map
6069 * DestTex: Destination texture
6070 * DestPoint: Point in the destination where the source image should be
6072 * SrcTex: Source texture
6073 * SrcRect: Source rectangle
6074 * Flags: Cubemap faces to load (DDSCAPS2_CUBEMAP_ALLFACES, DDSCAPS2_CUBEMAP_POSITIVEX,
6075 * DDSCAPS2_CUBEMAP_NEGATIVEX, DDSCAPS2_CUBEMAP_POSITIVEY, DDSCAPS2_CUBEMAP_NEGATIVEY,
6076 * DDSCAPS2_CUBEMAP_POSITIVEZ, DDSCAPS2_CUBEMAP_NEGATIVEZ)
6080 * DDERR_INVALIDPARAMS if DestTex or SrcTex are NULL, broken coordinates or anything unexpected.
6083 *****************************************************************************/
6086 IDirect3DDeviceImpl_7_Load(IDirect3DDevice7
*iface
,
6087 IDirectDrawSurface7
*DestTex
,
6089 IDirectDrawSurface7
*SrcTex
,
6093 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
6094 IDirectDrawSurfaceImpl
*dest
= unsafe_impl_from_IDirectDrawSurface7(DestTex
);
6095 IDirectDrawSurfaceImpl
*src
= unsafe_impl_from_IDirectDrawSurface7(SrcTex
);
6099 TRACE("iface %p, dst_texture %p, dst_pos %s, src_texture %p, src_rect %s, flags %#x.\n",
6100 iface
, DestTex
, wine_dbgstr_point(DestPoint
), SrcTex
, wine_dbgstr_rect(SrcRect
), Flags
);
6102 if( (!src
) || (!dest
) )
6103 return DDERR_INVALIDPARAMS
;
6105 wined3d_mutex_lock();
6107 if (SrcRect
) srcrect
= *SrcRect
;
6110 srcrect
.left
= srcrect
.top
= 0;
6111 srcrect
.right
= src
->surface_desc
.dwWidth
;
6112 srcrect
.bottom
= src
->surface_desc
.dwHeight
;
6115 if (DestPoint
) destpoint
= *DestPoint
;
6118 destpoint
.x
= destpoint
.y
= 0;
6120 /* Check bad dimensions. DestPoint is validated against src, not dest, because
6121 * destination can be a subset of mip levels, in which case actual coordinates used
6122 * for it may be divided. If any dimension of dest is larger than source, it can't be
6123 * mip level subset, so an error can be returned early.
6125 if (srcrect
.left
>= srcrect
.right
|| srcrect
.top
>= srcrect
.bottom
||
6126 srcrect
.right
> src
->surface_desc
.dwWidth
||
6127 srcrect
.bottom
> src
->surface_desc
.dwHeight
||
6128 destpoint
.x
+ srcrect
.right
- srcrect
.left
> src
->surface_desc
.dwWidth
||
6129 destpoint
.y
+ srcrect
.bottom
- srcrect
.top
> src
->surface_desc
.dwHeight
||
6130 dest
->surface_desc
.dwWidth
> src
->surface_desc
.dwWidth
||
6131 dest
->surface_desc
.dwHeight
> src
->surface_desc
.dwHeight
)
6133 wined3d_mutex_unlock();
6134 return DDERR_INVALIDPARAMS
;
6137 /* Must be top level surfaces. */
6138 if (src
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_MIPMAPSUBLEVEL
||
6139 dest
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_MIPMAPSUBLEVEL
)
6141 wined3d_mutex_unlock();
6142 return DDERR_INVALIDPARAMS
;
6145 if (src
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_CUBEMAP
)
6147 DWORD src_face_flag
, dest_face_flag
;
6148 IDirectDrawSurfaceImpl
*src_face
, *dest_face
;
6149 IDirectDrawSurface7
*temp
;
6150 DDSURFACEDESC2 ddsd
;
6153 if (!(dest
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_CUBEMAP
))
6155 wined3d_mutex_unlock();
6156 return DDERR_INVALIDPARAMS
;
6159 /* Iterate through cube faces 2 times. First time is just to check INVALIDPARAMS conditions, second
6160 * time it's actual surface loading. */
6161 for (i
= 0; i
< 2; i
++)
6166 for (;dest_face
&& src_face
;)
6168 src_face_flag
= src_face
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_CUBEMAP_ALLFACES
;
6169 dest_face_flag
= dest_face
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_CUBEMAP_ALLFACES
;
6171 if (src_face_flag
== dest_face_flag
)
6175 /* Destination mip levels must be subset of source mip levels. */
6176 if (!is_mip_level_subset(dest_face
, src_face
))
6178 wined3d_mutex_unlock();
6179 return DDERR_INVALIDPARAMS
;
6182 else if (Flags
& dest_face_flag
)
6184 copy_mipmap_chain(This
, dest_face
, src_face
, &destpoint
, &srcrect
);
6187 if (src_face_flag
< DDSCAPS2_CUBEMAP_NEGATIVEZ
)
6189 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
6190 ddsd
.ddsCaps
.dwCaps2
= DDSCAPS2_CUBEMAP
| (src_face_flag
<< 1);
6191 IDirectDrawSurface7_GetAttachedSurface(&src
->IDirectDrawSurface7_iface
, &ddsd
.ddsCaps
, &temp
);
6193 if (src_face
!= src
) IDirectDrawSurface7_Release(&src_face
->IDirectDrawSurface7_iface
);
6195 src_face
= unsafe_impl_from_IDirectDrawSurface7(temp
);
6199 if (src_face
!= src
) IDirectDrawSurface7_Release(&src_face
->IDirectDrawSurface7_iface
);
6205 if (dest_face_flag
< DDSCAPS2_CUBEMAP_NEGATIVEZ
)
6207 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
6208 ddsd
.ddsCaps
.dwCaps2
= DDSCAPS2_CUBEMAP
| (dest_face_flag
<< 1);
6209 IDirectDrawSurface7_GetAttachedSurface(&dest
->IDirectDrawSurface7_iface
, &ddsd
.ddsCaps
, &temp
);
6211 if (dest_face
!= dest
) IDirectDrawSurface7_Release(&dest_face
->IDirectDrawSurface7_iface
);
6213 dest_face
= unsafe_impl_from_IDirectDrawSurface7(temp
);
6217 if (dest_face
!= dest
) IDirectDrawSurface7_Release(&dest_face
->IDirectDrawSurface7_iface
);
6225 /* Native returns error if src faces are not subset of dest faces. */
6228 wined3d_mutex_unlock();
6229 return DDERR_INVALIDPARAMS
;
6234 wined3d_mutex_unlock();
6237 else if (dest
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_CUBEMAP
)
6239 wined3d_mutex_unlock();
6240 return DDERR_INVALIDPARAMS
;
6243 /* Handle non cube map textures. */
6245 /* Destination mip levels must be subset of source mip levels. */
6246 if (!is_mip_level_subset(dest
, src
))
6248 wined3d_mutex_unlock();
6249 return DDERR_INVALIDPARAMS
;
6252 copy_mipmap_chain(This
, dest
, src
, &destpoint
, &srcrect
);
6254 wined3d_mutex_unlock();
6259 static HRESULT WINAPI
6260 IDirect3DDeviceImpl_7_Load_FPUSetup(IDirect3DDevice7
*iface
,
6261 IDirectDrawSurface7
*DestTex
,
6263 IDirectDrawSurface7
*SrcTex
,
6267 return IDirect3DDeviceImpl_7_Load(iface
, DestTex
, DestPoint
, SrcTex
, SrcRect
, Flags
);
6270 static HRESULT WINAPI
6271 IDirect3DDeviceImpl_7_Load_FPUPreserve(IDirect3DDevice7
*iface
,
6272 IDirectDrawSurface7
*DestTex
,
6274 IDirectDrawSurface7
*SrcTex
,
6281 old_fpucw
= d3d_fpu_setup();
6282 hr
= IDirect3DDeviceImpl_7_Load(iface
, DestTex
, DestPoint
, SrcTex
, SrcRect
, Flags
);
6283 set_fpu_control_word(old_fpucw
);
6288 /*****************************************************************************
6289 * IDirect3DDevice7::LightEnable
6291 * Enables or disables a light
6293 * Version 7, IDirect3DLight uses this method too.
6296 * LightIndex: The index of the light to enable / disable
6297 * Enable: Enable or disable the light
6301 * For more details, see IWineD3DDevice::SetLightEnable
6303 *****************************************************************************/
6305 IDirect3DDeviceImpl_7_LightEnable(IDirect3DDevice7
*iface
,
6309 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
6312 TRACE("iface %p, light_idx %u, enabled %#x.\n", iface
, LightIndex
, Enable
);
6314 wined3d_mutex_lock();
6315 hr
= wined3d_device_set_light_enable(This
->wined3d_device
, LightIndex
, Enable
);
6316 wined3d_mutex_unlock();
6318 return hr_ddraw_from_wined3d(hr
);
6321 static HRESULT WINAPI
6322 IDirect3DDeviceImpl_7_LightEnable_FPUSetup(IDirect3DDevice7
*iface
,
6326 return IDirect3DDeviceImpl_7_LightEnable(iface
, LightIndex
, Enable
);
6329 static HRESULT WINAPI
6330 IDirect3DDeviceImpl_7_LightEnable_FPUPreserve(IDirect3DDevice7
*iface
,
6337 old_fpucw
= d3d_fpu_setup();
6338 hr
= IDirect3DDeviceImpl_7_LightEnable(iface
, LightIndex
, Enable
);
6339 set_fpu_control_word(old_fpucw
);
6344 /*****************************************************************************
6345 * IDirect3DDevice7::GetLightEnable
6347 * Retrieves if the light with the given index is enabled or not
6352 * LightIndex: Index of desired light
6353 * Enable: Pointer to a BOOL which contains the result
6357 * DDERR_INVALIDPARAMS if Enable is NULL
6358 * See IWineD3DDevice::GetLightEnable for more details
6360 *****************************************************************************/
6362 IDirect3DDeviceImpl_7_GetLightEnable(IDirect3DDevice7
*iface
,
6366 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
6369 TRACE("iface %p, light_idx %u, enabled %p.\n", iface
, LightIndex
, Enable
);
6372 return DDERR_INVALIDPARAMS
;
6374 wined3d_mutex_lock();
6375 hr
= wined3d_device_get_light_enable(This
->wined3d_device
, LightIndex
, Enable
);
6376 wined3d_mutex_unlock();
6378 return hr_ddraw_from_wined3d(hr
);
6381 static HRESULT WINAPI
6382 IDirect3DDeviceImpl_7_GetLightEnable_FPUSetup(IDirect3DDevice7
*iface
,
6386 return IDirect3DDeviceImpl_7_GetLightEnable(iface
, LightIndex
, Enable
);
6389 static HRESULT WINAPI
6390 IDirect3DDeviceImpl_7_GetLightEnable_FPUPreserve(IDirect3DDevice7
*iface
,
6397 old_fpucw
= d3d_fpu_setup();
6398 hr
= IDirect3DDeviceImpl_7_GetLightEnable(iface
, LightIndex
, Enable
);
6399 set_fpu_control_word(old_fpucw
);
6404 /*****************************************************************************
6405 * IDirect3DDevice7::SetClipPlane
6407 * Sets custom clipping plane
6412 * Index: The index of the clipping plane
6413 * PlaneEquation: An equation defining the clipping plane
6417 * DDERR_INVALIDPARAMS if PlaneEquation is NULL
6418 * See IWineD3DDevice::SetClipPlane for more details
6420 *****************************************************************************/
6422 IDirect3DDeviceImpl_7_SetClipPlane(IDirect3DDevice7
*iface
,
6424 D3DVALUE
* PlaneEquation
)
6426 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
6429 TRACE("iface %p, idx %u, plane %p.\n", iface
, Index
, PlaneEquation
);
6432 return DDERR_INVALIDPARAMS
;
6434 wined3d_mutex_lock();
6435 hr
= wined3d_device_set_clip_plane(This
->wined3d_device
, Index
, PlaneEquation
);
6436 wined3d_mutex_unlock();
6441 static HRESULT WINAPI
6442 IDirect3DDeviceImpl_7_SetClipPlane_FPUSetup(IDirect3DDevice7
*iface
,
6444 D3DVALUE
* PlaneEquation
)
6446 return IDirect3DDeviceImpl_7_SetClipPlane(iface
, Index
, PlaneEquation
);
6449 static HRESULT WINAPI
6450 IDirect3DDeviceImpl_7_SetClipPlane_FPUPreserve(IDirect3DDevice7
*iface
,
6452 D3DVALUE
* PlaneEquation
)
6457 old_fpucw
= d3d_fpu_setup();
6458 hr
= IDirect3DDeviceImpl_7_SetClipPlane(iface
, Index
, PlaneEquation
);
6459 set_fpu_control_word(old_fpucw
);
6464 /*****************************************************************************
6465 * IDirect3DDevice7::GetClipPlane
6467 * Returns the clipping plane with a specific index
6470 * Index: The index of the desired plane
6471 * PlaneEquation: Address to store the plane equation to
6475 * DDERR_INVALIDPARAMS if PlaneEquation is NULL
6476 * See IWineD3DDevice::GetClipPlane for more details
6478 *****************************************************************************/
6480 IDirect3DDeviceImpl_7_GetClipPlane(IDirect3DDevice7
*iface
,
6482 D3DVALUE
* PlaneEquation
)
6484 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
6487 TRACE("iface %p, idx %u, plane %p.\n", iface
, Index
, PlaneEquation
);
6490 return DDERR_INVALIDPARAMS
;
6492 wined3d_mutex_lock();
6493 hr
= wined3d_device_get_clip_plane(This
->wined3d_device
, Index
, PlaneEquation
);
6494 wined3d_mutex_unlock();
6499 static HRESULT WINAPI
6500 IDirect3DDeviceImpl_7_GetClipPlane_FPUSetup(IDirect3DDevice7
*iface
,
6502 D3DVALUE
* PlaneEquation
)
6504 return IDirect3DDeviceImpl_7_GetClipPlane(iface
, Index
, PlaneEquation
);
6507 static HRESULT WINAPI
6508 IDirect3DDeviceImpl_7_GetClipPlane_FPUPreserve(IDirect3DDevice7
*iface
,
6510 D3DVALUE
* PlaneEquation
)
6515 old_fpucw
= d3d_fpu_setup();
6516 hr
= IDirect3DDeviceImpl_7_GetClipPlane(iface
, Index
, PlaneEquation
);
6517 set_fpu_control_word(old_fpucw
);
6522 /*****************************************************************************
6523 * IDirect3DDevice7::GetInfo
6525 * Retrieves some information about the device. The DirectX sdk says that
6526 * this version returns S_FALSE for all retail builds of DirectX, that's what
6527 * this implementation does.
6530 * DevInfoID: Information type requested
6531 * DevInfoStruct: Pointer to a structure to store the info to
6532 * Size: Size of the structure
6535 * S_FALSE, because it's a non-debug driver
6537 *****************************************************************************/
6538 static HRESULT WINAPI
6539 IDirect3DDeviceImpl_7_GetInfo(IDirect3DDevice7
*iface
,
6541 void *DevInfoStruct
,
6544 TRACE("iface %p, info_id %#x, info %p, info_size %u.\n",
6545 iface
, DevInfoID
, DevInfoStruct
, Size
);
6547 if (TRACE_ON(ddraw
))
6549 TRACE(" info requested : ");
6552 case D3DDEVINFOID_TEXTUREMANAGER
: TRACE("D3DDEVINFOID_TEXTUREMANAGER\n"); break;
6553 case D3DDEVINFOID_D3DTEXTUREMANAGER
: TRACE("D3DDEVINFOID_D3DTEXTUREMANAGER\n"); break;
6554 case D3DDEVINFOID_TEXTURING
: TRACE("D3DDEVINFOID_TEXTURING\n"); break;
6555 default: ERR(" invalid flag !!!\n"); return DDERR_INVALIDPARAMS
;
6559 return S_FALSE
; /* According to MSDN, this is valid for a non-debug driver */
6562 /* For performance optimization, devices created in FPUSETUP and FPUPRESERVE modes
6563 * have separate vtables. Simple functions where this doesn't matter like GetDirect3D
6564 * are not duplicated.
6566 * Device created with DDSCL_FPUSETUP (d3d7 default) - device methods assume that FPU
6567 * has already been setup for optimal d3d operation.
6569 * Device created with DDSCL_FPUPRESERVE - resets and restores FPU mode when necessary in
6570 * d3d calls (FPU may be in a mode non-suitable for d3d when the app calls d3d). Required
6571 * by Sacrifice (game). */
6572 static const struct IDirect3DDevice7Vtbl d3d_device7_fpu_setup_vtbl
=
6574 /*** IUnknown Methods ***/
6575 IDirect3DDeviceImpl_7_QueryInterface
,
6576 IDirect3DDeviceImpl_7_AddRef
,
6577 IDirect3DDeviceImpl_7_Release
,
6578 /*** IDirect3DDevice7 ***/
6579 IDirect3DDeviceImpl_7_GetCaps_FPUSetup
,
6580 IDirect3DDeviceImpl_7_EnumTextureFormats_FPUSetup
,
6581 IDirect3DDeviceImpl_7_BeginScene_FPUSetup
,
6582 IDirect3DDeviceImpl_7_EndScene_FPUSetup
,
6583 IDirect3DDeviceImpl_7_GetDirect3D
,
6584 IDirect3DDeviceImpl_7_SetRenderTarget_FPUSetup
,
6585 IDirect3DDeviceImpl_7_GetRenderTarget
,
6586 IDirect3DDeviceImpl_7_Clear_FPUSetup
,
6587 IDirect3DDeviceImpl_7_SetTransform_FPUSetup
,
6588 IDirect3DDeviceImpl_7_GetTransform_FPUSetup
,
6589 IDirect3DDeviceImpl_7_SetViewport_FPUSetup
,
6590 IDirect3DDeviceImpl_7_MultiplyTransform_FPUSetup
,
6591 IDirect3DDeviceImpl_7_GetViewport_FPUSetup
,
6592 IDirect3DDeviceImpl_7_SetMaterial_FPUSetup
,
6593 IDirect3DDeviceImpl_7_GetMaterial_FPUSetup
,
6594 IDirect3DDeviceImpl_7_SetLight_FPUSetup
,
6595 IDirect3DDeviceImpl_7_GetLight_FPUSetup
,
6596 IDirect3DDeviceImpl_7_SetRenderState_FPUSetup
,
6597 IDirect3DDeviceImpl_7_GetRenderState_FPUSetup
,
6598 IDirect3DDeviceImpl_7_BeginStateBlock_FPUSetup
,
6599 IDirect3DDeviceImpl_7_EndStateBlock_FPUSetup
,
6600 IDirect3DDeviceImpl_7_PreLoad_FPUSetup
,
6601 IDirect3DDeviceImpl_7_DrawPrimitive_FPUSetup
,
6602 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUSetup
,
6603 IDirect3DDeviceImpl_7_SetClipStatus
,
6604 IDirect3DDeviceImpl_7_GetClipStatus
,
6605 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUSetup
,
6606 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUSetup
,
6607 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUSetup
,
6608 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUSetup
,
6609 IDirect3DDeviceImpl_7_ComputeSphereVisibility
,
6610 IDirect3DDeviceImpl_7_GetTexture_FPUSetup
,
6611 IDirect3DDeviceImpl_7_SetTexture_FPUSetup
,
6612 IDirect3DDeviceImpl_7_GetTextureStageState_FPUSetup
,
6613 IDirect3DDeviceImpl_7_SetTextureStageState_FPUSetup
,
6614 IDirect3DDeviceImpl_7_ValidateDevice_FPUSetup
,
6615 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUSetup
,
6616 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUSetup
,
6617 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUSetup
,
6618 IDirect3DDeviceImpl_7_CreateStateBlock_FPUSetup
,
6619 IDirect3DDeviceImpl_7_Load_FPUSetup
,
6620 IDirect3DDeviceImpl_7_LightEnable_FPUSetup
,
6621 IDirect3DDeviceImpl_7_GetLightEnable_FPUSetup
,
6622 IDirect3DDeviceImpl_7_SetClipPlane_FPUSetup
,
6623 IDirect3DDeviceImpl_7_GetClipPlane_FPUSetup
,
6624 IDirect3DDeviceImpl_7_GetInfo
6627 static const struct IDirect3DDevice7Vtbl d3d_device7_fpu_preserve_vtbl
=
6629 /*** IUnknown Methods ***/
6630 IDirect3DDeviceImpl_7_QueryInterface
,
6631 IDirect3DDeviceImpl_7_AddRef
,
6632 IDirect3DDeviceImpl_7_Release
,
6633 /*** IDirect3DDevice7 ***/
6634 IDirect3DDeviceImpl_7_GetCaps_FPUPreserve
,
6635 IDirect3DDeviceImpl_7_EnumTextureFormats_FPUPreserve
,
6636 IDirect3DDeviceImpl_7_BeginScene_FPUPreserve
,
6637 IDirect3DDeviceImpl_7_EndScene_FPUPreserve
,
6638 IDirect3DDeviceImpl_7_GetDirect3D
,
6639 IDirect3DDeviceImpl_7_SetRenderTarget_FPUPreserve
,
6640 IDirect3DDeviceImpl_7_GetRenderTarget
,
6641 IDirect3DDeviceImpl_7_Clear_FPUPreserve
,
6642 IDirect3DDeviceImpl_7_SetTransform_FPUPreserve
,
6643 IDirect3DDeviceImpl_7_GetTransform_FPUPreserve
,
6644 IDirect3DDeviceImpl_7_SetViewport_FPUPreserve
,
6645 IDirect3DDeviceImpl_7_MultiplyTransform_FPUPreserve
,
6646 IDirect3DDeviceImpl_7_GetViewport_FPUPreserve
,
6647 IDirect3DDeviceImpl_7_SetMaterial_FPUPreserve
,
6648 IDirect3DDeviceImpl_7_GetMaterial_FPUPreserve
,
6649 IDirect3DDeviceImpl_7_SetLight_FPUPreserve
,
6650 IDirect3DDeviceImpl_7_GetLight_FPUPreserve
,
6651 IDirect3DDeviceImpl_7_SetRenderState_FPUPreserve
,
6652 IDirect3DDeviceImpl_7_GetRenderState_FPUPreserve
,
6653 IDirect3DDeviceImpl_7_BeginStateBlock_FPUPreserve
,
6654 IDirect3DDeviceImpl_7_EndStateBlock_FPUPreserve
,
6655 IDirect3DDeviceImpl_7_PreLoad_FPUPreserve
,
6656 IDirect3DDeviceImpl_7_DrawPrimitive_FPUPreserve
,
6657 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUPreserve
,
6658 IDirect3DDeviceImpl_7_SetClipStatus
,
6659 IDirect3DDeviceImpl_7_GetClipStatus
,
6660 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUPreserve
,
6661 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUPreserve
,
6662 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUPreserve
,
6663 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUPreserve
,
6664 IDirect3DDeviceImpl_7_ComputeSphereVisibility
,
6665 IDirect3DDeviceImpl_7_GetTexture_FPUPreserve
,
6666 IDirect3DDeviceImpl_7_SetTexture_FPUPreserve
,
6667 IDirect3DDeviceImpl_7_GetTextureStageState_FPUPreserve
,
6668 IDirect3DDeviceImpl_7_SetTextureStageState_FPUPreserve
,
6669 IDirect3DDeviceImpl_7_ValidateDevice_FPUPreserve
,
6670 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUPreserve
,
6671 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUPreserve
,
6672 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUPreserve
,
6673 IDirect3DDeviceImpl_7_CreateStateBlock_FPUPreserve
,
6674 IDirect3DDeviceImpl_7_Load_FPUPreserve
,
6675 IDirect3DDeviceImpl_7_LightEnable_FPUPreserve
,
6676 IDirect3DDeviceImpl_7_GetLightEnable_FPUPreserve
,
6677 IDirect3DDeviceImpl_7_SetClipPlane_FPUPreserve
,
6678 IDirect3DDeviceImpl_7_GetClipPlane_FPUPreserve
,
6679 IDirect3DDeviceImpl_7_GetInfo
6682 static const struct IDirect3DDevice3Vtbl d3d_device3_vtbl
=
6684 /*** IUnknown Methods ***/
6685 IDirect3DDeviceImpl_3_QueryInterface
,
6686 IDirect3DDeviceImpl_3_AddRef
,
6687 IDirect3DDeviceImpl_3_Release
,
6688 /*** IDirect3DDevice3 ***/
6689 IDirect3DDeviceImpl_3_GetCaps
,
6690 IDirect3DDeviceImpl_3_GetStats
,
6691 IDirect3DDeviceImpl_3_AddViewport
,
6692 IDirect3DDeviceImpl_3_DeleteViewport
,
6693 IDirect3DDeviceImpl_3_NextViewport
,
6694 IDirect3DDeviceImpl_3_EnumTextureFormats
,
6695 IDirect3DDeviceImpl_3_BeginScene
,
6696 IDirect3DDeviceImpl_3_EndScene
,
6697 IDirect3DDeviceImpl_3_GetDirect3D
,
6698 IDirect3DDeviceImpl_3_SetCurrentViewport
,
6699 IDirect3DDeviceImpl_3_GetCurrentViewport
,
6700 IDirect3DDeviceImpl_3_SetRenderTarget
,
6701 IDirect3DDeviceImpl_3_GetRenderTarget
,
6702 IDirect3DDeviceImpl_3_Begin
,
6703 IDirect3DDeviceImpl_3_BeginIndexed
,
6704 IDirect3DDeviceImpl_3_Vertex
,
6705 IDirect3DDeviceImpl_3_Index
,
6706 IDirect3DDeviceImpl_3_End
,
6707 IDirect3DDeviceImpl_3_GetRenderState
,
6708 IDirect3DDeviceImpl_3_SetRenderState
,
6709 IDirect3DDeviceImpl_3_GetLightState
,
6710 IDirect3DDeviceImpl_3_SetLightState
,
6711 IDirect3DDeviceImpl_3_SetTransform
,
6712 IDirect3DDeviceImpl_3_GetTransform
,
6713 IDirect3DDeviceImpl_3_MultiplyTransform
,
6714 IDirect3DDeviceImpl_3_DrawPrimitive
,
6715 IDirect3DDeviceImpl_3_DrawIndexedPrimitive
,
6716 IDirect3DDeviceImpl_3_SetClipStatus
,
6717 IDirect3DDeviceImpl_3_GetClipStatus
,
6718 IDirect3DDeviceImpl_3_DrawPrimitiveStrided
,
6719 IDirect3DDeviceImpl_3_DrawIndexedPrimitiveStrided
,
6720 IDirect3DDeviceImpl_3_DrawPrimitiveVB
,
6721 IDirect3DDeviceImpl_3_DrawIndexedPrimitiveVB
,
6722 IDirect3DDeviceImpl_3_ComputeSphereVisibility
,
6723 IDirect3DDeviceImpl_3_GetTexture
,
6724 IDirect3DDeviceImpl_3_SetTexture
,
6725 IDirect3DDeviceImpl_3_GetTextureStageState
,
6726 IDirect3DDeviceImpl_3_SetTextureStageState
,
6727 IDirect3DDeviceImpl_3_ValidateDevice
6730 static const struct IDirect3DDevice2Vtbl d3d_device2_vtbl
=
6732 /*** IUnknown Methods ***/
6733 IDirect3DDeviceImpl_2_QueryInterface
,
6734 IDirect3DDeviceImpl_2_AddRef
,
6735 IDirect3DDeviceImpl_2_Release
,
6736 /*** IDirect3DDevice2 ***/
6737 IDirect3DDeviceImpl_2_GetCaps
,
6738 IDirect3DDeviceImpl_2_SwapTextureHandles
,
6739 IDirect3DDeviceImpl_2_GetStats
,
6740 IDirect3DDeviceImpl_2_AddViewport
,
6741 IDirect3DDeviceImpl_2_DeleteViewport
,
6742 IDirect3DDeviceImpl_2_NextViewport
,
6743 IDirect3DDeviceImpl_2_EnumTextureFormats
,
6744 IDirect3DDeviceImpl_2_BeginScene
,
6745 IDirect3DDeviceImpl_2_EndScene
,
6746 IDirect3DDeviceImpl_2_GetDirect3D
,
6747 IDirect3DDeviceImpl_2_SetCurrentViewport
,
6748 IDirect3DDeviceImpl_2_GetCurrentViewport
,
6749 IDirect3DDeviceImpl_2_SetRenderTarget
,
6750 IDirect3DDeviceImpl_2_GetRenderTarget
,
6751 IDirect3DDeviceImpl_2_Begin
,
6752 IDirect3DDeviceImpl_2_BeginIndexed
,
6753 IDirect3DDeviceImpl_2_Vertex
,
6754 IDirect3DDeviceImpl_2_Index
,
6755 IDirect3DDeviceImpl_2_End
,
6756 IDirect3DDeviceImpl_2_GetRenderState
,
6757 IDirect3DDeviceImpl_2_SetRenderState
,
6758 IDirect3DDeviceImpl_2_GetLightState
,
6759 IDirect3DDeviceImpl_2_SetLightState
,
6760 IDirect3DDeviceImpl_2_SetTransform
,
6761 IDirect3DDeviceImpl_2_GetTransform
,
6762 IDirect3DDeviceImpl_2_MultiplyTransform
,
6763 IDirect3DDeviceImpl_2_DrawPrimitive
,
6764 IDirect3DDeviceImpl_2_DrawIndexedPrimitive
,
6765 IDirect3DDeviceImpl_2_SetClipStatus
,
6766 IDirect3DDeviceImpl_2_GetClipStatus
6769 static const struct IDirect3DDeviceVtbl d3d_device1_vtbl
=
6771 /*** IUnknown Methods ***/
6772 IDirect3DDeviceImpl_1_QueryInterface
,
6773 IDirect3DDeviceImpl_1_AddRef
,
6774 IDirect3DDeviceImpl_1_Release
,
6775 /*** IDirect3DDevice1 ***/
6776 IDirect3DDeviceImpl_1_Initialize
,
6777 IDirect3DDeviceImpl_1_GetCaps
,
6778 IDirect3DDeviceImpl_1_SwapTextureHandles
,
6779 IDirect3DDeviceImpl_1_CreateExecuteBuffer
,
6780 IDirect3DDeviceImpl_1_GetStats
,
6781 IDirect3DDeviceImpl_1_Execute
,
6782 IDirect3DDeviceImpl_1_AddViewport
,
6783 IDirect3DDeviceImpl_1_DeleteViewport
,
6784 IDirect3DDeviceImpl_1_NextViewport
,
6785 IDirect3DDeviceImpl_1_Pick
,
6786 IDirect3DDeviceImpl_1_GetPickRecords
,
6787 IDirect3DDeviceImpl_1_EnumTextureFormats
,
6788 IDirect3DDeviceImpl_1_CreateMatrix
,
6789 IDirect3DDeviceImpl_1_SetMatrix
,
6790 IDirect3DDeviceImpl_1_GetMatrix
,
6791 IDirect3DDeviceImpl_1_DeleteMatrix
,
6792 IDirect3DDeviceImpl_1_BeginScene
,
6793 IDirect3DDeviceImpl_1_EndScene
,
6794 IDirect3DDeviceImpl_1_GetDirect3D
6797 IDirect3DDeviceImpl
*unsafe_impl_from_IDirect3DDevice7(IDirect3DDevice7
*iface
)
6799 if (!iface
) return NULL
;
6800 assert((iface
->lpVtbl
== &d3d_device7_fpu_preserve_vtbl
) || (iface
->lpVtbl
== &d3d_device7_fpu_setup_vtbl
));
6801 return CONTAINING_RECORD(iface
, IDirect3DDeviceImpl
, IDirect3DDevice7_iface
);
6804 IDirect3DDeviceImpl
*unsafe_impl_from_IDirect3DDevice3(IDirect3DDevice3
*iface
)
6806 if (!iface
) return NULL
;
6807 assert(iface
->lpVtbl
== &d3d_device3_vtbl
);
6808 return CONTAINING_RECORD(iface
, IDirect3DDeviceImpl
, IDirect3DDevice3_iface
);
6811 IDirect3DDeviceImpl
*unsafe_impl_from_IDirect3DDevice2(IDirect3DDevice2
*iface
)
6813 if (!iface
) return NULL
;
6814 assert(iface
->lpVtbl
== &d3d_device2_vtbl
);
6815 return CONTAINING_RECORD(iface
, IDirect3DDeviceImpl
, IDirect3DDevice2_iface
);
6818 IDirect3DDeviceImpl
*unsafe_impl_from_IDirect3DDevice(IDirect3DDevice
*iface
)
6820 if (!iface
) return NULL
;
6821 assert(iface
->lpVtbl
== &d3d_device1_vtbl
);
6822 return CONTAINING_RECORD(iface
, IDirect3DDeviceImpl
, IDirect3DDevice_iface
);
6825 /*****************************************************************************
6826 * IDirect3DDeviceImpl_UpdateDepthStencil
6828 * Checks the current render target for attached depth stencils and sets the
6829 * WineD3D depth stencil accordingly.
6832 * The depth stencil state to set if creating the device
6834 *****************************************************************************/
6836 IDirect3DDeviceImpl_UpdateDepthStencil(IDirect3DDeviceImpl
*This
)
6838 IDirectDrawSurface7
*depthStencil
= NULL
;
6839 IDirectDrawSurfaceImpl
*dsi
;
6840 static DDSCAPS2 depthcaps
= { DDSCAPS_ZBUFFER
, 0, 0, 0 };
6842 IDirectDrawSurface7_GetAttachedSurface(&This
->target
->IDirectDrawSurface7_iface
, &depthcaps
, &depthStencil
);
6845 TRACE("Setting wined3d depth stencil to NULL\n");
6846 wined3d_device_set_depth_stencil(This
->wined3d_device
, NULL
);
6847 return WINED3DZB_FALSE
;
6850 dsi
= impl_from_IDirectDrawSurface7(depthStencil
);
6851 TRACE("Setting wined3d depth stencil to %p (wined3d %p)\n", dsi
, dsi
->wined3d_surface
);
6852 wined3d_device_set_depth_stencil(This
->wined3d_device
, dsi
->wined3d_surface
);
6854 IDirectDrawSurface7_Release(depthStencil
);
6855 return WINED3DZB_TRUE
;
6858 HRESULT
d3d_device_init(IDirect3DDeviceImpl
*device
, IDirectDrawImpl
*ddraw
, IDirectDrawSurfaceImpl
*target
)
6862 if (ddraw
->cooperative_level
& DDSCL_FPUPRESERVE
)
6863 device
->IDirect3DDevice7_iface
.lpVtbl
= &d3d_device7_fpu_preserve_vtbl
;
6865 device
->IDirect3DDevice7_iface
.lpVtbl
= &d3d_device7_fpu_setup_vtbl
;
6867 device
->IDirect3DDevice3_iface
.lpVtbl
= &d3d_device3_vtbl
;
6868 device
->IDirect3DDevice2_iface
.lpVtbl
= &d3d_device2_vtbl
;
6869 device
->IDirect3DDevice_iface
.lpVtbl
= &d3d_device1_vtbl
;
6871 device
->ddraw
= ddraw
;
6872 device
->target
= target
;
6873 list_init(&device
->viewport_list
);
6875 if (!ddraw_handle_table_init(&device
->handle_table
, 64))
6877 ERR("Failed to initialize handle table.\n");
6878 return DDERR_OUTOFMEMORY
;
6881 device
->legacyTextureBlending
= FALSE
;
6883 /* Create an index buffer, it's needed for indexed drawing */
6884 hr
= wined3d_buffer_create_ib(ddraw
->wined3d_device
, 0x40000 /* Length. Don't know how long it should be */,
6885 WINED3DUSAGE_DYNAMIC
/* Usage */, WINED3DPOOL_DEFAULT
, NULL
,
6886 &ddraw_null_wined3d_parent_ops
, &device
->indexbuffer
);
6889 ERR("Failed to create an index buffer, hr %#x.\n", hr
);
6890 ddraw_handle_table_destroy(&device
->handle_table
);
6894 /* This is for convenience. */
6895 device
->wined3d_device
= ddraw
->wined3d_device
;
6896 wined3d_device_incref(ddraw
->wined3d_device
);
6898 /* Render to the back buffer */
6899 hr
= wined3d_device_set_render_target(ddraw
->wined3d_device
, 0, target
->wined3d_surface
, TRUE
);
6902 ERR("Failed to set render target, hr %#x.\n", hr
);
6903 wined3d_buffer_decref(device
->indexbuffer
);
6904 ddraw_handle_table_destroy(&device
->handle_table
);
6908 /* FIXME: This is broken. The target AddRef() makes some sense, because
6909 * we store a pointer during initialization, but then that's also where
6910 * the AddRef() should be. We don't store ddraw->d3d_target anywhere. */
6911 /* AddRef the render target. Also AddRef the render target from ddraw,
6912 * because if it is released before the app releases the D3D device, the
6913 * D3D capabilities of wined3d will be uninitialized, which has bad effects.
6915 * In most cases, those surfaces are the same anyway, but this will simply
6916 * add another ref which is released when the device is destroyed. */
6917 IDirectDrawSurface7_AddRef(&target
->IDirectDrawSurface7_iface
);
6918 IDirectDrawSurface7_AddRef(&ddraw
->d3d_target
->IDirectDrawSurface7_iface
);
6920 ddraw
->d3ddevice
= device
;
6922 wined3d_device_set_render_state(ddraw
->wined3d_device
, WINED3DRS_ZENABLE
,
6923 IDirect3DDeviceImpl_UpdateDepthStencil(device
));