2 * Copyright (c) 1998-2004 Lionel Ulmer
3 * Copyright (c) 2002-2005 Christian Costa
4 * Copyright (c) 2006 Stefan Dösinger
5 * Copyright (c) 2008 Alexander Dorofeyev
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 * IDirect3DDevice implementation, version 1, 2, 3 and 7. Rendering is relayed
22 * to WineD3D, some minimal DirectDraw specific management is handled here.
23 * The Direct3DDevice is NOT the parent of the WineD3DDevice, because d3d
24 * is initialized when DirectDraw creates the primary surface.
25 * Some type management is necessary, because some D3D types changed between
31 #include "wine/port.h"
33 #include "ddraw_private.h"
35 WINE_DEFAULT_DEBUG_CHANNEL(ddraw
);
38 const GUID IID_D3DDEVICE_WineD3D
= {
42 { 0xb7,0x98,0xc6,0x8a,0x77,0x2d,0x72,0x2a }
45 static inline void set_fpu_control_word(WORD fpucw
)
47 #if defined(__i386__) && defined(__GNUC__)
48 __asm__
volatile ("fldcw %0" : : "m" (fpucw
));
49 #elif defined(__i386__) && defined(_MSC_VER)
54 static inline WORD
d3d_fpu_setup(void)
58 #if defined(__i386__) && defined(__GNUC__)
59 __asm__
volatile ("fnstcw %0" : "=m" (oldcw
));
60 #elif defined(__i386__) && defined(_MSC_VER)
63 static BOOL warned
= FALSE
;
66 FIXME("FPUPRESERVE not implemented for this platform / compiler\n");
72 set_fpu_control_word(0x37f);
77 /*****************************************************************************
78 * IUnknown Methods. Common for Version 1, 2, 3 and 7
79 *****************************************************************************/
81 /*****************************************************************************
82 * IDirect3DDevice7::QueryInterface
84 * Used to query other interfaces from a Direct3DDevice interface.
85 * It can return interface pointers to all Direct3DDevice versions as well
86 * as IDirectDraw and IDirect3D. For a link to QueryInterface
87 * rules see ddraw.c, IDirectDraw7::QueryInterface
89 * Exists in Version 1, 2, 3 and 7
92 * refiid: Interface ID queried for
93 * obj: Used to return the interface pointer
96 * D3D_OK or E_NOINTERFACE
98 *****************************************************************************/
100 IDirect3DDeviceImpl_7_QueryInterface(IDirect3DDevice7
*iface
,
104 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
106 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(refiid
), obj
);
108 /* According to COM docs, if the QueryInterface fails, obj should be set to NULL */
112 return DDERR_INVALIDPARAMS
;
114 if ( IsEqualGUID( &IID_IUnknown
, refiid
) )
119 /* Check DirectDraw Interfaces. */
120 else if( IsEqualGUID( &IID_IDirectDraw7
, refiid
) )
122 *obj
= &This
->ddraw
->IDirectDraw7_iface
;
123 TRACE("(%p) Returning IDirectDraw7 interface at %p\n", This
, *obj
);
125 else if ( IsEqualGUID( &IID_IDirectDraw4
, refiid
) )
127 *obj
= &This
->ddraw
->IDirectDraw4_iface
;
128 TRACE("(%p) Returning IDirectDraw4 interface at %p\n", This
, *obj
);
130 else if ( IsEqualGUID( &IID_IDirectDraw2
, refiid
) )
132 *obj
= &This
->ddraw
->IDirectDraw2_iface
;
133 TRACE("(%p) Returning IDirectDraw2 interface at %p\n", This
, *obj
);
135 else if( IsEqualGUID( &IID_IDirectDraw
, refiid
) )
137 *obj
= &This
->ddraw
->IDirectDraw_iface
;
138 TRACE("(%p) Returning IDirectDraw interface at %p\n", This
, *obj
);
142 else if ( IsEqualGUID( &IID_IDirect3D
, refiid
) )
144 *obj
= &This
->ddraw
->IDirect3D_iface
;
145 TRACE("(%p) Returning IDirect3D interface at %p\n", This
, *obj
);
147 else if ( IsEqualGUID( &IID_IDirect3D2
, refiid
) )
149 *obj
= &This
->ddraw
->IDirect3D2_iface
;
150 TRACE("(%p) Returning IDirect3D2 interface at %p\n", This
, *obj
);
152 else if ( IsEqualGUID( &IID_IDirect3D3
, refiid
) )
154 *obj
= &This
->ddraw
->IDirect3D3_iface
;
155 TRACE("(%p) Returning IDirect3D3 interface at %p\n", This
, *obj
);
157 else if ( IsEqualGUID( &IID_IDirect3D7
, refiid
) )
159 *obj
= &This
->ddraw
->IDirect3D7_iface
;
160 TRACE("(%p) Returning IDirect3D7 interface at %p\n", This
, *obj
);
164 else if ( IsEqualGUID( &IID_IDirect3DDevice
, refiid
) )
166 *obj
= &This
->IDirect3DDevice_iface
;
167 TRACE("(%p) Returning IDirect3DDevice interface at %p\n", This
, *obj
);
169 else if ( IsEqualGUID( &IID_IDirect3DDevice2
, refiid
) ) {
170 *obj
= &This
->IDirect3DDevice2_iface
;
171 TRACE("(%p) Returning IDirect3DDevice2 interface at %p\n", This
, *obj
);
173 else if ( IsEqualGUID( &IID_IDirect3DDevice3
, refiid
) ) {
174 *obj
= &This
->IDirect3DDevice3_iface
;
175 TRACE("(%p) Returning IDirect3DDevice3 interface at %p\n", This
, *obj
);
177 else if ( IsEqualGUID( &IID_IDirect3DDevice7
, refiid
) ) {
179 TRACE("(%p) Returning IDirect3DDevice7 interface at %p\n", This
, *obj
);
182 /* Unknown interface */
185 ERR("(%p)->(%s, %p): No interface found\n", This
, debugstr_guid(refiid
), obj
);
186 return E_NOINTERFACE
;
189 /* AddRef the returned interface */
190 IUnknown_AddRef( (IUnknown
*) *obj
);
194 static HRESULT WINAPI
IDirect3DDeviceImpl_3_QueryInterface(IDirect3DDevice3
*iface
, REFIID riid
,
197 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
198 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), obj
);
200 return IDirect3DDevice7_QueryInterface(&This
->IDirect3DDevice7_iface
, riid
, obj
);
203 static HRESULT WINAPI
IDirect3DDeviceImpl_2_QueryInterface(IDirect3DDevice2
*iface
, REFIID riid
,
206 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
207 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), obj
);
209 return IDirect3DDevice7_QueryInterface(&This
->IDirect3DDevice7_iface
, riid
, obj
);
212 static HRESULT WINAPI
IDirect3DDeviceImpl_1_QueryInterface(IDirect3DDevice
*iface
, REFIID riid
,
215 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
216 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), obp
);
218 return IDirect3DDevice7_QueryInterface(&This
->IDirect3DDevice7_iface
, riid
, obp
);
221 /*****************************************************************************
222 * IDirect3DDevice7::AddRef
224 * Increases the refcount....
225 * The most exciting Method, definitely
227 * Exists in Version 1, 2, 3 and 7
232 *****************************************************************************/
234 IDirect3DDeviceImpl_7_AddRef(IDirect3DDevice7
*iface
)
236 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
237 ULONG ref
= InterlockedIncrement(&This
->ref
);
239 TRACE("%p increasing refcount to %u.\n", This
, ref
);
244 static ULONG WINAPI
IDirect3DDeviceImpl_3_AddRef(IDirect3DDevice3
*iface
)
246 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
247 TRACE("iface %p.\n", iface
);
249 return IDirect3DDevice7_AddRef(&This
->IDirect3DDevice7_iface
);
252 static ULONG WINAPI
IDirect3DDeviceImpl_2_AddRef(IDirect3DDevice2
*iface
)
254 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
255 TRACE("iface %p.\n", iface
);
257 return IDirect3DDevice7_AddRef(&This
->IDirect3DDevice7_iface
);
260 static ULONG WINAPI
IDirect3DDeviceImpl_1_AddRef(IDirect3DDevice
*iface
)
262 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
263 TRACE("iface %p.\n", iface
);
265 return IDirect3DDevice7_AddRef(&This
->IDirect3DDevice7_iface
);
268 /*****************************************************************************
269 * IDirect3DDevice7::Release
271 * Decreases the refcount of the interface
272 * When the refcount is reduced to 0, the object is destroyed.
274 * Exists in Version 1, 2, 3 and 7
279 *****************************************************************************/
281 IDirect3DDeviceImpl_7_Release(IDirect3DDevice7
*iface
)
283 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
284 ULONG ref
= InterlockedDecrement(&This
->ref
);
286 TRACE("%p decreasing refcount to %u.\n", This
, ref
);
288 /* This method doesn't destroy the WineD3DDevice, because it's still in use for
289 * 2D rendering. IDirectDrawSurface7::Release will destroy the WineD3DDevice
290 * when the render target is released
296 wined3d_mutex_lock();
298 /* There is no need to unset any resources here, wined3d will take
299 * care of that on Uninit3D(). */
301 /* Free the index buffer. */
302 wined3d_buffer_decref(This
->indexbuffer
);
304 /* Set the device up to render to the front buffer since the back
305 * buffer will vanish soon. */
306 wined3d_device_set_render_target(This
->wined3d_device
, 0,
307 This
->ddraw
->wined3d_frontbuffer
, TRUE
);
309 /* Release the WineD3DDevice. This won't destroy it. */
310 if (!wined3d_device_decref(This
->wined3d_device
))
311 ERR("The wined3d device (%p) was destroyed unexpectedly.\n", This
->wined3d_device
);
313 /* The texture handles should be unset by now, but there might be some bits
314 * missing in our reference counting(needs test). Do a sanity check. */
315 for (i
= 0; i
< This
->handle_table
.entry_count
; ++i
)
317 struct ddraw_handle_entry
*entry
= &This
->handle_table
.entries
[i
];
321 case DDRAW_HANDLE_FREE
:
324 case DDRAW_HANDLE_MATERIAL
:
326 IDirect3DMaterialImpl
*m
= entry
->object
;
327 FIXME("Material handle %#x (%p) not unset properly.\n", i
+ 1, m
);
332 case DDRAW_HANDLE_MATRIX
:
334 /* No FIXME here because this might happen because of sloppy applications. */
335 WARN("Leftover matrix handle %#x (%p), deleting.\n", i
+ 1, entry
->object
);
336 IDirect3DDevice_DeleteMatrix(&This
->IDirect3DDevice_iface
, i
+ 1);
340 case DDRAW_HANDLE_STATEBLOCK
:
342 /* No FIXME here because this might happen because of sloppy applications. */
343 WARN("Leftover stateblock handle %#x (%p), deleting.\n", i
+ 1, entry
->object
);
344 IDirect3DDevice7_DeleteStateBlock(iface
, i
+ 1);
348 case DDRAW_HANDLE_SURFACE
:
350 IDirectDrawSurfaceImpl
*surf
= entry
->object
;
351 FIXME("Texture handle %#x (%p) not unset properly.\n", i
+ 1, surf
);
357 FIXME("Handle %#x (%p) has unknown type %#x.\n", i
+ 1, entry
->object
, entry
->type
);
362 ddraw_handle_table_destroy(&This
->handle_table
);
364 TRACE("Releasing target %p %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
);
1056 struct wined3d_display_mode mode
;
1060 static const enum wined3d_format_id FormatList
[] =
1063 WINED3DFMT_B5G5R5X1_UNORM
,
1064 WINED3DFMT_B5G5R5A1_UNORM
,
1065 WINED3DFMT_B4G4R4A4_UNORM
,
1066 WINED3DFMT_B5G6R5_UNORM
,
1068 WINED3DFMT_B8G8R8X8_UNORM
,
1069 WINED3DFMT_B8G8R8A8_UNORM
,
1071 WINED3DFMT_B2G3R3_UNORM
,
1079 static const enum wined3d_format_id BumpFormatList
[] =
1081 WINED3DFMT_R8G8_SNORM
,
1082 WINED3DFMT_R5G5_SNORM_L6_UNORM
,
1083 WINED3DFMT_R8G8_SNORM_L8X8_UNORM
,
1084 WINED3DFMT_R16G16_SNORM
,
1085 WINED3DFMT_R10G11B11_SNORM
,
1086 WINED3DFMT_R10G10B10_SNORM_A2_UNORM
1089 TRACE("iface %p, callback %p, context %p.\n", iface
, Callback
, Arg
);
1092 return DDERR_INVALIDPARAMS
;
1094 wined3d_mutex_lock();
1096 memset(&mode
, 0, sizeof(mode
));
1097 hr
= wined3d_device_get_display_mode(This
->ddraw
->wined3d_device
, 0, &mode
);
1100 wined3d_mutex_unlock();
1101 WARN("Cannot get the current adapter format\n");
1105 for (i
= 0; i
< sizeof(FormatList
) / sizeof(*FormatList
); ++i
)
1107 hr
= wined3d_check_device_format(This
->ddraw
->wineD3D
, WINED3DADAPTER_DEFAULT
, WINED3DDEVTYPE_HAL
,
1108 mode
.format_id
, 0, WINED3DRTYPE_TEXTURE
, FormatList
[i
], SURFACE_OPENGL
);
1111 DDPIXELFORMAT pformat
;
1113 memset(&pformat
, 0, sizeof(pformat
));
1114 pformat
.dwSize
= sizeof(pformat
);
1115 PixelFormat_WineD3DtoDD(&pformat
, FormatList
[i
]);
1117 TRACE("Enumerating WineD3DFormat %d\n", FormatList
[i
]);
1118 hr
= Callback(&pformat
, Arg
);
1119 if(hr
!= DDENUMRET_OK
)
1121 TRACE("Format enumeration cancelled by application\n");
1122 wined3d_mutex_unlock();
1128 for (i
= 0; i
< sizeof(BumpFormatList
) / sizeof(*BumpFormatList
); ++i
)
1130 hr
= wined3d_check_device_format(This
->ddraw
->wineD3D
, WINED3DADAPTER_DEFAULT
,
1131 WINED3DDEVTYPE_HAL
, mode
.format_id
, WINED3DUSAGE_QUERY_LEGACYBUMPMAP
,
1132 WINED3DRTYPE_TEXTURE
, BumpFormatList
[i
], SURFACE_OPENGL
);
1135 DDPIXELFORMAT pformat
;
1137 memset(&pformat
, 0, sizeof(pformat
));
1138 pformat
.dwSize
= sizeof(pformat
);
1139 PixelFormat_WineD3DtoDD(&pformat
, BumpFormatList
[i
]);
1141 TRACE("Enumerating WineD3DFormat %d\n", BumpFormatList
[i
]);
1142 hr
= Callback(&pformat
, Arg
);
1143 if(hr
!= DDENUMRET_OK
)
1145 TRACE("Format enumeration cancelled by application\n");
1146 wined3d_mutex_unlock();
1151 TRACE("End of enumeration\n");
1152 wined3d_mutex_unlock();
1157 static HRESULT WINAPI
1158 IDirect3DDeviceImpl_7_EnumTextureFormats_FPUSetup(IDirect3DDevice7
*iface
,
1159 LPD3DENUMPIXELFORMATSCALLBACK Callback
,
1162 return IDirect3DDeviceImpl_7_EnumTextureFormats(iface
, Callback
, Arg
);
1165 static HRESULT WINAPI
1166 IDirect3DDeviceImpl_7_EnumTextureFormats_FPUPreserve(IDirect3DDevice7
*iface
,
1167 LPD3DENUMPIXELFORMATSCALLBACK Callback
,
1173 old_fpucw
= d3d_fpu_setup();
1174 hr
= IDirect3DDeviceImpl_7_EnumTextureFormats(iface
, Callback
, Arg
);
1175 set_fpu_control_word(old_fpucw
);
1180 static HRESULT WINAPI
IDirect3DDeviceImpl_3_EnumTextureFormats(IDirect3DDevice3
*iface
,
1181 LPD3DENUMPIXELFORMATSCALLBACK Callback
, void *Arg
)
1183 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
1185 TRACE("iface %p, callback %p, context %p.\n", iface
, Callback
, Arg
);
1187 return IDirect3DDevice7_EnumTextureFormats(&This
->IDirect3DDevice7_iface
, Callback
, Arg
);
1190 /*****************************************************************************
1191 * IDirect3DDevice2::EnumTextureformats
1193 * EnumTextureFormats for Version 1 and 2, see
1194 * IDirect3DDevice7::EnumTexureFormats for a more detailed description.
1196 * This version has a different callback and does not enumerate FourCC
1199 *****************************************************************************/
1200 static HRESULT WINAPI
1201 IDirect3DDeviceImpl_2_EnumTextureFormats(IDirect3DDevice2
*iface
,
1202 LPD3DENUMTEXTUREFORMATSCALLBACK Callback
,
1205 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
1206 struct wined3d_display_mode mode
;
1210 static const enum wined3d_format_id FormatList
[] =
1213 WINED3DFMT_B5G5R5X1_UNORM
,
1214 WINED3DFMT_B5G5R5A1_UNORM
,
1215 WINED3DFMT_B4G4R4A4_UNORM
,
1216 WINED3DFMT_B5G6R5_UNORM
,
1218 WINED3DFMT_B8G8R8X8_UNORM
,
1219 WINED3DFMT_B8G8R8A8_UNORM
,
1221 WINED3DFMT_B2G3R3_UNORM
,
1223 /* FOURCC codes - Not in this version*/
1226 TRACE("iface %p, callback %p, context %p.\n", iface
, Callback
, Arg
);
1229 return DDERR_INVALIDPARAMS
;
1231 wined3d_mutex_lock();
1233 memset(&mode
, 0, sizeof(mode
));
1234 hr
= wined3d_device_get_display_mode(This
->ddraw
->wined3d_device
, 0, &mode
);
1237 wined3d_mutex_unlock();
1238 WARN("Cannot get the current adapter format\n");
1242 for (i
= 0; i
< sizeof(FormatList
) / sizeof(*FormatList
); ++i
)
1244 hr
= wined3d_check_device_format(This
->ddraw
->wineD3D
, 0, WINED3DDEVTYPE_HAL
,
1245 mode
.format_id
, 0, WINED3DRTYPE_TEXTURE
, FormatList
[i
], SURFACE_OPENGL
);
1248 DDSURFACEDESC sdesc
;
1250 memset(&sdesc
, 0, sizeof(sdesc
));
1251 sdesc
.dwSize
= sizeof(sdesc
);
1252 sdesc
.dwFlags
= DDSD_PIXELFORMAT
| DDSD_CAPS
;
1253 sdesc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
1254 sdesc
.ddpfPixelFormat
.dwSize
= sizeof(sdesc
.ddpfPixelFormat
);
1255 PixelFormat_WineD3DtoDD(&sdesc
.ddpfPixelFormat
, FormatList
[i
]);
1257 TRACE("Enumerating WineD3DFormat %d\n", FormatList
[i
]);
1258 hr
= Callback(&sdesc
, Arg
);
1259 if(hr
!= DDENUMRET_OK
)
1261 TRACE("Format enumeration cancelled by application\n");
1262 wined3d_mutex_unlock();
1267 TRACE("End of enumeration\n");
1268 wined3d_mutex_unlock();
1273 static HRESULT WINAPI
IDirect3DDeviceImpl_1_EnumTextureFormats(IDirect3DDevice
*iface
,
1274 LPD3DENUMTEXTUREFORMATSCALLBACK Callback
, void *Arg
)
1276 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
1278 TRACE("iface %p, callback %p, context %p.\n", iface
, Callback
, Arg
);
1280 return IDirect3DDevice2_EnumTextureFormats(&This
->IDirect3DDevice2_iface
, Callback
, Arg
);
1283 /*****************************************************************************
1284 * IDirect3DDevice::CreateMatrix
1286 * Creates a matrix handle. A handle is created and memory for a D3DMATRIX is
1287 * allocated for the handle.
1292 * D3DMatHandle: Address to return the handle at
1296 * DDERR_INVALIDPARAMS if D3DMatHandle = NULL
1298 *****************************************************************************/
1299 static HRESULT WINAPI
1300 IDirect3DDeviceImpl_1_CreateMatrix(IDirect3DDevice
*iface
, D3DMATRIXHANDLE
*D3DMatHandle
)
1302 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
1306 TRACE("iface %p, matrix_handle %p.\n", iface
, D3DMatHandle
);
1309 return DDERR_INVALIDPARAMS
;
1311 Matrix
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(D3DMATRIX
));
1314 ERR("Out of memory when allocating a D3DMATRIX\n");
1315 return DDERR_OUTOFMEMORY
;
1318 wined3d_mutex_lock();
1320 h
= ddraw_allocate_handle(&This
->handle_table
, Matrix
, DDRAW_HANDLE_MATRIX
);
1321 if (h
== DDRAW_INVALID_HANDLE
)
1323 ERR("Failed to allocate a matrix handle.\n");
1324 HeapFree(GetProcessHeap(), 0, Matrix
);
1325 wined3d_mutex_unlock();
1326 return DDERR_OUTOFMEMORY
;
1329 *D3DMatHandle
= h
+ 1;
1331 TRACE(" returning matrix handle %d\n", *D3DMatHandle
);
1333 wined3d_mutex_unlock();
1338 /*****************************************************************************
1339 * IDirect3DDevice::SetMatrix
1341 * Sets a matrix for a matrix handle. The matrix is copied into the memory
1342 * allocated for the handle
1347 * D3DMatHandle: Handle to set the matrix to
1348 * D3DMatrix: Matrix to set
1352 * DDERR_INVALIDPARAMS if the handle of the matrix is invalid or the matrix
1355 *****************************************************************************/
1356 static HRESULT WINAPI
1357 IDirect3DDeviceImpl_1_SetMatrix(IDirect3DDevice
*iface
,
1358 D3DMATRIXHANDLE D3DMatHandle
,
1359 D3DMATRIX
*D3DMatrix
)
1361 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
1364 TRACE("iface %p, matrix_handle %#x, matrix %p.\n", iface
, D3DMatHandle
, D3DMatrix
);
1366 if (!D3DMatrix
) return DDERR_INVALIDPARAMS
;
1368 wined3d_mutex_lock();
1370 m
= ddraw_get_object(&This
->handle_table
, D3DMatHandle
- 1, DDRAW_HANDLE_MATRIX
);
1373 WARN("Invalid matrix handle.\n");
1374 wined3d_mutex_unlock();
1375 return DDERR_INVALIDPARAMS
;
1378 if (TRACE_ON(ddraw
))
1379 dump_D3DMATRIX(D3DMatrix
);
1383 if (D3DMatHandle
== This
->world
)
1384 wined3d_device_set_transform(This
->wined3d_device
,
1385 WINED3DTS_WORLDMATRIX(0), (struct wined3d_matrix
*)D3DMatrix
);
1387 if (D3DMatHandle
== This
->view
)
1388 wined3d_device_set_transform(This
->wined3d_device
,
1389 WINED3DTS_VIEW
, (struct wined3d_matrix
*)D3DMatrix
);
1391 if (D3DMatHandle
== This
->proj
)
1392 wined3d_device_set_transform(This
->wined3d_device
,
1393 WINED3DTS_PROJECTION
, (struct wined3d_matrix
*)D3DMatrix
);
1395 wined3d_mutex_unlock();
1400 /*****************************************************************************
1401 * IDirect3DDevice::GetMatrix
1403 * Returns the content of a D3DMATRIX handle
1408 * D3DMatHandle: Matrix handle to read the content from
1409 * D3DMatrix: Address to store the content at
1413 * DDERR_INVALIDPARAMS if D3DMatHandle is invalid or D3DMatrix is NULL
1415 *****************************************************************************/
1416 static HRESULT WINAPI
1417 IDirect3DDeviceImpl_1_GetMatrix(IDirect3DDevice
*iface
,
1418 D3DMATRIXHANDLE D3DMatHandle
,
1419 D3DMATRIX
*D3DMatrix
)
1421 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
1424 TRACE("iface %p, matrix_handle %#x, matrix %p.\n", iface
, D3DMatHandle
, D3DMatrix
);
1426 if (!D3DMatrix
) return DDERR_INVALIDPARAMS
;
1428 wined3d_mutex_lock();
1430 m
= ddraw_get_object(&This
->handle_table
, D3DMatHandle
- 1, DDRAW_HANDLE_MATRIX
);
1433 WARN("Invalid matrix handle.\n");
1434 wined3d_mutex_unlock();
1435 return DDERR_INVALIDPARAMS
;
1440 wined3d_mutex_unlock();
1445 /*****************************************************************************
1446 * IDirect3DDevice::DeleteMatrix
1448 * Destroys a Matrix handle. Frees the memory and unsets the handle data
1453 * D3DMatHandle: Handle to destroy
1457 * DDERR_INVALIDPARAMS if D3DMatHandle is invalid
1459 *****************************************************************************/
1460 static HRESULT WINAPI
1461 IDirect3DDeviceImpl_1_DeleteMatrix(IDirect3DDevice
*iface
,
1462 D3DMATRIXHANDLE D3DMatHandle
)
1464 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
1467 TRACE("iface %p, matrix_handle %#x.\n", iface
, D3DMatHandle
);
1469 wined3d_mutex_lock();
1471 m
= ddraw_free_handle(&This
->handle_table
, D3DMatHandle
- 1, DDRAW_HANDLE_MATRIX
);
1474 WARN("Invalid matrix handle.\n");
1475 wined3d_mutex_unlock();
1476 return DDERR_INVALIDPARAMS
;
1479 wined3d_mutex_unlock();
1481 HeapFree(GetProcessHeap(), 0, m
);
1486 /*****************************************************************************
1487 * IDirect3DDevice7::BeginScene
1489 * This method must be called before any rendering is performed.
1490 * IDirect3DDevice::EndScene has to be called after the scene is complete
1492 * Version 1, 2, 3 and 7
1495 * D3D_OK on success, for details see IWineD3DDevice::BeginScene
1496 * D3DERR_SCENE_IN_SCENE if WineD3D returns an error(Only in case of an already
1499 *****************************************************************************/
1501 IDirect3DDeviceImpl_7_BeginScene(IDirect3DDevice7
*iface
)
1503 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
1506 TRACE("iface %p.\n", iface
);
1508 wined3d_mutex_lock();
1509 hr
= wined3d_device_begin_scene(This
->wined3d_device
);
1510 wined3d_mutex_unlock();
1512 if(hr
== WINED3D_OK
) return D3D_OK
;
1513 else return D3DERR_SCENE_IN_SCENE
; /* TODO: Other possible causes of failure */
1516 static HRESULT WINAPI
1517 IDirect3DDeviceImpl_7_BeginScene_FPUSetup(IDirect3DDevice7
*iface
)
1519 return IDirect3DDeviceImpl_7_BeginScene(iface
);
1522 static HRESULT WINAPI
1523 IDirect3DDeviceImpl_7_BeginScene_FPUPreserve(IDirect3DDevice7
*iface
)
1528 old_fpucw
= d3d_fpu_setup();
1529 hr
= IDirect3DDeviceImpl_7_BeginScene(iface
);
1530 set_fpu_control_word(old_fpucw
);
1535 static HRESULT WINAPI
IDirect3DDeviceImpl_3_BeginScene(IDirect3DDevice3
*iface
)
1537 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
1538 TRACE("iface %p.\n", iface
);
1540 return IDirect3DDevice7_BeginScene(&This
->IDirect3DDevice7_iface
);
1543 static HRESULT WINAPI
IDirect3DDeviceImpl_2_BeginScene(IDirect3DDevice2
*iface
)
1545 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
1546 TRACE("iface %p.\n", iface
);
1548 return IDirect3DDevice7_BeginScene(&This
->IDirect3DDevice7_iface
);
1551 static HRESULT WINAPI
IDirect3DDeviceImpl_1_BeginScene(IDirect3DDevice
*iface
)
1553 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
1554 TRACE("iface %p.\n", iface
);
1556 return IDirect3DDevice7_BeginScene(&This
->IDirect3DDevice7_iface
);
1559 /*****************************************************************************
1560 * IDirect3DDevice7::EndScene
1562 * Ends a scene that has been begun with IDirect3DDevice7::BeginScene.
1563 * This method must be called after rendering is finished.
1565 * Version 1, 2, 3 and 7
1568 * D3D_OK on success, for details see IWineD3DDevice::EndScene
1569 * D3DERR_SCENE_NOT_IN_SCENE is returned if WineD3D returns an error. It does
1570 * that only if the scene was already ended.
1572 *****************************************************************************/
1574 IDirect3DDeviceImpl_7_EndScene(IDirect3DDevice7
*iface
)
1576 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
1579 TRACE("iface %p.\n", iface
);
1581 wined3d_mutex_lock();
1582 hr
= wined3d_device_end_scene(This
->wined3d_device
);
1583 wined3d_mutex_unlock();
1585 if(hr
== WINED3D_OK
) return D3D_OK
;
1586 else return D3DERR_SCENE_NOT_IN_SCENE
;
1589 static HRESULT WINAPI DECLSPEC_HOTPATCH
1590 IDirect3DDeviceImpl_7_EndScene_FPUSetup(IDirect3DDevice7
*iface
)
1592 return IDirect3DDeviceImpl_7_EndScene(iface
);
1595 static HRESULT WINAPI DECLSPEC_HOTPATCH
1596 IDirect3DDeviceImpl_7_EndScene_FPUPreserve(IDirect3DDevice7
*iface
)
1601 old_fpucw
= d3d_fpu_setup();
1602 hr
= IDirect3DDeviceImpl_7_EndScene(iface
);
1603 set_fpu_control_word(old_fpucw
);
1608 static HRESULT WINAPI DECLSPEC_HOTPATCH
IDirect3DDeviceImpl_3_EndScene(IDirect3DDevice3
*iface
)
1610 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
1611 TRACE("iface %p.\n", iface
);
1613 return IDirect3DDevice7_EndScene(&This
->IDirect3DDevice7_iface
);
1616 static HRESULT WINAPI DECLSPEC_HOTPATCH
IDirect3DDeviceImpl_2_EndScene(IDirect3DDevice2
*iface
)
1618 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
1619 TRACE("iface %p.\n", iface
);
1621 return IDirect3DDevice7_EndScene(&This
->IDirect3DDevice7_iface
);
1624 static HRESULT WINAPI DECLSPEC_HOTPATCH
IDirect3DDeviceImpl_1_EndScene(IDirect3DDevice
*iface
)
1626 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
1627 TRACE("iface %p.\n", iface
);
1629 return IDirect3DDevice7_EndScene(&This
->IDirect3DDevice7_iface
);
1632 /*****************************************************************************
1633 * IDirect3DDevice7::GetDirect3D
1635 * Returns the IDirect3D(= interface to the DirectDraw object) used to create
1639 * Direct3D7: Address to store the interface pointer at
1643 * DDERR_INVALIDPARAMS if Direct3D7 == NULL
1645 *****************************************************************************/
1646 static HRESULT WINAPI
1647 IDirect3DDeviceImpl_7_GetDirect3D(IDirect3DDevice7
*iface
,
1648 IDirect3D7
**Direct3D7
)
1650 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
1652 TRACE("iface %p, d3d %p.\n", iface
, Direct3D7
);
1655 return DDERR_INVALIDPARAMS
;
1657 *Direct3D7
= &This
->ddraw
->IDirect3D7_iface
;
1658 IDirect3D7_AddRef(*Direct3D7
);
1660 TRACE(" returning interface %p\n", *Direct3D7
);
1664 static HRESULT WINAPI
IDirect3DDeviceImpl_3_GetDirect3D(IDirect3DDevice3
*iface
,
1665 IDirect3D3
**Direct3D3
)
1667 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
1669 TRACE("iface %p, d3d %p.\n", iface
, Direct3D3
);
1672 return DDERR_INVALIDPARAMS
;
1674 IDirect3D3_AddRef(&This
->ddraw
->IDirect3D3_iface
);
1675 *Direct3D3
= &This
->ddraw
->IDirect3D3_iface
;
1676 TRACE(" returning interface %p\n", *Direct3D3
);
1680 static HRESULT WINAPI
IDirect3DDeviceImpl_2_GetDirect3D(IDirect3DDevice2
*iface
,
1681 IDirect3D2
**Direct3D2
)
1683 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
1685 TRACE("iface %p, d3d %p.\n", iface
, Direct3D2
);
1688 return DDERR_INVALIDPARAMS
;
1690 IDirect3D2_AddRef(&This
->ddraw
->IDirect3D2_iface
);
1691 *Direct3D2
= &This
->ddraw
->IDirect3D2_iface
;
1692 TRACE(" returning interface %p\n", *Direct3D2
);
1696 static HRESULT WINAPI
IDirect3DDeviceImpl_1_GetDirect3D(IDirect3DDevice
*iface
,
1697 IDirect3D
**Direct3D
)
1699 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
1701 TRACE("iface %p, d3d %p.\n", iface
, Direct3D
);
1704 return DDERR_INVALIDPARAMS
;
1706 IDirect3D_AddRef(&This
->ddraw
->IDirect3D_iface
);
1707 *Direct3D
= &This
->ddraw
->IDirect3D_iface
;
1708 TRACE(" returning interface %p\n", *Direct3D
);
1712 /*****************************************************************************
1713 * IDirect3DDevice3::SetCurrentViewport
1715 * Sets a Direct3DViewport as the current viewport.
1716 * For the thunks note that all viewport interface versions are equal
1719 * Direct3DViewport3: The viewport to set
1725 * (Is a NULL viewport valid?)
1727 *****************************************************************************/
1728 static HRESULT WINAPI
1729 IDirect3DDeviceImpl_3_SetCurrentViewport(IDirect3DDevice3
*iface
,
1730 IDirect3DViewport3
*Direct3DViewport3
)
1732 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
1733 IDirect3DViewportImpl
*vp
= unsafe_impl_from_IDirect3DViewport3(Direct3DViewport3
);
1735 TRACE("iface %p, viewport %p.\n", iface
, Direct3DViewport3
);
1737 wined3d_mutex_lock();
1738 /* Do nothing if the specified viewport is the same as the current one */
1739 if (This
->current_viewport
== vp
)
1741 wined3d_mutex_unlock();
1745 if (vp
->active_device
!= This
)
1747 WARN("Viewport %p active device is %p.\n", vp
, vp
->active_device
);
1748 wined3d_mutex_unlock();
1749 return DDERR_INVALIDPARAMS
;
1752 /* Release previous viewport and AddRef the new one */
1753 if (This
->current_viewport
)
1755 TRACE("ViewportImpl is at %p, interface is at %p\n", This
->current_viewport
,
1756 &This
->current_viewport
->IDirect3DViewport3_iface
);
1757 IDirect3DViewport3_Release(&This
->current_viewport
->IDirect3DViewport3_iface
);
1759 IDirect3DViewport3_AddRef(Direct3DViewport3
);
1761 /* Set this viewport as the current viewport */
1762 This
->current_viewport
= vp
;
1764 /* Activate this viewport */
1765 viewport_activate(This
->current_viewport
, FALSE
);
1767 wined3d_mutex_unlock();
1772 static HRESULT WINAPI
IDirect3DDeviceImpl_2_SetCurrentViewport(IDirect3DDevice2
*iface
,
1773 IDirect3DViewport2
*Direct3DViewport2
)
1775 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
1776 IDirect3DViewportImpl
*vp
= unsafe_impl_from_IDirect3DViewport2(Direct3DViewport2
);
1778 TRACE("iface %p, viewport %p.\n", iface
, Direct3DViewport2
);
1780 return IDirect3DDevice3_SetCurrentViewport(&This
->IDirect3DDevice3_iface
,
1781 &vp
->IDirect3DViewport3_iface
);
1784 /*****************************************************************************
1785 * IDirect3DDevice3::GetCurrentViewport
1787 * Returns the currently active viewport.
1792 * Direct3DViewport3: Address to return the interface pointer at
1796 * DDERR_INVALIDPARAMS if Direct3DViewport == NULL
1798 *****************************************************************************/
1799 static HRESULT WINAPI
1800 IDirect3DDeviceImpl_3_GetCurrentViewport(IDirect3DDevice3
*iface
,
1801 IDirect3DViewport3
**Direct3DViewport3
)
1803 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
1805 TRACE("iface %p, viewport %p.\n", iface
, Direct3DViewport3
);
1807 if(!Direct3DViewport3
)
1808 return DDERR_INVALIDPARAMS
;
1810 wined3d_mutex_lock();
1811 *Direct3DViewport3
= &This
->current_viewport
->IDirect3DViewport3_iface
;
1813 /* AddRef the returned viewport */
1814 if(*Direct3DViewport3
) IDirect3DViewport3_AddRef(*Direct3DViewport3
);
1816 TRACE(" returning interface %p\n", *Direct3DViewport3
);
1818 wined3d_mutex_unlock();
1823 static HRESULT WINAPI
IDirect3DDeviceImpl_2_GetCurrentViewport(IDirect3DDevice2
*iface
,
1824 IDirect3DViewport2
**Direct3DViewport2
)
1826 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
1829 TRACE("iface %p, viewport %p.\n", iface
, Direct3DViewport2
);
1831 hr
= IDirect3DDevice3_GetCurrentViewport(&This
->IDirect3DDevice3_iface
,
1832 (IDirect3DViewport3
**)Direct3DViewport2
);
1833 if(hr
!= D3D_OK
) return hr
;
1837 /*****************************************************************************
1838 * IDirect3DDevice7::SetRenderTarget
1840 * Sets the render target for the Direct3DDevice.
1841 * For the thunks note that IDirectDrawSurface7 == IDirectDrawSurface4 and
1842 * IDirectDrawSurface3 == IDirectDrawSurface
1844 * Version 2, 3 and 7
1847 * NewTarget: Pointer to an IDirectDrawSurface7 interface to set as the new
1852 * D3D_OK on success, for details see IWineD3DDevice::SetRenderTarget
1854 *****************************************************************************/
1855 static HRESULT
d3d_device_set_render_target(IDirect3DDeviceImpl
*This
, IDirectDrawSurfaceImpl
*Target
)
1859 wined3d_mutex_lock();
1861 if(This
->target
== Target
)
1863 TRACE("No-op SetRenderTarget operation, not doing anything\n");
1864 wined3d_mutex_unlock();
1867 This
->target
= Target
;
1868 hr
= wined3d_device_set_render_target(This
->wined3d_device
, 0,
1869 Target
? Target
->wined3d_surface
: NULL
, FALSE
);
1872 wined3d_mutex_unlock();
1875 IDirect3DDeviceImpl_UpdateDepthStencil(This
);
1877 wined3d_mutex_unlock();
1883 IDirect3DDeviceImpl_7_SetRenderTarget(IDirect3DDevice7
*iface
,
1884 IDirectDrawSurface7
*NewTarget
,
1887 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
1888 IDirectDrawSurfaceImpl
*Target
= unsafe_impl_from_IDirectDrawSurface7(NewTarget
);
1890 TRACE("iface %p, target %p, flags %#x.\n", iface
, NewTarget
, Flags
);
1891 /* Flags: Not used */
1893 IDirectDrawSurface7_AddRef(NewTarget
);
1894 IDirectDrawSurface7_Release(&This
->target
->IDirectDrawSurface7_iface
);
1895 return d3d_device_set_render_target(This
, Target
);
1898 static HRESULT WINAPI
1899 IDirect3DDeviceImpl_7_SetRenderTarget_FPUSetup(IDirect3DDevice7
*iface
,
1900 IDirectDrawSurface7
*NewTarget
,
1903 return IDirect3DDeviceImpl_7_SetRenderTarget(iface
, NewTarget
, Flags
);
1906 static HRESULT WINAPI
1907 IDirect3DDeviceImpl_7_SetRenderTarget_FPUPreserve(IDirect3DDevice7
*iface
,
1908 IDirectDrawSurface7
*NewTarget
,
1914 old_fpucw
= d3d_fpu_setup();
1915 hr
= IDirect3DDeviceImpl_7_SetRenderTarget(iface
, NewTarget
, Flags
);
1916 set_fpu_control_word(old_fpucw
);
1921 static HRESULT WINAPI
IDirect3DDeviceImpl_3_SetRenderTarget(IDirect3DDevice3
*iface
,
1922 IDirectDrawSurface4
*NewRenderTarget
, DWORD Flags
)
1924 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
1925 IDirectDrawSurfaceImpl
*Target
= unsafe_impl_from_IDirectDrawSurface4(NewRenderTarget
);
1927 TRACE("iface %p, target %p, flags %#x.\n", iface
, NewRenderTarget
, Flags
);
1929 IDirectDrawSurface4_AddRef(NewRenderTarget
);
1930 IDirectDrawSurface4_Release(&This
->target
->IDirectDrawSurface4_iface
);
1931 return d3d_device_set_render_target(This
, Target
);
1934 static HRESULT WINAPI
IDirect3DDeviceImpl_2_SetRenderTarget(IDirect3DDevice2
*iface
,
1935 IDirectDrawSurface
*NewRenderTarget
, DWORD Flags
)
1937 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
1938 IDirectDrawSurfaceImpl
*Target
= unsafe_impl_from_IDirectDrawSurface(NewRenderTarget
);
1940 TRACE("iface %p, target %p, flags %#x.\n", iface
, NewRenderTarget
, Flags
);
1942 IDirectDrawSurface_AddRef(NewRenderTarget
);
1943 IDirectDrawSurface_Release(&This
->target
->IDirectDrawSurface_iface
);
1944 return d3d_device_set_render_target(This
, Target
);
1947 /*****************************************************************************
1948 * IDirect3DDevice7::GetRenderTarget
1950 * Returns the current render target.
1951 * This is handled locally, because the WineD3D render target's parent
1954 * Version 2, 3 and 7
1957 * RenderTarget: Address to store the surface interface pointer
1961 * DDERR_INVALIDPARAMS if RenderTarget == NULL
1963 *****************************************************************************/
1964 static HRESULT WINAPI
1965 IDirect3DDeviceImpl_7_GetRenderTarget(IDirect3DDevice7
*iface
,
1966 IDirectDrawSurface7
**RenderTarget
)
1968 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
1970 TRACE("iface %p, target %p.\n", iface
, RenderTarget
);
1973 return DDERR_INVALIDPARAMS
;
1975 wined3d_mutex_lock();
1976 *RenderTarget
= &This
->target
->IDirectDrawSurface7_iface
;
1977 IDirectDrawSurface7_AddRef(*RenderTarget
);
1978 wined3d_mutex_unlock();
1983 static HRESULT WINAPI
IDirect3DDeviceImpl_3_GetRenderTarget(IDirect3DDevice3
*iface
,
1984 IDirectDrawSurface4
**RenderTarget
)
1986 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
1987 IDirectDrawSurface7
*RenderTarget7
;
1988 IDirectDrawSurfaceImpl
*RenderTargetImpl
;
1991 TRACE("iface %p, target %p.\n", iface
, RenderTarget
);
1994 return DDERR_INVALIDPARAMS
;
1996 hr
= IDirect3DDevice7_GetRenderTarget(&This
->IDirect3DDevice7_iface
, &RenderTarget7
);
1997 if(hr
!= D3D_OK
) return hr
;
1998 RenderTargetImpl
= impl_from_IDirectDrawSurface7(RenderTarget7
);
1999 *RenderTarget
= &RenderTargetImpl
->IDirectDrawSurface4_iface
;
2000 IDirectDrawSurface4_AddRef(*RenderTarget
);
2001 IDirectDrawSurface7_Release(RenderTarget7
);
2005 static HRESULT WINAPI
IDirect3DDeviceImpl_2_GetRenderTarget(IDirect3DDevice2
*iface
,
2006 IDirectDrawSurface
**RenderTarget
)
2008 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
2009 IDirectDrawSurface7
*RenderTarget7
;
2010 IDirectDrawSurfaceImpl
*RenderTargetImpl
;
2013 TRACE("iface %p, target %p.\n", iface
, RenderTarget
);
2016 return DDERR_INVALIDPARAMS
;
2018 hr
= IDirect3DDevice7_GetRenderTarget(&This
->IDirect3DDevice7_iface
, &RenderTarget7
);
2019 if(hr
!= D3D_OK
) return hr
;
2020 RenderTargetImpl
= impl_from_IDirectDrawSurface7(RenderTarget7
);
2021 *RenderTarget
= &RenderTargetImpl
->IDirectDrawSurface_iface
;
2022 IDirectDrawSurface_AddRef(*RenderTarget
);
2023 IDirectDrawSurface7_Release(RenderTarget7
);
2027 /*****************************************************************************
2028 * IDirect3DDevice3::Begin
2030 * Begins a description block of vertices. This is similar to glBegin()
2031 * and glEnd(). After a call to IDirect3DDevice3::End, the vertices
2032 * described with IDirect3DDevice::Vertex are drawn.
2037 * PrimitiveType: The type of primitives to draw
2038 * VertexTypeDesc: A flexible vertex format description of the vertices
2039 * Flags: Some flags..
2044 *****************************************************************************/
2045 static HRESULT WINAPI
2046 IDirect3DDeviceImpl_3_Begin(IDirect3DDevice3
*iface
,
2047 D3DPRIMITIVETYPE PrimitiveType
,
2048 DWORD VertexTypeDesc
,
2051 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
2053 TRACE("iface %p, primitive_type %#x, FVF %#x, flags %#x.\n",
2054 iface
, PrimitiveType
, VertexTypeDesc
, Flags
);
2056 wined3d_mutex_lock();
2057 This
->primitive_type
= PrimitiveType
;
2058 This
->vertex_type
= VertexTypeDesc
;
2059 This
->render_flags
= Flags
;
2060 This
->vertex_size
= get_flexible_vertex_size(This
->vertex_type
);
2061 This
->nb_vertices
= 0;
2062 wined3d_mutex_unlock();
2067 static HRESULT WINAPI
IDirect3DDeviceImpl_2_Begin(IDirect3DDevice2
*iface
, D3DPRIMITIVETYPE d3dpt
,
2068 D3DVERTEXTYPE dwVertexTypeDesc
, DWORD dwFlags
)
2071 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
2073 TRACE("iface %p, primitive_type %#x, vertex_type %#x, flags %#x.\n",
2074 iface
, d3dpt
, dwVertexTypeDesc
, dwFlags
);
2076 switch(dwVertexTypeDesc
)
2078 case D3DVT_VERTEX
: FVF
= D3DFVF_VERTEX
; break;
2079 case D3DVT_LVERTEX
: FVF
= D3DFVF_LVERTEX
; break;
2080 case D3DVT_TLVERTEX
: FVF
= D3DFVF_TLVERTEX
; break;
2082 ERR("Unexpected vertex type %d\n", dwVertexTypeDesc
);
2083 return DDERR_INVALIDPARAMS
; /* Should never happen */
2086 return IDirect3DDevice3_Begin(&This
->IDirect3DDevice3_iface
, d3dpt
, FVF
, dwFlags
);
2089 /*****************************************************************************
2090 * IDirect3DDevice3::BeginIndexed
2092 * Draws primitives based on vertices in a vertex array which are specified
2098 * PrimitiveType: Primitive type to draw
2099 * VertexType: A FVF description of the vertex format
2100 * Vertices: pointer to an array containing the vertices
2101 * NumVertices: The number of vertices in the vertex array
2102 * Flags: Some flags ...
2105 * D3D_OK, because it's a stub
2107 *****************************************************************************/
2108 static HRESULT WINAPI
2109 IDirect3DDeviceImpl_3_BeginIndexed(IDirect3DDevice3
*iface
,
2110 D3DPRIMITIVETYPE PrimitiveType
,
2116 FIXME("iface %p, primitive_type %#x, FVF %#x, vertices %p, vertex_count %u, flags %#x stub!\n",
2117 iface
, PrimitiveType
, VertexType
, Vertices
, NumVertices
, Flags
);
2123 static HRESULT WINAPI
IDirect3DDeviceImpl_2_BeginIndexed(IDirect3DDevice2
*iface
,
2124 D3DPRIMITIVETYPE d3dptPrimitiveType
, D3DVERTEXTYPE d3dvtVertexType
,
2125 void *lpvVertices
, DWORD dwNumVertices
, DWORD dwFlags
)
2128 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
2130 TRACE("iface %p, primitive_type %#x, vertex_type %#x, vertices %p, vertex_count %u, flags %#x stub!\n",
2131 iface
, d3dptPrimitiveType
, d3dvtVertexType
, lpvVertices
, dwNumVertices
, dwFlags
);
2133 switch(d3dvtVertexType
)
2135 case D3DVT_VERTEX
: FVF
= D3DFVF_VERTEX
; break;
2136 case D3DVT_LVERTEX
: FVF
= D3DFVF_LVERTEX
; break;
2137 case D3DVT_TLVERTEX
: FVF
= D3DFVF_TLVERTEX
; break;
2139 ERR("Unexpected vertex type %d\n", d3dvtVertexType
);
2140 return DDERR_INVALIDPARAMS
; /* Should never happen */
2143 return IDirect3DDevice3_BeginIndexed(&This
->IDirect3DDevice3_iface
,
2144 d3dptPrimitiveType
, FVF
, lpvVertices
, dwNumVertices
, dwFlags
);
2147 /*****************************************************************************
2148 * IDirect3DDevice3::Vertex
2150 * Draws a vertex as described by IDirect3DDevice3::Begin. It places all
2151 * drawn vertices in a vertex buffer. If the buffer is too small, its
2152 * size is increased.
2157 * Vertex: Pointer to the vertex
2160 * D3D_OK, on success
2161 * DDERR_INVALIDPARAMS if Vertex is NULL
2163 *****************************************************************************/
2164 static HRESULT WINAPI
2165 IDirect3DDeviceImpl_3_Vertex(IDirect3DDevice3
*iface
,
2168 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
2170 TRACE("iface %p, vertex %p.\n", iface
, Vertex
);
2173 return DDERR_INVALIDPARAMS
;
2175 wined3d_mutex_lock();
2176 if ((This
->nb_vertices
+1)*This
->vertex_size
> This
->buffer_size
)
2179 This
->buffer_size
= This
->buffer_size
? This
->buffer_size
* 2 : This
->vertex_size
* 3;
2180 old_buffer
= This
->vertex_buffer
;
2181 This
->vertex_buffer
= HeapAlloc(GetProcessHeap(), 0, This
->buffer_size
);
2184 CopyMemory(This
->vertex_buffer
, old_buffer
, This
->nb_vertices
* This
->vertex_size
);
2185 HeapFree(GetProcessHeap(), 0, old_buffer
);
2189 CopyMemory(This
->vertex_buffer
+ This
->nb_vertices
++ * This
->vertex_size
, Vertex
, This
->vertex_size
);
2190 wined3d_mutex_unlock();
2195 static HRESULT WINAPI
IDirect3DDeviceImpl_2_Vertex(IDirect3DDevice2
*iface
, void *lpVertexType
)
2197 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
2199 TRACE("iface %p, vertex %p.\n", iface
, lpVertexType
);
2201 return IDirect3DDevice3_Vertex(&This
->IDirect3DDevice3_iface
, lpVertexType
);
2204 /*****************************************************************************
2205 * IDirect3DDevice3::Index
2207 * Specifies an index to a vertex to be drawn. The vertex array has to
2208 * be specified with BeginIndexed first.
2211 * VertexIndex: The index of the vertex to draw
2214 * D3D_OK because it's a stub
2216 *****************************************************************************/
2217 static HRESULT WINAPI
2218 IDirect3DDeviceImpl_3_Index(IDirect3DDevice3
*iface
,
2221 FIXME("iface %p, index %#x stub!\n", iface
, VertexIndex
);
2226 static HRESULT WINAPI
IDirect3DDeviceImpl_2_Index(IDirect3DDevice2
*iface
, WORD wVertexIndex
)
2228 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
2230 TRACE("iface %p, index %#x.\n", iface
, wVertexIndex
);
2232 return IDirect3DDevice3_Index(&This
->IDirect3DDevice3_iface
, wVertexIndex
);
2235 /*****************************************************************************
2236 * IDirect3DDevice3::End
2238 * Ends a draw begun with IDirect3DDevice3::Begin or
2239 * IDirect3DDevice::BeginIndexed. The vertices specified with
2240 * IDirect3DDevice::Vertex or IDirect3DDevice::Index are drawn using
2241 * the IDirect3DDevice7::DrawPrimitive method. So far only
2242 * non-indexed mode is supported
2247 * Flags: Some flags, as usual. Don't know which are defined
2250 * The return value of IDirect3DDevice7::DrawPrimitive
2252 *****************************************************************************/
2253 static HRESULT WINAPI
2254 IDirect3DDeviceImpl_3_End(IDirect3DDevice3
*iface
,
2257 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
2259 TRACE("iface %p, flags %#x.\n", iface
, Flags
);
2261 return IDirect3DDevice7_DrawPrimitive(&This
->IDirect3DDevice7_iface
, This
->primitive_type
,
2262 This
->vertex_type
, This
->vertex_buffer
, This
->nb_vertices
, This
->render_flags
);
2265 static HRESULT WINAPI
IDirect3DDeviceImpl_2_End(IDirect3DDevice2
*iface
, DWORD dwFlags
)
2267 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
2269 TRACE("iface %p, flags %#x.\n", iface
, dwFlags
);
2271 return IDirect3DDevice3_End(&This
->IDirect3DDevice3_iface
, dwFlags
);
2274 /*****************************************************************************
2275 * IDirect3DDevice7::GetRenderState
2277 * Returns the value of a render state. The possible render states are
2278 * defined in include/d3dtypes.h
2280 * Version 2, 3 and 7
2283 * RenderStateType: Render state to return the current setting of
2284 * Value: Address to store the value at
2287 * D3D_OK on success, for details see IWineD3DDevice::GetRenderState
2288 * DDERR_INVALIDPARAMS if Value == NULL
2290 *****************************************************************************/
2291 static HRESULT
IDirect3DDeviceImpl_7_GetRenderState(IDirect3DDevice7
*iface
,
2292 D3DRENDERSTATETYPE RenderStateType
, DWORD
*Value
)
2294 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
2297 TRACE("iface %p, state %#x, value %p.\n", iface
, RenderStateType
, Value
);
2300 return DDERR_INVALIDPARAMS
;
2302 wined3d_mutex_lock();
2303 switch(RenderStateType
)
2305 case D3DRENDERSTATE_TEXTUREMAG
:
2307 WINED3DTEXTUREFILTERTYPE tex_mag
;
2309 hr
= wined3d_device_get_sampler_state(This
->wined3d_device
, 0, WINED3DSAMP_MAGFILTER
, &tex_mag
);
2313 case WINED3DTEXF_POINT
:
2314 *Value
= D3DFILTER_NEAREST
;
2316 case WINED3DTEXF_LINEAR
:
2317 *Value
= D3DFILTER_LINEAR
;
2320 ERR("Unhandled texture mag %d !\n",tex_mag
);
2326 case D3DRENDERSTATE_TEXTUREMIN
:
2328 WINED3DTEXTUREFILTERTYPE tex_min
;
2329 WINED3DTEXTUREFILTERTYPE tex_mip
;
2331 hr
= wined3d_device_get_sampler_state(This
->wined3d_device
,
2332 0, WINED3DSAMP_MINFILTER
, &tex_min
);
2335 wined3d_mutex_unlock();
2338 hr
= wined3d_device_get_sampler_state(This
->wined3d_device
,
2339 0, WINED3DSAMP_MIPFILTER
, &tex_mip
);
2343 case WINED3DTEXF_POINT
:
2346 case WINED3DTEXF_NONE
:
2347 *Value
= D3DFILTER_NEAREST
;
2349 case WINED3DTEXF_POINT
:
2350 *Value
= D3DFILTER_MIPNEAREST
;
2352 case WINED3DTEXF_LINEAR
:
2353 *Value
= D3DFILTER_LINEARMIPNEAREST
;
2356 ERR("Unhandled mip filter %#x.\n", tex_mip
);
2357 *Value
= D3DFILTER_NEAREST
;
2361 case WINED3DTEXF_LINEAR
:
2364 case WINED3DTEXF_NONE
:
2365 *Value
= D3DFILTER_LINEAR
;
2367 case WINED3DTEXF_POINT
:
2368 *Value
= D3DFILTER_MIPLINEAR
;
2370 case WINED3DTEXF_LINEAR
:
2371 *Value
= D3DFILTER_LINEARMIPLINEAR
;
2374 ERR("Unhandled mip filter %#x.\n", tex_mip
);
2375 *Value
= D3DFILTER_LINEAR
;
2380 ERR("Unhandled texture min filter %#x.\n",tex_min
);
2381 *Value
= D3DFILTER_NEAREST
;
2387 case D3DRENDERSTATE_TEXTUREADDRESS
:
2388 case D3DRENDERSTATE_TEXTUREADDRESSU
:
2389 hr
= wined3d_device_get_sampler_state(This
->wined3d_device
,
2390 0, WINED3DSAMP_ADDRESSU
, Value
);
2392 case D3DRENDERSTATE_TEXTUREADDRESSV
:
2393 hr
= wined3d_device_get_sampler_state(This
->wined3d_device
,
2394 0, WINED3DSAMP_ADDRESSV
, Value
);
2397 case D3DRENDERSTATE_BORDERCOLOR
:
2398 FIXME("Unhandled render state D3DRENDERSTATE_BORDERCOLOR.\n");
2402 case D3DRENDERSTATE_TEXTUREHANDLE
:
2403 case D3DRENDERSTATE_TEXTUREMAPBLEND
:
2404 WARN("Render state %#x is invalid in d3d7.\n", RenderStateType
);
2405 hr
= DDERR_INVALIDPARAMS
;
2408 case D3DRENDERSTATE_ZBIAS
:
2409 hr
= wined3d_device_get_render_state(This
->wined3d_device
, WINED3DRS_DEPTHBIAS
, Value
);
2413 if (RenderStateType
>= D3DRENDERSTATE_STIPPLEPATTERN00
2414 && RenderStateType
<= D3DRENDERSTATE_STIPPLEPATTERN31
)
2416 FIXME("Unhandled stipple pattern render state (%#x).\n",
2421 hr
= wined3d_device_get_render_state(This
->wined3d_device
, RenderStateType
, Value
);
2423 wined3d_mutex_unlock();
2428 static HRESULT WINAPI
2429 IDirect3DDeviceImpl_7_GetRenderState_FPUSetup(IDirect3DDevice7
*iface
,
2430 D3DRENDERSTATETYPE RenderStateType
,
2433 return IDirect3DDeviceImpl_7_GetRenderState(iface
, RenderStateType
, Value
);
2436 static HRESULT WINAPI
2437 IDirect3DDeviceImpl_7_GetRenderState_FPUPreserve(IDirect3DDevice7
*iface
,
2438 D3DRENDERSTATETYPE RenderStateType
,
2444 old_fpucw
= d3d_fpu_setup();
2445 hr
= IDirect3DDeviceImpl_7_GetRenderState(iface
, RenderStateType
, Value
);
2446 set_fpu_control_word(old_fpucw
);
2451 static HRESULT WINAPI
2452 IDirect3DDeviceImpl_3_GetRenderState(IDirect3DDevice3
*iface
,
2453 D3DRENDERSTATETYPE dwRenderStateType
,
2454 DWORD
*lpdwRenderState
)
2456 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
2459 TRACE("iface %p, state %#x, value %p.\n", iface
, dwRenderStateType
, lpdwRenderState
);
2461 switch(dwRenderStateType
)
2463 case D3DRENDERSTATE_TEXTUREHANDLE
:
2465 /* This state is wrapped to SetTexture in SetRenderState, so
2466 * it has to be wrapped to GetTexture here. */
2467 struct wined3d_texture
*tex
= NULL
;
2468 *lpdwRenderState
= 0;
2470 wined3d_mutex_lock();
2471 hr
= wined3d_device_get_texture(This
->wined3d_device
, 0, &tex
);
2472 if (SUCCEEDED(hr
) && tex
)
2474 /* The parent of the texture is the IDirectDrawSurface7
2475 * interface of the ddraw surface. */
2476 IDirectDrawSurfaceImpl
*parent
= wined3d_texture_get_parent(tex
);
2477 if (parent
) *lpdwRenderState
= parent
->Handle
;
2478 wined3d_texture_decref(tex
);
2480 wined3d_mutex_unlock();
2485 case D3DRENDERSTATE_TEXTUREMAPBLEND
:
2487 /* D3DRENDERSTATE_TEXTUREMAPBLEND is mapped to texture state stages in SetRenderState; reverse
2488 the mapping to get the value. */
2489 DWORD colorop
, colorarg1
, colorarg2
;
2490 DWORD alphaop
, alphaarg1
, alphaarg2
;
2492 wined3d_mutex_lock();
2494 This
->legacyTextureBlending
= TRUE
;
2496 wined3d_device_get_texture_stage_state(This
->wined3d_device
, 0, WINED3DTSS_COLOROP
, &colorop
);
2497 wined3d_device_get_texture_stage_state(This
->wined3d_device
, 0, WINED3DTSS_COLORARG1
, &colorarg1
);
2498 wined3d_device_get_texture_stage_state(This
->wined3d_device
, 0, WINED3DTSS_COLORARG2
, &colorarg2
);
2499 wined3d_device_get_texture_stage_state(This
->wined3d_device
, 0, WINED3DTSS_ALPHAOP
, &alphaop
);
2500 wined3d_device_get_texture_stage_state(This
->wined3d_device
, 0, WINED3DTSS_ALPHAARG1
, &alphaarg1
);
2501 wined3d_device_get_texture_stage_state(This
->wined3d_device
, 0, WINED3DTSS_ALPHAARG2
, &alphaarg2
);
2503 if (colorop
== WINED3DTOP_SELECTARG1
&& colorarg1
== WINED3DTA_TEXTURE
&&
2504 alphaop
== WINED3DTOP_SELECTARG1
&& alphaarg1
== WINED3DTA_TEXTURE
)
2506 *lpdwRenderState
= D3DTBLEND_DECAL
;
2508 else if (colorop
== WINED3DTOP_SELECTARG1
&& colorarg1
== WINED3DTA_TEXTURE
&&
2509 alphaop
== WINED3DTOP_MODULATE
&& alphaarg1
== WINED3DTA_TEXTURE
&& alphaarg2
== WINED3DTA_CURRENT
)
2511 *lpdwRenderState
= D3DTBLEND_DECALALPHA
;
2513 else if (colorop
== WINED3DTOP_MODULATE
&& colorarg1
== WINED3DTA_TEXTURE
&& colorarg2
== WINED3DTA_CURRENT
&&
2514 alphaop
== WINED3DTOP_MODULATE
&& alphaarg1
== WINED3DTA_TEXTURE
&& alphaarg2
== WINED3DTA_CURRENT
)
2516 *lpdwRenderState
= D3DTBLEND_MODULATEALPHA
;
2520 struct wined3d_texture
*tex
= NULL
;
2522 BOOL tex_alpha
= FALSE
;
2523 DDPIXELFORMAT ddfmt
;
2525 hr
= wined3d_device_get_texture(This
->wined3d_device
, 0, &tex
);
2527 if(hr
== WINED3D_OK
&& tex
)
2529 struct wined3d_resource
*sub_resource
;
2531 if ((sub_resource
= wined3d_texture_get_sub_resource(tex
, 0)))
2533 struct wined3d_resource_desc desc
;
2535 wined3d_resource_get_desc(sub_resource
, &desc
);
2536 ddfmt
.dwSize
= sizeof(ddfmt
);
2537 PixelFormat_WineD3DtoDD(&ddfmt
, desc
.format
);
2538 if (ddfmt
.u5
.dwRGBAlphaBitMask
) tex_alpha
= TRUE
;
2541 wined3d_texture_decref(tex
);
2544 if (!(colorop
== WINED3DTOP_MODULATE
&& colorarg1
== WINED3DTA_TEXTURE
&& colorarg2
== WINED3DTA_CURRENT
&&
2545 alphaop
== (tex_alpha
? WINED3DTOP_SELECTARG1
: WINED3DTOP_SELECTARG2
) &&
2546 alphaarg1
== WINED3DTA_TEXTURE
&& alphaarg2
== WINED3DTA_CURRENT
))
2548 ERR("Unexpected texture stage state setup, returning D3DTBLEND_MODULATE - likely erroneous\n");
2551 *lpdwRenderState
= D3DTBLEND_MODULATE
;
2554 wined3d_mutex_unlock();
2560 return IDirect3DDevice7_GetRenderState(&This
->IDirect3DDevice7_iface
, dwRenderStateType
, lpdwRenderState
);
2564 static HRESULT WINAPI
IDirect3DDeviceImpl_2_GetRenderState(IDirect3DDevice2
*iface
,
2565 D3DRENDERSTATETYPE dwRenderStateType
, DWORD
*lpdwRenderState
)
2567 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
2569 TRACE("iface %p, state %#x, value %p.\n", iface
, dwRenderStateType
, lpdwRenderState
);
2571 return IDirect3DDevice3_GetRenderState(&This
->IDirect3DDevice3_iface
,
2572 dwRenderStateType
, lpdwRenderState
);
2575 /*****************************************************************************
2576 * IDirect3DDevice7::SetRenderState
2578 * Sets a render state. The possible render states are defined in
2579 * include/d3dtypes.h
2581 * Version 2, 3 and 7
2584 * RenderStateType: State to set
2585 * Value: Value to assign to that state
2588 * D3D_OK on success,
2589 * for details see IWineD3DDevice::SetRenderState
2591 *****************************************************************************/
2593 IDirect3DDeviceImpl_7_SetRenderState(IDirect3DDevice7
*iface
,
2594 D3DRENDERSTATETYPE RenderStateType
,
2597 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
2600 TRACE("iface %p, state %#x, value %#x.\n", iface
, RenderStateType
, Value
);
2602 wined3d_mutex_lock();
2603 /* Some render states need special care */
2604 switch(RenderStateType
)
2607 * The ddraw texture filter mapping works like this:
2608 * D3DFILTER_NEAREST Point min/mag, no mip
2609 * D3DFILTER_MIPNEAREST Point min/mag, point mip
2610 * D3DFILTER_LINEARMIPNEAREST: Point min/mag, linear mip
2612 * D3DFILTER_LINEAR Linear min/mag, no mip
2613 * D3DFILTER_MIPLINEAR Linear min/mag, point mip
2614 * D3DFILTER_LINEARMIPLINEAR Linear min/mag, linear mip
2616 * This is the opposite of the GL naming convention,
2617 * D3DFILTER_LINEARMIPNEAREST corresponds to GL_NEAREST_MIPMAP_LINEAR.
2619 case D3DRENDERSTATE_TEXTUREMAG
:
2621 WINED3DTEXTUREFILTERTYPE tex_mag
;
2625 case D3DFILTER_NEAREST
:
2626 case D3DFILTER_MIPNEAREST
:
2627 case D3DFILTER_LINEARMIPNEAREST
:
2628 tex_mag
= WINED3DTEXF_POINT
;
2630 case D3DFILTER_LINEAR
:
2631 case D3DFILTER_MIPLINEAR
:
2632 case D3DFILTER_LINEARMIPLINEAR
:
2633 tex_mag
= WINED3DTEXF_LINEAR
;
2636 tex_mag
= WINED3DTEXF_POINT
;
2637 ERR("Unhandled texture mag %d !\n",Value
);
2641 hr
= wined3d_device_set_sampler_state(This
->wined3d_device
, 0, WINED3DSAMP_MAGFILTER
, tex_mag
);
2645 case D3DRENDERSTATE_TEXTUREMIN
:
2647 WINED3DTEXTUREFILTERTYPE tex_min
;
2648 WINED3DTEXTUREFILTERTYPE tex_mip
;
2650 switch ((D3DTEXTUREFILTER
) Value
)
2652 case D3DFILTER_NEAREST
:
2653 tex_min
= WINED3DTEXF_POINT
;
2654 tex_mip
= WINED3DTEXF_NONE
;
2656 case D3DFILTER_LINEAR
:
2657 tex_min
= WINED3DTEXF_LINEAR
;
2658 tex_mip
= WINED3DTEXF_NONE
;
2660 case D3DFILTER_MIPNEAREST
:
2661 tex_min
= WINED3DTEXF_POINT
;
2662 tex_mip
= WINED3DTEXF_POINT
;
2664 case D3DFILTER_MIPLINEAR
:
2665 tex_min
= WINED3DTEXF_LINEAR
;
2666 tex_mip
= WINED3DTEXF_POINT
;
2668 case D3DFILTER_LINEARMIPNEAREST
:
2669 tex_min
= WINED3DTEXF_POINT
;
2670 tex_mip
= WINED3DTEXF_LINEAR
;
2672 case D3DFILTER_LINEARMIPLINEAR
:
2673 tex_min
= WINED3DTEXF_LINEAR
;
2674 tex_mip
= WINED3DTEXF_LINEAR
;
2678 ERR("Unhandled texture min %d !\n",Value
);
2679 tex_min
= WINED3DTEXF_POINT
;
2680 tex_mip
= WINED3DTEXF_NONE
;
2684 wined3d_device_set_sampler_state(This
->wined3d_device
,
2685 0, WINED3DSAMP_MIPFILTER
, tex_mip
);
2686 hr
= wined3d_device_set_sampler_state(This
->wined3d_device
,
2687 0, WINED3DSAMP_MINFILTER
, tex_min
);
2691 case D3DRENDERSTATE_TEXTUREADDRESS
:
2692 wined3d_device_set_sampler_state(This
->wined3d_device
,
2693 0, WINED3DSAMP_ADDRESSV
, Value
);
2695 case D3DRENDERSTATE_TEXTUREADDRESSU
:
2696 hr
= wined3d_device_set_sampler_state(This
->wined3d_device
,
2697 0, WINED3DSAMP_ADDRESSU
, Value
);
2699 case D3DRENDERSTATE_TEXTUREADDRESSV
:
2700 hr
= wined3d_device_set_sampler_state(This
->wined3d_device
,
2701 0, WINED3DSAMP_ADDRESSV
, Value
);
2704 case D3DRENDERSTATE_BORDERCOLOR
:
2705 /* This should probably just forward to the corresponding sampler
2706 * state. Needs tests. */
2707 FIXME("Unhandled render state D3DRENDERSTATE_BORDERCOLOR.\n");
2711 case D3DRENDERSTATE_TEXTUREHANDLE
:
2712 case D3DRENDERSTATE_TEXTUREMAPBLEND
:
2713 WARN("Render state %#x is invalid in d3d7.\n", RenderStateType
);
2714 hr
= DDERR_INVALIDPARAMS
;
2717 case D3DRENDERSTATE_ZBIAS
:
2718 hr
= wined3d_device_set_render_state(This
->wined3d_device
, WINED3DRS_DEPTHBIAS
, Value
);
2722 if (RenderStateType
>= D3DRENDERSTATE_STIPPLEPATTERN00
2723 && RenderStateType
<= D3DRENDERSTATE_STIPPLEPATTERN31
)
2725 FIXME("Unhandled stipple pattern render state (%#x).\n",
2731 hr
= wined3d_device_set_render_state(This
->wined3d_device
, RenderStateType
, Value
);
2734 wined3d_mutex_unlock();
2739 static HRESULT WINAPI
2740 IDirect3DDeviceImpl_7_SetRenderState_FPUSetup(IDirect3DDevice7
*iface
,
2741 D3DRENDERSTATETYPE RenderStateType
,
2744 return IDirect3DDeviceImpl_7_SetRenderState(iface
, RenderStateType
, Value
);
2747 static HRESULT WINAPI
2748 IDirect3DDeviceImpl_7_SetRenderState_FPUPreserve(IDirect3DDevice7
*iface
,
2749 D3DRENDERSTATETYPE RenderStateType
,
2755 old_fpucw
= d3d_fpu_setup();
2756 hr
= IDirect3DDeviceImpl_7_SetRenderState(iface
, RenderStateType
, Value
);
2757 set_fpu_control_word(old_fpucw
);
2762 static HRESULT WINAPI
2763 IDirect3DDeviceImpl_3_SetRenderState(IDirect3DDevice3
*iface
,
2764 D3DRENDERSTATETYPE RenderStateType
,
2767 /* Note about D3DRENDERSTATE_TEXTUREMAPBLEND implementation: most of values
2768 for this state can be directly mapped to texture stage colorop and alphaop, but
2769 D3DTBLEND_MODULATE is tricky: it uses alpha from texture when available and alpha
2770 from diffuse otherwise. So changing the texture must be monitored in SetTexture to modify
2771 alphaarg when needed.
2773 Aliens vs Predator 1 depends on accurate D3DTBLEND_MODULATE emulation
2775 Legacy texture blending (TEXTUREMAPBLEND) and texture stage states: directx6 docs state that
2776 TEXTUREMAPBLEND is deprecated, yet can still be used. Games must not use both or results
2777 are undefined. D3DTBLEND_MODULATE mode in particular is dependent on texture pixel format and
2778 requires fixup of stage 0 texture states when texture changes, but this fixup can interfere
2779 with games not using this deprecated state. So a flag 'legacyTextureBlending' has to be kept
2780 in device - TRUE if the app is using TEXTUREMAPBLEND.
2782 Tests show that setting TEXTUREMAPBLEND on native doesn't seem to change values returned by
2783 GetTextureStageState and vice versa. Not so on Wine, but it is 'undefined' anyway so, probably, ok,
2784 unless some broken game will be found that cares. */
2787 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
2789 TRACE("iface %p, state %#x, value %#x.\n", iface
, RenderStateType
, Value
);
2791 wined3d_mutex_lock();
2793 switch(RenderStateType
)
2795 case D3DRENDERSTATE_TEXTUREHANDLE
:
2797 IDirectDrawSurfaceImpl
*surf
;
2801 hr
= wined3d_device_set_texture(This
->wined3d_device
, 0, NULL
);
2805 surf
= ddraw_get_object(&This
->handle_table
, Value
- 1, DDRAW_HANDLE_SURFACE
);
2808 WARN("Invalid texture handle.\n");
2809 hr
= DDERR_INVALIDPARAMS
;
2813 hr
= IDirect3DDevice3_SetTexture(iface
, 0, &surf
->IDirect3DTexture2_iface
);
2817 case D3DRENDERSTATE_TEXTUREMAPBLEND
:
2819 This
->legacyTextureBlending
= TRUE
;
2821 switch ( (D3DTEXTUREBLEND
) Value
)
2823 case D3DTBLEND_MODULATE
:
2825 struct wined3d_texture
*tex
= NULL
;
2826 BOOL tex_alpha
= FALSE
;
2827 DDPIXELFORMAT ddfmt
;
2829 hr
= wined3d_device_get_texture(This
->wined3d_device
, 0, &tex
);
2831 if(hr
== WINED3D_OK
&& tex
)
2833 struct wined3d_resource
*sub_resource
;
2835 if ((sub_resource
= wined3d_texture_get_sub_resource(tex
, 0)))
2837 struct wined3d_resource_desc desc
;
2839 wined3d_resource_get_desc(sub_resource
, &desc
);
2840 ddfmt
.dwSize
= sizeof(ddfmt
);
2841 PixelFormat_WineD3DtoDD(&ddfmt
, desc
.format
);
2842 if (ddfmt
.u5
.dwRGBAlphaBitMask
) tex_alpha
= TRUE
;
2845 wined3d_texture_decref(tex
);
2849 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2850 0, WINED3DTSS_ALPHAOP
, WINED3DTOP_SELECTARG1
);
2852 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2853 0, WINED3DTSS_ALPHAOP
, WINED3DTOP_SELECTARG2
);
2854 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2855 0, WINED3DTSS_ALPHAARG1
, WINED3DTA_TEXTURE
);
2856 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2857 0, WINED3DTSS_ALPHAARG2
, WINED3DTA_CURRENT
);
2858 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2859 0, WINED3DTSS_COLORARG1
, WINED3DTA_TEXTURE
);
2860 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2861 0, WINED3DTSS_COLORARG2
, WINED3DTA_CURRENT
);
2862 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2863 0, WINED3DTSS_COLOROP
, WINED3DTOP_MODULATE
);
2868 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2869 0, WINED3DTSS_COLOROP
, WINED3DTOP_ADD
);
2870 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2871 0, WINED3DTSS_COLORARG1
, WINED3DTA_TEXTURE
);
2872 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2873 0, WINED3DTSS_COLORARG2
, WINED3DTA_CURRENT
);
2874 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2875 0, WINED3DTSS_ALPHAOP
, WINED3DTOP_SELECTARG2
);
2876 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2877 0, WINED3DTSS_ALPHAARG2
, WINED3DTA_CURRENT
);
2880 case D3DTBLEND_MODULATEALPHA
:
2881 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2882 0, WINED3DTSS_COLORARG1
, WINED3DTA_TEXTURE
);
2883 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2884 0, WINED3DTSS_ALPHAARG1
, WINED3DTA_TEXTURE
);
2885 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2886 0, WINED3DTSS_COLORARG2
, WINED3DTA_CURRENT
);
2887 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2888 0, WINED3DTSS_ALPHAARG2
, WINED3DTA_CURRENT
);
2889 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2890 0, WINED3DTSS_COLOROP
, WINED3DTOP_MODULATE
);
2891 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2892 0, WINED3DTSS_ALPHAOP
, WINED3DTOP_MODULATE
);
2895 case D3DTBLEND_COPY
:
2896 case D3DTBLEND_DECAL
:
2897 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2898 0, WINED3DTSS_COLORARG1
, WINED3DTA_TEXTURE
);
2899 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2900 0, WINED3DTSS_ALPHAARG1
, WINED3DTA_TEXTURE
);
2901 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2902 0, WINED3DTSS_COLOROP
, WINED3DTOP_SELECTARG1
);
2903 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2904 0, WINED3DTSS_ALPHAOP
, WINED3DTOP_SELECTARG1
);
2907 case D3DTBLEND_DECALALPHA
:
2908 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2909 0, WINED3DTSS_COLOROP
, WINED3DTOP_BLENDTEXTUREALPHA
);
2910 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2911 0, WINED3DTSS_COLORARG1
, WINED3DTA_TEXTURE
);
2912 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2913 0, WINED3DTSS_COLORARG2
, WINED3DTA_CURRENT
);
2914 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2915 0, WINED3DTSS_ALPHAOP
, WINED3DTOP_SELECTARG2
);
2916 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2917 0, WINED3DTSS_ALPHAARG2
, WINED3DTA_CURRENT
);
2921 ERR("Unhandled texture environment %d !\n",Value
);
2929 hr
= IDirect3DDevice7_SetRenderState(&This
->IDirect3DDevice7_iface
, RenderStateType
, Value
);
2932 wined3d_mutex_unlock();
2937 static HRESULT WINAPI
IDirect3DDeviceImpl_2_SetRenderState(IDirect3DDevice2
*iface
,
2938 D3DRENDERSTATETYPE RenderStateType
, DWORD Value
)
2940 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
2942 TRACE("iface %p, state %#x, value %#x.\n", iface
, RenderStateType
, Value
);
2944 return IDirect3DDevice3_SetRenderState(&This
->IDirect3DDevice3_iface
, RenderStateType
, Value
);
2947 /*****************************************************************************
2948 * Direct3DDevice3::SetLightState
2950 * Sets a light state for Direct3DDevice3 and Direct3DDevice2. The
2951 * light states are forwarded to Direct3DDevice7 render states
2956 * LightStateType: The light state to change
2957 * Value: The value to assign to that light state
2961 * DDERR_INVALIDPARAMS if the parameters were incorrect
2962 * Also check IDirect3DDevice7::SetRenderState
2964 *****************************************************************************/
2965 static HRESULT WINAPI
2966 IDirect3DDeviceImpl_3_SetLightState(IDirect3DDevice3
*iface
,
2967 D3DLIGHTSTATETYPE LightStateType
,
2970 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
2973 TRACE("iface %p, state %#x, value %#x.\n", iface
, LightStateType
, Value
);
2975 if (!LightStateType
|| (LightStateType
> D3DLIGHTSTATE_COLORVERTEX
))
2977 TRACE("Unexpected Light State Type\n");
2978 return DDERR_INVALIDPARAMS
;
2981 wined3d_mutex_lock();
2982 if (LightStateType
== D3DLIGHTSTATE_MATERIAL
/* 1 */)
2984 IDirect3DMaterialImpl
*m
= ddraw_get_object(&This
->handle_table
, Value
- 1, DDRAW_HANDLE_MATERIAL
);
2987 WARN("Invalid material handle.\n");
2988 wined3d_mutex_unlock();
2989 return DDERR_INVALIDPARAMS
;
2992 TRACE(" activating material %p.\n", m
);
2993 material_activate(m
);
2995 This
->material
= Value
;
2997 else if (LightStateType
== D3DLIGHTSTATE_COLORMODEL
/* 3 */)
3002 ERR("DDCOLOR_MONO should not happen!\n");
3005 /* We are already in this mode */
3006 TRACE("Setting color model to RGB (no-op).\n");
3009 ERR("Unknown color model!\n");
3010 wined3d_mutex_unlock();
3011 return DDERR_INVALIDPARAMS
;
3016 D3DRENDERSTATETYPE rs
;
3017 switch (LightStateType
)
3019 case D3DLIGHTSTATE_AMBIENT
: /* 2 */
3020 rs
= D3DRENDERSTATE_AMBIENT
;
3022 case D3DLIGHTSTATE_FOGMODE
: /* 4 */
3023 rs
= D3DRENDERSTATE_FOGVERTEXMODE
;
3025 case D3DLIGHTSTATE_FOGSTART
: /* 5 */
3026 rs
= D3DRENDERSTATE_FOGSTART
;
3028 case D3DLIGHTSTATE_FOGEND
: /* 6 */
3029 rs
= D3DRENDERSTATE_FOGEND
;
3031 case D3DLIGHTSTATE_FOGDENSITY
: /* 7 */
3032 rs
= D3DRENDERSTATE_FOGDENSITY
;
3034 case D3DLIGHTSTATE_COLORVERTEX
: /* 8 */
3035 rs
= D3DRENDERSTATE_COLORVERTEX
;
3038 ERR("Unknown D3DLIGHTSTATETYPE %d.\n", LightStateType
);
3039 wined3d_mutex_unlock();
3040 return DDERR_INVALIDPARAMS
;
3043 hr
= IDirect3DDevice7_SetRenderState(&This
->IDirect3DDevice7_iface
, rs
, Value
);
3044 wined3d_mutex_unlock();
3047 wined3d_mutex_unlock();
3052 static HRESULT WINAPI
IDirect3DDeviceImpl_2_SetLightState(IDirect3DDevice2
*iface
,
3053 D3DLIGHTSTATETYPE LightStateType
, DWORD Value
)
3055 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
3057 TRACE("iface %p, state %#x, value %#x.\n", iface
, LightStateType
, Value
);
3059 return IDirect3DDevice3_SetLightState(&This
->IDirect3DDevice3_iface
, LightStateType
, Value
);
3062 /*****************************************************************************
3063 * IDirect3DDevice3::GetLightState
3065 * Returns the current setting of a light state. The state is read from
3066 * the Direct3DDevice7 render state.
3071 * LightStateType: The light state to return
3072 * Value: The address to store the light state setting at
3076 * DDDERR_INVALIDPARAMS if the parameters were incorrect
3077 * Also see IDirect3DDevice7::GetRenderState
3079 *****************************************************************************/
3080 static HRESULT WINAPI
3081 IDirect3DDeviceImpl_3_GetLightState(IDirect3DDevice3
*iface
,
3082 D3DLIGHTSTATETYPE LightStateType
,
3085 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
3088 TRACE("iface %p, state %#x, value %p.\n", iface
, LightStateType
, Value
);
3090 if (!LightStateType
|| (LightStateType
> D3DLIGHTSTATE_COLORVERTEX
))
3092 TRACE("Unexpected Light State Type\n");
3093 return DDERR_INVALIDPARAMS
;
3097 return DDERR_INVALIDPARAMS
;
3099 wined3d_mutex_lock();
3100 if (LightStateType
== D3DLIGHTSTATE_MATERIAL
/* 1 */)
3102 *Value
= This
->material
;
3104 else if (LightStateType
== D3DLIGHTSTATE_COLORMODEL
/* 3 */)
3106 *Value
= D3DCOLOR_RGB
;
3110 D3DRENDERSTATETYPE rs
;
3111 switch (LightStateType
)
3113 case D3DLIGHTSTATE_AMBIENT
: /* 2 */
3114 rs
= D3DRENDERSTATE_AMBIENT
;
3116 case D3DLIGHTSTATE_FOGMODE
: /* 4 */
3117 rs
= D3DRENDERSTATE_FOGVERTEXMODE
;
3119 case D3DLIGHTSTATE_FOGSTART
: /* 5 */
3120 rs
= D3DRENDERSTATE_FOGSTART
;
3122 case D3DLIGHTSTATE_FOGEND
: /* 6 */
3123 rs
= D3DRENDERSTATE_FOGEND
;
3125 case D3DLIGHTSTATE_FOGDENSITY
: /* 7 */
3126 rs
= D3DRENDERSTATE_FOGDENSITY
;
3128 case D3DLIGHTSTATE_COLORVERTEX
: /* 8 */
3129 rs
= D3DRENDERSTATE_COLORVERTEX
;
3132 ERR("Unknown D3DLIGHTSTATETYPE %d.\n", LightStateType
);
3133 wined3d_mutex_unlock();
3134 return DDERR_INVALIDPARAMS
;
3137 hr
= IDirect3DDevice7_GetRenderState(&This
->IDirect3DDevice7_iface
, rs
, Value
);
3138 wined3d_mutex_unlock();
3141 wined3d_mutex_unlock();
3146 static HRESULT WINAPI
IDirect3DDeviceImpl_2_GetLightState(IDirect3DDevice2
*iface
,
3147 D3DLIGHTSTATETYPE LightStateType
, DWORD
*Value
)
3149 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
3151 TRACE("iface %p, state %#x, value %p.\n", iface
, LightStateType
, Value
);
3153 return IDirect3DDevice3_GetLightState(&This
->IDirect3DDevice3_iface
, LightStateType
, Value
);
3156 /*****************************************************************************
3157 * IDirect3DDevice7::SetTransform
3159 * Assigns a D3DMATRIX to a transform type. The transform types are defined
3160 * in include/d3dtypes.h.
3161 * The D3DTRANSFORMSTATE_WORLD (=1) is translated to D3DTS_WORLDMATRIX(0)
3162 * (=255) for wined3d, because the 1 transform state was removed in d3d8
3163 * and WineD3D already understands the replacement D3DTS_WORLDMATRIX(0)
3165 * Version 2, 3 and 7
3168 * TransformStateType: transform state to set
3169 * Matrix: Matrix to assign to the state
3173 * DDERR_INVALIDPARAMS if Matrix == NULL
3174 * For details see IWineD3DDevice::SetTransform
3176 *****************************************************************************/
3178 IDirect3DDeviceImpl_7_SetTransform(IDirect3DDevice7
*iface
,
3179 D3DTRANSFORMSTATETYPE TransformStateType
,
3182 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
3183 D3DTRANSFORMSTATETYPE type
;
3186 TRACE("iface %p, state %#x, matrix %p.\n", iface
, TransformStateType
, Matrix
);
3188 switch(TransformStateType
)
3190 case D3DTRANSFORMSTATE_WORLD
: type
= WINED3DTS_WORLDMATRIX(0); break;
3191 case D3DTRANSFORMSTATE_WORLD1
: type
= WINED3DTS_WORLDMATRIX(1); break;
3192 case D3DTRANSFORMSTATE_WORLD2
: type
= WINED3DTS_WORLDMATRIX(2); break;
3193 case D3DTRANSFORMSTATE_WORLD3
: type
= WINED3DTS_WORLDMATRIX(3); break;
3194 default: type
= TransformStateType
;
3198 return DDERR_INVALIDPARAMS
;
3200 /* Note: D3DMATRIX is compatible with struct wined3d_matrix. */
3201 wined3d_mutex_lock();
3202 hr
= wined3d_device_set_transform(This
->wined3d_device
, type
, (struct wined3d_matrix
*)Matrix
);
3203 wined3d_mutex_unlock();
3208 static HRESULT WINAPI
3209 IDirect3DDeviceImpl_7_SetTransform_FPUSetup(IDirect3DDevice7
*iface
,
3210 D3DTRANSFORMSTATETYPE TransformStateType
,
3213 return IDirect3DDeviceImpl_7_SetTransform(iface
, TransformStateType
, Matrix
);
3216 static HRESULT WINAPI
3217 IDirect3DDeviceImpl_7_SetTransform_FPUPreserve(IDirect3DDevice7
*iface
,
3218 D3DTRANSFORMSTATETYPE TransformStateType
,
3224 old_fpucw
= d3d_fpu_setup();
3225 hr
= IDirect3DDeviceImpl_7_SetTransform(iface
, TransformStateType
, Matrix
);
3226 set_fpu_control_word(old_fpucw
);
3231 static HRESULT WINAPI
IDirect3DDeviceImpl_3_SetTransform(IDirect3DDevice3
*iface
,
3232 D3DTRANSFORMSTATETYPE TransformStateType
, D3DMATRIX
*D3DMatrix
)
3234 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
3236 TRACE("iface %p, state %#x, matrix %p.\n", iface
, TransformStateType
, D3DMatrix
);
3238 return IDirect3DDevice7_SetTransform(&This
->IDirect3DDevice7_iface
, TransformStateType
, D3DMatrix
);
3241 static HRESULT WINAPI
IDirect3DDeviceImpl_2_SetTransform(IDirect3DDevice2
*iface
,
3242 D3DTRANSFORMSTATETYPE TransformStateType
, D3DMATRIX
*D3DMatrix
)
3244 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
3246 TRACE("iface %p, state %#x, matrix %p.\n", iface
, TransformStateType
, D3DMatrix
);
3248 return IDirect3DDevice7_SetTransform(&This
->IDirect3DDevice7_iface
, TransformStateType
, D3DMatrix
);
3251 /*****************************************************************************
3252 * IDirect3DDevice7::GetTransform
3254 * Returns the matrix assigned to a transform state
3255 * D3DTRANSFORMSTATE_WORLD is translated to D3DTS_WORLDMATRIX(0), see
3259 * TransformStateType: State to read the matrix from
3260 * Matrix: Address to store the matrix at
3264 * DDERR_INVALIDPARAMS if Matrix == NULL
3265 * For details, see IWineD3DDevice::GetTransform
3267 *****************************************************************************/
3269 IDirect3DDeviceImpl_7_GetTransform(IDirect3DDevice7
*iface
,
3270 D3DTRANSFORMSTATETYPE TransformStateType
,
3273 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
3274 D3DTRANSFORMSTATETYPE type
;
3277 TRACE("iface %p, state %#x, matrix %p.\n", iface
, TransformStateType
, Matrix
);
3279 switch(TransformStateType
)
3281 case D3DTRANSFORMSTATE_WORLD
: type
= WINED3DTS_WORLDMATRIX(0); break;
3282 case D3DTRANSFORMSTATE_WORLD1
: type
= WINED3DTS_WORLDMATRIX(1); break;
3283 case D3DTRANSFORMSTATE_WORLD2
: type
= WINED3DTS_WORLDMATRIX(2); break;
3284 case D3DTRANSFORMSTATE_WORLD3
: type
= WINED3DTS_WORLDMATRIX(3); break;
3285 default: type
= TransformStateType
;
3289 return DDERR_INVALIDPARAMS
;
3291 /* Note: D3DMATRIX is compatible with struct wined3d_matrix. */
3292 wined3d_mutex_lock();
3293 hr
= wined3d_device_get_transform(This
->wined3d_device
, type
, (struct wined3d_matrix
*)Matrix
);
3294 wined3d_mutex_unlock();
3299 static HRESULT WINAPI
3300 IDirect3DDeviceImpl_7_GetTransform_FPUSetup(IDirect3DDevice7
*iface
,
3301 D3DTRANSFORMSTATETYPE TransformStateType
,
3304 return IDirect3DDeviceImpl_7_GetTransform(iface
, TransformStateType
, Matrix
);
3307 static HRESULT WINAPI
3308 IDirect3DDeviceImpl_7_GetTransform_FPUPreserve(IDirect3DDevice7
*iface
,
3309 D3DTRANSFORMSTATETYPE TransformStateType
,
3315 old_fpucw
= d3d_fpu_setup();
3316 hr
= IDirect3DDeviceImpl_7_GetTransform(iface
, TransformStateType
, Matrix
);
3317 set_fpu_control_word(old_fpucw
);
3322 static HRESULT WINAPI
IDirect3DDeviceImpl_3_GetTransform(IDirect3DDevice3
*iface
,
3323 D3DTRANSFORMSTATETYPE TransformStateType
, D3DMATRIX
*D3DMatrix
)
3325 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
3327 TRACE("iface %p, state %#x, matrix %p.\n", iface
, TransformStateType
, D3DMatrix
);
3329 return IDirect3DDevice7_GetTransform(&This
->IDirect3DDevice7_iface
, TransformStateType
, D3DMatrix
);
3332 static HRESULT WINAPI
IDirect3DDeviceImpl_2_GetTransform(IDirect3DDevice2
*iface
,
3333 D3DTRANSFORMSTATETYPE TransformStateType
, D3DMATRIX
*D3DMatrix
)
3335 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
3337 TRACE("iface %p, state %#x, matrix %p.\n", iface
, TransformStateType
, D3DMatrix
);
3339 return IDirect3DDevice7_GetTransform(&This
->IDirect3DDevice7_iface
, TransformStateType
, D3DMatrix
);
3342 /*****************************************************************************
3343 * IDirect3DDevice7::MultiplyTransform
3345 * Multiplies the already-set transform matrix of a transform state
3346 * with another matrix. For the world matrix, see SetTransform
3348 * Version 2, 3 and 7
3351 * TransformStateType: Transform state to multiply
3352 * D3DMatrix Matrix to multiply with.
3356 * DDERR_INVALIDPARAMS if D3DMatrix is NULL
3357 * For details, see IWineD3DDevice::MultiplyTransform
3359 *****************************************************************************/
3361 IDirect3DDeviceImpl_7_MultiplyTransform(IDirect3DDevice7
*iface
,
3362 D3DTRANSFORMSTATETYPE TransformStateType
,
3363 D3DMATRIX
*D3DMatrix
)
3365 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
3367 D3DTRANSFORMSTATETYPE type
;
3369 TRACE("iface %p, state %#x, matrix %p.\n", iface
, TransformStateType
, D3DMatrix
);
3371 switch(TransformStateType
)
3373 case D3DTRANSFORMSTATE_WORLD
: type
= WINED3DTS_WORLDMATRIX(0); break;
3374 case D3DTRANSFORMSTATE_WORLD1
: type
= WINED3DTS_WORLDMATRIX(1); break;
3375 case D3DTRANSFORMSTATE_WORLD2
: type
= WINED3DTS_WORLDMATRIX(2); break;
3376 case D3DTRANSFORMSTATE_WORLD3
: type
= WINED3DTS_WORLDMATRIX(3); break;
3377 default: type
= TransformStateType
;
3380 /* Note: D3DMATRIX is compatible with struct wined3d_matrix. */
3381 wined3d_mutex_lock();
3382 hr
= wined3d_device_multiply_transform(This
->wined3d_device
,
3383 type
, (struct wined3d_matrix
*)D3DMatrix
);
3384 wined3d_mutex_unlock();
3389 static HRESULT WINAPI
3390 IDirect3DDeviceImpl_7_MultiplyTransform_FPUSetup(IDirect3DDevice7
*iface
,
3391 D3DTRANSFORMSTATETYPE TransformStateType
,
3392 D3DMATRIX
*D3DMatrix
)
3394 return IDirect3DDeviceImpl_7_MultiplyTransform(iface
, TransformStateType
, D3DMatrix
);
3397 static HRESULT WINAPI
3398 IDirect3DDeviceImpl_7_MultiplyTransform_FPUPreserve(IDirect3DDevice7
*iface
,
3399 D3DTRANSFORMSTATETYPE TransformStateType
,
3400 D3DMATRIX
*D3DMatrix
)
3405 old_fpucw
= d3d_fpu_setup();
3406 hr
= IDirect3DDeviceImpl_7_MultiplyTransform(iface
, TransformStateType
, D3DMatrix
);
3407 set_fpu_control_word(old_fpucw
);
3412 static HRESULT WINAPI
IDirect3DDeviceImpl_3_MultiplyTransform(IDirect3DDevice3
*iface
,
3413 D3DTRANSFORMSTATETYPE TransformStateType
, D3DMATRIX
*D3DMatrix
)
3415 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
3417 TRACE("iface %p, state %#x, matrix %p.\n", iface
, TransformStateType
, D3DMatrix
);
3419 return IDirect3DDevice7_MultiplyTransform(&This
->IDirect3DDevice7_iface
, TransformStateType
, D3DMatrix
);
3422 static HRESULT WINAPI
IDirect3DDeviceImpl_2_MultiplyTransform(IDirect3DDevice2
*iface
,
3423 D3DTRANSFORMSTATETYPE TransformStateType
, D3DMATRIX
*D3DMatrix
)
3425 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
3427 TRACE("iface %p, state %#x, matrix %p.\n", iface
, TransformStateType
, D3DMatrix
);
3429 return IDirect3DDevice7_MultiplyTransform(&This
->IDirect3DDevice7_iface
, TransformStateType
, D3DMatrix
);
3432 /*****************************************************************************
3433 * IDirect3DDevice7::DrawPrimitive
3435 * Draws primitives based on vertices in an application-provided pointer
3437 * Version 2, 3 and 7. The IDirect3DDevice2 thunk converts the fixed vertex type into
3438 * an FVF format for D3D7
3441 * PrimitiveType: The type of the primitives to draw
3442 * Vertex type: Flexible vertex format vertex description
3443 * Vertices: Pointer to the vertex array
3444 * VertexCount: The number of vertices to draw
3445 * Flags: As usual a few flags
3449 * DDERR_INVALIDPARAMS if Vertices is NULL
3450 * For details, see IWineD3DDevice::DrawPrimitiveUP
3452 *****************************************************************************/
3454 IDirect3DDeviceImpl_7_DrawPrimitive(IDirect3DDevice7
*iface
,
3455 D3DPRIMITIVETYPE PrimitiveType
,
3461 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
3465 TRACE("iface %p, primitive_type %#x, FVF %#x, vertices %p, vertex_count %u, flags %#x.\n",
3466 iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Flags
);
3469 return DDERR_INVALIDPARAMS
;
3471 /* Get the stride */
3472 stride
= get_flexible_vertex_size(VertexType
);
3475 wined3d_mutex_lock();
3476 hr
= wined3d_device_set_vertex_declaration(This
->wined3d_device
, ddraw_find_decl(This
->ddraw
, VertexType
));
3479 wined3d_mutex_unlock();
3483 /* This method translates to the user pointer draw of WineD3D */
3484 wined3d_device_set_primitive_type(This
->wined3d_device
, PrimitiveType
);
3485 hr
= wined3d_device_draw_primitive_up(This
->wined3d_device
, VertexCount
, Vertices
, stride
);
3486 wined3d_mutex_unlock();
3491 static HRESULT WINAPI
3492 IDirect3DDeviceImpl_7_DrawPrimitive_FPUSetup(IDirect3DDevice7
*iface
,
3493 D3DPRIMITIVETYPE PrimitiveType
,
3499 return IDirect3DDeviceImpl_7_DrawPrimitive(iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Flags
);
3502 static HRESULT WINAPI
3503 IDirect3DDeviceImpl_7_DrawPrimitive_FPUPreserve(IDirect3DDevice7
*iface
,
3504 D3DPRIMITIVETYPE PrimitiveType
,
3513 old_fpucw
= d3d_fpu_setup();
3514 hr
= IDirect3DDeviceImpl_7_DrawPrimitive(iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Flags
);
3515 set_fpu_control_word(old_fpucw
);
3520 static HRESULT WINAPI
IDirect3DDeviceImpl_3_DrawPrimitive(IDirect3DDevice3
*iface
,
3521 D3DPRIMITIVETYPE PrimitiveType
, DWORD VertexType
, void *Vertices
, DWORD VertexCount
,
3524 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
3525 TRACE("iface %p, primitive_type %#x, FVF %#x, vertices %p, vertex_count %u, flags %#x.\n",
3526 iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Flags
);
3528 return IDirect3DDevice7_DrawPrimitive(&This
->IDirect3DDevice7_iface
,
3529 PrimitiveType
, VertexType
, Vertices
, VertexCount
, Flags
);
3532 static HRESULT WINAPI
IDirect3DDeviceImpl_2_DrawPrimitive(IDirect3DDevice2
*iface
,
3533 D3DPRIMITIVETYPE PrimitiveType
, D3DVERTEXTYPE VertexType
, void *Vertices
,
3534 DWORD VertexCount
, DWORD Flags
)
3536 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
3539 TRACE("iface %p, primitive_type %#x, vertex_type %#x, vertices %p, vertex_count %u, flags %#x.\n",
3540 iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Flags
);
3544 case D3DVT_VERTEX
: FVF
= D3DFVF_VERTEX
; break;
3545 case D3DVT_LVERTEX
: FVF
= D3DFVF_LVERTEX
; break;
3546 case D3DVT_TLVERTEX
: FVF
= D3DFVF_TLVERTEX
; break;
3548 ERR("Unexpected vertex type %d\n", VertexType
);
3549 return DDERR_INVALIDPARAMS
; /* Should never happen */
3552 return IDirect3DDevice7_DrawPrimitive(&This
->IDirect3DDevice7_iface
,
3553 PrimitiveType
, FVF
, Vertices
, VertexCount
, Flags
);
3556 /*****************************************************************************
3557 * IDirect3DDevice7::DrawIndexedPrimitive
3559 * Draws vertices from an application-provided pointer, based on the index
3560 * numbers in a WORD array.
3562 * Version 2, 3 and 7. The version 7 thunk translates the vertex type into
3563 * an FVF format for D3D7
3566 * PrimitiveType: The primitive type to draw
3567 * VertexType: The FVF vertex description
3568 * Vertices: Pointer to the vertex array
3570 * Indices: Pointer to the index array
3571 * IndexCount: Number of indices = Number of vertices to draw
3572 * Flags: As usual, some flags
3576 * DDERR_INVALIDPARAMS if Vertices or Indices is NULL
3577 * For details, see IWineD3DDevice::DrawIndexedPrimitiveUP
3579 *****************************************************************************/
3581 IDirect3DDeviceImpl_7_DrawIndexedPrimitive(IDirect3DDevice7
*iface
,
3582 D3DPRIMITIVETYPE PrimitiveType
,
3590 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
3593 TRACE("iface %p, primitive_type %#x, FVF %#x, vertices %p, vertex_count %u, indices %p, index_count %u, flags %#x.\n",
3594 iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Indices
, IndexCount
, Flags
);
3596 /* Set the D3DDevice's FVF */
3597 wined3d_mutex_lock();
3598 hr
= wined3d_device_set_vertex_declaration(This
->wined3d_device
, ddraw_find_decl(This
->ddraw
, VertexType
));
3601 ERR(" (%p) Setting the FVF failed, hr = %x!\n", This
, hr
);
3602 wined3d_mutex_unlock();
3606 wined3d_device_set_primitive_type(This
->wined3d_device
, PrimitiveType
);
3607 hr
= wined3d_device_draw_indexed_primitive_up(This
->wined3d_device
, IndexCount
, Indices
,
3608 WINED3DFMT_R16_UINT
, Vertices
, get_flexible_vertex_size(VertexType
));
3609 wined3d_mutex_unlock();
3614 static HRESULT WINAPI
3615 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUSetup(IDirect3DDevice7
*iface
,
3616 D3DPRIMITIVETYPE PrimitiveType
,
3624 return IDirect3DDeviceImpl_7_DrawIndexedPrimitive(iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Indices
, IndexCount
, Flags
);
3627 static HRESULT WINAPI
3628 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUPreserve(IDirect3DDevice7
*iface
,
3629 D3DPRIMITIVETYPE PrimitiveType
,
3640 old_fpucw
= d3d_fpu_setup();
3641 hr
= IDirect3DDeviceImpl_7_DrawIndexedPrimitive(iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Indices
, IndexCount
, Flags
);
3642 set_fpu_control_word(old_fpucw
);
3647 static HRESULT WINAPI
IDirect3DDeviceImpl_3_DrawIndexedPrimitive(IDirect3DDevice3
*iface
,
3648 D3DPRIMITIVETYPE PrimitiveType
, DWORD VertexType
, void *Vertices
, DWORD VertexCount
,
3649 WORD
*Indices
, DWORD IndexCount
, DWORD Flags
)
3651 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
3652 TRACE("iface %p, primitive_type %#x, FVF %#x, vertices %p, vertex_count %u, indices %p, index_count %u, flags %#x.\n",
3653 iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Indices
, IndexCount
, Flags
);
3655 return IDirect3DDevice7_DrawIndexedPrimitive(&This
->IDirect3DDevice7_iface
,
3656 PrimitiveType
, VertexType
, Vertices
, VertexCount
, Indices
, IndexCount
, Flags
);
3659 static HRESULT WINAPI
IDirect3DDeviceImpl_2_DrawIndexedPrimitive(IDirect3DDevice2
*iface
,
3660 D3DPRIMITIVETYPE PrimitiveType
, D3DVERTEXTYPE VertexType
, void *Vertices
,
3661 DWORD VertexCount
, WORD
*Indices
, DWORD IndexCount
, DWORD Flags
)
3663 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
3666 TRACE("iface %p, primitive_type %#x, vertex_type %#x, vertices %p, vertex_count %u, indices %p, index_count %u, flags %#x.\n",
3667 iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Indices
, IndexCount
, Flags
);
3671 case D3DVT_VERTEX
: FVF
= D3DFVF_VERTEX
; break;
3672 case D3DVT_LVERTEX
: FVF
= D3DFVF_LVERTEX
; break;
3673 case D3DVT_TLVERTEX
: FVF
= D3DFVF_TLVERTEX
; break;
3675 ERR("Unexpected vertex type %d\n", VertexType
);
3676 return DDERR_INVALIDPARAMS
; /* Should never happen */
3679 return IDirect3DDevice7_DrawIndexedPrimitive(&This
->IDirect3DDevice7_iface
,
3680 PrimitiveType
, FVF
, Vertices
, VertexCount
, Indices
, IndexCount
, Flags
);
3683 /*****************************************************************************
3684 * IDirect3DDevice7::SetClipStatus
3686 * Sets the clip status. This defines things as clipping conditions and
3687 * the extents of the clipping region.
3689 * Version 2, 3 and 7
3695 * D3D_OK because it's a stub
3696 * (DDERR_INVALIDPARAMS if ClipStatus == NULL)
3698 *****************************************************************************/
3699 static HRESULT WINAPI
3700 IDirect3DDeviceImpl_7_SetClipStatus(IDirect3DDevice7
*iface
,
3701 D3DCLIPSTATUS
*ClipStatus
)
3703 FIXME("iface %p, clip_status %p stub!\n", iface
, ClipStatus
);
3705 /* D3DCLIPSTATUS and WINED3DCLIPSTATUS are different. I don't know how to convert them
3706 * Perhaps this needs a new data type and an additional IWineD3DDevice method
3708 /* return IWineD3DDevice_SetClipStatus(This->wineD3DDevice, ClipStatus);*/
3712 static HRESULT WINAPI
IDirect3DDeviceImpl_3_SetClipStatus(IDirect3DDevice3
*iface
,
3713 D3DCLIPSTATUS
*ClipStatus
)
3715 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
3716 TRACE("iface %p, clip_status %p.\n", iface
, ClipStatus
);
3718 return IDirect3DDevice7_SetClipStatus(&This
->IDirect3DDevice7_iface
, ClipStatus
);
3721 static HRESULT WINAPI
IDirect3DDeviceImpl_2_SetClipStatus(IDirect3DDevice2
*iface
,
3722 D3DCLIPSTATUS
*ClipStatus
)
3724 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
3725 TRACE("iface %p, clip_status %p.\n", iface
, ClipStatus
);
3727 return IDirect3DDevice7_SetClipStatus(&This
->IDirect3DDevice7_iface
, ClipStatus
);
3730 /*****************************************************************************
3731 * IDirect3DDevice7::GetClipStatus
3733 * Returns the clip status
3736 * ClipStatus: Address to write the clip status to
3739 * D3D_OK because it's a stub
3741 *****************************************************************************/
3742 static HRESULT WINAPI
3743 IDirect3DDeviceImpl_7_GetClipStatus(IDirect3DDevice7
*iface
,
3744 D3DCLIPSTATUS
*ClipStatus
)
3746 FIXME("iface %p, clip_status %p stub!\n", iface
, ClipStatus
);
3748 /* D3DCLIPSTATUS and WINED3DCLIPSTATUS are different. I don't know how to convert them */
3749 /* return IWineD3DDevice_GetClipStatus(This->wineD3DDevice, ClipStatus);*/
3753 static HRESULT WINAPI
IDirect3DDeviceImpl_3_GetClipStatus(IDirect3DDevice3
*iface
,
3754 D3DCLIPSTATUS
*ClipStatus
)
3756 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
3757 TRACE("iface %p, clip_status %p.\n", iface
, ClipStatus
);
3759 return IDirect3DDevice7_GetClipStatus(&This
->IDirect3DDevice7_iface
, ClipStatus
);
3762 static HRESULT WINAPI
IDirect3DDeviceImpl_2_GetClipStatus(IDirect3DDevice2
*iface
,
3763 D3DCLIPSTATUS
*ClipStatus
)
3765 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
3766 TRACE("iface %p, clip_status %p.\n", iface
, ClipStatus
);
3768 return IDirect3DDevice7_GetClipStatus(&This
->IDirect3DDevice7_iface
, ClipStatus
);
3771 /*****************************************************************************
3772 * IDirect3DDevice::DrawPrimitiveStrided
3774 * Draws vertices described by a D3DDRAWPRIMITIVESTRIDEDDATA structure.
3779 * PrimitiveType: The primitive type to draw
3780 * VertexType: The FVF description of the vertices to draw (for the stride??)
3781 * D3DDrawPrimStrideData: A D3DDRAWPRIMITIVESTRIDEDDATA structure describing
3782 * the vertex data locations
3783 * VertexCount: The number of vertices to draw
3787 * D3D_OK, because it's a stub
3788 * (DDERR_INVALIDPARAMS if D3DDrawPrimStrideData is NULL)
3789 * (For details, see IWineD3DDevice::DrawPrimitiveStrided)
3791 *****************************************************************************/
3793 IDirect3DDeviceImpl_7_DrawPrimitiveStrided(IDirect3DDevice7
*iface
,
3794 D3DPRIMITIVETYPE PrimitiveType
,
3796 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
,
3800 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
3801 WineDirect3DVertexStridedData WineD3DStrided
;
3805 TRACE("iface %p, primitive_type %#x, FVF %#x, strided_data %p, vertex_count %u, flags %#x.\n",
3806 iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Flags
);
3808 memset(&WineD3DStrided
, 0, sizeof(WineD3DStrided
));
3809 /* Get the strided data right. the wined3d structure is a bit bigger
3810 * Watch out: The contents of the strided data are determined by the fvf,
3811 * not by the members set in D3DDrawPrimStrideData. So it's valid
3812 * to have diffuse.lpvData set to 0xdeadbeef if the diffuse flag is
3813 * not set in the fvf.
3815 if(VertexType
& D3DFVF_POSITION_MASK
)
3817 WineD3DStrided
.position
.format
= WINED3DFMT_R32G32B32_FLOAT
;
3818 WineD3DStrided
.position
.lpData
= D3DDrawPrimStrideData
->position
.lpvData
;
3819 WineD3DStrided
.position
.dwStride
= D3DDrawPrimStrideData
->position
.dwStride
;
3820 if (VertexType
& D3DFVF_XYZRHW
)
3822 WineD3DStrided
.position
.format
= WINED3DFMT_R32G32B32A32_FLOAT
;
3823 WineD3DStrided
.position_transformed
= TRUE
;
3825 WineD3DStrided
.position_transformed
= FALSE
;
3828 if(VertexType
& D3DFVF_NORMAL
)
3830 WineD3DStrided
.normal
.format
= WINED3DFMT_R32G32B32_FLOAT
;
3831 WineD3DStrided
.normal
.lpData
= D3DDrawPrimStrideData
->normal
.lpvData
;
3832 WineD3DStrided
.normal
.dwStride
= D3DDrawPrimStrideData
->normal
.dwStride
;
3835 if(VertexType
& D3DFVF_DIFFUSE
)
3837 WineD3DStrided
.diffuse
.format
= WINED3DFMT_B8G8R8A8_UNORM
;
3838 WineD3DStrided
.diffuse
.lpData
= D3DDrawPrimStrideData
->diffuse
.lpvData
;
3839 WineD3DStrided
.diffuse
.dwStride
= D3DDrawPrimStrideData
->diffuse
.dwStride
;
3842 if(VertexType
& D3DFVF_SPECULAR
)
3844 WineD3DStrided
.specular
.format
= WINED3DFMT_B8G8R8A8_UNORM
;
3845 WineD3DStrided
.specular
.lpData
= D3DDrawPrimStrideData
->specular
.lpvData
;
3846 WineD3DStrided
.specular
.dwStride
= D3DDrawPrimStrideData
->specular
.dwStride
;
3849 for( i
= 0; i
< GET_TEXCOUNT_FROM_FVF(VertexType
); i
++)
3851 switch(GET_TEXCOORD_SIZE_FROM_FVF(VertexType
, i
))
3853 case 1: WineD3DStrided
.texCoords
[i
].format
= WINED3DFMT_R32_FLOAT
; break;
3854 case 2: WineD3DStrided
.texCoords
[i
].format
= WINED3DFMT_R32G32_FLOAT
; break;
3855 case 3: WineD3DStrided
.texCoords
[i
].format
= WINED3DFMT_R32G32B32_FLOAT
; break;
3856 case 4: WineD3DStrided
.texCoords
[i
].format
= WINED3DFMT_R32G32B32A32_FLOAT
; break;
3857 default: ERR("Unexpected texture coordinate size %d\n",
3858 GET_TEXCOORD_SIZE_FROM_FVF(VertexType
, i
));
3860 WineD3DStrided
.texCoords
[i
].lpData
= D3DDrawPrimStrideData
->textureCoords
[i
].lpvData
;
3861 WineD3DStrided
.texCoords
[i
].dwStride
= D3DDrawPrimStrideData
->textureCoords
[i
].dwStride
;
3864 /* WineD3D doesn't need the FVF here */
3865 wined3d_mutex_lock();
3866 wined3d_device_set_primitive_type(This
->wined3d_device
, PrimitiveType
);
3867 hr
= wined3d_device_draw_primitive_strided(This
->wined3d_device
, VertexCount
, &WineD3DStrided
);
3868 wined3d_mutex_unlock();
3873 static HRESULT WINAPI
3874 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUSetup(IDirect3DDevice7
*iface
,
3875 D3DPRIMITIVETYPE PrimitiveType
,
3877 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
,
3881 return IDirect3DDeviceImpl_7_DrawPrimitiveStrided(iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Flags
);
3884 static HRESULT WINAPI
3885 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUPreserve(IDirect3DDevice7
*iface
,
3886 D3DPRIMITIVETYPE PrimitiveType
,
3888 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
,
3895 old_fpucw
= d3d_fpu_setup();
3896 hr
= IDirect3DDeviceImpl_7_DrawPrimitiveStrided(iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Flags
);
3897 set_fpu_control_word(old_fpucw
);
3902 static HRESULT WINAPI
IDirect3DDeviceImpl_3_DrawPrimitiveStrided(IDirect3DDevice3
*iface
,
3903 D3DPRIMITIVETYPE PrimitiveType
, DWORD VertexType
,
3904 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
, DWORD VertexCount
, DWORD Flags
)
3906 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
3908 TRACE("iface %p, primitive_type %#x, FVF %#x, strided_data %p, vertex_count %u, flags %#x.\n",
3909 iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Flags
);
3911 return IDirect3DDevice7_DrawPrimitiveStrided(&This
->IDirect3DDevice7_iface
,
3912 PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Flags
);
3915 /*****************************************************************************
3916 * IDirect3DDevice7::DrawIndexedPrimitiveStrided
3918 * Draws primitives specified by strided data locations based on indices
3926 * D3D_OK, because it's a stub
3927 * (DDERR_INVALIDPARAMS if D3DDrawPrimStrideData is NULL)
3928 * (DDERR_INVALIDPARAMS if Indices is NULL)
3929 * (For more details, see IWineD3DDevice::DrawIndexedPrimitiveStrided)
3931 *****************************************************************************/
3933 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided(IDirect3DDevice7
*iface
,
3934 D3DPRIMITIVETYPE PrimitiveType
,
3936 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
,
3942 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
3943 WineDirect3DVertexStridedData WineD3DStrided
;
3947 TRACE("iface %p, primitive_type %#x, FVF %#x, strided_data %p, vertex_count %u, indices %p, index_count %u, flags %#x.\n",
3948 iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Indices
, IndexCount
, Flags
);
3950 memset(&WineD3DStrided
, 0, sizeof(WineD3DStrided
));
3951 /* Get the strided data right. the wined3d structure is a bit bigger
3952 * Watch out: The contents of the strided data are determined by the fvf,
3953 * not by the members set in D3DDrawPrimStrideData. So it's valid
3954 * to have diffuse.lpvData set to 0xdeadbeef if the diffuse flag is
3955 * not set in the fvf.
3957 if(VertexType
& D3DFVF_POSITION_MASK
)
3959 WineD3DStrided
.position
.format
= WINED3DFMT_R32G32B32_FLOAT
;
3960 WineD3DStrided
.position
.lpData
= D3DDrawPrimStrideData
->position
.lpvData
;
3961 WineD3DStrided
.position
.dwStride
= D3DDrawPrimStrideData
->position
.dwStride
;
3962 if (VertexType
& D3DFVF_XYZRHW
)
3964 WineD3DStrided
.position
.format
= WINED3DFMT_R32G32B32A32_FLOAT
;
3965 WineD3DStrided
.position_transformed
= TRUE
;
3967 WineD3DStrided
.position_transformed
= FALSE
;
3970 if(VertexType
& D3DFVF_NORMAL
)
3972 WineD3DStrided
.normal
.format
= WINED3DFMT_R32G32B32_FLOAT
;
3973 WineD3DStrided
.normal
.lpData
= D3DDrawPrimStrideData
->normal
.lpvData
;
3974 WineD3DStrided
.normal
.dwStride
= D3DDrawPrimStrideData
->normal
.dwStride
;
3977 if(VertexType
& D3DFVF_DIFFUSE
)
3979 WineD3DStrided
.diffuse
.format
= WINED3DFMT_B8G8R8A8_UNORM
;
3980 WineD3DStrided
.diffuse
.lpData
= D3DDrawPrimStrideData
->diffuse
.lpvData
;
3981 WineD3DStrided
.diffuse
.dwStride
= D3DDrawPrimStrideData
->diffuse
.dwStride
;
3984 if(VertexType
& D3DFVF_SPECULAR
)
3986 WineD3DStrided
.specular
.format
= WINED3DFMT_B8G8R8A8_UNORM
;
3987 WineD3DStrided
.specular
.lpData
= D3DDrawPrimStrideData
->specular
.lpvData
;
3988 WineD3DStrided
.specular
.dwStride
= D3DDrawPrimStrideData
->specular
.dwStride
;
3991 for( i
= 0; i
< GET_TEXCOUNT_FROM_FVF(VertexType
); i
++)
3993 switch(GET_TEXCOORD_SIZE_FROM_FVF(VertexType
, i
))
3995 case 1: WineD3DStrided
.texCoords
[i
].format
= WINED3DFMT_R32_FLOAT
; break;
3996 case 2: WineD3DStrided
.texCoords
[i
].format
= WINED3DFMT_R32G32_FLOAT
; break;
3997 case 3: WineD3DStrided
.texCoords
[i
].format
= WINED3DFMT_R32G32B32_FLOAT
; break;
3998 case 4: WineD3DStrided
.texCoords
[i
].format
= WINED3DFMT_R32G32B32A32_FLOAT
; break;
3999 default: ERR("Unexpected texture coordinate size %d\n",
4000 GET_TEXCOORD_SIZE_FROM_FVF(VertexType
, i
));
4002 WineD3DStrided
.texCoords
[i
].lpData
= D3DDrawPrimStrideData
->textureCoords
[i
].lpvData
;
4003 WineD3DStrided
.texCoords
[i
].dwStride
= D3DDrawPrimStrideData
->textureCoords
[i
].dwStride
;
4006 /* WineD3D doesn't need the FVF here */
4007 wined3d_mutex_lock();
4008 wined3d_device_set_primitive_type(This
->wined3d_device
, PrimitiveType
);
4009 hr
= wined3d_device_draw_indexed_primitive_strided(This
->wined3d_device
,
4010 IndexCount
, &WineD3DStrided
, VertexCount
, Indices
, WINED3DFMT_R16_UINT
);
4011 wined3d_mutex_unlock();
4016 static HRESULT WINAPI
4017 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUSetup(IDirect3DDevice7
*iface
,
4018 D3DPRIMITIVETYPE PrimitiveType
,
4020 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
,
4026 return IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided(iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Indices
, IndexCount
, Flags
);
4029 static HRESULT WINAPI
4030 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUPreserve(IDirect3DDevice7
*iface
,
4031 D3DPRIMITIVETYPE PrimitiveType
,
4033 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
,
4042 old_fpucw
= d3d_fpu_setup();
4043 hr
= IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided(iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Indices
, IndexCount
, Flags
);
4044 set_fpu_control_word(old_fpucw
);
4049 static HRESULT WINAPI
IDirect3DDeviceImpl_3_DrawIndexedPrimitiveStrided(IDirect3DDevice3
*iface
,
4050 D3DPRIMITIVETYPE PrimitiveType
, DWORD VertexType
,
4051 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
, DWORD VertexCount
, WORD
*Indices
,
4052 DWORD IndexCount
, DWORD Flags
)
4054 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
4056 TRACE("iface %p, primitive_type %#x, FVF %#x, strided_data %p, vertex_count %u, indices %p, index_count %u, flags %#x.\n",
4057 iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Indices
, IndexCount
, Flags
);
4059 return IDirect3DDevice7_DrawIndexedPrimitiveStrided(&This
->IDirect3DDevice7_iface
,
4060 PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Indices
, IndexCount
, Flags
);
4063 /*****************************************************************************
4064 * IDirect3DDevice7::DrawPrimitiveVB
4066 * Draws primitives from a vertex buffer to the screen.
4071 * PrimitiveType: Type of primitive to be rendered.
4072 * D3DVertexBuf: Source Vertex Buffer
4073 * StartVertex: Index of the first vertex from the buffer to be rendered
4074 * NumVertices: Number of vertices to be rendered
4075 * Flags: Can be D3DDP_WAIT to wait until rendering has finished
4079 * DDERR_INVALIDPARAMS if D3DVertexBuf is NULL
4081 *****************************************************************************/
4083 IDirect3DDeviceImpl_7_DrawPrimitiveVB(IDirect3DDevice7
*iface
,
4084 D3DPRIMITIVETYPE PrimitiveType
,
4085 IDirect3DVertexBuffer7
*D3DVertexBuf
,
4090 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
4091 IDirect3DVertexBufferImpl
*vb
= unsafe_impl_from_IDirect3DVertexBuffer7(D3DVertexBuf
);
4095 TRACE("iface %p, primitive_type %#x, vb %p, start_vertex %u, vertex_count %u, flags %#x.\n",
4096 iface
, PrimitiveType
, D3DVertexBuf
, StartVertex
, NumVertices
, Flags
);
4101 ERR("(%p) No Vertex buffer specified\n", This
);
4102 return DDERR_INVALIDPARAMS
;
4104 stride
= get_flexible_vertex_size(vb
->fvf
);
4106 wined3d_mutex_lock();
4107 hr
= wined3d_device_set_vertex_declaration(This
->wined3d_device
, vb
->wineD3DVertexDeclaration
);
4110 ERR(" (%p) Setting the FVF failed, hr = %x!\n", This
, hr
);
4111 wined3d_mutex_unlock();
4115 /* Set the vertex stream source */
4116 hr
= wined3d_device_set_stream_source(This
->wined3d_device
, 0, vb
->wineD3DVertexBuffer
, 0, stride
);
4119 ERR("(%p) IDirect3DDevice::SetStreamSource failed with hr = %08x\n", This
, hr
);
4120 wined3d_mutex_unlock();
4124 /* Now draw the primitives */
4125 wined3d_device_set_primitive_type(This
->wined3d_device
, PrimitiveType
);
4126 hr
= wined3d_device_draw_primitive(This
->wined3d_device
, StartVertex
, NumVertices
);
4127 wined3d_mutex_unlock();
4132 static HRESULT WINAPI
4133 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUSetup(IDirect3DDevice7
*iface
,
4134 D3DPRIMITIVETYPE PrimitiveType
,
4135 IDirect3DVertexBuffer7
*D3DVertexBuf
,
4140 return IDirect3DDeviceImpl_7_DrawPrimitiveVB(iface
, PrimitiveType
, D3DVertexBuf
, StartVertex
, NumVertices
, Flags
);
4143 static HRESULT WINAPI
4144 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUPreserve(IDirect3DDevice7
*iface
,
4145 D3DPRIMITIVETYPE PrimitiveType
,
4146 IDirect3DVertexBuffer7
*D3DVertexBuf
,
4154 old_fpucw
= d3d_fpu_setup();
4155 hr
= IDirect3DDeviceImpl_7_DrawPrimitiveVB(iface
, PrimitiveType
, D3DVertexBuf
, StartVertex
, NumVertices
, Flags
);
4156 set_fpu_control_word(old_fpucw
);
4161 static HRESULT WINAPI
IDirect3DDeviceImpl_3_DrawPrimitiveVB(IDirect3DDevice3
*iface
,
4162 D3DPRIMITIVETYPE PrimitiveType
, IDirect3DVertexBuffer
*D3DVertexBuf
, DWORD StartVertex
,
4163 DWORD NumVertices
, DWORD Flags
)
4165 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
4166 IDirect3DVertexBufferImpl
*vb
= unsafe_impl_from_IDirect3DVertexBuffer(D3DVertexBuf
);
4168 TRACE("iface %p, primitive_type %#x, vb %p, start_vertex %u, vertex_count %u, flags %#x.\n",
4169 iface
, PrimitiveType
, D3DVertexBuf
, StartVertex
, NumVertices
, Flags
);
4171 return IDirect3DDevice7_DrawPrimitiveVB(&This
->IDirect3DDevice7_iface
,
4172 PrimitiveType
, &vb
->IDirect3DVertexBuffer7_iface
, StartVertex
, NumVertices
, Flags
);
4176 /*****************************************************************************
4177 * IDirect3DDevice7::DrawIndexedPrimitiveVB
4179 * Draws primitives from a vertex buffer to the screen
4182 * PrimitiveType: Type of primitive to be rendered.
4183 * D3DVertexBuf: Source Vertex Buffer
4184 * StartVertex: Index of the first vertex from the buffer to be rendered
4185 * NumVertices: Number of vertices to be rendered
4186 * Indices: Array of DWORDs used to index into the Vertices
4187 * IndexCount: Number of indices in Indices
4188 * Flags: Can be D3DDP_WAIT to wait until rendering has finished
4192 *****************************************************************************/
4194 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB(IDirect3DDevice7
*iface
,
4195 D3DPRIMITIVETYPE PrimitiveType
,
4196 IDirect3DVertexBuffer7
*D3DVertexBuf
,
4203 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
4204 IDirect3DVertexBufferImpl
*vb
= unsafe_impl_from_IDirect3DVertexBuffer7(D3DVertexBuf
);
4205 DWORD stride
= get_flexible_vertex_size(vb
->fvf
);
4206 struct wined3d_resource
*wined3d_resource
;
4207 struct wined3d_resource_desc desc
;
4208 WORD
*LockedIndices
;
4211 TRACE("iface %p, primitive_type %#x, vb %p, start_vertex %u, vertex_count %u, indices %p, index_count %u, flags %#x.\n",
4212 iface
, PrimitiveType
, D3DVertexBuf
, StartVertex
, NumVertices
, Indices
, IndexCount
, Flags
);
4215 * 1) Upload the Indices to the index buffer
4216 * 2) Set the index source
4217 * 3) Set the Vertex Buffer as the Stream source
4218 * 4) Call IWineD3DDevice::DrawIndexedPrimitive
4221 wined3d_mutex_lock();
4223 hr
= wined3d_device_set_vertex_declaration(This
->wined3d_device
, vb
->wineD3DVertexDeclaration
);
4226 ERR(" (%p) Setting the FVF failed, hr = %x!\n", This
, hr
);
4227 wined3d_mutex_unlock();
4231 /* check that the buffer is large enough to hold the indices,
4232 * reallocate if necessary. */
4233 wined3d_resource
= wined3d_buffer_get_resource(This
->indexbuffer
);
4234 wined3d_resource_get_desc(wined3d_resource
, &desc
);
4235 if (desc
.size
< IndexCount
* sizeof(WORD
))
4237 UINT size
= max(desc
.size
* 2, IndexCount
* sizeof(WORD
));
4238 struct wined3d_buffer
*buffer
;
4240 TRACE("Growing index buffer to %u bytes\n", size
);
4242 hr
= wined3d_buffer_create_ib(This
->wined3d_device
, size
, WINED3DUSAGE_DYNAMIC
/* Usage */,
4243 WINED3DPOOL_DEFAULT
, NULL
, &ddraw_null_wined3d_parent_ops
, &buffer
);
4246 ERR("(%p) IWineD3DDevice::CreateIndexBuffer failed with hr = %08x\n", This
, hr
);
4247 wined3d_mutex_unlock();
4251 wined3d_buffer_decref(This
->indexbuffer
);
4252 This
->indexbuffer
= buffer
;
4255 /* Copy the index stream into the index buffer. A new IWineD3DDevice
4256 * method could be created which takes an user pointer containing the
4257 * indices or a SetData-Method for the index buffer, which overrides the
4258 * index buffer data with our pointer. */
4259 hr
= wined3d_buffer_map(This
->indexbuffer
, 0, IndexCount
* sizeof(WORD
),
4260 (BYTE
**)&LockedIndices
, 0);
4263 ERR("Failed to map buffer, hr %#x.\n", hr
);
4264 wined3d_mutex_unlock();
4267 memcpy(LockedIndices
, Indices
, IndexCount
* sizeof(WORD
));
4268 wined3d_buffer_unmap(This
->indexbuffer
);
4270 /* Set the index stream */
4271 wined3d_device_set_base_vertex_index(This
->wined3d_device
, StartVertex
);
4272 hr
= wined3d_device_set_index_buffer(This
->wined3d_device
, This
->indexbuffer
, WINED3DFMT_R16_UINT
);
4274 /* Set the vertex stream source */
4275 hr
= wined3d_device_set_stream_source(This
->wined3d_device
, 0, vb
->wineD3DVertexBuffer
, 0, stride
);
4278 ERR("(%p) IDirect3DDevice::SetStreamSource failed with hr = %08x\n", This
, hr
);
4279 wined3d_mutex_unlock();
4284 wined3d_device_set_primitive_type(This
->wined3d_device
, PrimitiveType
);
4285 hr
= wined3d_device_draw_indexed_primitive(This
->wined3d_device
, 0, IndexCount
);
4287 wined3d_mutex_unlock();
4292 static HRESULT WINAPI
4293 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUSetup(IDirect3DDevice7
*iface
,
4294 D3DPRIMITIVETYPE PrimitiveType
,
4295 IDirect3DVertexBuffer7
*D3DVertexBuf
,
4302 return IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB(iface
, PrimitiveType
, D3DVertexBuf
, StartVertex
, NumVertices
, Indices
, IndexCount
, Flags
);
4305 static HRESULT WINAPI
4306 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUPreserve(IDirect3DDevice7
*iface
,
4307 D3DPRIMITIVETYPE PrimitiveType
,
4308 IDirect3DVertexBuffer7
*D3DVertexBuf
,
4318 old_fpucw
= d3d_fpu_setup();
4319 hr
= IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB(iface
, PrimitiveType
, D3DVertexBuf
, StartVertex
, NumVertices
, Indices
, IndexCount
, Flags
);
4320 set_fpu_control_word(old_fpucw
);
4325 static HRESULT WINAPI
IDirect3DDeviceImpl_3_DrawIndexedPrimitiveVB(IDirect3DDevice3
*iface
,
4326 D3DPRIMITIVETYPE PrimitiveType
, IDirect3DVertexBuffer
*D3DVertexBuf
, WORD
*Indices
,
4327 DWORD IndexCount
, DWORD Flags
)
4329 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
4330 IDirect3DVertexBufferImpl
*vb
= unsafe_impl_from_IDirect3DVertexBuffer(D3DVertexBuf
);
4332 TRACE("iface %p, primitive_type %#x, vb %p, indices %p, index_count %u, flags %#x.\n",
4333 iface
, PrimitiveType
, D3DVertexBuf
, Indices
, IndexCount
, Flags
);
4335 return IDirect3DDevice7_DrawIndexedPrimitiveVB(&This
->IDirect3DDevice7_iface
,
4336 PrimitiveType
, &vb
->IDirect3DVertexBuffer7_iface
, 0, IndexCount
, Indices
, IndexCount
,
4340 /*****************************************************************************
4341 * IDirect3DDevice7::ComputeSphereVisibility
4343 * Calculates the visibility of spheres in the current viewport. The spheres
4344 * are passed in the Centers and Radii arrays, the results are passed back
4345 * in the ReturnValues array. Return values are either completely visible,
4346 * partially visible or completely invisible.
4347 * The return value consist of a combination of D3DCLIP_* flags, or it's
4348 * 0 if the sphere is completely visible(according to the SDK, not checked)
4353 * Centers: Array containing the sphere centers
4354 * Radii: Array containing the sphere radii
4355 * NumSpheres: The number of centers and radii in the arrays
4357 * ReturnValues: Array to write the results to
4361 * (DDERR_INVALIDPARAMS if Centers, Radii or ReturnValues are NULL)
4362 * (D3DERR_INVALIDMATRIX if the combined world, view and proj matrix
4365 *****************************************************************************/
4367 static DWORD
in_plane(UINT plane
, D3DVECTOR normal
, D3DVALUE origin_plane
, D3DVECTOR center
, D3DVALUE radius
)
4369 float distance
, norm
;
4371 norm
= sqrt( normal
.u1
.x
* normal
.u1
.x
+ normal
.u2
.y
* normal
.u2
.y
+ normal
.u3
.z
* normal
.u3
.z
);
4372 distance
= ( origin_plane
+ normal
.u1
.x
* center
.u1
.x
+ normal
.u2
.y
* center
.u2
.y
+ normal
.u3
.z
* center
.u3
.z
) / norm
;
4374 if ( fabs( distance
) < radius
) return D3DSTATUS_CLIPUNIONLEFT
<< plane
;
4375 if ( distance
< -radius
) return (D3DSTATUS_CLIPUNIONLEFT
| D3DSTATUS_CLIPINTERSECTIONLEFT
) << plane
;
4379 static HRESULT WINAPI
4380 IDirect3DDeviceImpl_7_ComputeSphereVisibility(IDirect3DDevice7
*iface
,
4385 DWORD
*ReturnValues
)
4388 D3DVALUE origin_plane
[6];
4393 TRACE("iface %p, centers %p, radii %p, sphere_count %u, flags %#x, return_values %p.\n",
4394 iface
, Centers
, Radii
, NumSpheres
, Flags
, ReturnValues
);
4396 hr
= IDirect3DDeviceImpl_7_GetTransform(iface
, D3DTRANSFORMSTATE_WORLD
, &m
);
4397 if ( hr
!= DD_OK
) return DDERR_INVALIDPARAMS
;
4398 hr
= IDirect3DDeviceImpl_7_GetTransform(iface
, D3DTRANSFORMSTATE_VIEW
, &temp
);
4399 if ( hr
!= DD_OK
) return DDERR_INVALIDPARAMS
;
4400 multiply_matrix(&m
, &temp
, &m
);
4402 hr
= IDirect3DDeviceImpl_7_GetTransform(iface
, D3DTRANSFORMSTATE_PROJECTION
, &temp
);
4403 if ( hr
!= DD_OK
) return DDERR_INVALIDPARAMS
;
4404 multiply_matrix(&m
, &temp
, &m
);
4407 vec
[0].u1
.x
= m
._14
+ m
._11
;
4408 vec
[0].u2
.y
= m
._24
+ m
._21
;
4409 vec
[0].u3
.z
= m
._34
+ m
._31
;
4410 origin_plane
[0] = m
._44
+ m
._41
;
4413 vec
[1].u1
.x
= m
._14
- m
._11
;
4414 vec
[1].u2
.y
= m
._24
- m
._21
;
4415 vec
[1].u3
.z
= m
._34
- m
._31
;
4416 origin_plane
[1] = m
._44
- m
._41
;
4419 vec
[2].u1
.x
= m
._14
- m
._12
;
4420 vec
[2].u2
.y
= m
._24
- m
._22
;
4421 vec
[2].u3
.z
= m
._34
- m
._32
;
4422 origin_plane
[2] = m
._44
- m
._42
;
4425 vec
[3].u1
.x
= m
._14
+ m
._12
;
4426 vec
[3].u2
.y
= m
._24
+ m
._22
;
4427 vec
[3].u3
.z
= m
._34
+ m
._32
;
4428 origin_plane
[3] = m
._44
+ m
._42
;
4431 vec
[4].u1
.x
= m
._13
;
4432 vec
[4].u2
.y
= m
._23
;
4433 vec
[4].u3
.z
= m
._33
;
4434 origin_plane
[4] = m
._43
;
4437 vec
[5].u1
.x
= m
._14
- m
._13
;
4438 vec
[5].u2
.y
= m
._24
- m
._23
;
4439 vec
[5].u3
.z
= m
._34
- m
._33
;
4440 origin_plane
[5] = m
._44
- m
._43
;
4442 for(i
=0; i
<NumSpheres
; i
++)
4444 ReturnValues
[i
] = 0;
4445 for(j
=0; j
<6; j
++) ReturnValues
[i
] |= in_plane(j
, vec
[j
], origin_plane
[j
], Centers
[i
], Radii
[i
]);
4451 static HRESULT WINAPI
IDirect3DDeviceImpl_3_ComputeSphereVisibility(IDirect3DDevice3
*iface
,
4452 D3DVECTOR
*Centers
, D3DVALUE
*Radii
, DWORD NumSpheres
, DWORD Flags
, DWORD
*ReturnValues
)
4454 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
4456 TRACE("iface %p, centers %p, radii %p, sphere_count %u, flags %#x, return_values %p.\n",
4457 iface
, Centers
, Radii
, NumSpheres
, Flags
, ReturnValues
);
4459 return IDirect3DDevice7_ComputeSphereVisibility(&This
->IDirect3DDevice7_iface
,
4460 Centers
, Radii
, NumSpheres
, Flags
, ReturnValues
);
4463 /*****************************************************************************
4464 * IDirect3DDevice7::GetTexture
4466 * Returns the texture interface handle assigned to a texture stage.
4467 * The returned texture is AddRefed. This is taken from old ddraw,
4468 * not checked in Windows.
4473 * Stage: Texture stage to read the texture from
4474 * Texture: Address to store the interface pointer at
4478 * DDERR_INVALIDPARAMS if Texture is NULL
4479 * For details, see IWineD3DDevice::GetTexture
4481 *****************************************************************************/
4483 IDirect3DDeviceImpl_7_GetTexture(IDirect3DDevice7
*iface
,
4485 IDirectDrawSurface7
**Texture
)
4487 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
4488 struct wined3d_texture
*wined3d_texture
;
4491 TRACE("iface %p, stage %u, texture %p.\n", iface
, Stage
, Texture
);
4495 TRACE("Texture == NULL, failing with DDERR_INVALIDPARAMS\n");
4496 return DDERR_INVALIDPARAMS
;
4499 wined3d_mutex_lock();
4500 hr
= wined3d_device_get_texture(This
->wined3d_device
, Stage
, &wined3d_texture
);
4501 if (FAILED(hr
) || !wined3d_texture
)
4504 wined3d_mutex_unlock();
4508 *Texture
= wined3d_texture_get_parent(wined3d_texture
);
4509 IDirectDrawSurface7_AddRef(*Texture
);
4510 wined3d_texture_decref(wined3d_texture
);
4511 wined3d_mutex_unlock();
4516 static HRESULT WINAPI
4517 IDirect3DDeviceImpl_7_GetTexture_FPUSetup(IDirect3DDevice7
*iface
,
4519 IDirectDrawSurface7
**Texture
)
4521 return IDirect3DDeviceImpl_7_GetTexture(iface
, Stage
, Texture
);
4524 static HRESULT WINAPI
4525 IDirect3DDeviceImpl_7_GetTexture_FPUPreserve(IDirect3DDevice7
*iface
,
4527 IDirectDrawSurface7
**Texture
)
4532 old_fpucw
= d3d_fpu_setup();
4533 hr
= IDirect3DDeviceImpl_7_GetTexture(iface
, Stage
, Texture
);
4534 set_fpu_control_word(old_fpucw
);
4539 static HRESULT WINAPI
IDirect3DDeviceImpl_3_GetTexture(IDirect3DDevice3
*iface
, DWORD Stage
,
4540 IDirect3DTexture2
**Texture2
)
4542 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
4544 IDirectDrawSurface7
*ret_val
;
4545 IDirectDrawSurfaceImpl
*ret_val_impl
;
4547 TRACE("iface %p, stage %u, texture %p.\n", iface
, Stage
, Texture2
);
4549 ret
= IDirect3DDevice7_GetTexture(&This
->IDirect3DDevice7_iface
, Stage
, &ret_val
);
4551 ret_val_impl
= unsafe_impl_from_IDirectDrawSurface7(ret_val
);
4552 *Texture2
= ret_val_impl
? &ret_val_impl
->IDirect3DTexture2_iface
: NULL
;
4554 TRACE("Returning texture %p.\n", *Texture2
);
4559 /*****************************************************************************
4560 * IDirect3DDevice7::SetTexture
4562 * Assigns a texture to a texture stage. Is the texture AddRef-ed?
4567 * Stage: The stage to assign the texture to
4568 * Texture: Interface pointer to the texture surface
4572 * For details, see IWineD3DDevice::SetTexture
4574 *****************************************************************************/
4576 IDirect3DDeviceImpl_7_SetTexture(IDirect3DDevice7
*iface
,
4578 IDirectDrawSurface7
*Texture
)
4580 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
4581 IDirectDrawSurfaceImpl
*surf
= unsafe_impl_from_IDirectDrawSurface7(Texture
);
4584 TRACE("iface %p, stage %u, texture %p.\n", iface
, Stage
, Texture
);
4586 /* Texture may be NULL here */
4587 wined3d_mutex_lock();
4588 hr
= wined3d_device_set_texture(This
->wined3d_device
,
4589 Stage
, surf
? surf
->wined3d_texture
: NULL
);
4590 wined3d_mutex_unlock();
4595 static HRESULT WINAPI
4596 IDirect3DDeviceImpl_7_SetTexture_FPUSetup(IDirect3DDevice7
*iface
,
4598 IDirectDrawSurface7
*Texture
)
4600 return IDirect3DDeviceImpl_7_SetTexture(iface
, Stage
, Texture
);
4603 static HRESULT WINAPI
4604 IDirect3DDeviceImpl_7_SetTexture_FPUPreserve(IDirect3DDevice7
*iface
,
4606 IDirectDrawSurface7
*Texture
)
4611 old_fpucw
= d3d_fpu_setup();
4612 hr
= IDirect3DDeviceImpl_7_SetTexture(iface
, Stage
, Texture
);
4613 set_fpu_control_word(old_fpucw
);
4618 static HRESULT WINAPI
4619 IDirect3DDeviceImpl_3_SetTexture(IDirect3DDevice3
*iface
,
4621 IDirect3DTexture2
*Texture2
)
4623 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
4624 IDirectDrawSurfaceImpl
*tex
= unsafe_impl_from_IDirect3DTexture2(Texture2
);
4628 TRACE("iface %p, stage %u, texture %p.\n", iface
, Stage
, Texture2
);
4630 wined3d_mutex_lock();
4632 if (This
->legacyTextureBlending
)
4633 IDirect3DDevice3_GetRenderState(iface
, D3DRENDERSTATE_TEXTUREMAPBLEND
, &texmapblend
);
4635 hr
= IDirect3DDevice7_SetTexture(&This
->IDirect3DDevice7_iface
, Stage
, &tex
->IDirectDrawSurface7_iface
);
4637 if (This
->legacyTextureBlending
&& texmapblend
== D3DTBLEND_MODULATE
)
4639 /* This fixup is required by the way D3DTBLEND_MODULATE maps to texture stage states.
4640 See IDirect3DDeviceImpl_3_SetRenderState for details. */
4641 struct wined3d_texture
*tex
= NULL
;
4642 BOOL tex_alpha
= FALSE
;
4643 DDPIXELFORMAT ddfmt
;
4646 result
= wined3d_device_get_texture(This
->wined3d_device
, 0, &tex
);
4647 if (result
== WINED3D_OK
&& tex
)
4649 struct wined3d_resource
*sub_resource
;
4651 if ((sub_resource
= wined3d_texture_get_sub_resource(tex
, 0)))
4653 struct wined3d_resource_desc desc
;
4655 wined3d_resource_get_desc(sub_resource
, &desc
);
4656 ddfmt
.dwSize
= sizeof(ddfmt
);
4657 PixelFormat_WineD3DtoDD(&ddfmt
, desc
.format
);
4658 if (ddfmt
.u5
.dwRGBAlphaBitMask
) tex_alpha
= TRUE
;
4661 wined3d_texture_decref(tex
);
4664 /* Arg 1/2 are already set to WINED3DTA_TEXTURE/WINED3DTA_CURRENT in case of D3DTBLEND_MODULATE */
4666 wined3d_device_set_texture_stage_state(This
->wined3d_device
, 0, WINED3DTSS_ALPHAOP
, WINED3DTOP_SELECTARG1
);
4668 wined3d_device_set_texture_stage_state(This
->wined3d_device
, 0, WINED3DTSS_ALPHAOP
, WINED3DTOP_SELECTARG2
);
4671 wined3d_mutex_unlock();
4676 static const struct tss_lookup
4683 {FALSE
, WINED3DTSS_FORCE_DWORD
}, /* 0, unused */
4684 {FALSE
, WINED3DTSS_COLOROP
}, /* 1, D3DTSS_COLOROP */
4685 {FALSE
, WINED3DTSS_COLORARG1
}, /* 2, D3DTSS_COLORARG1 */
4686 {FALSE
, WINED3DTSS_COLORARG2
}, /* 3, D3DTSS_COLORARG2 */
4687 {FALSE
, WINED3DTSS_ALPHAOP
}, /* 4, D3DTSS_ALPHAOP */
4688 {FALSE
, WINED3DTSS_ALPHAARG1
}, /* 5, D3DTSS_ALPHAARG1 */
4689 {FALSE
, WINED3DTSS_ALPHAARG2
}, /* 6, D3DTSS_ALPHAARG2 */
4690 {FALSE
, WINED3DTSS_BUMPENVMAT00
}, /* 7, D3DTSS_BUMPENVMAT00 */
4691 {FALSE
, WINED3DTSS_BUMPENVMAT01
}, /* 8, D3DTSS_BUMPENVMAT01 */
4692 {FALSE
, WINED3DTSS_BUMPENVMAT10
}, /* 9, D3DTSS_BUMPENVMAT10 */
4693 {FALSE
, WINED3DTSS_BUMPENVMAT11
}, /* 10, D3DTSS_BUMPENVMAT11 */
4694 {FALSE
, WINED3DTSS_TEXCOORDINDEX
}, /* 11, D3DTSS_TEXCOORDINDEX */
4695 {TRUE
, WINED3DSAMP_ADDRESSU
}, /* 12, D3DTSS_ADDRESS */
4696 {TRUE
, WINED3DSAMP_ADDRESSU
}, /* 13, D3DTSS_ADDRESSU */
4697 {TRUE
, WINED3DSAMP_ADDRESSV
}, /* 14, D3DTSS_ADDRESSV */
4698 {TRUE
, WINED3DSAMP_BORDERCOLOR
}, /* 15, D3DTSS_BORDERCOLOR */
4699 {TRUE
, WINED3DSAMP_MAGFILTER
}, /* 16, D3DTSS_MAGFILTER */
4700 {TRUE
, WINED3DSAMP_MINFILTER
}, /* 17, D3DTSS_MINFILTER */
4701 {TRUE
, WINED3DSAMP_MIPFILTER
}, /* 18, D3DTSS_MIPFILTER */
4702 {TRUE
, WINED3DSAMP_MIPMAPLODBIAS
}, /* 19, D3DTSS_MIPMAPLODBIAS */
4703 {TRUE
, WINED3DSAMP_MAXMIPLEVEL
}, /* 20, D3DTSS_MAXMIPLEVEL */
4704 {TRUE
, WINED3DSAMP_MAXANISOTROPY
}, /* 21, D3DTSS_MAXANISOTROPY */
4705 {FALSE
, WINED3DTSS_BUMPENVLSCALE
}, /* 22, D3DTSS_BUMPENVLSCALE */
4706 {FALSE
, WINED3DTSS_BUMPENVLOFFSET
}, /* 23, D3DTSS_BUMPENVLOFFSET */
4707 {FALSE
, WINED3DTSS_TEXTURETRANSFORMFLAGS
}, /* 24, D3DTSS_TEXTURETRANSFORMFLAGS */
4710 /*****************************************************************************
4711 * IDirect3DDevice7::GetTextureStageState
4713 * Retrieves a state from a texture stage.
4718 * Stage: The stage to retrieve the state from
4719 * TexStageStateType: The state type to retrieve
4720 * State: Address to store the state's value at
4724 * DDERR_INVALIDPARAMS if State is NULL
4725 * For details, see IWineD3DDevice::GetTextureStageState
4727 *****************************************************************************/
4729 IDirect3DDeviceImpl_7_GetTextureStageState(IDirect3DDevice7
*iface
,
4731 D3DTEXTURESTAGESTATETYPE TexStageStateType
,
4734 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
4736 const struct tss_lookup
*l
;
4738 TRACE("iface %p, stage %u, state %#x, value %p.\n",
4739 iface
, Stage
, TexStageStateType
, State
);
4742 return DDERR_INVALIDPARAMS
;
4744 if (TexStageStateType
> D3DTSS_TEXTURETRANSFORMFLAGS
)
4746 WARN("Invalid TexStageStateType %#x passed.\n", TexStageStateType
);
4750 l
= &tss_lookup
[TexStageStateType
];
4752 wined3d_mutex_lock();
4754 if (l
->sampler_state
)
4756 hr
= wined3d_device_get_sampler_state(This
->wined3d_device
, Stage
, l
->state
, State
);
4758 switch(TexStageStateType
)
4760 /* Mipfilter is a sampler state with different values */
4761 case D3DTSS_MIPFILTER
:
4765 case WINED3DTEXF_NONE
: *State
= D3DTFP_NONE
; break;
4766 case WINED3DTEXF_POINT
: *State
= D3DTFP_POINT
; break;
4767 case WINED3DTEXF_LINEAR
: *State
= D3DTFP_LINEAR
; break;
4769 ERR("Unexpected mipfilter value %#x\n", *State
);
4770 *State
= D3DTFP_NONE
;
4776 /* Magfilter has slightly different values */
4777 case D3DTSS_MAGFILTER
:
4781 case WINED3DTEXF_POINT
: *State
= D3DTFG_POINT
; break;
4782 case WINED3DTEXF_LINEAR
: *State
= D3DTFG_LINEAR
; break;
4783 case WINED3DTEXF_ANISOTROPIC
: *State
= D3DTFG_ANISOTROPIC
; break;
4784 case WINED3DTEXF_FLATCUBIC
: *State
= D3DTFG_FLATCUBIC
; break;
4785 case WINED3DTEXF_GAUSSIANCUBIC
: *State
= D3DTFG_GAUSSIANCUBIC
; break;
4787 ERR("Unexpected wined3d mag filter value %#x\n", *State
);
4788 *State
= D3DTFG_POINT
;
4800 hr
= wined3d_device_get_texture_stage_state(This
->wined3d_device
, Stage
, l
->state
, State
);
4803 wined3d_mutex_unlock();
4808 static HRESULT WINAPI
4809 IDirect3DDeviceImpl_7_GetTextureStageState_FPUSetup(IDirect3DDevice7
*iface
,
4811 D3DTEXTURESTAGESTATETYPE TexStageStateType
,
4814 return IDirect3DDeviceImpl_7_GetTextureStageState(iface
, Stage
, TexStageStateType
, State
);
4817 static HRESULT WINAPI
4818 IDirect3DDeviceImpl_7_GetTextureStageState_FPUPreserve(IDirect3DDevice7
*iface
,
4820 D3DTEXTURESTAGESTATETYPE TexStageStateType
,
4826 old_fpucw
= d3d_fpu_setup();
4827 hr
= IDirect3DDeviceImpl_7_GetTextureStageState(iface
, Stage
, TexStageStateType
, State
);
4828 set_fpu_control_word(old_fpucw
);
4833 static HRESULT WINAPI
IDirect3DDeviceImpl_3_GetTextureStageState(IDirect3DDevice3
*iface
,
4834 DWORD Stage
, D3DTEXTURESTAGESTATETYPE TexStageStateType
, DWORD
*State
)
4836 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
4838 TRACE("iface %p, stage %u, state %#x, value %p.\n",
4839 iface
, Stage
, TexStageStateType
, State
);
4841 return IDirect3DDevice7_GetTextureStageState(&This
->IDirect3DDevice7_iface
,
4842 Stage
, TexStageStateType
, State
);
4845 /*****************************************************************************
4846 * IDirect3DDevice7::SetTextureStageState
4848 * Sets a texture stage state. Some stage types need to be handled specially,
4849 * because they do not exist in WineD3D and were moved to another place
4854 * Stage: The stage to modify
4855 * TexStageStateType: The state to change
4856 * State: The new value for the state
4860 * For details, see IWineD3DDevice::SetTextureStageState
4862 *****************************************************************************/
4864 IDirect3DDeviceImpl_7_SetTextureStageState(IDirect3DDevice7
*iface
,
4866 D3DTEXTURESTAGESTATETYPE TexStageStateType
,
4869 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
4870 const struct tss_lookup
*l
;
4873 TRACE("iface %p, stage %u, state %#x, value %#x.\n",
4874 iface
, Stage
, TexStageStateType
, State
);
4876 if (TexStageStateType
> D3DTSS_TEXTURETRANSFORMFLAGS
)
4878 WARN("Invalid TexStageStateType %#x passed.\n", TexStageStateType
);
4882 l
= &tss_lookup
[TexStageStateType
];
4884 wined3d_mutex_lock();
4886 if (l
->sampler_state
)
4888 switch(TexStageStateType
)
4890 /* Mipfilter is a sampler state with different values */
4891 case D3DTSS_MIPFILTER
:
4895 case D3DTFP_NONE
: State
= WINED3DTEXF_NONE
; break;
4896 case D3DTFP_POINT
: State
= WINED3DTEXF_POINT
; break;
4897 case 0: /* Unchecked */
4898 case D3DTFP_LINEAR
: State
= WINED3DTEXF_LINEAR
; break;
4900 ERR("Unexpected mipfilter value %d\n", State
);
4901 State
= WINED3DTEXF_NONE
;
4907 /* Magfilter has slightly different values */
4908 case D3DTSS_MAGFILTER
:
4912 case D3DTFG_POINT
: State
= WINED3DTEXF_POINT
; break;
4913 case D3DTFG_LINEAR
: State
= WINED3DTEXF_LINEAR
; break;
4914 case D3DTFG_FLATCUBIC
: State
= WINED3DTEXF_FLATCUBIC
; break;
4915 case D3DTFG_GAUSSIANCUBIC
: State
= WINED3DTEXF_GAUSSIANCUBIC
; break;
4916 case D3DTFG_ANISOTROPIC
: State
= WINED3DTEXF_ANISOTROPIC
; break;
4918 ERR("Unexpected d3d7 mag filter type %d\n", State
);
4919 State
= WINED3DTEXF_POINT
;
4925 case D3DTSS_ADDRESS
:
4926 wined3d_device_set_sampler_state(This
->wined3d_device
, Stage
, WINED3DSAMP_ADDRESSV
, State
);
4933 hr
= wined3d_device_set_sampler_state(This
->wined3d_device
, Stage
, l
->state
, State
);
4937 hr
= wined3d_device_set_texture_stage_state(This
->wined3d_device
, Stage
, l
->state
, State
);
4940 wined3d_mutex_unlock();
4945 static HRESULT WINAPI
4946 IDirect3DDeviceImpl_7_SetTextureStageState_FPUSetup(IDirect3DDevice7
*iface
,
4948 D3DTEXTURESTAGESTATETYPE TexStageStateType
,
4951 return IDirect3DDeviceImpl_7_SetTextureStageState(iface
, Stage
, TexStageStateType
, State
);
4954 static HRESULT WINAPI
4955 IDirect3DDeviceImpl_7_SetTextureStageState_FPUPreserve(IDirect3DDevice7
*iface
,
4957 D3DTEXTURESTAGESTATETYPE TexStageStateType
,
4963 old_fpucw
= d3d_fpu_setup();
4964 hr
= IDirect3DDeviceImpl_7_SetTextureStageState(iface
, Stage
, TexStageStateType
, State
);
4965 set_fpu_control_word(old_fpucw
);
4970 static HRESULT WINAPI
IDirect3DDeviceImpl_3_SetTextureStageState(IDirect3DDevice3
*iface
,
4971 DWORD Stage
, D3DTEXTURESTAGESTATETYPE TexStageStateType
, DWORD State
)
4973 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
4975 TRACE("iface %p, stage %u, state %#x, value %#x.\n",
4976 iface
, Stage
, TexStageStateType
, State
);
4978 return IDirect3DDevice7_SetTextureStageState(&This
->IDirect3DDevice7_iface
,
4979 Stage
, TexStageStateType
, State
);
4982 /*****************************************************************************
4983 * IDirect3DDevice7::ValidateDevice
4985 * SDK: "Reports the device's ability to render the currently set
4986 * texture-blending operations in a single pass". Whatever that means
4992 * NumPasses: Address to write the number of necessary passes for the
4993 * desired effect to.
4997 * See IWineD3DDevice::ValidateDevice for more details
4999 *****************************************************************************/
5001 IDirect3DDeviceImpl_7_ValidateDevice(IDirect3DDevice7
*iface
,
5004 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
5007 TRACE("iface %p, pass_count %p.\n", iface
, NumPasses
);
5009 wined3d_mutex_lock();
5010 hr
= wined3d_device_validate_device(This
->wined3d_device
, NumPasses
);
5011 wined3d_mutex_unlock();
5016 static HRESULT WINAPI
5017 IDirect3DDeviceImpl_7_ValidateDevice_FPUSetup(IDirect3DDevice7
*iface
,
5020 return IDirect3DDeviceImpl_7_ValidateDevice(iface
, NumPasses
);
5023 static HRESULT WINAPI
5024 IDirect3DDeviceImpl_7_ValidateDevice_FPUPreserve(IDirect3DDevice7
*iface
,
5030 old_fpucw
= d3d_fpu_setup();
5031 hr
= IDirect3DDeviceImpl_7_ValidateDevice(iface
, NumPasses
);
5032 set_fpu_control_word(old_fpucw
);
5037 static HRESULT WINAPI
IDirect3DDeviceImpl_3_ValidateDevice(IDirect3DDevice3
*iface
, DWORD
*Passes
)
5039 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
5041 TRACE("iface %p, pass_count %p.\n", iface
, Passes
);
5043 return IDirect3DDevice7_ValidateDevice(&This
->IDirect3DDevice7_iface
, Passes
);
5046 /*****************************************************************************
5047 * IDirect3DDevice7::Clear
5049 * Fills the render target, the z buffer and the stencil buffer with a
5050 * clear color / value
5055 * Count: Number of rectangles in Rects must be 0 if Rects is NULL
5056 * Rects: Rectangles to clear. If NULL, the whole surface is cleared
5057 * Flags: Some flags, as usual
5058 * Color: Clear color for the render target
5059 * Z: Clear value for the Z buffer
5060 * Stencil: Clear value to store in each stencil buffer entry
5064 * For details, see IWineD3DDevice::Clear
5066 *****************************************************************************/
5067 static HRESULT
IDirect3DDeviceImpl_7_Clear(IDirect3DDevice7
*iface
, DWORD count
,
5068 D3DRECT
*rects
, DWORD flags
, D3DCOLOR color
, D3DVALUE z
, DWORD stencil
)
5070 const struct wined3d_color c
=
5072 ((color
>> 16) & 0xff) / 255.0f
,
5073 ((color
>> 8) & 0xff) / 255.0f
,
5074 (color
& 0xff) / 255.0f
,
5075 ((color
>> 24) & 0xff) / 255.0f
,
5077 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
5080 TRACE("iface %p, count %u, rects %p, flags %#x, color 0x%08x, z %.8e, stencil %#x.\n",
5081 iface
, count
, rects
, flags
, color
, z
, stencil
);
5083 wined3d_mutex_lock();
5084 hr
= wined3d_device_clear(This
->wined3d_device
, count
, (RECT
*)rects
, flags
, &c
, z
, stencil
);
5085 wined3d_mutex_unlock();
5090 static HRESULT WINAPI
5091 IDirect3DDeviceImpl_7_Clear_FPUSetup(IDirect3DDevice7
*iface
,
5099 return IDirect3DDeviceImpl_7_Clear(iface
, Count
, Rects
, Flags
, Color
, Z
, Stencil
);
5102 static HRESULT WINAPI
5103 IDirect3DDeviceImpl_7_Clear_FPUPreserve(IDirect3DDevice7
*iface
,
5114 old_fpucw
= d3d_fpu_setup();
5115 hr
= IDirect3DDeviceImpl_7_Clear(iface
, Count
, Rects
, Flags
, Color
, Z
, Stencil
);
5116 set_fpu_control_word(old_fpucw
);
5121 /*****************************************************************************
5122 * IDirect3DDevice7::SetViewport
5124 * Sets the current viewport.
5126 * Version 7 only, but IDirect3DViewport uses this call for older
5130 * Data: The new viewport to set
5134 * DDERR_INVALIDPARAMS if Data is NULL
5135 * For more details, see IWineDDDevice::SetViewport
5137 *****************************************************************************/
5139 IDirect3DDeviceImpl_7_SetViewport(IDirect3DDevice7
*iface
,
5142 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
5145 TRACE("iface %p, viewport %p.\n", iface
, Data
);
5148 return DDERR_INVALIDPARAMS
;
5150 /* Note: D3DVIEWPORT7 is compatible with struct wined3d_viewport. */
5151 wined3d_mutex_lock();
5152 hr
= wined3d_device_set_viewport(This
->wined3d_device
, (struct wined3d_viewport
*)Data
);
5153 wined3d_mutex_unlock();
5158 static HRESULT WINAPI
5159 IDirect3DDeviceImpl_7_SetViewport_FPUSetup(IDirect3DDevice7
*iface
,
5162 return IDirect3DDeviceImpl_7_SetViewport(iface
, Data
);
5165 static HRESULT WINAPI
5166 IDirect3DDeviceImpl_7_SetViewport_FPUPreserve(IDirect3DDevice7
*iface
,
5172 old_fpucw
= d3d_fpu_setup();
5173 hr
= IDirect3DDeviceImpl_7_SetViewport(iface
, Data
);
5174 set_fpu_control_word(old_fpucw
);
5179 /*****************************************************************************
5180 * IDirect3DDevice::GetViewport
5182 * Returns the current viewport
5187 * Data: D3D7Viewport structure to write the viewport information to
5191 * DDERR_INVALIDPARAMS if Data is NULL
5192 * For more details, see IWineD3DDevice::GetViewport
5194 *****************************************************************************/
5196 IDirect3DDeviceImpl_7_GetViewport(IDirect3DDevice7
*iface
,
5199 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
5202 TRACE("iface %p, viewport %p.\n", iface
, Data
);
5205 return DDERR_INVALIDPARAMS
;
5207 /* Note: D3DVIEWPORT7 is compatible with struct wined3d_viewport. */
5208 wined3d_mutex_lock();
5209 hr
= wined3d_device_get_viewport(This
->wined3d_device
, (struct wined3d_viewport
*)Data
);
5210 wined3d_mutex_unlock();
5212 return hr_ddraw_from_wined3d(hr
);
5215 static HRESULT WINAPI
5216 IDirect3DDeviceImpl_7_GetViewport_FPUSetup(IDirect3DDevice7
*iface
,
5219 return IDirect3DDeviceImpl_7_GetViewport(iface
, Data
);
5222 static HRESULT WINAPI
5223 IDirect3DDeviceImpl_7_GetViewport_FPUPreserve(IDirect3DDevice7
*iface
,
5229 old_fpucw
= d3d_fpu_setup();
5230 hr
= IDirect3DDeviceImpl_7_GetViewport(iface
, Data
);
5231 set_fpu_control_word(old_fpucw
);
5236 /*****************************************************************************
5237 * IDirect3DDevice7::SetMaterial
5244 * Mat: The material to set
5248 * DDERR_INVALIDPARAMS if Mat is NULL.
5249 * For more details, see IWineD3DDevice::SetMaterial
5251 *****************************************************************************/
5253 IDirect3DDeviceImpl_7_SetMaterial(IDirect3DDevice7
*iface
,
5256 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
5259 TRACE("iface %p, material %p.\n", iface
, Mat
);
5261 if (!Mat
) return DDERR_INVALIDPARAMS
;
5263 wined3d_mutex_lock();
5264 /* Note: D3DMATERIAL7 is compatible with struct wined3d_material. */
5265 hr
= wined3d_device_set_material(This
->wined3d_device
, (struct wined3d_material
*)Mat
);
5266 wined3d_mutex_unlock();
5268 return hr_ddraw_from_wined3d(hr
);
5271 static HRESULT WINAPI
5272 IDirect3DDeviceImpl_7_SetMaterial_FPUSetup(IDirect3DDevice7
*iface
,
5275 return IDirect3DDeviceImpl_7_SetMaterial(iface
, Mat
);
5278 static HRESULT WINAPI
5279 IDirect3DDeviceImpl_7_SetMaterial_FPUPreserve(IDirect3DDevice7
*iface
,
5285 old_fpucw
= d3d_fpu_setup();
5286 hr
= IDirect3DDeviceImpl_7_SetMaterial(iface
, Mat
);
5287 set_fpu_control_word(old_fpucw
);
5292 /*****************************************************************************
5293 * IDirect3DDevice7::GetMaterial
5295 * Returns the current material
5300 * Mat: D3DMATERIAL7 structure to write the material parameters to
5304 * DDERR_INVALIDPARAMS if Mat is NULL
5305 * For more details, see IWineD3DDevice::GetMaterial
5307 *****************************************************************************/
5309 IDirect3DDeviceImpl_7_GetMaterial(IDirect3DDevice7
*iface
,
5312 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
5315 TRACE("iface %p, material %p.\n", iface
, Mat
);
5317 wined3d_mutex_lock();
5318 /* Note: D3DMATERIAL7 is compatible with struct wined3d_material. */
5319 hr
= wined3d_device_get_material(This
->wined3d_device
, (struct wined3d_material
*)Mat
);
5320 wined3d_mutex_unlock();
5322 return hr_ddraw_from_wined3d(hr
);
5325 static HRESULT WINAPI
5326 IDirect3DDeviceImpl_7_GetMaterial_FPUSetup(IDirect3DDevice7
*iface
,
5329 return IDirect3DDeviceImpl_7_GetMaterial(iface
, Mat
);
5332 static HRESULT WINAPI
5333 IDirect3DDeviceImpl_7_GetMaterial_FPUPreserve(IDirect3DDevice7
*iface
,
5339 old_fpucw
= d3d_fpu_setup();
5340 hr
= IDirect3DDeviceImpl_7_GetMaterial(iface
, Mat
);
5341 set_fpu_control_word(old_fpucw
);
5346 /*****************************************************************************
5347 * IDirect3DDevice7::SetLight
5349 * Assigns a light to a light index, but doesn't activate it yet.
5351 * Version 7, IDirect3DLight uses this method for older versions
5354 * LightIndex: The index of the new light
5355 * Light: A D3DLIGHT7 structure describing the light
5359 * For more details, see IWineD3DDevice::SetLight
5361 *****************************************************************************/
5363 IDirect3DDeviceImpl_7_SetLight(IDirect3DDevice7
*iface
,
5367 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
5370 TRACE("iface %p, light_idx %u, light %p.\n", iface
, LightIndex
, Light
);
5372 wined3d_mutex_lock();
5373 /* Note: D3DLIGHT7 is compatible with struct wined3d_light. */
5374 hr
= wined3d_device_set_light(This
->wined3d_device
, LightIndex
, (struct wined3d_light
*)Light
);
5375 wined3d_mutex_unlock();
5377 return hr_ddraw_from_wined3d(hr
);
5380 static HRESULT WINAPI
5381 IDirect3DDeviceImpl_7_SetLight_FPUSetup(IDirect3DDevice7
*iface
,
5385 return IDirect3DDeviceImpl_7_SetLight(iface
, LightIndex
, Light
);
5388 static HRESULT WINAPI
5389 IDirect3DDeviceImpl_7_SetLight_FPUPreserve(IDirect3DDevice7
*iface
,
5396 old_fpucw
= d3d_fpu_setup();
5397 hr
= IDirect3DDeviceImpl_7_SetLight(iface
, LightIndex
, Light
);
5398 set_fpu_control_word(old_fpucw
);
5403 /*****************************************************************************
5404 * IDirect3DDevice7::GetLight
5406 * Returns the light assigned to a light index
5409 * Light: Structure to write the light information to
5413 * DDERR_INVALIDPARAMS if Light is NULL
5414 * For details, see IWineD3DDevice::GetLight
5416 *****************************************************************************/
5418 IDirect3DDeviceImpl_7_GetLight(IDirect3DDevice7
*iface
,
5422 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
5425 TRACE("iface %p, light_idx %u, light %p.\n", iface
, LightIndex
, Light
);
5427 wined3d_mutex_lock();
5428 /* Note: D3DLIGHT7 is compatible with struct wined3d_light. */
5429 rc
= wined3d_device_get_light(This
->wined3d_device
, LightIndex
, (struct wined3d_light
*)Light
);
5430 wined3d_mutex_unlock();
5432 /* Translate the result. WineD3D returns other values than D3D7 */
5433 return hr_ddraw_from_wined3d(rc
);
5436 static HRESULT WINAPI
5437 IDirect3DDeviceImpl_7_GetLight_FPUSetup(IDirect3DDevice7
*iface
,
5441 return IDirect3DDeviceImpl_7_GetLight(iface
, LightIndex
, Light
);
5444 static HRESULT WINAPI
5445 IDirect3DDeviceImpl_7_GetLight_FPUPreserve(IDirect3DDevice7
*iface
,
5452 old_fpucw
= d3d_fpu_setup();
5453 hr
= IDirect3DDeviceImpl_7_GetLight(iface
, LightIndex
, Light
);
5454 set_fpu_control_word(old_fpucw
);
5459 /*****************************************************************************
5460 * IDirect3DDevice7::BeginStateBlock
5462 * Begins recording to a stateblock
5468 * For details see IWineD3DDevice::BeginStateBlock
5470 *****************************************************************************/
5472 IDirect3DDeviceImpl_7_BeginStateBlock(IDirect3DDevice7
*iface
)
5474 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
5477 TRACE("iface %p.\n", iface
);
5479 wined3d_mutex_lock();
5480 hr
= wined3d_device_begin_stateblock(This
->wined3d_device
);
5481 wined3d_mutex_unlock();
5483 return hr_ddraw_from_wined3d(hr
);
5486 static HRESULT WINAPI
5487 IDirect3DDeviceImpl_7_BeginStateBlock_FPUSetup(IDirect3DDevice7
*iface
)
5489 return IDirect3DDeviceImpl_7_BeginStateBlock(iface
);
5492 static HRESULT WINAPI
5493 IDirect3DDeviceImpl_7_BeginStateBlock_FPUPreserve(IDirect3DDevice7
*iface
)
5498 old_fpucw
= d3d_fpu_setup();
5499 hr
= IDirect3DDeviceImpl_7_BeginStateBlock(iface
);
5500 set_fpu_control_word(old_fpucw
);
5505 /*****************************************************************************
5506 * IDirect3DDevice7::EndStateBlock
5508 * Stops recording to a state block and returns the created stateblock
5514 * BlockHandle: Address to store the stateblock's handle to
5518 * DDERR_INVALIDPARAMS if BlockHandle is NULL
5519 * See IWineD3DDevice::EndStateBlock for more details
5521 *****************************************************************************/
5523 IDirect3DDeviceImpl_7_EndStateBlock(IDirect3DDevice7
*iface
,
5526 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
5527 struct wined3d_stateblock
*wined3d_sb
;
5531 TRACE("iface %p, stateblock %p.\n", iface
, BlockHandle
);
5535 WARN("BlockHandle == NULL, returning DDERR_INVALIDPARAMS\n");
5536 return DDERR_INVALIDPARAMS
;
5539 wined3d_mutex_lock();
5541 hr
= wined3d_device_end_stateblock(This
->wined3d_device
, &wined3d_sb
);
5544 WARN("Failed to end stateblock, hr %#x.\n", hr
);
5545 wined3d_mutex_unlock();
5547 return hr_ddraw_from_wined3d(hr
);
5550 h
= ddraw_allocate_handle(&This
->handle_table
, wined3d_sb
, DDRAW_HANDLE_STATEBLOCK
);
5551 if (h
== DDRAW_INVALID_HANDLE
)
5553 ERR("Failed to allocate a stateblock handle.\n");
5554 wined3d_stateblock_decref(wined3d_sb
);
5555 wined3d_mutex_unlock();
5557 return DDERR_OUTOFMEMORY
;
5560 wined3d_mutex_unlock();
5561 *BlockHandle
= h
+ 1;
5563 return hr_ddraw_from_wined3d(hr
);
5566 static HRESULT WINAPI
5567 IDirect3DDeviceImpl_7_EndStateBlock_FPUSetup(IDirect3DDevice7
*iface
,
5570 return IDirect3DDeviceImpl_7_EndStateBlock(iface
, BlockHandle
);
5573 static HRESULT WINAPI
5574 IDirect3DDeviceImpl_7_EndStateBlock_FPUPreserve(IDirect3DDevice7
*iface
,
5580 old_fpucw
= d3d_fpu_setup();
5581 hr
= IDirect3DDeviceImpl_7_EndStateBlock(iface
, BlockHandle
);
5582 set_fpu_control_word(old_fpucw
);
5587 /*****************************************************************************
5588 * IDirect3DDevice7::PreLoad
5590 * Allows the app to signal that a texture will be used soon, to allow
5591 * the Direct3DDevice to load it to the video card in the meantime.
5596 * Texture: The texture to preload
5600 * DDERR_INVALIDPARAMS if Texture is NULL
5601 * See IWineD3DSurface::PreLoad for details
5603 *****************************************************************************/
5605 IDirect3DDeviceImpl_7_PreLoad(IDirect3DDevice7
*iface
,
5606 IDirectDrawSurface7
*Texture
)
5608 IDirectDrawSurfaceImpl
*surf
= unsafe_impl_from_IDirectDrawSurface7(Texture
);
5610 TRACE("iface %p, texture %p.\n", iface
, Texture
);
5613 return DDERR_INVALIDPARAMS
;
5615 wined3d_mutex_lock();
5616 wined3d_surface_preload(surf
->wined3d_surface
);
5617 wined3d_mutex_unlock();
5622 static HRESULT WINAPI
5623 IDirect3DDeviceImpl_7_PreLoad_FPUSetup(IDirect3DDevice7
*iface
,
5624 IDirectDrawSurface7
*Texture
)
5626 return IDirect3DDeviceImpl_7_PreLoad(iface
, Texture
);
5629 static HRESULT WINAPI
5630 IDirect3DDeviceImpl_7_PreLoad_FPUPreserve(IDirect3DDevice7
*iface
,
5631 IDirectDrawSurface7
*Texture
)
5636 old_fpucw
= d3d_fpu_setup();
5637 hr
= IDirect3DDeviceImpl_7_PreLoad(iface
, Texture
);
5638 set_fpu_control_word(old_fpucw
);
5643 /*****************************************************************************
5644 * IDirect3DDevice7::ApplyStateBlock
5646 * Activates the state stored in a state block handle.
5649 * BlockHandle: The stateblock handle to activate
5653 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is NULL
5655 *****************************************************************************/
5657 IDirect3DDeviceImpl_7_ApplyStateBlock(IDirect3DDevice7
*iface
,
5660 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
5661 struct wined3d_stateblock
*wined3d_sb
;
5664 TRACE("iface %p, stateblock %#x.\n", iface
, BlockHandle
);
5666 wined3d_mutex_lock();
5667 wined3d_sb
= ddraw_get_object(&This
->handle_table
, BlockHandle
- 1, DDRAW_HANDLE_STATEBLOCK
);
5670 WARN("Invalid stateblock handle.\n");
5671 wined3d_mutex_unlock();
5672 return D3DERR_INVALIDSTATEBLOCK
;
5675 hr
= wined3d_stateblock_apply(wined3d_sb
);
5676 wined3d_mutex_unlock();
5678 return hr_ddraw_from_wined3d(hr
);
5681 static HRESULT WINAPI
5682 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUSetup(IDirect3DDevice7
*iface
,
5685 return IDirect3DDeviceImpl_7_ApplyStateBlock(iface
, BlockHandle
);
5688 static HRESULT WINAPI
5689 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUPreserve(IDirect3DDevice7
*iface
,
5695 old_fpucw
= d3d_fpu_setup();
5696 hr
= IDirect3DDeviceImpl_7_ApplyStateBlock(iface
, BlockHandle
);
5697 set_fpu_control_word(old_fpucw
);
5702 /*****************************************************************************
5703 * IDirect3DDevice7::CaptureStateBlock
5705 * Updates a stateblock's values to the values currently set for the device
5710 * BlockHandle: Stateblock to update
5714 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is NULL
5715 * See IWineD3DDevice::CaptureStateBlock for more details
5717 *****************************************************************************/
5719 IDirect3DDeviceImpl_7_CaptureStateBlock(IDirect3DDevice7
*iface
,
5722 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
5723 struct wined3d_stateblock
*wined3d_sb
;
5726 TRACE("iface %p, stateblock %#x.\n", iface
, BlockHandle
);
5728 wined3d_mutex_lock();
5729 wined3d_sb
= ddraw_get_object(&This
->handle_table
, BlockHandle
- 1, DDRAW_HANDLE_STATEBLOCK
);
5732 WARN("Invalid stateblock handle.\n");
5733 wined3d_mutex_unlock();
5734 return D3DERR_INVALIDSTATEBLOCK
;
5737 hr
= wined3d_stateblock_capture(wined3d_sb
);
5738 wined3d_mutex_unlock();
5740 return hr_ddraw_from_wined3d(hr
);
5743 static HRESULT WINAPI
5744 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUSetup(IDirect3DDevice7
*iface
,
5747 return IDirect3DDeviceImpl_7_CaptureStateBlock(iface
, BlockHandle
);
5750 static HRESULT WINAPI
5751 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUPreserve(IDirect3DDevice7
*iface
,
5757 old_fpucw
= d3d_fpu_setup();
5758 hr
= IDirect3DDeviceImpl_7_CaptureStateBlock(iface
, BlockHandle
);
5759 set_fpu_control_word(old_fpucw
);
5764 /*****************************************************************************
5765 * IDirect3DDevice7::DeleteStateBlock
5767 * Deletes a stateblock handle. This means releasing the WineD3DStateBlock
5772 * BlockHandle: Stateblock handle to delete
5776 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is 0
5778 *****************************************************************************/
5780 IDirect3DDeviceImpl_7_DeleteStateBlock(IDirect3DDevice7
*iface
,
5783 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
5784 struct wined3d_stateblock
*wined3d_sb
;
5787 TRACE("iface %p, stateblock %#x.\n", iface
, BlockHandle
);
5789 wined3d_mutex_lock();
5791 wined3d_sb
= ddraw_free_handle(&This
->handle_table
, BlockHandle
- 1, DDRAW_HANDLE_STATEBLOCK
);
5794 WARN("Invalid stateblock handle.\n");
5795 wined3d_mutex_unlock();
5796 return D3DERR_INVALIDSTATEBLOCK
;
5799 if ((ref
= wined3d_stateblock_decref(wined3d_sb
)))
5801 ERR("Something is still holding stateblock %p (refcount %u).\n", wined3d_sb
, ref
);
5804 wined3d_mutex_unlock();
5809 static HRESULT WINAPI
5810 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUSetup(IDirect3DDevice7
*iface
,
5813 return IDirect3DDeviceImpl_7_DeleteStateBlock(iface
, BlockHandle
);
5816 static HRESULT WINAPI
5817 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUPreserve(IDirect3DDevice7
*iface
,
5823 old_fpucw
= d3d_fpu_setup();
5824 hr
= IDirect3DDeviceImpl_7_DeleteStateBlock(iface
, BlockHandle
);
5825 set_fpu_control_word(old_fpucw
);
5830 /*****************************************************************************
5831 * IDirect3DDevice7::CreateStateBlock
5833 * Creates a new state block handle.
5838 * Type: The state block type
5839 * BlockHandle: Address to write the created handle to
5843 * DDERR_INVALIDPARAMS if BlockHandle is NULL
5845 *****************************************************************************/
5847 IDirect3DDeviceImpl_7_CreateStateBlock(IDirect3DDevice7
*iface
,
5848 D3DSTATEBLOCKTYPE Type
,
5851 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
5852 struct wined3d_stateblock
*wined3d_sb
;
5856 TRACE("iface %p, type %#x, stateblock %p.\n", iface
, Type
, BlockHandle
);
5860 WARN("BlockHandle == NULL, returning DDERR_INVALIDPARAMS\n");
5861 return DDERR_INVALIDPARAMS
;
5863 if(Type
!= D3DSBT_ALL
&& Type
!= D3DSBT_PIXELSTATE
&&
5864 Type
!= D3DSBT_VERTEXSTATE
) {
5865 WARN("Unexpected stateblock type, returning DDERR_INVALIDPARAMS\n");
5866 return DDERR_INVALIDPARAMS
;
5869 wined3d_mutex_lock();
5871 /* The D3DSTATEBLOCKTYPE enum is fine here. */
5872 hr
= wined3d_stateblock_create(This
->wined3d_device
, Type
, &wined3d_sb
);
5875 WARN("Failed to create stateblock, hr %#x.\n", hr
);
5876 wined3d_mutex_unlock();
5877 return hr_ddraw_from_wined3d(hr
);
5880 h
= ddraw_allocate_handle(&This
->handle_table
, wined3d_sb
, DDRAW_HANDLE_STATEBLOCK
);
5881 if (h
== DDRAW_INVALID_HANDLE
)
5883 ERR("Failed to allocate stateblock handle.\n");
5884 wined3d_stateblock_decref(wined3d_sb
);
5885 wined3d_mutex_unlock();
5886 return DDERR_OUTOFMEMORY
;
5889 *BlockHandle
= h
+ 1;
5890 wined3d_mutex_unlock();
5892 return hr_ddraw_from_wined3d(hr
);
5895 static HRESULT WINAPI
5896 IDirect3DDeviceImpl_7_CreateStateBlock_FPUSetup(IDirect3DDevice7
*iface
,
5897 D3DSTATEBLOCKTYPE Type
,
5900 return IDirect3DDeviceImpl_7_CreateStateBlock(iface
, Type
, BlockHandle
);
5903 static HRESULT WINAPI
5904 IDirect3DDeviceImpl_7_CreateStateBlock_FPUPreserve(IDirect3DDevice7
*iface
,
5905 D3DSTATEBLOCKTYPE Type
,
5911 old_fpucw
= d3d_fpu_setup();
5912 hr
=IDirect3DDeviceImpl_7_CreateStateBlock(iface
, Type
, BlockHandle
);
5913 set_fpu_control_word(old_fpucw
);
5918 /* Helper function for IDirect3DDeviceImpl_7_Load. */
5919 static BOOL
is_mip_level_subset(IDirectDrawSurfaceImpl
*dest
,
5920 IDirectDrawSurfaceImpl
*src
)
5922 IDirectDrawSurfaceImpl
*src_level
, *dest_level
;
5923 IDirectDrawSurface7
*temp
;
5924 DDSURFACEDESC2 ddsd
;
5925 BOOL levelFound
; /* at least one suitable sublevel in dest found */
5927 /* To satisfy "destination is mip level subset of source" criteria (regular texture counts as 1 level),
5928 * 1) there must be at least one mip level in destination that matched dimensions of some mip level in source and
5929 * 2) there must be no destination levels that don't match any levels in source. Otherwise it's INVALIDPARAMS.
5936 for (;src_level
&& dest_level
;)
5938 if (src_level
->surface_desc
.dwWidth
== dest_level
->surface_desc
.dwWidth
&&
5939 src_level
->surface_desc
.dwHeight
== dest_level
->surface_desc
.dwHeight
)
5943 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
5944 ddsd
.ddsCaps
.dwCaps2
= DDSCAPS2_MIPMAPSUBLEVEL
;
5945 IDirectDrawSurface7_GetAttachedSurface(&dest_level
->IDirectDrawSurface7_iface
, &ddsd
.ddsCaps
, &temp
);
5947 if (dest_level
!= dest
) IDirectDrawSurface7_Release(&dest_level
->IDirectDrawSurface7_iface
);
5949 dest_level
= unsafe_impl_from_IDirectDrawSurface7(temp
);
5952 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
5953 ddsd
.ddsCaps
.dwCaps2
= DDSCAPS2_MIPMAPSUBLEVEL
;
5954 IDirectDrawSurface7_GetAttachedSurface(&src_level
->IDirectDrawSurface7_iface
, &ddsd
.ddsCaps
, &temp
);
5956 if (src_level
!= src
) IDirectDrawSurface7_Release(&src_level
->IDirectDrawSurface7_iface
);
5958 src_level
= unsafe_impl_from_IDirectDrawSurface7(temp
);
5961 if (src_level
&& src_level
!= src
) IDirectDrawSurface7_Release(&src_level
->IDirectDrawSurface7_iface
);
5962 if (dest_level
&& dest_level
!= dest
) IDirectDrawSurface7_Release(&dest_level
->IDirectDrawSurface7_iface
);
5964 return !dest_level
&& levelFound
;
5967 /* Helper function for IDirect3DDeviceImpl_7_Load. */
5968 static void copy_mipmap_chain(IDirect3DDeviceImpl
*device
,
5969 IDirectDrawSurfaceImpl
*dest
,
5970 IDirectDrawSurfaceImpl
*src
,
5971 const POINT
*DestPoint
,
5972 const RECT
*SrcRect
)
5974 IDirectDrawSurfaceImpl
*src_level
, *dest_level
;
5975 IDirectDrawSurface7
*temp
;
5976 DDSURFACEDESC2 ddsd
;
5980 IDirectDrawPalette
*pal
= NULL
, *pal_src
= NULL
;
5984 /* Copy palette, if possible. */
5985 IDirectDrawSurface7_GetPalette(&src
->IDirectDrawSurface7_iface
, &pal_src
);
5986 IDirectDrawSurface7_GetPalette(&dest
->IDirectDrawSurface7_iface
, &pal
);
5988 if (pal_src
!= NULL
&& pal
!= NULL
)
5990 PALETTEENTRY palent
[256];
5992 IDirectDrawPalette_GetEntries(pal_src
, 0, 0, 256, palent
);
5993 IDirectDrawPalette_SetEntries(pal
, 0, 0, 256, palent
);
5996 if (pal
) IDirectDrawPalette_Release(pal
);
5997 if (pal_src
) IDirectDrawPalette_Release(pal_src
);
5999 /* Copy colorkeys, if present. */
6000 for (ckeyflag
= DDCKEY_DESTBLT
; ckeyflag
<= DDCKEY_SRCOVERLAY
; ckeyflag
<<= 1)
6002 hr
= IDirectDrawSurface7_GetColorKey(&src
->IDirectDrawSurface7_iface
, ckeyflag
, &ddckey
);
6006 IDirectDrawSurface7_SetColorKey(&dest
->IDirectDrawSurface7_iface
, ckeyflag
, &ddckey
);
6014 src_rect
= *SrcRect
;
6016 for (;src_level
&& dest_level
;)
6018 if (src_level
->surface_desc
.dwWidth
== dest_level
->surface_desc
.dwWidth
&&
6019 src_level
->surface_desc
.dwHeight
== dest_level
->surface_desc
.dwHeight
)
6021 UINT src_w
= src_rect
.right
- src_rect
.left
;
6022 UINT src_h
= src_rect
.bottom
- src_rect
.top
;
6023 RECT dst_rect
= {point
.x
, point
.y
, point
.x
+ src_w
, point
.y
+ src_h
};
6025 if (FAILED(hr
= wined3d_surface_blt(dest_level
->wined3d_surface
, &dst_rect
,
6026 src_level
->wined3d_surface
, &src_rect
, 0, NULL
, WINED3DTEXF_POINT
)))
6027 ERR("Blit failed, hr %#x.\n", hr
);
6029 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
6030 ddsd
.ddsCaps
.dwCaps2
= DDSCAPS2_MIPMAPSUBLEVEL
;
6031 IDirectDrawSurface7_GetAttachedSurface(&dest_level
->IDirectDrawSurface7_iface
, &ddsd
.ddsCaps
, &temp
);
6033 if (dest_level
!= dest
) IDirectDrawSurface7_Release(&dest_level
->IDirectDrawSurface7_iface
);
6035 dest_level
= unsafe_impl_from_IDirectDrawSurface7(temp
);
6038 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
6039 ddsd
.ddsCaps
.dwCaps2
= DDSCAPS2_MIPMAPSUBLEVEL
;
6040 IDirectDrawSurface7_GetAttachedSurface(&src_level
->IDirectDrawSurface7_iface
, &ddsd
.ddsCaps
, &temp
);
6042 if (src_level
!= src
) IDirectDrawSurface7_Release(&src_level
->IDirectDrawSurface7_iface
);
6044 src_level
= unsafe_impl_from_IDirectDrawSurface7(temp
);
6051 src_rect
.right
= (src_rect
.right
+ 1) / 2;
6052 src_rect
.bottom
= (src_rect
.bottom
+ 1) / 2;
6055 if (src_level
&& src_level
!= src
) IDirectDrawSurface7_Release(&src_level
->IDirectDrawSurface7_iface
);
6056 if (dest_level
&& dest_level
!= dest
) IDirectDrawSurface7_Release(&dest_level
->IDirectDrawSurface7_iface
);
6059 /*****************************************************************************
6060 * IDirect3DDevice7::Load
6062 * Loads a rectangular area from the source into the destination texture.
6063 * It can also copy the source to the faces of a cubic environment map
6068 * DestTex: Destination texture
6069 * DestPoint: Point in the destination where the source image should be
6071 * SrcTex: Source texture
6072 * SrcRect: Source rectangle
6073 * Flags: Cubemap faces to load (DDSCAPS2_CUBEMAP_ALLFACES, DDSCAPS2_CUBEMAP_POSITIVEX,
6074 * DDSCAPS2_CUBEMAP_NEGATIVEX, DDSCAPS2_CUBEMAP_POSITIVEY, DDSCAPS2_CUBEMAP_NEGATIVEY,
6075 * DDSCAPS2_CUBEMAP_POSITIVEZ, DDSCAPS2_CUBEMAP_NEGATIVEZ)
6079 * DDERR_INVALIDPARAMS if DestTex or SrcTex are NULL, broken coordinates or anything unexpected.
6082 *****************************************************************************/
6085 IDirect3DDeviceImpl_7_Load(IDirect3DDevice7
*iface
,
6086 IDirectDrawSurface7
*DestTex
,
6088 IDirectDrawSurface7
*SrcTex
,
6092 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
6093 IDirectDrawSurfaceImpl
*dest
= unsafe_impl_from_IDirectDrawSurface7(DestTex
);
6094 IDirectDrawSurfaceImpl
*src
= unsafe_impl_from_IDirectDrawSurface7(SrcTex
);
6098 TRACE("iface %p, dst_texture %p, dst_pos %s, src_texture %p, src_rect %s, flags %#x.\n",
6099 iface
, DestTex
, wine_dbgstr_point(DestPoint
), SrcTex
, wine_dbgstr_rect(SrcRect
), Flags
);
6101 if( (!src
) || (!dest
) )
6102 return DDERR_INVALIDPARAMS
;
6104 wined3d_mutex_lock();
6106 if (SrcRect
) srcrect
= *SrcRect
;
6109 srcrect
.left
= srcrect
.top
= 0;
6110 srcrect
.right
= src
->surface_desc
.dwWidth
;
6111 srcrect
.bottom
= src
->surface_desc
.dwHeight
;
6114 if (DestPoint
) destpoint
= *DestPoint
;
6117 destpoint
.x
= destpoint
.y
= 0;
6119 /* Check bad dimensions. DestPoint is validated against src, not dest, because
6120 * destination can be a subset of mip levels, in which case actual coordinates used
6121 * for it may be divided. If any dimension of dest is larger than source, it can't be
6122 * mip level subset, so an error can be returned early.
6124 if (srcrect
.left
>= srcrect
.right
|| srcrect
.top
>= srcrect
.bottom
||
6125 srcrect
.right
> src
->surface_desc
.dwWidth
||
6126 srcrect
.bottom
> src
->surface_desc
.dwHeight
||
6127 destpoint
.x
+ srcrect
.right
- srcrect
.left
> src
->surface_desc
.dwWidth
||
6128 destpoint
.y
+ srcrect
.bottom
- srcrect
.top
> src
->surface_desc
.dwHeight
||
6129 dest
->surface_desc
.dwWidth
> src
->surface_desc
.dwWidth
||
6130 dest
->surface_desc
.dwHeight
> src
->surface_desc
.dwHeight
)
6132 wined3d_mutex_unlock();
6133 return DDERR_INVALIDPARAMS
;
6136 /* Must be top level surfaces. */
6137 if (src
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_MIPMAPSUBLEVEL
||
6138 dest
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_MIPMAPSUBLEVEL
)
6140 wined3d_mutex_unlock();
6141 return DDERR_INVALIDPARAMS
;
6144 if (src
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_CUBEMAP
)
6146 DWORD src_face_flag
, dest_face_flag
;
6147 IDirectDrawSurfaceImpl
*src_face
, *dest_face
;
6148 IDirectDrawSurface7
*temp
;
6149 DDSURFACEDESC2 ddsd
;
6152 if (!(dest
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_CUBEMAP
))
6154 wined3d_mutex_unlock();
6155 return DDERR_INVALIDPARAMS
;
6158 /* Iterate through cube faces 2 times. First time is just to check INVALIDPARAMS conditions, second
6159 * time it's actual surface loading. */
6160 for (i
= 0; i
< 2; i
++)
6165 for (;dest_face
&& src_face
;)
6167 src_face_flag
= src_face
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_CUBEMAP_ALLFACES
;
6168 dest_face_flag
= dest_face
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_CUBEMAP_ALLFACES
;
6170 if (src_face_flag
== dest_face_flag
)
6174 /* Destination mip levels must be subset of source mip levels. */
6175 if (!is_mip_level_subset(dest_face
, src_face
))
6177 wined3d_mutex_unlock();
6178 return DDERR_INVALIDPARAMS
;
6181 else if (Flags
& dest_face_flag
)
6183 copy_mipmap_chain(This
, dest_face
, src_face
, &destpoint
, &srcrect
);
6186 if (src_face_flag
< DDSCAPS2_CUBEMAP_NEGATIVEZ
)
6188 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
6189 ddsd
.ddsCaps
.dwCaps2
= DDSCAPS2_CUBEMAP
| (src_face_flag
<< 1);
6190 IDirectDrawSurface7_GetAttachedSurface(&src
->IDirectDrawSurface7_iface
, &ddsd
.ddsCaps
, &temp
);
6192 if (src_face
!= src
) IDirectDrawSurface7_Release(&src_face
->IDirectDrawSurface7_iface
);
6194 src_face
= unsafe_impl_from_IDirectDrawSurface7(temp
);
6198 if (src_face
!= src
) IDirectDrawSurface7_Release(&src_face
->IDirectDrawSurface7_iface
);
6204 if (dest_face_flag
< DDSCAPS2_CUBEMAP_NEGATIVEZ
)
6206 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
6207 ddsd
.ddsCaps
.dwCaps2
= DDSCAPS2_CUBEMAP
| (dest_face_flag
<< 1);
6208 IDirectDrawSurface7_GetAttachedSurface(&dest
->IDirectDrawSurface7_iface
, &ddsd
.ddsCaps
, &temp
);
6210 if (dest_face
!= dest
) IDirectDrawSurface7_Release(&dest_face
->IDirectDrawSurface7_iface
);
6212 dest_face
= unsafe_impl_from_IDirectDrawSurface7(temp
);
6216 if (dest_face
!= dest
) IDirectDrawSurface7_Release(&dest_face
->IDirectDrawSurface7_iface
);
6224 /* Native returns error if src faces are not subset of dest faces. */
6227 wined3d_mutex_unlock();
6228 return DDERR_INVALIDPARAMS
;
6233 wined3d_mutex_unlock();
6236 else if (dest
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_CUBEMAP
)
6238 wined3d_mutex_unlock();
6239 return DDERR_INVALIDPARAMS
;
6242 /* Handle non cube map textures. */
6244 /* Destination mip levels must be subset of source mip levels. */
6245 if (!is_mip_level_subset(dest
, src
))
6247 wined3d_mutex_unlock();
6248 return DDERR_INVALIDPARAMS
;
6251 copy_mipmap_chain(This
, dest
, src
, &destpoint
, &srcrect
);
6253 wined3d_mutex_unlock();
6258 static HRESULT WINAPI
6259 IDirect3DDeviceImpl_7_Load_FPUSetup(IDirect3DDevice7
*iface
,
6260 IDirectDrawSurface7
*DestTex
,
6262 IDirectDrawSurface7
*SrcTex
,
6266 return IDirect3DDeviceImpl_7_Load(iface
, DestTex
, DestPoint
, SrcTex
, SrcRect
, Flags
);
6269 static HRESULT WINAPI
6270 IDirect3DDeviceImpl_7_Load_FPUPreserve(IDirect3DDevice7
*iface
,
6271 IDirectDrawSurface7
*DestTex
,
6273 IDirectDrawSurface7
*SrcTex
,
6280 old_fpucw
= d3d_fpu_setup();
6281 hr
= IDirect3DDeviceImpl_7_Load(iface
, DestTex
, DestPoint
, SrcTex
, SrcRect
, Flags
);
6282 set_fpu_control_word(old_fpucw
);
6287 /*****************************************************************************
6288 * IDirect3DDevice7::LightEnable
6290 * Enables or disables a light
6292 * Version 7, IDirect3DLight uses this method too.
6295 * LightIndex: The index of the light to enable / disable
6296 * Enable: Enable or disable the light
6300 * For more details, see IWineD3DDevice::SetLightEnable
6302 *****************************************************************************/
6304 IDirect3DDeviceImpl_7_LightEnable(IDirect3DDevice7
*iface
,
6308 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
6311 TRACE("iface %p, light_idx %u, enabled %#x.\n", iface
, LightIndex
, Enable
);
6313 wined3d_mutex_lock();
6314 hr
= wined3d_device_set_light_enable(This
->wined3d_device
, LightIndex
, Enable
);
6315 wined3d_mutex_unlock();
6317 return hr_ddraw_from_wined3d(hr
);
6320 static HRESULT WINAPI
6321 IDirect3DDeviceImpl_7_LightEnable_FPUSetup(IDirect3DDevice7
*iface
,
6325 return IDirect3DDeviceImpl_7_LightEnable(iface
, LightIndex
, Enable
);
6328 static HRESULT WINAPI
6329 IDirect3DDeviceImpl_7_LightEnable_FPUPreserve(IDirect3DDevice7
*iface
,
6336 old_fpucw
= d3d_fpu_setup();
6337 hr
= IDirect3DDeviceImpl_7_LightEnable(iface
, LightIndex
, Enable
);
6338 set_fpu_control_word(old_fpucw
);
6343 /*****************************************************************************
6344 * IDirect3DDevice7::GetLightEnable
6346 * Retrieves if the light with the given index is enabled or not
6351 * LightIndex: Index of desired light
6352 * Enable: Pointer to a BOOL which contains the result
6356 * DDERR_INVALIDPARAMS if Enable is NULL
6357 * See IWineD3DDevice::GetLightEnable for more details
6359 *****************************************************************************/
6361 IDirect3DDeviceImpl_7_GetLightEnable(IDirect3DDevice7
*iface
,
6365 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
6368 TRACE("iface %p, light_idx %u, enabled %p.\n", iface
, LightIndex
, Enable
);
6371 return DDERR_INVALIDPARAMS
;
6373 wined3d_mutex_lock();
6374 hr
= wined3d_device_get_light_enable(This
->wined3d_device
, LightIndex
, Enable
);
6375 wined3d_mutex_unlock();
6377 return hr_ddraw_from_wined3d(hr
);
6380 static HRESULT WINAPI
6381 IDirect3DDeviceImpl_7_GetLightEnable_FPUSetup(IDirect3DDevice7
*iface
,
6385 return IDirect3DDeviceImpl_7_GetLightEnable(iface
, LightIndex
, Enable
);
6388 static HRESULT WINAPI
6389 IDirect3DDeviceImpl_7_GetLightEnable_FPUPreserve(IDirect3DDevice7
*iface
,
6396 old_fpucw
= d3d_fpu_setup();
6397 hr
= IDirect3DDeviceImpl_7_GetLightEnable(iface
, LightIndex
, Enable
);
6398 set_fpu_control_word(old_fpucw
);
6403 /*****************************************************************************
6404 * IDirect3DDevice7::SetClipPlane
6406 * Sets custom clipping plane
6411 * Index: The index of the clipping plane
6412 * PlaneEquation: An equation defining the clipping plane
6416 * DDERR_INVALIDPARAMS if PlaneEquation is NULL
6417 * See IWineD3DDevice::SetClipPlane for more details
6419 *****************************************************************************/
6421 IDirect3DDeviceImpl_7_SetClipPlane(IDirect3DDevice7
*iface
,
6423 D3DVALUE
* PlaneEquation
)
6425 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
6428 TRACE("iface %p, idx %u, plane %p.\n", iface
, Index
, PlaneEquation
);
6431 return DDERR_INVALIDPARAMS
;
6433 wined3d_mutex_lock();
6434 hr
= wined3d_device_set_clip_plane(This
->wined3d_device
, Index
, PlaneEquation
);
6435 wined3d_mutex_unlock();
6440 static HRESULT WINAPI
6441 IDirect3DDeviceImpl_7_SetClipPlane_FPUSetup(IDirect3DDevice7
*iface
,
6443 D3DVALUE
* PlaneEquation
)
6445 return IDirect3DDeviceImpl_7_SetClipPlane(iface
, Index
, PlaneEquation
);
6448 static HRESULT WINAPI
6449 IDirect3DDeviceImpl_7_SetClipPlane_FPUPreserve(IDirect3DDevice7
*iface
,
6451 D3DVALUE
* PlaneEquation
)
6456 old_fpucw
= d3d_fpu_setup();
6457 hr
= IDirect3DDeviceImpl_7_SetClipPlane(iface
, Index
, PlaneEquation
);
6458 set_fpu_control_word(old_fpucw
);
6463 /*****************************************************************************
6464 * IDirect3DDevice7::GetClipPlane
6466 * Returns the clipping plane with a specific index
6469 * Index: The index of the desired plane
6470 * PlaneEquation: Address to store the plane equation to
6474 * DDERR_INVALIDPARAMS if PlaneEquation is NULL
6475 * See IWineD3DDevice::GetClipPlane for more details
6477 *****************************************************************************/
6479 IDirect3DDeviceImpl_7_GetClipPlane(IDirect3DDevice7
*iface
,
6481 D3DVALUE
* PlaneEquation
)
6483 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
6486 TRACE("iface %p, idx %u, plane %p.\n", iface
, Index
, PlaneEquation
);
6489 return DDERR_INVALIDPARAMS
;
6491 wined3d_mutex_lock();
6492 hr
= wined3d_device_get_clip_plane(This
->wined3d_device
, Index
, PlaneEquation
);
6493 wined3d_mutex_unlock();
6498 static HRESULT WINAPI
6499 IDirect3DDeviceImpl_7_GetClipPlane_FPUSetup(IDirect3DDevice7
*iface
,
6501 D3DVALUE
* PlaneEquation
)
6503 return IDirect3DDeviceImpl_7_GetClipPlane(iface
, Index
, PlaneEquation
);
6506 static HRESULT WINAPI
6507 IDirect3DDeviceImpl_7_GetClipPlane_FPUPreserve(IDirect3DDevice7
*iface
,
6509 D3DVALUE
* PlaneEquation
)
6514 old_fpucw
= d3d_fpu_setup();
6515 hr
= IDirect3DDeviceImpl_7_GetClipPlane(iface
, Index
, PlaneEquation
);
6516 set_fpu_control_word(old_fpucw
);
6521 /*****************************************************************************
6522 * IDirect3DDevice7::GetInfo
6524 * Retrieves some information about the device. The DirectX sdk says that
6525 * this version returns S_FALSE for all retail builds of DirectX, that's what
6526 * this implementation does.
6529 * DevInfoID: Information type requested
6530 * DevInfoStruct: Pointer to a structure to store the info to
6531 * Size: Size of the structure
6534 * S_FALSE, because it's a non-debug driver
6536 *****************************************************************************/
6537 static HRESULT WINAPI
6538 IDirect3DDeviceImpl_7_GetInfo(IDirect3DDevice7
*iface
,
6540 void *DevInfoStruct
,
6543 TRACE("iface %p, info_id %#x, info %p, info_size %u.\n",
6544 iface
, DevInfoID
, DevInfoStruct
, Size
);
6546 if (TRACE_ON(ddraw
))
6548 TRACE(" info requested : ");
6551 case D3DDEVINFOID_TEXTUREMANAGER
: TRACE("D3DDEVINFOID_TEXTUREMANAGER\n"); break;
6552 case D3DDEVINFOID_D3DTEXTUREMANAGER
: TRACE("D3DDEVINFOID_D3DTEXTUREMANAGER\n"); break;
6553 case D3DDEVINFOID_TEXTURING
: TRACE("D3DDEVINFOID_TEXTURING\n"); break;
6554 default: ERR(" invalid flag !!!\n"); return DDERR_INVALIDPARAMS
;
6558 return S_FALSE
; /* According to MSDN, this is valid for a non-debug driver */
6561 /* For performance optimization, devices created in FPUSETUP and FPUPRESERVE modes
6562 * have separate vtables. Simple functions where this doesn't matter like GetDirect3D
6563 * are not duplicated.
6565 * Device created with DDSCL_FPUSETUP (d3d7 default) - device methods assume that FPU
6566 * has already been setup for optimal d3d operation.
6568 * Device created with DDSCL_FPUPRESERVE - resets and restores FPU mode when necessary in
6569 * d3d calls (FPU may be in a mode non-suitable for d3d when the app calls d3d). Required
6570 * by Sacrifice (game). */
6571 static const struct IDirect3DDevice7Vtbl d3d_device7_fpu_setup_vtbl
=
6573 /*** IUnknown Methods ***/
6574 IDirect3DDeviceImpl_7_QueryInterface
,
6575 IDirect3DDeviceImpl_7_AddRef
,
6576 IDirect3DDeviceImpl_7_Release
,
6577 /*** IDirect3DDevice7 ***/
6578 IDirect3DDeviceImpl_7_GetCaps_FPUSetup
,
6579 IDirect3DDeviceImpl_7_EnumTextureFormats_FPUSetup
,
6580 IDirect3DDeviceImpl_7_BeginScene_FPUSetup
,
6581 IDirect3DDeviceImpl_7_EndScene_FPUSetup
,
6582 IDirect3DDeviceImpl_7_GetDirect3D
,
6583 IDirect3DDeviceImpl_7_SetRenderTarget_FPUSetup
,
6584 IDirect3DDeviceImpl_7_GetRenderTarget
,
6585 IDirect3DDeviceImpl_7_Clear_FPUSetup
,
6586 IDirect3DDeviceImpl_7_SetTransform_FPUSetup
,
6587 IDirect3DDeviceImpl_7_GetTransform_FPUSetup
,
6588 IDirect3DDeviceImpl_7_SetViewport_FPUSetup
,
6589 IDirect3DDeviceImpl_7_MultiplyTransform_FPUSetup
,
6590 IDirect3DDeviceImpl_7_GetViewport_FPUSetup
,
6591 IDirect3DDeviceImpl_7_SetMaterial_FPUSetup
,
6592 IDirect3DDeviceImpl_7_GetMaterial_FPUSetup
,
6593 IDirect3DDeviceImpl_7_SetLight_FPUSetup
,
6594 IDirect3DDeviceImpl_7_GetLight_FPUSetup
,
6595 IDirect3DDeviceImpl_7_SetRenderState_FPUSetup
,
6596 IDirect3DDeviceImpl_7_GetRenderState_FPUSetup
,
6597 IDirect3DDeviceImpl_7_BeginStateBlock_FPUSetup
,
6598 IDirect3DDeviceImpl_7_EndStateBlock_FPUSetup
,
6599 IDirect3DDeviceImpl_7_PreLoad_FPUSetup
,
6600 IDirect3DDeviceImpl_7_DrawPrimitive_FPUSetup
,
6601 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUSetup
,
6602 IDirect3DDeviceImpl_7_SetClipStatus
,
6603 IDirect3DDeviceImpl_7_GetClipStatus
,
6604 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUSetup
,
6605 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUSetup
,
6606 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUSetup
,
6607 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUSetup
,
6608 IDirect3DDeviceImpl_7_ComputeSphereVisibility
,
6609 IDirect3DDeviceImpl_7_GetTexture_FPUSetup
,
6610 IDirect3DDeviceImpl_7_SetTexture_FPUSetup
,
6611 IDirect3DDeviceImpl_7_GetTextureStageState_FPUSetup
,
6612 IDirect3DDeviceImpl_7_SetTextureStageState_FPUSetup
,
6613 IDirect3DDeviceImpl_7_ValidateDevice_FPUSetup
,
6614 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUSetup
,
6615 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUSetup
,
6616 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUSetup
,
6617 IDirect3DDeviceImpl_7_CreateStateBlock_FPUSetup
,
6618 IDirect3DDeviceImpl_7_Load_FPUSetup
,
6619 IDirect3DDeviceImpl_7_LightEnable_FPUSetup
,
6620 IDirect3DDeviceImpl_7_GetLightEnable_FPUSetup
,
6621 IDirect3DDeviceImpl_7_SetClipPlane_FPUSetup
,
6622 IDirect3DDeviceImpl_7_GetClipPlane_FPUSetup
,
6623 IDirect3DDeviceImpl_7_GetInfo
6626 static const struct IDirect3DDevice7Vtbl d3d_device7_fpu_preserve_vtbl
=
6628 /*** IUnknown Methods ***/
6629 IDirect3DDeviceImpl_7_QueryInterface
,
6630 IDirect3DDeviceImpl_7_AddRef
,
6631 IDirect3DDeviceImpl_7_Release
,
6632 /*** IDirect3DDevice7 ***/
6633 IDirect3DDeviceImpl_7_GetCaps_FPUPreserve
,
6634 IDirect3DDeviceImpl_7_EnumTextureFormats_FPUPreserve
,
6635 IDirect3DDeviceImpl_7_BeginScene_FPUPreserve
,
6636 IDirect3DDeviceImpl_7_EndScene_FPUPreserve
,
6637 IDirect3DDeviceImpl_7_GetDirect3D
,
6638 IDirect3DDeviceImpl_7_SetRenderTarget_FPUPreserve
,
6639 IDirect3DDeviceImpl_7_GetRenderTarget
,
6640 IDirect3DDeviceImpl_7_Clear_FPUPreserve
,
6641 IDirect3DDeviceImpl_7_SetTransform_FPUPreserve
,
6642 IDirect3DDeviceImpl_7_GetTransform_FPUPreserve
,
6643 IDirect3DDeviceImpl_7_SetViewport_FPUPreserve
,
6644 IDirect3DDeviceImpl_7_MultiplyTransform_FPUPreserve
,
6645 IDirect3DDeviceImpl_7_GetViewport_FPUPreserve
,
6646 IDirect3DDeviceImpl_7_SetMaterial_FPUPreserve
,
6647 IDirect3DDeviceImpl_7_GetMaterial_FPUPreserve
,
6648 IDirect3DDeviceImpl_7_SetLight_FPUPreserve
,
6649 IDirect3DDeviceImpl_7_GetLight_FPUPreserve
,
6650 IDirect3DDeviceImpl_7_SetRenderState_FPUPreserve
,
6651 IDirect3DDeviceImpl_7_GetRenderState_FPUPreserve
,
6652 IDirect3DDeviceImpl_7_BeginStateBlock_FPUPreserve
,
6653 IDirect3DDeviceImpl_7_EndStateBlock_FPUPreserve
,
6654 IDirect3DDeviceImpl_7_PreLoad_FPUPreserve
,
6655 IDirect3DDeviceImpl_7_DrawPrimitive_FPUPreserve
,
6656 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUPreserve
,
6657 IDirect3DDeviceImpl_7_SetClipStatus
,
6658 IDirect3DDeviceImpl_7_GetClipStatus
,
6659 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUPreserve
,
6660 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUPreserve
,
6661 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUPreserve
,
6662 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUPreserve
,
6663 IDirect3DDeviceImpl_7_ComputeSphereVisibility
,
6664 IDirect3DDeviceImpl_7_GetTexture_FPUPreserve
,
6665 IDirect3DDeviceImpl_7_SetTexture_FPUPreserve
,
6666 IDirect3DDeviceImpl_7_GetTextureStageState_FPUPreserve
,
6667 IDirect3DDeviceImpl_7_SetTextureStageState_FPUPreserve
,
6668 IDirect3DDeviceImpl_7_ValidateDevice_FPUPreserve
,
6669 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUPreserve
,
6670 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUPreserve
,
6671 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUPreserve
,
6672 IDirect3DDeviceImpl_7_CreateStateBlock_FPUPreserve
,
6673 IDirect3DDeviceImpl_7_Load_FPUPreserve
,
6674 IDirect3DDeviceImpl_7_LightEnable_FPUPreserve
,
6675 IDirect3DDeviceImpl_7_GetLightEnable_FPUPreserve
,
6676 IDirect3DDeviceImpl_7_SetClipPlane_FPUPreserve
,
6677 IDirect3DDeviceImpl_7_GetClipPlane_FPUPreserve
,
6678 IDirect3DDeviceImpl_7_GetInfo
6681 static const struct IDirect3DDevice3Vtbl d3d_device3_vtbl
=
6683 /*** IUnknown Methods ***/
6684 IDirect3DDeviceImpl_3_QueryInterface
,
6685 IDirect3DDeviceImpl_3_AddRef
,
6686 IDirect3DDeviceImpl_3_Release
,
6687 /*** IDirect3DDevice3 ***/
6688 IDirect3DDeviceImpl_3_GetCaps
,
6689 IDirect3DDeviceImpl_3_GetStats
,
6690 IDirect3DDeviceImpl_3_AddViewport
,
6691 IDirect3DDeviceImpl_3_DeleteViewport
,
6692 IDirect3DDeviceImpl_3_NextViewport
,
6693 IDirect3DDeviceImpl_3_EnumTextureFormats
,
6694 IDirect3DDeviceImpl_3_BeginScene
,
6695 IDirect3DDeviceImpl_3_EndScene
,
6696 IDirect3DDeviceImpl_3_GetDirect3D
,
6697 IDirect3DDeviceImpl_3_SetCurrentViewport
,
6698 IDirect3DDeviceImpl_3_GetCurrentViewport
,
6699 IDirect3DDeviceImpl_3_SetRenderTarget
,
6700 IDirect3DDeviceImpl_3_GetRenderTarget
,
6701 IDirect3DDeviceImpl_3_Begin
,
6702 IDirect3DDeviceImpl_3_BeginIndexed
,
6703 IDirect3DDeviceImpl_3_Vertex
,
6704 IDirect3DDeviceImpl_3_Index
,
6705 IDirect3DDeviceImpl_3_End
,
6706 IDirect3DDeviceImpl_3_GetRenderState
,
6707 IDirect3DDeviceImpl_3_SetRenderState
,
6708 IDirect3DDeviceImpl_3_GetLightState
,
6709 IDirect3DDeviceImpl_3_SetLightState
,
6710 IDirect3DDeviceImpl_3_SetTransform
,
6711 IDirect3DDeviceImpl_3_GetTransform
,
6712 IDirect3DDeviceImpl_3_MultiplyTransform
,
6713 IDirect3DDeviceImpl_3_DrawPrimitive
,
6714 IDirect3DDeviceImpl_3_DrawIndexedPrimitive
,
6715 IDirect3DDeviceImpl_3_SetClipStatus
,
6716 IDirect3DDeviceImpl_3_GetClipStatus
,
6717 IDirect3DDeviceImpl_3_DrawPrimitiveStrided
,
6718 IDirect3DDeviceImpl_3_DrawIndexedPrimitiveStrided
,
6719 IDirect3DDeviceImpl_3_DrawPrimitiveVB
,
6720 IDirect3DDeviceImpl_3_DrawIndexedPrimitiveVB
,
6721 IDirect3DDeviceImpl_3_ComputeSphereVisibility
,
6722 IDirect3DDeviceImpl_3_GetTexture
,
6723 IDirect3DDeviceImpl_3_SetTexture
,
6724 IDirect3DDeviceImpl_3_GetTextureStageState
,
6725 IDirect3DDeviceImpl_3_SetTextureStageState
,
6726 IDirect3DDeviceImpl_3_ValidateDevice
6729 static const struct IDirect3DDevice2Vtbl d3d_device2_vtbl
=
6731 /*** IUnknown Methods ***/
6732 IDirect3DDeviceImpl_2_QueryInterface
,
6733 IDirect3DDeviceImpl_2_AddRef
,
6734 IDirect3DDeviceImpl_2_Release
,
6735 /*** IDirect3DDevice2 ***/
6736 IDirect3DDeviceImpl_2_GetCaps
,
6737 IDirect3DDeviceImpl_2_SwapTextureHandles
,
6738 IDirect3DDeviceImpl_2_GetStats
,
6739 IDirect3DDeviceImpl_2_AddViewport
,
6740 IDirect3DDeviceImpl_2_DeleteViewport
,
6741 IDirect3DDeviceImpl_2_NextViewport
,
6742 IDirect3DDeviceImpl_2_EnumTextureFormats
,
6743 IDirect3DDeviceImpl_2_BeginScene
,
6744 IDirect3DDeviceImpl_2_EndScene
,
6745 IDirect3DDeviceImpl_2_GetDirect3D
,
6746 IDirect3DDeviceImpl_2_SetCurrentViewport
,
6747 IDirect3DDeviceImpl_2_GetCurrentViewport
,
6748 IDirect3DDeviceImpl_2_SetRenderTarget
,
6749 IDirect3DDeviceImpl_2_GetRenderTarget
,
6750 IDirect3DDeviceImpl_2_Begin
,
6751 IDirect3DDeviceImpl_2_BeginIndexed
,
6752 IDirect3DDeviceImpl_2_Vertex
,
6753 IDirect3DDeviceImpl_2_Index
,
6754 IDirect3DDeviceImpl_2_End
,
6755 IDirect3DDeviceImpl_2_GetRenderState
,
6756 IDirect3DDeviceImpl_2_SetRenderState
,
6757 IDirect3DDeviceImpl_2_GetLightState
,
6758 IDirect3DDeviceImpl_2_SetLightState
,
6759 IDirect3DDeviceImpl_2_SetTransform
,
6760 IDirect3DDeviceImpl_2_GetTransform
,
6761 IDirect3DDeviceImpl_2_MultiplyTransform
,
6762 IDirect3DDeviceImpl_2_DrawPrimitive
,
6763 IDirect3DDeviceImpl_2_DrawIndexedPrimitive
,
6764 IDirect3DDeviceImpl_2_SetClipStatus
,
6765 IDirect3DDeviceImpl_2_GetClipStatus
6768 static const struct IDirect3DDeviceVtbl d3d_device1_vtbl
=
6770 /*** IUnknown Methods ***/
6771 IDirect3DDeviceImpl_1_QueryInterface
,
6772 IDirect3DDeviceImpl_1_AddRef
,
6773 IDirect3DDeviceImpl_1_Release
,
6774 /*** IDirect3DDevice1 ***/
6775 IDirect3DDeviceImpl_1_Initialize
,
6776 IDirect3DDeviceImpl_1_GetCaps
,
6777 IDirect3DDeviceImpl_1_SwapTextureHandles
,
6778 IDirect3DDeviceImpl_1_CreateExecuteBuffer
,
6779 IDirect3DDeviceImpl_1_GetStats
,
6780 IDirect3DDeviceImpl_1_Execute
,
6781 IDirect3DDeviceImpl_1_AddViewport
,
6782 IDirect3DDeviceImpl_1_DeleteViewport
,
6783 IDirect3DDeviceImpl_1_NextViewport
,
6784 IDirect3DDeviceImpl_1_Pick
,
6785 IDirect3DDeviceImpl_1_GetPickRecords
,
6786 IDirect3DDeviceImpl_1_EnumTextureFormats
,
6787 IDirect3DDeviceImpl_1_CreateMatrix
,
6788 IDirect3DDeviceImpl_1_SetMatrix
,
6789 IDirect3DDeviceImpl_1_GetMatrix
,
6790 IDirect3DDeviceImpl_1_DeleteMatrix
,
6791 IDirect3DDeviceImpl_1_BeginScene
,
6792 IDirect3DDeviceImpl_1_EndScene
,
6793 IDirect3DDeviceImpl_1_GetDirect3D
6796 IDirect3DDeviceImpl
*unsafe_impl_from_IDirect3DDevice7(IDirect3DDevice7
*iface
)
6798 if (!iface
) return NULL
;
6799 assert((iface
->lpVtbl
== &d3d_device7_fpu_preserve_vtbl
) || (iface
->lpVtbl
== &d3d_device7_fpu_setup_vtbl
));
6800 return CONTAINING_RECORD(iface
, IDirect3DDeviceImpl
, IDirect3DDevice7_iface
);
6803 IDirect3DDeviceImpl
*unsafe_impl_from_IDirect3DDevice3(IDirect3DDevice3
*iface
)
6805 if (!iface
) return NULL
;
6806 assert(iface
->lpVtbl
== &d3d_device3_vtbl
);
6807 return CONTAINING_RECORD(iface
, IDirect3DDeviceImpl
, IDirect3DDevice3_iface
);
6810 IDirect3DDeviceImpl
*unsafe_impl_from_IDirect3DDevice2(IDirect3DDevice2
*iface
)
6812 if (!iface
) return NULL
;
6813 assert(iface
->lpVtbl
== &d3d_device2_vtbl
);
6814 return CONTAINING_RECORD(iface
, IDirect3DDeviceImpl
, IDirect3DDevice2_iface
);
6817 IDirect3DDeviceImpl
*unsafe_impl_from_IDirect3DDevice(IDirect3DDevice
*iface
)
6819 if (!iface
) return NULL
;
6820 assert(iface
->lpVtbl
== &d3d_device1_vtbl
);
6821 return CONTAINING_RECORD(iface
, IDirect3DDeviceImpl
, IDirect3DDevice_iface
);
6824 /*****************************************************************************
6825 * IDirect3DDeviceImpl_UpdateDepthStencil
6827 * Checks the current render target for attached depth stencils and sets the
6828 * WineD3D depth stencil accordingly.
6831 * The depth stencil state to set if creating the device
6833 *****************************************************************************/
6835 IDirect3DDeviceImpl_UpdateDepthStencil(IDirect3DDeviceImpl
*This
)
6837 IDirectDrawSurface7
*depthStencil
= NULL
;
6838 IDirectDrawSurfaceImpl
*dsi
;
6839 static DDSCAPS2 depthcaps
= { DDSCAPS_ZBUFFER
, 0, 0, 0 };
6841 IDirectDrawSurface7_GetAttachedSurface(&This
->target
->IDirectDrawSurface7_iface
, &depthcaps
, &depthStencil
);
6844 TRACE("Setting wined3d depth stencil to NULL\n");
6845 wined3d_device_set_depth_stencil(This
->wined3d_device
, NULL
);
6846 return WINED3DZB_FALSE
;
6849 dsi
= impl_from_IDirectDrawSurface7(depthStencil
);
6850 TRACE("Setting wined3d depth stencil to %p (wined3d %p)\n", dsi
, dsi
->wined3d_surface
);
6851 wined3d_device_set_depth_stencil(This
->wined3d_device
, dsi
->wined3d_surface
);
6853 IDirectDrawSurface7_Release(depthStencil
);
6854 return WINED3DZB_TRUE
;
6857 HRESULT
d3d_device_init(IDirect3DDeviceImpl
*device
, IDirectDrawImpl
*ddraw
, IDirectDrawSurfaceImpl
*target
)
6861 if (ddraw
->cooperative_level
& DDSCL_FPUPRESERVE
)
6862 device
->IDirect3DDevice7_iface
.lpVtbl
= &d3d_device7_fpu_preserve_vtbl
;
6864 device
->IDirect3DDevice7_iface
.lpVtbl
= &d3d_device7_fpu_setup_vtbl
;
6866 device
->IDirect3DDevice3_iface
.lpVtbl
= &d3d_device3_vtbl
;
6867 device
->IDirect3DDevice2_iface
.lpVtbl
= &d3d_device2_vtbl
;
6868 device
->IDirect3DDevice_iface
.lpVtbl
= &d3d_device1_vtbl
;
6870 device
->ddraw
= ddraw
;
6871 device
->target
= target
;
6872 list_init(&device
->viewport_list
);
6874 if (!ddraw_handle_table_init(&device
->handle_table
, 64))
6876 ERR("Failed to initialize handle table.\n");
6877 return DDERR_OUTOFMEMORY
;
6880 device
->legacyTextureBlending
= FALSE
;
6882 /* Create an index buffer, it's needed for indexed drawing */
6883 hr
= wined3d_buffer_create_ib(ddraw
->wined3d_device
, 0x40000 /* Length. Don't know how long it should be */,
6884 WINED3DUSAGE_DYNAMIC
/* Usage */, WINED3DPOOL_DEFAULT
, NULL
,
6885 &ddraw_null_wined3d_parent_ops
, &device
->indexbuffer
);
6888 ERR("Failed to create an index buffer, hr %#x.\n", hr
);
6889 ddraw_handle_table_destroy(&device
->handle_table
);
6893 /* This is for convenience. */
6894 device
->wined3d_device
= ddraw
->wined3d_device
;
6895 wined3d_device_incref(ddraw
->wined3d_device
);
6897 /* Render to the back buffer */
6898 hr
= wined3d_device_set_render_target(ddraw
->wined3d_device
, 0, target
->wined3d_surface
, TRUE
);
6901 ERR("Failed to set render target, hr %#x.\n", hr
);
6902 wined3d_buffer_decref(device
->indexbuffer
);
6903 ddraw_handle_table_destroy(&device
->handle_table
);
6907 /* FIXME: This is broken. The target AddRef() makes some sense, because
6908 * we store a pointer during initialization, but then that's also where
6909 * the AddRef() should be. We don't store ddraw->d3d_target anywhere. */
6910 /* AddRef the render target. Also AddRef the render target from ddraw,
6911 * because if it is released before the app releases the D3D device, the
6912 * D3D capabilities of wined3d will be uninitialized, which has bad effects.
6914 * In most cases, those surfaces are the same anyway, but this will simply
6915 * add another ref which is released when the device is destroyed. */
6916 IDirectDrawSurface7_AddRef(&target
->IDirectDrawSurface7_iface
);
6917 IDirectDrawSurface7_AddRef(&ddraw
->d3d_target
->IDirectDrawSurface7_iface
);
6919 ddraw
->d3ddevice
= device
;
6921 wined3d_device_set_render_state(ddraw
->wined3d_device
, WINED3DRS_ZENABLE
,
6922 IDirect3DDeviceImpl_UpdateDepthStencil(device
));