2 * Copyright (c) 1998-2004 Lionel Ulmer
3 * Copyright (c) 2002-2005 Christian Costa
4 * Copyright (c) 2006-2009, 2011-2013 Stefan Dösinger
5 * Copyright (c) 2008 Alexander Dorofeyev
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 * IDirect3DDevice implementation, version 1, 2, 3 and 7. Rendering is relayed
22 * to WineD3D, some minimal DirectDraw specific management is handled here.
23 * The Direct3DDevice is NOT the parent of the WineD3DDevice, because d3d
24 * is initialized when DirectDraw creates the primary surface.
25 * Some type management is necessary, because some D3D types changed between
31 #include "wine/port.h"
33 #include "ddraw_private.h"
35 WINE_DEFAULT_DEBUG_CHANNEL(ddraw
);
36 WINE_DECLARE_DEBUG_CHANNEL(winediag
);
39 const GUID IID_D3DDEVICE_WineD3D
= {
43 { 0xb7,0x98,0xc6,0x8a,0x77,0x2d,0x72,0x2a }
46 static inline void set_fpu_control_word(WORD fpucw
)
48 #if defined(__i386__) && defined(__GNUC__)
49 __asm__
volatile ("fldcw %0" : : "m" (fpucw
));
50 #elif defined(__i386__) && defined(_MSC_VER)
55 static inline WORD
d3d_fpu_setup(void)
59 #if defined(__i386__) && defined(__GNUC__)
60 __asm__
volatile ("fnstcw %0" : "=m" (oldcw
));
61 #elif defined(__i386__) && defined(_MSC_VER)
64 static BOOL warned
= FALSE
;
67 FIXME("FPUPRESERVE not implemented for this platform / compiler\n");
73 set_fpu_control_word(0x37f);
78 static inline struct d3d_device
*impl_from_IUnknown(IUnknown
*iface
)
80 return CONTAINING_RECORD(iface
, struct d3d_device
, IUnknown_inner
);
83 static HRESULT WINAPI
d3d_device_inner_QueryInterface(IUnknown
*iface
, REFIID riid
, void **out
)
85 struct d3d_device
*device
= impl_from_IUnknown(iface
);
87 TRACE("iface %p, riid %s, out %p.\n", iface
, debugstr_guid(riid
), out
);
92 return DDERR_INVALIDPARAMS
;
95 if (IsEqualGUID(&IID_IUnknown
, riid
))
97 IDirect3DDevice7_AddRef(&device
->IDirect3DDevice7_iface
);
98 *out
= &device
->IDirect3DDevice7_iface
;
102 if (device
->version
== 7)
104 if (IsEqualGUID(&IID_IDirect3DDevice7
, riid
))
106 IDirect3DDevice7_AddRef(&device
->IDirect3DDevice7_iface
);
107 *out
= &device
->IDirect3DDevice7_iface
;
113 if (IsEqualGUID(&IID_IDirect3DDevice3
, riid
) && device
->version
== 3)
115 IDirect3DDevice3_AddRef(&device
->IDirect3DDevice3_iface
);
116 *out
= &device
->IDirect3DDevice3_iface
;
120 if (IsEqualGUID(&IID_IDirect3DDevice2
, riid
) && device
->version
>= 2)
122 IDirect3DDevice2_AddRef(&device
->IDirect3DDevice2_iface
);
123 *out
= &device
->IDirect3DDevice2_iface
;
127 if (IsEqualGUID(&IID_IDirect3DDevice
, riid
))
129 IDirect3DDevice_AddRef(&device
->IDirect3DDevice_iface
);
130 *out
= &device
->IDirect3DDevice_iface
;
135 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid
));
138 return E_NOINTERFACE
;
141 static HRESULT WINAPI
d3d_device7_QueryInterface(IDirect3DDevice7
*iface
, REFIID riid
, void **out
)
143 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
145 TRACE("iface %p, riid %s, out %p.\n", iface
, debugstr_guid(riid
), out
);
147 return IUnknown_QueryInterface(device
->outer_unknown
, riid
, out
);
150 static HRESULT WINAPI
d3d_device3_QueryInterface(IDirect3DDevice3
*iface
, REFIID riid
, void **out
)
152 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
154 TRACE("iface %p, riid %s, out %p.\n", iface
, debugstr_guid(riid
), out
);
156 return IUnknown_QueryInterface(device
->outer_unknown
, riid
, out
);
159 static HRESULT WINAPI
d3d_device2_QueryInterface(IDirect3DDevice2
*iface
, REFIID riid
, void **out
)
161 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
163 TRACE("iface %p, riid %s, out %p.\n", iface
, debugstr_guid(riid
), out
);
165 return IUnknown_QueryInterface(device
->outer_unknown
, riid
, out
);
168 static HRESULT WINAPI
d3d_device1_QueryInterface(IDirect3DDevice
*iface
, REFIID riid
, void **out
)
170 struct d3d_device
*device
= impl_from_IDirect3DDevice(iface
);
172 TRACE("iface %p, riid %s, out %p.\n", iface
, debugstr_guid(riid
), out
);
174 return IUnknown_QueryInterface(device
->outer_unknown
, riid
, out
);
177 static ULONG WINAPI
d3d_device_inner_AddRef(IUnknown
*iface
)
179 struct d3d_device
*device
= impl_from_IUnknown(iface
);
180 ULONG ref
= InterlockedIncrement(&device
->ref
);
182 TRACE("%p increasing refcount to %u.\n", device
, ref
);
187 static ULONG WINAPI
d3d_device7_AddRef(IDirect3DDevice7
*iface
)
189 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
191 TRACE("iface %p.\n", iface
);
193 return IUnknown_AddRef(device
->outer_unknown
);
196 static ULONG WINAPI
d3d_device3_AddRef(IDirect3DDevice3
*iface
)
198 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
200 TRACE("iface %p.\n", iface
);
202 return IUnknown_AddRef(device
->outer_unknown
);
205 static ULONG WINAPI
d3d_device2_AddRef(IDirect3DDevice2
*iface
)
207 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
209 TRACE("iface %p.\n", iface
);
211 return IUnknown_AddRef(device
->outer_unknown
);
214 static ULONG WINAPI
d3d_device1_AddRef(IDirect3DDevice
*iface
)
216 struct d3d_device
*device
= impl_from_IDirect3DDevice(iface
);
218 TRACE("iface %p.\n", iface
);
220 return IUnknown_AddRef(device
->outer_unknown
);
223 static ULONG WINAPI
d3d_device_inner_Release(IUnknown
*iface
)
225 struct d3d_device
*This
= impl_from_IUnknown(iface
);
226 ULONG ref
= InterlockedDecrement(&This
->ref
);
229 TRACE("%p decreasing refcount to %u.\n", This
, ref
);
231 /* This method doesn't destroy the wined3d device, because it's still in
232 * use for 2D rendering. IDirectDrawSurface7::Release will destroy the
233 * wined3d device when the render target is released. */
237 struct list
*vp_entry
, *vp_entry2
;
239 wined3d_mutex_lock();
241 /* There is no need to unset any resources here, wined3d will take
242 * care of that on uninit_3d(). */
244 if (This
->index_buffer
)
245 wined3d_buffer_decref(This
->index_buffer
);
246 if (This
->vertex_buffer
)
247 wined3d_buffer_decref(This
->vertex_buffer
);
249 wined3d_device_set_rendertarget_view(This
->wined3d_device
, 0, NULL
, FALSE
);
251 /* Release the wined3d device. This won't destroy it. */
252 if (!wined3d_device_decref(This
->wined3d_device
))
253 ERR("The wined3d device (%p) was destroyed unexpectedly.\n", This
->wined3d_device
);
255 /* The texture handles should be unset by now, but there might be some bits
256 * missing in our reference counting(needs test). Do a sanity check. */
257 for (i
= 0; i
< This
->handle_table
.entry_count
; ++i
)
259 struct ddraw_handle_entry
*entry
= &This
->handle_table
.entries
[i
];
263 case DDRAW_HANDLE_FREE
:
266 case DDRAW_HANDLE_MATERIAL
:
268 struct d3d_material
*m
= entry
->object
;
269 FIXME("Material handle %#x (%p) not unset properly.\n", i
+ 1, m
);
274 case DDRAW_HANDLE_MATRIX
:
276 /* No FIXME here because this might happen because of sloppy applications. */
277 WARN("Leftover matrix handle %#x (%p), deleting.\n", i
+ 1, entry
->object
);
278 IDirect3DDevice_DeleteMatrix(&This
->IDirect3DDevice_iface
, i
+ 1);
282 case DDRAW_HANDLE_STATEBLOCK
:
284 /* No FIXME here because this might happen because of sloppy applications. */
285 WARN("Leftover stateblock handle %#x (%p), deleting.\n", i
+ 1, entry
->object
);
286 IDirect3DDevice7_DeleteStateBlock(&This
->IDirect3DDevice7_iface
, i
+ 1);
290 case DDRAW_HANDLE_SURFACE
:
292 struct ddraw_surface
*surf
= entry
->object
;
293 FIXME("Texture handle %#x (%p) not unset properly.\n", i
+ 1, surf
);
299 FIXME("Handle %#x (%p) has unknown type %#x.\n", i
+ 1, entry
->object
, entry
->type
);
304 ddraw_handle_table_destroy(&This
->handle_table
);
306 LIST_FOR_EACH_SAFE(vp_entry
, vp_entry2
, &This
->viewport_list
)
308 struct d3d_viewport
*vp
= LIST_ENTRY(vp_entry
, struct d3d_viewport
, entry
);
309 IDirect3DDevice3_DeleteViewport(&This
->IDirect3DDevice3_iface
, &vp
->IDirect3DViewport3_iface
);
312 TRACE("Releasing render target %p.\n", This
->rt_iface
);
313 rt_iface
= This
->rt_iface
;
314 This
->rt_iface
= NULL
;
315 if (This
->version
!= 1)
316 IUnknown_Release(rt_iface
);
317 TRACE("Render target release done.\n");
319 /* Releasing the render target above may have released the last
320 * reference to the ddraw object. */
322 This
->ddraw
->d3ddevice
= NULL
;
324 /* Now free the structure */
325 HeapFree(GetProcessHeap(), 0, This
);
326 wined3d_mutex_unlock();
333 static ULONG WINAPI
d3d_device7_Release(IDirect3DDevice7
*iface
)
335 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
337 TRACE("iface %p.\n", iface
);
339 return IUnknown_Release(device
->outer_unknown
);
342 static ULONG WINAPI
d3d_device3_Release(IDirect3DDevice3
*iface
)
344 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
346 TRACE("iface %p.\n", iface
);
348 return IUnknown_Release(device
->outer_unknown
);
351 static ULONG WINAPI
d3d_device2_Release(IDirect3DDevice2
*iface
)
353 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
355 TRACE("iface %p.\n", iface
);
357 return IUnknown_Release(device
->outer_unknown
);
360 static ULONG WINAPI
d3d_device1_Release(IDirect3DDevice
*iface
)
362 struct d3d_device
*device
= impl_from_IDirect3DDevice(iface
);
364 TRACE("iface %p.\n", iface
);
366 return IUnknown_Release(device
->outer_unknown
);
369 /*****************************************************************************
370 * IDirect3DDevice Methods
371 *****************************************************************************/
373 /*****************************************************************************
374 * IDirect3DDevice::Initialize
376 * Initializes a Direct3DDevice. This implementation is a no-op, as all
377 * initialization is done at create time.
379 * Exists in Version 1
382 * No idea what they mean, as the MSDN page is gone
386 *****************************************************************************/
387 static HRESULT WINAPI
d3d_device1_Initialize(IDirect3DDevice
*iface
,
388 IDirect3D
*d3d
, GUID
*guid
, D3DDEVICEDESC
*device_desc
)
390 /* It shouldn't be crucial, but print a FIXME, I'm interested if
391 * any game calls it and when. */
392 FIXME("iface %p, d3d %p, guid %s, device_desc %p nop!\n",
393 iface
, d3d
, debugstr_guid(guid
), device_desc
);
398 static HRESULT
d3d_device7_GetCaps(IDirect3DDevice7
*iface
, D3DDEVICEDESC7
*device_desc
)
400 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
402 TRACE("iface %p, device_desc %p.\n", iface
, device_desc
);
406 WARN("device_desc is NULL, returning DDERR_INVALIDPARAMS.\n");
407 return DDERR_INVALIDPARAMS
;
410 /* Call the same function used by IDirect3D, this saves code */
411 return ddraw_get_d3dcaps(device
->ddraw
, device_desc
);
414 static HRESULT WINAPI
d3d_device7_GetCaps_FPUSetup(IDirect3DDevice7
*iface
, D3DDEVICEDESC7
*desc
)
416 return d3d_device7_GetCaps(iface
, desc
);
419 static HRESULT WINAPI
d3d_device7_GetCaps_FPUPreserve(IDirect3DDevice7
*iface
, D3DDEVICEDESC7
*desc
)
424 old_fpucw
= d3d_fpu_setup();
425 hr
= d3d_device7_GetCaps(iface
, desc
);
426 set_fpu_control_word(old_fpucw
);
430 /*****************************************************************************
431 * IDirect3DDevice3::GetCaps
433 * Retrieves the capabilities of the hardware device and the emulation
434 * device. For Wine, hardware and emulation are the same (it's all HW).
436 * This implementation is used for Version 1, 2, and 3. Version 7 has its own
439 * HWDesc: Structure to fill with the HW caps
440 * HelDesc: Structure to fill with the hardware emulation caps
444 * D3DERR_* if a problem occurs. See WineD3D
446 *****************************************************************************/
448 /* There are 3 versions of D3DDEVICEDESC. All 3 share the same name because
449 * Microsoft just expanded the existing structure without naming them
450 * D3DDEVICEDESC2 and D3DDEVICEDESC3. Which version is used have depends
451 * on the version of the DirectX SDK. DirectX 6+ and Wine use the latest
452 * one with 252 bytes.
454 * All 3 versions are allowed as parameters and only the specified amount of
457 * Note that Direct3D7 and earlier are not available in native Win64
458 * ddraw.dll builds, so possible size differences between 32 bit and
459 * 64 bit are a non-issue.
461 static inline BOOL
check_d3ddevicedesc_size(DWORD size
)
463 if (size
== FIELD_OFFSET(D3DDEVICEDESC
, dwMinTextureWidth
) /* 172 */
464 || size
== FIELD_OFFSET(D3DDEVICEDESC
, dwMaxTextureRepeat
) /* 204 */
465 || size
== sizeof(D3DDEVICEDESC
) /* 252 */) return TRUE
;
469 static HRESULT WINAPI
d3d_device3_GetCaps(IDirect3DDevice3
*iface
,
470 D3DDEVICEDESC
*HWDesc
, D3DDEVICEDESC
*HelDesc
)
472 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
473 D3DDEVICEDESC7 desc7
;
477 TRACE("iface %p, hw_desc %p, hel_desc %p.\n", iface
, HWDesc
, HelDesc
);
481 WARN("HWDesc is NULL, returning DDERR_INVALIDPARAMS.\n");
482 return DDERR_INVALIDPARAMS
;
484 if (!check_d3ddevicedesc_size(HWDesc
->dwSize
))
486 WARN("HWDesc->dwSize is %u, returning DDERR_INVALIDPARAMS.\n", HWDesc
->dwSize
);
487 return DDERR_INVALIDPARAMS
;
491 WARN("HelDesc is NULL, returning DDERR_INVALIDPARAMS.\n");
492 return DDERR_INVALIDPARAMS
;
494 if (!check_d3ddevicedesc_size(HelDesc
->dwSize
))
496 WARN("HelDesc->dwSize is %u, returning DDERR_INVALIDPARAMS.\n", HelDesc
->dwSize
);
497 return DDERR_INVALIDPARAMS
;
500 if (FAILED(hr
= ddraw_get_d3dcaps(device
->ddraw
, &desc7
)))
503 ddraw_d3dcaps1_from_7(&desc1
, &desc7
);
504 DD_STRUCT_COPY_BYSIZE(HWDesc
, &desc1
);
505 DD_STRUCT_COPY_BYSIZE(HelDesc
, &desc1
);
509 static HRESULT WINAPI
d3d_device2_GetCaps(IDirect3DDevice2
*iface
,
510 D3DDEVICEDESC
*hw_desc
, D3DDEVICEDESC
*hel_desc
)
512 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
514 TRACE("iface %p, hw_desc %p, hel_desc %p.\n", iface
, hw_desc
, hel_desc
);
516 return d3d_device3_GetCaps(&device
->IDirect3DDevice3_iface
, hw_desc
, hel_desc
);
519 static HRESULT WINAPI
d3d_device1_GetCaps(IDirect3DDevice
*iface
,
520 D3DDEVICEDESC
*hw_desc
, D3DDEVICEDESC
*hel_desc
)
522 struct d3d_device
*device
= impl_from_IDirect3DDevice(iface
);
524 TRACE("iface %p, hw_desc %p, hel_desc %p.\n", iface
, hw_desc
, hel_desc
);
526 return d3d_device3_GetCaps(&device
->IDirect3DDevice3_iface
, hw_desc
, hel_desc
);
529 /*****************************************************************************
530 * IDirect3DDevice2::SwapTextureHandles
532 * Swaps the texture handles of 2 Texture interfaces. Version 1 and 2
535 * Tex1, Tex2: The 2 Textures to swap
540 *****************************************************************************/
541 static HRESULT WINAPI
d3d_device2_SwapTextureHandles(IDirect3DDevice2
*iface
,
542 IDirect3DTexture2
*tex1
, IDirect3DTexture2
*tex2
)
544 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
545 struct ddraw_surface
*surf1
= unsafe_impl_from_IDirect3DTexture2(tex1
);
546 struct ddraw_surface
*surf2
= unsafe_impl_from_IDirect3DTexture2(tex2
);
549 TRACE("iface %p, tex1 %p, tex2 %p.\n", iface
, tex1
, tex2
);
551 wined3d_mutex_lock();
553 h1
= surf1
->Handle
- 1;
554 h2
= surf2
->Handle
- 1;
555 device
->handle_table
.entries
[h1
].object
= surf2
;
556 device
->handle_table
.entries
[h2
].object
= surf1
;
557 surf2
->Handle
= h1
+ 1;
558 surf1
->Handle
= h2
+ 1;
560 wined3d_mutex_unlock();
565 static HRESULT WINAPI
d3d_device1_SwapTextureHandles(IDirect3DDevice
*iface
,
566 IDirect3DTexture
*tex1
, IDirect3DTexture
*tex2
)
568 struct d3d_device
*device
= impl_from_IDirect3DDevice(iface
);
569 struct ddraw_surface
*surf1
= unsafe_impl_from_IDirect3DTexture(tex1
);
570 struct ddraw_surface
*surf2
= unsafe_impl_from_IDirect3DTexture(tex2
);
571 IDirect3DTexture2
*t1
= surf1
? &surf1
->IDirect3DTexture2_iface
: NULL
;
572 IDirect3DTexture2
*t2
= surf2
? &surf2
->IDirect3DTexture2_iface
: NULL
;
574 TRACE("iface %p, tex1 %p, tex2 %p.\n", iface
, tex1
, tex2
);
576 return d3d_device2_SwapTextureHandles(&device
->IDirect3DDevice2_iface
, t1
, t2
);
579 /*****************************************************************************
580 * IDirect3DDevice3::GetStats
582 * This method seems to retrieve some stats from the device.
583 * The MSDN documentation doesn't exist any more, but the D3DSTATS
584 * structure suggests that the amount of drawn primitives and processed
585 * vertices is returned.
587 * Exists in Version 1, 2 and 3
590 * Stats: Pointer to a D3DSTATS structure to be filled
594 * DDERR_INVALIDPARAMS if Stats == NULL
596 *****************************************************************************/
597 static HRESULT WINAPI
d3d_device3_GetStats(IDirect3DDevice3
*iface
, D3DSTATS
*Stats
)
599 FIXME("iface %p, stats %p stub!\n", iface
, Stats
);
602 return DDERR_INVALIDPARAMS
;
604 /* Fill the Stats with 0 */
605 Stats
->dwTrianglesDrawn
= 0;
606 Stats
->dwLinesDrawn
= 0;
607 Stats
->dwPointsDrawn
= 0;
608 Stats
->dwSpansDrawn
= 0;
609 Stats
->dwVerticesProcessed
= 0;
614 static HRESULT WINAPI
d3d_device2_GetStats(IDirect3DDevice2
*iface
, D3DSTATS
*stats
)
616 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
618 TRACE("iface %p, stats %p.\n", iface
, stats
);
620 return d3d_device3_GetStats(&device
->IDirect3DDevice3_iface
, stats
);
623 static HRESULT WINAPI
d3d_device1_GetStats(IDirect3DDevice
*iface
, D3DSTATS
*stats
)
625 struct d3d_device
*device
= impl_from_IDirect3DDevice(iface
);
627 TRACE("iface %p, stats %p.\n", iface
, stats
);
629 return d3d_device3_GetStats(&device
->IDirect3DDevice3_iface
, stats
);
632 /*****************************************************************************
633 * IDirect3DDevice::CreateExecuteBuffer
635 * Creates an IDirect3DExecuteBuffer, used for rendering with a
641 * Desc: Buffer description
642 * ExecuteBuffer: Address to return the Interface pointer at
643 * UnkOuter: Must be NULL. Basically for aggregation, which ddraw doesn't
647 * CLASS_E_NOAGGREGATION if UnkOuter != NULL
648 * DDERR_OUTOFMEMORY if we ran out of memory
651 *****************************************************************************/
652 static HRESULT WINAPI
d3d_device1_CreateExecuteBuffer(IDirect3DDevice
*iface
,
653 D3DEXECUTEBUFFERDESC
*buffer_desc
, IDirect3DExecuteBuffer
**ExecuteBuffer
, IUnknown
*outer_unknown
)
655 struct d3d_device
*device
= impl_from_IDirect3DDevice(iface
);
656 struct d3d_execute_buffer
*object
;
659 TRACE("iface %p, buffer_desc %p, buffer %p, outer_unknown %p.\n",
660 iface
, buffer_desc
, ExecuteBuffer
, outer_unknown
);
663 return CLASS_E_NOAGGREGATION
;
665 /* Allocate the new Execute Buffer */
666 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*object
));
669 ERR("Failed to allocate execute buffer memory.\n");
670 return DDERR_OUTOFMEMORY
;
673 hr
= d3d_execute_buffer_init(object
, device
, buffer_desc
);
676 WARN("Failed to initialize execute buffer, hr %#x.\n", hr
);
677 HeapFree(GetProcessHeap(), 0, object
);
681 *ExecuteBuffer
= &object
->IDirect3DExecuteBuffer_iface
;
683 TRACE(" Returning IDirect3DExecuteBuffer at %p, implementation is at %p\n", *ExecuteBuffer
, object
);
688 /*****************************************************************************
689 * IDirect3DDevice::Execute
691 * Executes all the stuff in an execute buffer.
694 * ExecuteBuffer: The buffer to execute
695 * Viewport: The viewport used for rendering
699 * DDERR_INVALIDPARAMS if ExecuteBuffer == NULL
702 *****************************************************************************/
703 static HRESULT WINAPI
d3d_device1_Execute(IDirect3DDevice
*iface
,
704 IDirect3DExecuteBuffer
*ExecuteBuffer
, IDirect3DViewport
*viewport
, DWORD flags
)
706 struct d3d_device
*device
= impl_from_IDirect3DDevice(iface
);
707 struct d3d_execute_buffer
*buffer
= unsafe_impl_from_IDirect3DExecuteBuffer(ExecuteBuffer
);
708 struct d3d_viewport
*viewport_impl
= unsafe_impl_from_IDirect3DViewport(viewport
);
711 TRACE("iface %p, buffer %p, viewport %p, flags %#x.\n", iface
, ExecuteBuffer
, viewport
, flags
);
714 return DDERR_INVALIDPARAMS
;
717 wined3d_mutex_lock();
718 hr
= d3d_execute_buffer_execute(buffer
, device
, viewport_impl
);
719 wined3d_mutex_unlock();
724 /*****************************************************************************
725 * IDirect3DDevice3::AddViewport
727 * Add a Direct3DViewport to the device's viewport list. These viewports
728 * are wrapped to IDirect3DDevice7 viewports in viewport.c
730 * Exists in Version 1, 2 and 3. Note that IDirect3DViewport 1, 2 and 3
731 * are the same interfaces.
734 * Viewport: The viewport to add
737 * DDERR_INVALIDPARAMS if Viewport == NULL
740 *****************************************************************************/
741 static HRESULT WINAPI
d3d_device3_AddViewport(IDirect3DDevice3
*iface
, IDirect3DViewport3
*viewport
)
743 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
744 struct d3d_viewport
*vp
= unsafe_impl_from_IDirect3DViewport3(viewport
);
746 TRACE("iface %p, viewport %p.\n", iface
, viewport
);
750 return DDERR_INVALIDPARAMS
;
752 wined3d_mutex_lock();
753 IDirect3DViewport3_AddRef(viewport
);
754 list_add_head(&device
->viewport_list
, &vp
->entry
);
755 /* Viewport must be usable for Clear() after AddViewport, so set active_device here. */
756 vp
->active_device
= device
;
757 wined3d_mutex_unlock();
762 static HRESULT WINAPI
d3d_device2_AddViewport(IDirect3DDevice2
*iface
,
763 IDirect3DViewport2
*viewport
)
765 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
766 struct d3d_viewport
*vp
= unsafe_impl_from_IDirect3DViewport2(viewport
);
768 TRACE("iface %p, viewport %p.\n", iface
, viewport
);
770 return d3d_device3_AddViewport(&device
->IDirect3DDevice3_iface
, &vp
->IDirect3DViewport3_iface
);
773 static HRESULT WINAPI
d3d_device1_AddViewport(IDirect3DDevice
*iface
, IDirect3DViewport
*viewport
)
775 struct d3d_device
*device
= impl_from_IDirect3DDevice(iface
);
776 struct d3d_viewport
*vp
= unsafe_impl_from_IDirect3DViewport(viewport
);
778 TRACE("iface %p, viewport %p.\n", iface
, viewport
);
780 return d3d_device3_AddViewport(&device
->IDirect3DDevice3_iface
, &vp
->IDirect3DViewport3_iface
);
783 /*****************************************************************************
784 * IDirect3DDevice3::DeleteViewport
786 * Deletes a Direct3DViewport from the device's viewport list.
788 * Exists in Version 1, 2 and 3. Note that all Viewport interface versions
792 * Viewport: The viewport to delete
796 * DDERR_INVALIDPARAMS if the viewport wasn't found in the list
798 *****************************************************************************/
799 static HRESULT WINAPI
d3d_device3_DeleteViewport(IDirect3DDevice3
*iface
, IDirect3DViewport3
*viewport
)
801 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
802 struct d3d_viewport
*vp
= unsafe_impl_from_IDirect3DViewport3(viewport
);
804 TRACE("iface %p, viewport %p.\n", iface
, viewport
);
808 WARN("NULL viewport, returning DDERR_INVALIDPARAMS\n");
809 return DDERR_INVALIDPARAMS
;
812 wined3d_mutex_lock();
814 if (vp
->active_device
!= device
)
816 WARN("Viewport %p active device is %p.\n", vp
, vp
->active_device
);
817 wined3d_mutex_unlock();
818 return DDERR_INVALIDPARAMS
;
821 if (device
->current_viewport
== vp
)
823 TRACE("Deleting current viewport, unsetting and releasing\n");
824 IDirect3DViewport3_Release(viewport
);
825 device
->current_viewport
= NULL
;
828 vp
->active_device
= NULL
;
829 list_remove(&vp
->entry
);
831 IDirect3DViewport3_Release(viewport
);
833 wined3d_mutex_unlock();
838 static HRESULT WINAPI
d3d_device2_DeleteViewport(IDirect3DDevice2
*iface
, IDirect3DViewport2
*viewport
)
840 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
841 struct d3d_viewport
*vp
= unsafe_impl_from_IDirect3DViewport2(viewport
);
843 TRACE("iface %p, viewport %p.\n", iface
, viewport
);
845 return d3d_device3_DeleteViewport(&device
->IDirect3DDevice3_iface
,
846 vp
? &vp
->IDirect3DViewport3_iface
: NULL
);
849 static HRESULT WINAPI
d3d_device1_DeleteViewport(IDirect3DDevice
*iface
, IDirect3DViewport
*viewport
)
851 struct d3d_device
*device
= impl_from_IDirect3DDevice(iface
);
852 struct d3d_viewport
*vp
= unsafe_impl_from_IDirect3DViewport(viewport
);
854 TRACE("iface %p, viewport %p.\n", iface
, viewport
);
856 return d3d_device3_DeleteViewport(&device
->IDirect3DDevice3_iface
,
857 vp
? &vp
->IDirect3DViewport3_iface
: NULL
);
860 /*****************************************************************************
861 * IDirect3DDevice3::NextViewport
863 * Returns a viewport from the viewport list, depending on the
864 * passed viewport and the flags.
866 * Exists in Version 1, 2 and 3. Note that all Viewport interface versions
870 * Viewport: Viewport to use for beginning the search
871 * Flags: D3DNEXT_NEXT, D3DNEXT_HEAD or D3DNEXT_TAIL
875 * DDERR_INVALIDPARAMS if the flags were wrong, or Viewport was NULL
877 *****************************************************************************/
878 static HRESULT WINAPI
d3d_device3_NextViewport(IDirect3DDevice3
*iface
,
879 IDirect3DViewport3
*Viewport3
, IDirect3DViewport3
**lplpDirect3DViewport3
, DWORD flags
)
881 struct d3d_device
*This
= impl_from_IDirect3DDevice3(iface
);
882 struct d3d_viewport
*vp
= unsafe_impl_from_IDirect3DViewport3(Viewport3
);
883 struct d3d_viewport
*next
;
886 TRACE("iface %p, viewport %p, next %p, flags %#x.\n",
887 iface
, Viewport3
, lplpDirect3DViewport3
, flags
);
891 *lplpDirect3DViewport3
= NULL
;
892 return DDERR_INVALIDPARAMS
;
896 wined3d_mutex_lock();
900 entry
= list_next(&This
->viewport_list
, &vp
->entry
);
904 entry
= list_head(&This
->viewport_list
);
908 entry
= list_tail(&This
->viewport_list
);
912 WARN("Invalid flags %#x.\n", flags
);
913 *lplpDirect3DViewport3
= NULL
;
914 wined3d_mutex_unlock();
915 return DDERR_INVALIDPARAMS
;
920 next
= LIST_ENTRY(entry
, struct d3d_viewport
, entry
);
921 *lplpDirect3DViewport3
= &next
->IDirect3DViewport3_iface
;
924 *lplpDirect3DViewport3
= NULL
;
926 wined3d_mutex_unlock();
931 static HRESULT WINAPI
d3d_device2_NextViewport(IDirect3DDevice2
*iface
,
932 IDirect3DViewport2
*viewport
, IDirect3DViewport2
**next
, DWORD flags
)
934 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
935 struct d3d_viewport
*vp
= unsafe_impl_from_IDirect3DViewport2(viewport
);
936 IDirect3DViewport3
*res
;
939 TRACE("iface %p, viewport %p, next %p, flags %#x.\n",
940 iface
, viewport
, next
, flags
);
942 hr
= d3d_device3_NextViewport(&device
->IDirect3DDevice3_iface
,
943 &vp
->IDirect3DViewport3_iface
, &res
, flags
);
944 *next
= (IDirect3DViewport2
*)res
;
948 static HRESULT WINAPI
d3d_device1_NextViewport(IDirect3DDevice
*iface
,
949 IDirect3DViewport
*viewport
, IDirect3DViewport
**next
, DWORD flags
)
951 struct d3d_device
*device
= impl_from_IDirect3DDevice(iface
);
952 struct d3d_viewport
*vp
= unsafe_impl_from_IDirect3DViewport(viewport
);
953 IDirect3DViewport3
*res
;
956 TRACE("iface %p, viewport %p, next %p, flags %#x.\n",
957 iface
, viewport
, next
, flags
);
959 hr
= d3d_device3_NextViewport(&device
->IDirect3DDevice3_iface
,
960 &vp
->IDirect3DViewport3_iface
, &res
, flags
);
961 *next
= (IDirect3DViewport
*)res
;
965 /*****************************************************************************
966 * IDirect3DDevice::Pick
968 * Executes an execute buffer without performing rendering. Instead, a
969 * list of primitives that intersect with (x1,y1) of the passed rectangle
970 * is created. IDirect3DDevice::GetPickRecords can be used to retrieve
976 * ExecuteBuffer: Buffer to execute
977 * Viewport: Viewport to use for execution
978 * Flags: None are defined, according to the SDK
979 * Rect: Specifies the coordinates to be picked. Only x1 and y2 are used,
980 * x2 and y2 are ignored.
983 * D3D_OK because it's a stub
985 *****************************************************************************/
986 static HRESULT WINAPI
d3d_device1_Pick(IDirect3DDevice
*iface
, IDirect3DExecuteBuffer
*buffer
,
987 IDirect3DViewport
*viewport
, DWORD flags
, D3DRECT
*rect
)
989 FIXME("iface %p, buffer %p, viewport %p, flags %#x, rect %s stub!\n",
990 iface
, buffer
, viewport
, flags
, wine_dbgstr_rect((RECT
*)rect
));
995 /*****************************************************************************
996 * IDirect3DDevice::GetPickRecords
998 * Retrieves the pick records generated by IDirect3DDevice::GetPickRecords
1003 * Count: Pointer to a DWORD containing the numbers of pick records to
1005 * D3DPickRec: Address to store the resulting D3DPICKRECORD array.
1008 * D3D_OK, because it's a stub
1010 *****************************************************************************/
1011 static HRESULT WINAPI
d3d_device1_GetPickRecords(IDirect3DDevice
*iface
,
1012 DWORD
*count
, D3DPICKRECORD
*records
)
1014 FIXME("iface %p, count %p, records %p stub!\n", iface
, count
, records
);
1019 /*****************************************************************************
1020 * IDirect3DDevice7::EnumTextureformats
1022 * Enumerates the supported texture formats. It checks against a list of all possible
1023 * formats to see if WineD3D supports it. If so, then it is passed to the app.
1025 * This is for Version 7 and 3, older versions have a different
1026 * callback function and their own implementation
1029 * Callback: Callback to call for each enumerated format
1030 * Arg: Argument to pass to the callback
1034 * DDERR_INVALIDPARAMS if Callback == NULL
1036 *****************************************************************************/
1037 static HRESULT
d3d_device7_EnumTextureFormats(IDirect3DDevice7
*iface
,
1038 LPD3DENUMPIXELFORMATSCALLBACK callback
, void *context
)
1040 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
1041 struct wined3d_display_mode mode
;
1045 static const enum wined3d_format_id FormatList
[] =
1048 WINED3DFMT_B5G5R5X1_UNORM
,
1049 WINED3DFMT_B5G5R5A1_UNORM
,
1050 WINED3DFMT_B4G4R4A4_UNORM
,
1051 WINED3DFMT_B5G6R5_UNORM
,
1053 WINED3DFMT_B8G8R8X8_UNORM
,
1054 WINED3DFMT_B8G8R8A8_UNORM
,
1056 WINED3DFMT_B2G3R3_UNORM
,
1066 static const enum wined3d_format_id BumpFormatList
[] =
1068 WINED3DFMT_R8G8_SNORM
,
1069 WINED3DFMT_R5G5_SNORM_L6_UNORM
,
1070 WINED3DFMT_R8G8_SNORM_L8X8_UNORM
,
1071 WINED3DFMT_R10G11B11_SNORM
,
1072 WINED3DFMT_R10G10B10_SNORM_A2_UNORM
1075 TRACE("iface %p, callback %p, context %p.\n", iface
, callback
, context
);
1078 return DDERR_INVALIDPARAMS
;
1080 wined3d_mutex_lock();
1082 memset(&mode
, 0, sizeof(mode
));
1083 if (FAILED(hr
= wined3d_get_adapter_display_mode(device
->ddraw
->wined3d
, WINED3DADAPTER_DEFAULT
, &mode
, NULL
)))
1085 wined3d_mutex_unlock();
1086 WARN("Cannot get the current adapter format\n");
1090 for (i
= 0; i
< sizeof(FormatList
) / sizeof(*FormatList
); ++i
)
1092 if (wined3d_check_device_format(device
->ddraw
->wined3d
, WINED3DADAPTER_DEFAULT
, WINED3D_DEVICE_TYPE_HAL
,
1093 mode
.format_id
, WINED3DUSAGE_TEXTURE
, WINED3D_RTYPE_TEXTURE_2D
, FormatList
[i
]) == D3D_OK
)
1095 DDPIXELFORMAT pformat
;
1097 memset(&pformat
, 0, sizeof(pformat
));
1098 pformat
.dwSize
= sizeof(pformat
);
1099 ddrawformat_from_wined3dformat(&pformat
, FormatList
[i
]);
1101 TRACE("Enumerating WineD3DFormat %d\n", FormatList
[i
]);
1102 hr
= callback(&pformat
, context
);
1103 if(hr
!= DDENUMRET_OK
)
1105 TRACE("Format enumeration cancelled by application\n");
1106 wined3d_mutex_unlock();
1112 for (i
= 0; i
< sizeof(BumpFormatList
) / sizeof(*BumpFormatList
); ++i
)
1114 if (wined3d_check_device_format(device
->ddraw
->wined3d
, WINED3DADAPTER_DEFAULT
,
1115 WINED3D_DEVICE_TYPE_HAL
, mode
.format_id
, WINED3DUSAGE_TEXTURE
| WINED3DUSAGE_QUERY_LEGACYBUMPMAP
,
1116 WINED3D_RTYPE_TEXTURE_2D
, BumpFormatList
[i
]) == D3D_OK
)
1118 DDPIXELFORMAT pformat
;
1120 memset(&pformat
, 0, sizeof(pformat
));
1121 pformat
.dwSize
= sizeof(pformat
);
1122 ddrawformat_from_wined3dformat(&pformat
, BumpFormatList
[i
]);
1124 TRACE("Enumerating WineD3DFormat %d\n", BumpFormatList
[i
]);
1125 hr
= callback(&pformat
, context
);
1126 if(hr
!= DDENUMRET_OK
)
1128 TRACE("Format enumeration cancelled by application\n");
1129 wined3d_mutex_unlock();
1134 TRACE("End of enumeration\n");
1135 wined3d_mutex_unlock();
1140 static HRESULT WINAPI
d3d_device7_EnumTextureFormats_FPUSetup(IDirect3DDevice7
*iface
,
1141 LPD3DENUMPIXELFORMATSCALLBACK callback
, void *context
)
1143 return d3d_device7_EnumTextureFormats(iface
, callback
, context
);
1146 static HRESULT WINAPI
d3d_device7_EnumTextureFormats_FPUPreserve(IDirect3DDevice7
*iface
,
1147 LPD3DENUMPIXELFORMATSCALLBACK callback
, void *context
)
1152 old_fpucw
= d3d_fpu_setup();
1153 hr
= d3d_device7_EnumTextureFormats(iface
, callback
, context
);
1154 set_fpu_control_word(old_fpucw
);
1159 static HRESULT WINAPI
d3d_device3_EnumTextureFormats(IDirect3DDevice3
*iface
,
1160 LPD3DENUMPIXELFORMATSCALLBACK callback
, void *context
)
1162 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
1164 TRACE("iface %p, callback %p, context %p.\n", iface
, callback
, context
);
1166 return IDirect3DDevice7_EnumTextureFormats(&device
->IDirect3DDevice7_iface
, callback
, context
);
1169 /*****************************************************************************
1170 * IDirect3DDevice2::EnumTextureformats
1172 * EnumTextureFormats for Version 1 and 2, see
1173 * IDirect3DDevice7::EnumTexureFormats for a more detailed description.
1175 * This version has a different callback and does not enumerate FourCC
1178 *****************************************************************************/
1179 static HRESULT WINAPI
d3d_device2_EnumTextureFormats(IDirect3DDevice2
*iface
,
1180 LPD3DENUMTEXTUREFORMATSCALLBACK callback
, void *context
)
1182 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
1183 struct wined3d_display_mode mode
;
1187 static const enum wined3d_format_id FormatList
[] =
1190 WINED3DFMT_B5G5R5X1_UNORM
,
1191 WINED3DFMT_B5G5R5A1_UNORM
,
1192 WINED3DFMT_B4G4R4A4_UNORM
,
1193 WINED3DFMT_B5G6R5_UNORM
,
1195 WINED3DFMT_B8G8R8X8_UNORM
,
1196 WINED3DFMT_B8G8R8A8_UNORM
,
1198 WINED3DFMT_B2G3R3_UNORM
,
1200 /* FOURCC codes - Not in this version*/
1203 TRACE("iface %p, callback %p, context %p.\n", iface
, callback
, context
);
1206 return DDERR_INVALIDPARAMS
;
1208 wined3d_mutex_lock();
1210 memset(&mode
, 0, sizeof(mode
));
1211 if (FAILED(hr
= wined3d_get_adapter_display_mode(device
->ddraw
->wined3d
, WINED3DADAPTER_DEFAULT
, &mode
, NULL
)))
1213 wined3d_mutex_unlock();
1214 WARN("Cannot get the current adapter format\n");
1218 for (i
= 0; i
< sizeof(FormatList
) / sizeof(*FormatList
); ++i
)
1220 if (wined3d_check_device_format(device
->ddraw
->wined3d
, 0, WINED3D_DEVICE_TYPE_HAL
,
1221 mode
.format_id
, WINED3DUSAGE_TEXTURE
, WINED3D_RTYPE_TEXTURE_2D
, FormatList
[i
]) == D3D_OK
)
1223 DDSURFACEDESC sdesc
;
1225 memset(&sdesc
, 0, sizeof(sdesc
));
1226 sdesc
.dwSize
= sizeof(sdesc
);
1227 sdesc
.dwFlags
= DDSD_PIXELFORMAT
| DDSD_CAPS
;
1228 sdesc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
1229 sdesc
.ddpfPixelFormat
.dwSize
= sizeof(sdesc
.ddpfPixelFormat
);
1230 ddrawformat_from_wined3dformat(&sdesc
.ddpfPixelFormat
, FormatList
[i
]);
1232 TRACE("Enumerating WineD3DFormat %d\n", FormatList
[i
]);
1233 hr
= callback(&sdesc
, context
);
1234 if(hr
!= DDENUMRET_OK
)
1236 TRACE("Format enumeration cancelled by application\n");
1237 wined3d_mutex_unlock();
1242 TRACE("End of enumeration\n");
1243 wined3d_mutex_unlock();
1248 static HRESULT WINAPI
d3d_device1_EnumTextureFormats(IDirect3DDevice
*iface
,
1249 LPD3DENUMTEXTUREFORMATSCALLBACK callback
, void *context
)
1251 struct d3d_device
*device
= impl_from_IDirect3DDevice(iface
);
1253 TRACE("iface %p, callback %p, context %p.\n", iface
, callback
, context
);
1255 return d3d_device2_EnumTextureFormats(&device
->IDirect3DDevice2_iface
, callback
, context
);
1258 /*****************************************************************************
1259 * IDirect3DDevice::CreateMatrix
1261 * Creates a matrix handle. A handle is created and memory for a D3DMATRIX is
1262 * allocated for the handle.
1267 * D3DMatHandle: Address to return the handle at
1271 * DDERR_INVALIDPARAMS if D3DMatHandle = NULL
1273 *****************************************************************************/
1274 static HRESULT WINAPI
d3d_device1_CreateMatrix(IDirect3DDevice
*iface
, D3DMATRIXHANDLE
*D3DMatHandle
)
1276 struct d3d_device
*device
= impl_from_IDirect3DDevice(iface
);
1280 TRACE("iface %p, matrix_handle %p.\n", iface
, D3DMatHandle
);
1283 return DDERR_INVALIDPARAMS
;
1285 Matrix
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(D3DMATRIX
));
1288 ERR("Out of memory when allocating a D3DMATRIX\n");
1289 return DDERR_OUTOFMEMORY
;
1292 wined3d_mutex_lock();
1294 h
= ddraw_allocate_handle(&device
->handle_table
, Matrix
, DDRAW_HANDLE_MATRIX
);
1295 if (h
== DDRAW_INVALID_HANDLE
)
1297 ERR("Failed to allocate a matrix handle.\n");
1298 HeapFree(GetProcessHeap(), 0, Matrix
);
1299 wined3d_mutex_unlock();
1300 return DDERR_OUTOFMEMORY
;
1303 *D3DMatHandle
= h
+ 1;
1305 TRACE(" returning matrix handle %d\n", *D3DMatHandle
);
1307 wined3d_mutex_unlock();
1312 /*****************************************************************************
1313 * IDirect3DDevice::SetMatrix
1315 * Sets a matrix for a matrix handle. The matrix is copied into the memory
1316 * allocated for the handle
1321 * D3DMatHandle: Handle to set the matrix to
1322 * D3DMatrix: Matrix to set
1326 * DDERR_INVALIDPARAMS if the handle of the matrix is invalid or the matrix
1329 *****************************************************************************/
1330 static HRESULT WINAPI
d3d_device1_SetMatrix(IDirect3DDevice
*iface
,
1331 D3DMATRIXHANDLE D3DMatHandle
, D3DMATRIX
*D3DMatrix
)
1333 struct d3d_device
*This
= impl_from_IDirect3DDevice(iface
);
1336 TRACE("iface %p, matrix_handle %#x, matrix %p.\n", iface
, D3DMatHandle
, D3DMatrix
);
1338 if (!D3DMatrix
) return DDERR_INVALIDPARAMS
;
1340 wined3d_mutex_lock();
1342 m
= ddraw_get_object(&This
->handle_table
, D3DMatHandle
- 1, DDRAW_HANDLE_MATRIX
);
1345 WARN("Invalid matrix handle.\n");
1346 wined3d_mutex_unlock();
1347 return DDERR_INVALIDPARAMS
;
1350 if (TRACE_ON(ddraw
))
1351 dump_D3DMATRIX(D3DMatrix
);
1355 if (D3DMatHandle
== This
->world
)
1356 wined3d_device_set_transform(This
->wined3d_device
,
1357 WINED3D_TS_WORLD_MATRIX(0), (struct wined3d_matrix
*)D3DMatrix
);
1359 if (D3DMatHandle
== This
->view
)
1360 wined3d_device_set_transform(This
->wined3d_device
,
1361 WINED3D_TS_VIEW
, (struct wined3d_matrix
*)D3DMatrix
);
1363 if (D3DMatHandle
== This
->proj
)
1364 wined3d_device_set_transform(This
->wined3d_device
,
1365 WINED3D_TS_PROJECTION
, (struct wined3d_matrix
*)D3DMatrix
);
1367 wined3d_mutex_unlock();
1372 /*****************************************************************************
1373 * IDirect3DDevice::GetMatrix
1375 * Returns the content of a D3DMATRIX handle
1380 * D3DMatHandle: Matrix handle to read the content from
1381 * D3DMatrix: Address to store the content at
1385 * DDERR_INVALIDPARAMS if D3DMatHandle is invalid or D3DMatrix is NULL
1387 *****************************************************************************/
1388 static HRESULT WINAPI
d3d_device1_GetMatrix(IDirect3DDevice
*iface
,
1389 D3DMATRIXHANDLE D3DMatHandle
, D3DMATRIX
*D3DMatrix
)
1391 struct d3d_device
*device
= impl_from_IDirect3DDevice(iface
);
1394 TRACE("iface %p, matrix_handle %#x, matrix %p.\n", iface
, D3DMatHandle
, D3DMatrix
);
1396 if (!D3DMatrix
) return DDERR_INVALIDPARAMS
;
1398 wined3d_mutex_lock();
1400 m
= ddraw_get_object(&device
->handle_table
, D3DMatHandle
- 1, DDRAW_HANDLE_MATRIX
);
1403 WARN("Invalid matrix handle.\n");
1404 wined3d_mutex_unlock();
1405 return DDERR_INVALIDPARAMS
;
1410 wined3d_mutex_unlock();
1415 /*****************************************************************************
1416 * IDirect3DDevice::DeleteMatrix
1418 * Destroys a Matrix handle. Frees the memory and unsets the handle data
1423 * D3DMatHandle: Handle to destroy
1427 * DDERR_INVALIDPARAMS if D3DMatHandle is invalid
1429 *****************************************************************************/
1430 static HRESULT WINAPI
d3d_device1_DeleteMatrix(IDirect3DDevice
*iface
, D3DMATRIXHANDLE D3DMatHandle
)
1432 struct d3d_device
*device
= impl_from_IDirect3DDevice(iface
);
1435 TRACE("iface %p, matrix_handle %#x.\n", iface
, D3DMatHandle
);
1437 wined3d_mutex_lock();
1439 m
= ddraw_free_handle(&device
->handle_table
, D3DMatHandle
- 1, DDRAW_HANDLE_MATRIX
);
1442 WARN("Invalid matrix handle.\n");
1443 wined3d_mutex_unlock();
1444 return DDERR_INVALIDPARAMS
;
1447 wined3d_mutex_unlock();
1449 HeapFree(GetProcessHeap(), 0, m
);
1454 /*****************************************************************************
1455 * IDirect3DDevice7::BeginScene
1457 * This method must be called before any rendering is performed.
1458 * IDirect3DDevice::EndScene has to be called after the scene is complete
1460 * Version 1, 2, 3 and 7
1463 * D3D_OK on success,
1464 * D3DERR_SCENE_IN_SCENE if WineD3D returns an error(Only in case of an already
1467 *****************************************************************************/
1468 static HRESULT
d3d_device7_BeginScene(IDirect3DDevice7
*iface
)
1470 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
1473 TRACE("iface %p.\n", iface
);
1475 wined3d_mutex_lock();
1476 hr
= wined3d_device_begin_scene(device
->wined3d_device
);
1477 wined3d_mutex_unlock();
1479 if(hr
== WINED3D_OK
) return D3D_OK
;
1480 else return D3DERR_SCENE_IN_SCENE
; /* TODO: Other possible causes of failure */
1483 static HRESULT WINAPI
d3d_device7_BeginScene_FPUSetup(IDirect3DDevice7
*iface
)
1485 return d3d_device7_BeginScene(iface
);
1488 static HRESULT WINAPI
d3d_device7_BeginScene_FPUPreserve(IDirect3DDevice7
*iface
)
1493 old_fpucw
= d3d_fpu_setup();
1494 hr
= d3d_device7_BeginScene(iface
);
1495 set_fpu_control_word(old_fpucw
);
1500 static HRESULT WINAPI
d3d_device3_BeginScene(IDirect3DDevice3
*iface
)
1502 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
1504 TRACE("iface %p.\n", iface
);
1506 return IDirect3DDevice7_BeginScene(&device
->IDirect3DDevice7_iface
);
1509 static HRESULT WINAPI
d3d_device2_BeginScene(IDirect3DDevice2
*iface
)
1511 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
1513 TRACE("iface %p.\n", iface
);
1515 return IDirect3DDevice7_BeginScene(&device
->IDirect3DDevice7_iface
);
1518 static HRESULT WINAPI
d3d_device1_BeginScene(IDirect3DDevice
*iface
)
1520 struct d3d_device
*device
= impl_from_IDirect3DDevice(iface
);
1522 TRACE("iface %p.\n", iface
);
1524 return IDirect3DDevice7_BeginScene(&device
->IDirect3DDevice7_iface
);
1527 /*****************************************************************************
1528 * IDirect3DDevice7::EndScene
1530 * Ends a scene that has been begun with IDirect3DDevice7::BeginScene.
1531 * This method must be called after rendering is finished.
1533 * Version 1, 2, 3 and 7
1536 * D3D_OK on success,
1537 * D3DERR_SCENE_NOT_IN_SCENE is returned if WineD3D returns an error. It does
1538 * that only if the scene was already ended.
1540 *****************************************************************************/
1541 static HRESULT
d3d_device7_EndScene(IDirect3DDevice7
*iface
)
1543 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
1546 TRACE("iface %p.\n", iface
);
1548 wined3d_mutex_lock();
1549 hr
= wined3d_device_end_scene(device
->wined3d_device
);
1550 wined3d_mutex_unlock();
1552 if(hr
== WINED3D_OK
) return D3D_OK
;
1553 else return D3DERR_SCENE_NOT_IN_SCENE
;
1556 static HRESULT WINAPI DECLSPEC_HOTPATCH
d3d_device7_EndScene_FPUSetup(IDirect3DDevice7
*iface
)
1558 return d3d_device7_EndScene(iface
);
1561 static HRESULT WINAPI DECLSPEC_HOTPATCH
d3d_device7_EndScene_FPUPreserve(IDirect3DDevice7
*iface
)
1566 old_fpucw
= d3d_fpu_setup();
1567 hr
= d3d_device7_EndScene(iface
);
1568 set_fpu_control_word(old_fpucw
);
1573 static HRESULT WINAPI DECLSPEC_HOTPATCH
d3d_device3_EndScene(IDirect3DDevice3
*iface
)
1575 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
1577 TRACE("iface %p.\n", iface
);
1579 return IDirect3DDevice7_EndScene(&device
->IDirect3DDevice7_iface
);
1582 static HRESULT WINAPI DECLSPEC_HOTPATCH
d3d_device2_EndScene(IDirect3DDevice2
*iface
)
1584 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
1586 TRACE("iface %p.\n", iface
);
1588 return IDirect3DDevice7_EndScene(&device
->IDirect3DDevice7_iface
);
1591 static HRESULT WINAPI DECLSPEC_HOTPATCH
d3d_device1_EndScene(IDirect3DDevice
*iface
)
1593 struct d3d_device
*device
= impl_from_IDirect3DDevice(iface
);
1595 TRACE("iface %p.\n", iface
);
1597 return IDirect3DDevice7_EndScene(&device
->IDirect3DDevice7_iface
);
1600 /*****************************************************************************
1601 * IDirect3DDevice7::GetDirect3D
1603 * Returns the IDirect3D(= interface to the DirectDraw object) used to create
1607 * Direct3D7: Address to store the interface pointer at
1611 * DDERR_INVALIDPARAMS if Direct3D7 == NULL
1613 *****************************************************************************/
1614 static HRESULT WINAPI
d3d_device7_GetDirect3D(IDirect3DDevice7
*iface
, IDirect3D7
**d3d
)
1616 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
1618 TRACE("iface %p, d3d %p.\n", iface
, d3d
);
1621 return DDERR_INVALIDPARAMS
;
1623 *d3d
= &device
->ddraw
->IDirect3D7_iface
;
1624 IDirect3D7_AddRef(*d3d
);
1626 TRACE("Returning interface %p.\n", *d3d
);
1630 static HRESULT WINAPI
d3d_device3_GetDirect3D(IDirect3DDevice3
*iface
, IDirect3D3
**d3d
)
1632 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
1634 TRACE("iface %p, d3d %p.\n", iface
, d3d
);
1637 return DDERR_INVALIDPARAMS
;
1639 *d3d
= &device
->ddraw
->IDirect3D3_iface
;
1640 IDirect3D3_AddRef(*d3d
);
1642 TRACE("Returning interface %p.\n", *d3d
);
1646 static HRESULT WINAPI
d3d_device2_GetDirect3D(IDirect3DDevice2
*iface
, IDirect3D2
**d3d
)
1648 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
1650 TRACE("iface %p, d3d %p.\n", iface
, d3d
);
1653 return DDERR_INVALIDPARAMS
;
1655 *d3d
= &device
->ddraw
->IDirect3D2_iface
;
1656 IDirect3D2_AddRef(*d3d
);
1658 TRACE("Returning interface %p.\n", *d3d
);
1662 static HRESULT WINAPI
d3d_device1_GetDirect3D(IDirect3DDevice
*iface
, IDirect3D
**d3d
)
1664 struct d3d_device
*device
= impl_from_IDirect3DDevice(iface
);
1666 TRACE("iface %p, d3d %p.\n", iface
, d3d
);
1669 return DDERR_INVALIDPARAMS
;
1671 *d3d
= &device
->ddraw
->IDirect3D_iface
;
1672 IDirect3D_AddRef(*d3d
);
1674 TRACE("Returning interface %p.\n", *d3d
);
1678 /*****************************************************************************
1679 * IDirect3DDevice3::SetCurrentViewport
1681 * Sets a Direct3DViewport as the current viewport.
1682 * For the thunks note that all viewport interface versions are equal
1685 * Direct3DViewport3: The viewport to set
1691 * (Is a NULL viewport valid?)
1693 *****************************************************************************/
1694 static HRESULT WINAPI
d3d_device3_SetCurrentViewport(IDirect3DDevice3
*iface
, IDirect3DViewport3
*Direct3DViewport3
)
1696 struct d3d_device
*This
= impl_from_IDirect3DDevice3(iface
);
1697 struct d3d_viewport
*vp
= unsafe_impl_from_IDirect3DViewport3(Direct3DViewport3
);
1699 TRACE("iface %p, viewport %p.\n", iface
, Direct3DViewport3
);
1703 WARN("Direct3DViewport3 is NULL, returning DDERR_INVALIDPARAMS\n");
1704 return DDERR_INVALIDPARAMS
;
1707 wined3d_mutex_lock();
1708 /* Do nothing if the specified viewport is the same as the current one */
1709 if (This
->current_viewport
== vp
)
1711 wined3d_mutex_unlock();
1715 if (vp
->active_device
!= This
)
1717 WARN("Viewport %p active device is %p.\n", vp
, vp
->active_device
);
1718 wined3d_mutex_unlock();
1719 return DDERR_INVALIDPARAMS
;
1722 /* Release previous viewport and AddRef the new one */
1723 if (This
->current_viewport
)
1725 TRACE("ViewportImpl is at %p, interface is at %p\n", This
->current_viewport
,
1726 &This
->current_viewport
->IDirect3DViewport3_iface
);
1727 IDirect3DViewport3_Release(&This
->current_viewport
->IDirect3DViewport3_iface
);
1729 IDirect3DViewport3_AddRef(Direct3DViewport3
);
1731 /* Set this viewport as the current viewport */
1732 This
->current_viewport
= vp
;
1734 /* Activate this viewport */
1735 viewport_activate(This
->current_viewport
, FALSE
);
1737 wined3d_mutex_unlock();
1742 static HRESULT WINAPI
d3d_device2_SetCurrentViewport(IDirect3DDevice2
*iface
, IDirect3DViewport2
*viewport
)
1744 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
1745 struct d3d_viewport
*vp
= unsafe_impl_from_IDirect3DViewport2(viewport
);
1747 TRACE("iface %p, viewport %p.\n", iface
, viewport
);
1749 return d3d_device3_SetCurrentViewport(&device
->IDirect3DDevice3_iface
,
1750 vp
? &vp
->IDirect3DViewport3_iface
: NULL
);
1753 /*****************************************************************************
1754 * IDirect3DDevice3::GetCurrentViewport
1756 * Returns the currently active viewport.
1761 * Direct3DViewport3: Address to return the interface pointer at
1765 * DDERR_INVALIDPARAMS if Direct3DViewport == NULL
1767 *****************************************************************************/
1768 static HRESULT WINAPI
d3d_device3_GetCurrentViewport(IDirect3DDevice3
*iface
, IDirect3DViewport3
**viewport
)
1770 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
1772 TRACE("iface %p, viewport %p.\n", iface
, viewport
);
1774 wined3d_mutex_lock();
1775 if (!device
->current_viewport
)
1777 wined3d_mutex_unlock();
1778 WARN("No current viewport, returning D3DERR_NOCURRENTVIEWPORT\n");
1779 return D3DERR_NOCURRENTVIEWPORT
;
1782 *viewport
= &device
->current_viewport
->IDirect3DViewport3_iface
;
1783 IDirect3DViewport3_AddRef(*viewport
);
1785 TRACE("Returning interface %p.\n", *viewport
);
1786 wined3d_mutex_unlock();
1790 static HRESULT WINAPI
d3d_device2_GetCurrentViewport(IDirect3DDevice2
*iface
, IDirect3DViewport2
**viewport
)
1792 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
1794 TRACE("iface %p, viewport %p.\n", iface
, viewport
);
1796 return d3d_device3_GetCurrentViewport(&device
->IDirect3DDevice3_iface
,
1797 (IDirect3DViewport3
**)viewport
);
1800 static BOOL
validate_surface_palette(struct ddraw_surface
*surface
)
1802 return !format_is_paletteindexed(&surface
->surface_desc
.u4
.ddpfPixelFormat
)
1803 || surface
->palette
;
1806 static HRESULT
d3d_device_set_render_target(struct d3d_device
*device
,
1807 struct ddraw_surface
*target
, IUnknown
*rt_iface
)
1811 if (device
->rt_iface
== rt_iface
)
1813 TRACE("No-op SetRenderTarget operation, not doing anything\n");
1818 WARN("Trying to set render target to NULL.\n");
1819 return DDERR_INVALIDPARAMS
;
1822 if (FAILED(hr
= wined3d_device_set_rendertarget_view(device
->wined3d_device
,
1823 0, ddraw_surface_get_rendertarget_view(target
), FALSE
)))
1826 IUnknown_AddRef(rt_iface
);
1827 IUnknown_Release(device
->rt_iface
);
1828 device
->rt_iface
= rt_iface
;
1829 d3d_device_update_depth_stencil(device
);
1834 static HRESULT
d3d_device7_SetRenderTarget(IDirect3DDevice7
*iface
,
1835 IDirectDrawSurface7
*target
, DWORD flags
)
1837 struct ddraw_surface
*target_impl
= unsafe_impl_from_IDirectDrawSurface7(target
);
1838 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
1841 TRACE("iface %p, target %p, flags %#x.\n", iface
, target
, flags
);
1843 wined3d_mutex_lock();
1845 if (!validate_surface_palette(target_impl
))
1847 WARN("Surface %p has an indexed pixel format, but no palette.\n", target_impl
);
1848 wined3d_mutex_unlock();
1849 return DDERR_INVALIDCAPS
;
1852 if (!(target_impl
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_3DDEVICE
))
1854 WARN("Surface %p is not a render target.\n", target_impl
);
1855 wined3d_mutex_unlock();
1856 return DDERR_INVALIDCAPS
;
1859 if (!(target_impl
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_VIDEOMEMORY
))
1861 WARN("Surface %p is not in video memory.\n", target_impl
);
1862 wined3d_mutex_unlock();
1863 return DDERR_INVALIDPARAMS
;
1866 if (target_impl
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_ZBUFFER
)
1868 WARN("Surface %p is a depth buffer.\n", target_impl
);
1869 IDirectDrawSurface7_AddRef(target
);
1870 IUnknown_Release(device
->rt_iface
);
1871 device
->rt_iface
= (IUnknown
*)target
;
1872 wined3d_mutex_unlock();
1873 return DDERR_INVALIDPIXELFORMAT
;
1876 hr
= d3d_device_set_render_target(device
, target_impl
, (IUnknown
*)target
);
1877 wined3d_mutex_unlock();
1881 static HRESULT WINAPI
d3d_device7_SetRenderTarget_FPUSetup(IDirect3DDevice7
*iface
,
1882 IDirectDrawSurface7
*NewTarget
, DWORD flags
)
1884 return d3d_device7_SetRenderTarget(iface
, NewTarget
, flags
);
1887 static HRESULT WINAPI
d3d_device7_SetRenderTarget_FPUPreserve(IDirect3DDevice7
*iface
,
1888 IDirectDrawSurface7
*NewTarget
, DWORD flags
)
1893 old_fpucw
= d3d_fpu_setup();
1894 hr
= d3d_device7_SetRenderTarget(iface
, NewTarget
, flags
);
1895 set_fpu_control_word(old_fpucw
);
1900 static HRESULT WINAPI
d3d_device3_SetRenderTarget(IDirect3DDevice3
*iface
,
1901 IDirectDrawSurface4
*target
, DWORD flags
)
1903 struct ddraw_surface
*target_impl
= unsafe_impl_from_IDirectDrawSurface4(target
);
1904 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
1907 TRACE("iface %p, target %p, flags %#x.\n", iface
, target
, flags
);
1909 wined3d_mutex_lock();
1911 if (!validate_surface_palette(target_impl
))
1913 WARN("Surface %p has an indexed pixel format, but no palette.\n", target_impl
);
1914 wined3d_mutex_unlock();
1915 return DDERR_INVALIDCAPS
;
1918 if (!(target_impl
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_3DDEVICE
))
1920 WARN("Surface %p is not a render target.\n", target_impl
);
1921 wined3d_mutex_unlock();
1922 return DDERR_INVALIDCAPS
;
1925 if (target_impl
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_ZBUFFER
)
1927 WARN("Surface %p is a depth buffer.\n", target_impl
);
1928 IDirectDrawSurface4_AddRef(target
);
1929 IUnknown_Release(device
->rt_iface
);
1930 device
->rt_iface
= (IUnknown
*)target
;
1931 wined3d_mutex_unlock();
1932 return DDERR_INVALIDPIXELFORMAT
;
1935 if (!(target_impl
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_VIDEOMEMORY
))
1937 WARN("Surface %p is not in video memory.\n", target_impl
);
1938 IDirectDrawSurface4_AddRef(target
);
1939 IUnknown_Release(device
->rt_iface
);
1940 device
->rt_iface
= (IUnknown
*)target
;
1941 wined3d_mutex_unlock();
1945 hr
= d3d_device_set_render_target(device
, target_impl
, (IUnknown
*)target
);
1946 wined3d_mutex_unlock();
1950 static HRESULT WINAPI
d3d_device2_SetRenderTarget(IDirect3DDevice2
*iface
,
1951 IDirectDrawSurface
*target
, DWORD flags
)
1953 struct ddraw_surface
*target_impl
= unsafe_impl_from_IDirectDrawSurface(target
);
1954 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
1957 TRACE("iface %p, target %p, flags %#x.\n", iface
, target
, flags
);
1959 wined3d_mutex_lock();
1961 if (!validate_surface_palette(target_impl
))
1963 WARN("Surface %p has an indexed pixel format, but no palette.\n", target_impl
);
1964 wined3d_mutex_unlock();
1965 return DDERR_INVALIDCAPS
;
1968 if (!(target_impl
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_3DDEVICE
))
1970 WARN("Surface %p is not a render target.\n", target_impl
);
1971 wined3d_mutex_unlock();
1972 return DDERR_INVALIDCAPS
;
1975 if (target_impl
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_ZBUFFER
)
1977 WARN("Surface %p is a depth buffer.\n", target_impl
);
1978 IUnknown_Release(device
->rt_iface
);
1979 device
->rt_iface
= (IUnknown
*)target
;
1980 wined3d_mutex_unlock();
1981 return DDERR_INVALIDPIXELFORMAT
;
1984 if (!(target_impl
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_VIDEOMEMORY
))
1986 WARN("Surface %p is not in video memory.\n", target_impl
);
1987 IDirectDrawSurface_AddRef(target
);
1988 IUnknown_Release(device
->rt_iface
);
1989 device
->rt_iface
= (IUnknown
*)target
;
1990 wined3d_mutex_unlock();
1994 hr
= d3d_device_set_render_target(device
, target_impl
, (IUnknown
*)target
);
1995 wined3d_mutex_unlock();
1999 /*****************************************************************************
2000 * IDirect3DDevice7::GetRenderTarget
2002 * Returns the current render target.
2003 * This is handled locally, because the WineD3D render target's parent
2006 * Version 2, 3 and 7
2009 * RenderTarget: Address to store the surface interface pointer
2013 * DDERR_INVALIDPARAMS if RenderTarget == NULL
2015 *****************************************************************************/
2016 static HRESULT WINAPI
d3d_device7_GetRenderTarget(IDirect3DDevice7
*iface
, IDirectDrawSurface7
**RenderTarget
)
2018 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
2021 TRACE("iface %p, target %p.\n", iface
, RenderTarget
);
2024 return DDERR_INVALIDPARAMS
;
2026 wined3d_mutex_lock();
2027 hr
= IUnknown_QueryInterface(device
->rt_iface
, &IID_IDirectDrawSurface7
, (void **)RenderTarget
);
2028 wined3d_mutex_unlock();
2033 static HRESULT WINAPI
d3d_device3_GetRenderTarget(IDirect3DDevice3
*iface
, IDirectDrawSurface4
**RenderTarget
)
2035 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
2036 IDirectDrawSurface7
*RenderTarget7
;
2037 struct ddraw_surface
*RenderTargetImpl
;
2040 TRACE("iface %p, target %p.\n", iface
, RenderTarget
);
2043 return DDERR_INVALIDPARAMS
;
2045 hr
= d3d_device7_GetRenderTarget(&device
->IDirect3DDevice7_iface
, &RenderTarget7
);
2046 if(hr
!= D3D_OK
) return hr
;
2047 RenderTargetImpl
= impl_from_IDirectDrawSurface7(RenderTarget7
);
2048 *RenderTarget
= &RenderTargetImpl
->IDirectDrawSurface4_iface
;
2049 IDirectDrawSurface4_AddRef(*RenderTarget
);
2050 IDirectDrawSurface7_Release(RenderTarget7
);
2054 static HRESULT WINAPI
d3d_device2_GetRenderTarget(IDirect3DDevice2
*iface
, IDirectDrawSurface
**RenderTarget
)
2056 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
2057 IDirectDrawSurface7
*RenderTarget7
;
2058 struct ddraw_surface
*RenderTargetImpl
;
2061 TRACE("iface %p, target %p.\n", iface
, RenderTarget
);
2064 return DDERR_INVALIDPARAMS
;
2066 hr
= d3d_device7_GetRenderTarget(&device
->IDirect3DDevice7_iface
, &RenderTarget7
);
2067 if(hr
!= D3D_OK
) return hr
;
2068 RenderTargetImpl
= impl_from_IDirectDrawSurface7(RenderTarget7
);
2069 *RenderTarget
= &RenderTargetImpl
->IDirectDrawSurface_iface
;
2070 IDirectDrawSurface_AddRef(*RenderTarget
);
2071 IDirectDrawSurface7_Release(RenderTarget7
);
2075 /*****************************************************************************
2076 * IDirect3DDevice3::Begin
2078 * Begins a description block of vertices. This is similar to glBegin()
2079 * and glEnd(). After a call to IDirect3DDevice3::End, the vertices
2080 * described with IDirect3DDevice::Vertex are drawn.
2085 * PrimitiveType: The type of primitives to draw
2086 * VertexTypeDesc: A flexible vertex format description of the vertices
2087 * Flags: Some flags..
2092 *****************************************************************************/
2093 static HRESULT WINAPI
d3d_device3_Begin(IDirect3DDevice3
*iface
,
2094 D3DPRIMITIVETYPE primitive_type
, DWORD fvf
, DWORD flags
)
2096 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
2098 TRACE("iface %p, primitive_type %#x, fvf %#x, flags %#x.\n",
2099 iface
, primitive_type
, fvf
, flags
);
2101 wined3d_mutex_lock();
2102 device
->primitive_type
= primitive_type
;
2103 device
->vertex_type
= fvf
;
2104 device
->render_flags
= flags
;
2105 device
->vertex_size
= get_flexible_vertex_size(device
->vertex_type
);
2106 device
->nb_vertices
= 0;
2107 wined3d_mutex_unlock();
2112 static HRESULT WINAPI
d3d_device2_Begin(IDirect3DDevice2
*iface
,
2113 D3DPRIMITIVETYPE primitive_type
, D3DVERTEXTYPE vertex_type
, DWORD flags
)
2115 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
2118 TRACE("iface %p, primitive_type %#x, vertex_type %#x, flags %#x.\n",
2119 iface
, primitive_type
, vertex_type
, flags
);
2121 switch (vertex_type
)
2123 case D3DVT_VERTEX
: fvf
= D3DFVF_VERTEX
; break;
2124 case D3DVT_LVERTEX
: fvf
= D3DFVF_LVERTEX
; break;
2125 case D3DVT_TLVERTEX
: fvf
= D3DFVF_TLVERTEX
; break;
2127 ERR("Unexpected vertex type %#x.\n", vertex_type
);
2128 return DDERR_INVALIDPARAMS
; /* Should never happen */
2131 return d3d_device3_Begin(&device
->IDirect3DDevice3_iface
, primitive_type
, fvf
, flags
);
2134 /*****************************************************************************
2135 * IDirect3DDevice3::BeginIndexed
2137 * Draws primitives based on vertices in a vertex array which are specified
2143 * PrimitiveType: Primitive type to draw
2144 * VertexType: A FVF description of the vertex format
2145 * Vertices: pointer to an array containing the vertices
2146 * NumVertices: The number of vertices in the vertex array
2147 * Flags: Some flags ...
2150 * D3D_OK, because it's a stub
2152 *****************************************************************************/
2153 static HRESULT WINAPI
d3d_device3_BeginIndexed(IDirect3DDevice3
*iface
,
2154 D3DPRIMITIVETYPE primitive_type
, DWORD fvf
,
2155 void *vertices
, DWORD vertex_count
, DWORD flags
)
2157 FIXME("iface %p, primitive_type %#x, fvf %#x, vertices %p, vertex_count %u, flags %#x stub!\n",
2158 iface
, primitive_type
, fvf
, vertices
, vertex_count
, flags
);
2164 static HRESULT WINAPI
d3d_device2_BeginIndexed(IDirect3DDevice2
*iface
,
2165 D3DPRIMITIVETYPE primitive_type
, D3DVERTEXTYPE vertex_type
,
2166 void *vertices
, DWORD vertex_count
, DWORD flags
)
2168 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
2171 TRACE("iface %p, primitive_type %#x, vertex_type %#x, vertices %p, vertex_count %u, flags %#x stub!\n",
2172 iface
, primitive_type
, vertex_type
, vertices
, vertex_count
, flags
);
2174 switch (vertex_type
)
2176 case D3DVT_VERTEX
: fvf
= D3DFVF_VERTEX
; break;
2177 case D3DVT_LVERTEX
: fvf
= D3DFVF_LVERTEX
; break;
2178 case D3DVT_TLVERTEX
: fvf
= D3DFVF_TLVERTEX
; break;
2180 ERR("Unexpected vertex type %#x.\n", vertex_type
);
2181 return DDERR_INVALIDPARAMS
; /* Should never happen */
2184 return d3d_device3_BeginIndexed(&device
->IDirect3DDevice3_iface
,
2185 primitive_type
, fvf
, vertices
, vertex_count
, flags
);
2188 /*****************************************************************************
2189 * IDirect3DDevice3::Vertex
2191 * Draws a vertex as described by IDirect3DDevice3::Begin. It places all
2192 * drawn vertices in a vertex buffer. If the buffer is too small, its
2193 * size is increased.
2198 * Vertex: Pointer to the vertex
2201 * D3D_OK, on success
2202 * DDERR_INVALIDPARAMS if Vertex is NULL
2204 *****************************************************************************/
2205 static HRESULT WINAPI
d3d_device3_Vertex(IDirect3DDevice3
*iface
, void *vertex
)
2207 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
2209 TRACE("iface %p, vertex %p.\n", iface
, vertex
);
2212 return DDERR_INVALIDPARAMS
;
2214 wined3d_mutex_lock();
2215 if ((device
->nb_vertices
+ 1) * device
->vertex_size
> device
->buffer_size
)
2219 device
->buffer_size
= device
->buffer_size
? device
->buffer_size
* 2 : device
->vertex_size
* 3;
2220 old_buffer
= device
->sysmem_vertex_buffer
;
2221 device
->sysmem_vertex_buffer
= HeapAlloc(GetProcessHeap(), 0, device
->buffer_size
);
2224 memcpy(device
->sysmem_vertex_buffer
, old_buffer
, device
->nb_vertices
* device
->vertex_size
);
2225 HeapFree(GetProcessHeap(), 0, old_buffer
);
2229 memcpy(device
->sysmem_vertex_buffer
+ device
->nb_vertices
++ * device
->vertex_size
, vertex
, device
->vertex_size
);
2230 wined3d_mutex_unlock();
2235 static HRESULT WINAPI
d3d_device2_Vertex(IDirect3DDevice2
*iface
, void *vertex
)
2237 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
2239 TRACE("iface %p, vertex %p.\n", iface
, vertex
);
2241 return d3d_device3_Vertex(&device
->IDirect3DDevice3_iface
, vertex
);
2244 /*****************************************************************************
2245 * IDirect3DDevice3::Index
2247 * Specifies an index to a vertex to be drawn. The vertex array has to
2248 * be specified with BeginIndexed first.
2251 * VertexIndex: The index of the vertex to draw
2254 * D3D_OK because it's a stub
2256 *****************************************************************************/
2257 static HRESULT WINAPI
d3d_device3_Index(IDirect3DDevice3
*iface
, WORD index
)
2259 FIXME("iface %p, index %#x stub!\n", iface
, index
);
2264 static HRESULT WINAPI
d3d_device2_Index(IDirect3DDevice2
*iface
, WORD index
)
2266 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
2268 TRACE("iface %p, index %#x.\n", iface
, index
);
2270 return d3d_device3_Index(&device
->IDirect3DDevice3_iface
, index
);
2273 /*****************************************************************************
2274 * IDirect3DDevice7::GetRenderState
2276 * Returns the value of a render state. The possible render states are
2277 * defined in include/d3dtypes.h
2279 * Version 2, 3 and 7
2282 * RenderStateType: Render state to return the current setting of
2283 * Value: Address to store the value at
2286 * D3D_OK on success,
2287 * DDERR_INVALIDPARAMS if Value == NULL
2289 *****************************************************************************/
2290 static HRESULT
d3d_device7_GetRenderState(IDirect3DDevice7
*iface
,
2291 D3DRENDERSTATETYPE state
, DWORD
*value
)
2293 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
2294 HRESULT hr
= D3D_OK
;
2296 TRACE("iface %p, state %#x, value %p.\n", iface
, state
, value
);
2299 return DDERR_INVALIDPARAMS
;
2301 wined3d_mutex_lock();
2304 case D3DRENDERSTATE_TEXTUREMAG
:
2306 enum wined3d_texture_filter_type tex_mag
;
2308 tex_mag
= wined3d_device_get_sampler_state(device
->wined3d_device
, 0, WINED3D_SAMP_MAG_FILTER
);
2311 case WINED3D_TEXF_POINT
:
2312 *value
= D3DFILTER_NEAREST
;
2314 case WINED3D_TEXF_LINEAR
:
2315 *value
= D3DFILTER_LINEAR
;
2318 ERR("Unhandled texture mag %d !\n",tex_mag
);
2324 case D3DRENDERSTATE_TEXTUREMIN
:
2326 enum wined3d_texture_filter_type tex_min
;
2327 enum wined3d_texture_filter_type tex_mip
;
2329 tex_min
= wined3d_device_get_sampler_state(device
->wined3d_device
, 0, WINED3D_SAMP_MIN_FILTER
);
2330 tex_mip
= wined3d_device_get_sampler_state(device
->wined3d_device
, 0, WINED3D_SAMP_MIP_FILTER
);
2333 case WINED3D_TEXF_POINT
:
2336 case WINED3D_TEXF_NONE
:
2337 *value
= D3DFILTER_NEAREST
;
2339 case WINED3D_TEXF_POINT
:
2340 *value
= D3DFILTER_MIPNEAREST
;
2342 case WINED3D_TEXF_LINEAR
:
2343 *value
= D3DFILTER_LINEARMIPNEAREST
;
2346 ERR("Unhandled mip filter %#x.\n", tex_mip
);
2347 *value
= D3DFILTER_NEAREST
;
2351 case WINED3D_TEXF_LINEAR
:
2354 case WINED3D_TEXF_NONE
:
2355 *value
= D3DFILTER_LINEAR
;
2357 case WINED3D_TEXF_POINT
:
2358 *value
= D3DFILTER_MIPLINEAR
;
2360 case WINED3D_TEXF_LINEAR
:
2361 *value
= D3DFILTER_LINEARMIPLINEAR
;
2364 ERR("Unhandled mip filter %#x.\n", tex_mip
);
2365 *value
= D3DFILTER_LINEAR
;
2370 ERR("Unhandled texture min filter %#x.\n",tex_min
);
2371 *value
= D3DFILTER_NEAREST
;
2377 case D3DRENDERSTATE_TEXTUREADDRESS
:
2378 case D3DRENDERSTATE_TEXTUREADDRESSU
:
2379 *value
= wined3d_device_get_sampler_state(device
->wined3d_device
, 0, WINED3D_SAMP_ADDRESS_U
);
2381 case D3DRENDERSTATE_TEXTUREADDRESSV
:
2382 *value
= wined3d_device_get_sampler_state(device
->wined3d_device
, 0, WINED3D_SAMP_ADDRESS_V
);
2385 case D3DRENDERSTATE_BORDERCOLOR
:
2386 FIXME("Unhandled render state D3DRENDERSTATE_BORDERCOLOR.\n");
2390 case D3DRENDERSTATE_TEXTUREHANDLE
:
2391 case D3DRENDERSTATE_TEXTUREMAPBLEND
:
2392 WARN("Render state %#x is invalid in d3d7.\n", state
);
2393 hr
= DDERR_INVALIDPARAMS
;
2396 case D3DRENDERSTATE_ZBIAS
:
2397 *value
= wined3d_device_get_render_state(device
->wined3d_device
, WINED3D_RS_DEPTHBIAS
);
2401 if (state
>= D3DRENDERSTATE_STIPPLEPATTERN00
2402 && state
<= D3DRENDERSTATE_STIPPLEPATTERN31
)
2404 FIXME("Unhandled stipple pattern render state (%#x).\n", state
);
2408 *value
= wined3d_device_get_render_state(device
->wined3d_device
, state
);
2410 wined3d_mutex_unlock();
2415 static HRESULT WINAPI
d3d_device7_GetRenderState_FPUSetup(IDirect3DDevice7
*iface
,
2416 D3DRENDERSTATETYPE state
, DWORD
*value
)
2418 return d3d_device7_GetRenderState(iface
, state
, value
);
2421 static HRESULT WINAPI
d3d_device7_GetRenderState_FPUPreserve(IDirect3DDevice7
*iface
,
2422 D3DRENDERSTATETYPE state
, DWORD
*value
)
2427 old_fpucw
= d3d_fpu_setup();
2428 hr
= d3d_device7_GetRenderState(iface
, state
, value
);
2429 set_fpu_control_word(old_fpucw
);
2434 static HRESULT WINAPI
d3d_device3_GetRenderState(IDirect3DDevice3
*iface
,
2435 D3DRENDERSTATETYPE state
, DWORD
*value
)
2437 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
2439 TRACE("iface %p, state %#x, value %p.\n", iface
, state
, value
);
2443 case D3DRENDERSTATE_TEXTUREHANDLE
:
2445 /* This state is wrapped to SetTexture in SetRenderState, so
2446 * it has to be wrapped to GetTexture here. */
2447 struct wined3d_texture
*tex
= NULL
;
2450 wined3d_mutex_lock();
2451 if ((tex
= wined3d_device_get_texture(device
->wined3d_device
, 0)))
2453 /* The parent of the texture is the IDirectDrawSurface7
2454 * interface of the ddraw surface. */
2455 struct ddraw_texture
*parent
= wined3d_texture_get_parent(tex
);
2457 *value
= parent
->root
->Handle
;
2459 wined3d_mutex_unlock();
2464 case D3DRENDERSTATE_TEXTUREMAPBLEND
:
2466 /* D3DRENDERSTATE_TEXTUREMAPBLEND is mapped to texture state stages in SetRenderState; reverse
2467 the mapping to get the value. */
2468 DWORD colorop
, colorarg1
, colorarg2
;
2469 DWORD alphaop
, alphaarg1
, alphaarg2
;
2471 wined3d_mutex_lock();
2473 device
->legacyTextureBlending
= TRUE
;
2475 colorop
= wined3d_device_get_texture_stage_state(device
->wined3d_device
, 0, WINED3D_TSS_COLOR_OP
);
2476 colorarg1
= wined3d_device_get_texture_stage_state(device
->wined3d_device
, 0, WINED3D_TSS_COLOR_ARG1
);
2477 colorarg2
= wined3d_device_get_texture_stage_state(device
->wined3d_device
, 0, WINED3D_TSS_COLOR_ARG2
);
2478 alphaop
= wined3d_device_get_texture_stage_state(device
->wined3d_device
, 0, WINED3D_TSS_ALPHA_OP
);
2479 alphaarg1
= wined3d_device_get_texture_stage_state(device
->wined3d_device
, 0, WINED3D_TSS_ALPHA_ARG1
);
2480 alphaarg2
= wined3d_device_get_texture_stage_state(device
->wined3d_device
, 0, WINED3D_TSS_ALPHA_ARG2
);
2482 if (colorop
== WINED3D_TOP_SELECT_ARG1
&& colorarg1
== WINED3DTA_TEXTURE
2483 && alphaop
== WINED3D_TOP_SELECT_ARG1
&& alphaarg1
== WINED3DTA_TEXTURE
)
2484 *value
= D3DTBLEND_DECAL
;
2485 else if (colorop
== WINED3D_TOP_SELECT_ARG1
&& colorarg1
== WINED3DTA_TEXTURE
2486 && alphaop
== WINED3D_TOP_MODULATE
2487 && alphaarg1
== WINED3DTA_TEXTURE
&& alphaarg2
== WINED3DTA_CURRENT
)
2488 *value
= D3DTBLEND_DECALALPHA
;
2489 else if (colorop
== WINED3D_TOP_MODULATE
2490 && colorarg1
== WINED3DTA_TEXTURE
&& colorarg2
== WINED3DTA_CURRENT
2491 && alphaop
== WINED3D_TOP_MODULATE
2492 && alphaarg1
== WINED3DTA_TEXTURE
&& alphaarg2
== WINED3DTA_CURRENT
)
2493 *value
= D3DTBLEND_MODULATEALPHA
;
2496 struct wined3d_texture
*tex
= NULL
;
2497 BOOL tex_alpha
= FALSE
;
2498 DDPIXELFORMAT ddfmt
;
2500 if ((tex
= wined3d_device_get_texture(device
->wined3d_device
, 0)))
2502 struct wined3d_resource_desc desc
;
2504 wined3d_resource_get_desc(wined3d_texture_get_resource(tex
), &desc
);
2505 ddfmt
.dwSize
= sizeof(ddfmt
);
2506 ddrawformat_from_wined3dformat(&ddfmt
, desc
.format
);
2507 if (ddfmt
.u5
.dwRGBAlphaBitMask
)
2511 if (!(colorop
== WINED3D_TOP_MODULATE
2512 && colorarg1
== WINED3DTA_TEXTURE
&& colorarg2
== WINED3DTA_CURRENT
2513 && alphaop
== (tex_alpha
? WINED3D_TOP_SELECT_ARG1
: WINED3D_TOP_SELECT_ARG2
)
2514 && alphaarg1
== WINED3DTA_TEXTURE
&& alphaarg2
== WINED3DTA_CURRENT
))
2515 ERR("Unexpected texture stage state setup, returning D3DTBLEND_MODULATE - likely erroneous.\n");
2517 *value
= D3DTBLEND_MODULATE
;
2520 wined3d_mutex_unlock();
2525 case D3DRENDERSTATE_LIGHTING
:
2526 case D3DRENDERSTATE_NORMALIZENORMALS
:
2527 case D3DRENDERSTATE_LOCALVIEWER
:
2528 *value
= 0xffffffff;
2532 return IDirect3DDevice7_GetRenderState(&device
->IDirect3DDevice7_iface
, state
, value
);
2536 static HRESULT WINAPI
d3d_device2_GetRenderState(IDirect3DDevice2
*iface
,
2537 D3DRENDERSTATETYPE state
, DWORD
*value
)
2539 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
2541 TRACE("iface %p, state %#x, value %p.\n", iface
, state
, value
);
2543 return IDirect3DDevice3_GetRenderState(&device
->IDirect3DDevice3_iface
, state
, value
);
2546 /*****************************************************************************
2547 * IDirect3DDevice7::SetRenderState
2549 * Sets a render state. The possible render states are defined in
2550 * include/d3dtypes.h
2552 * Version 2, 3 and 7
2555 * RenderStateType: State to set
2556 * Value: Value to assign to that state
2558 *****************************************************************************/
2559 static HRESULT
d3d_device7_SetRenderState(IDirect3DDevice7
*iface
,
2560 D3DRENDERSTATETYPE state
, DWORD value
)
2562 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
2563 HRESULT hr
= D3D_OK
;
2565 TRACE("iface %p, state %#x, value %#x.\n", iface
, state
, value
);
2567 wined3d_mutex_lock();
2568 /* Some render states need special care */
2572 * The ddraw texture filter mapping works like this:
2573 * D3DFILTER_NEAREST Point min/mag, no mip
2574 * D3DFILTER_MIPNEAREST Point min/mag, point mip
2575 * D3DFILTER_LINEARMIPNEAREST: Point min/mag, linear mip
2577 * D3DFILTER_LINEAR Linear min/mag, no mip
2578 * D3DFILTER_MIPLINEAR Linear min/mag, point mip
2579 * D3DFILTER_LINEARMIPLINEAR Linear min/mag, linear mip
2581 * This is the opposite of the GL naming convention,
2582 * D3DFILTER_LINEARMIPNEAREST corresponds to GL_NEAREST_MIPMAP_LINEAR.
2584 case D3DRENDERSTATE_TEXTUREMAG
:
2586 enum wined3d_texture_filter_type tex_mag
;
2590 case D3DFILTER_NEAREST
:
2591 case D3DFILTER_MIPNEAREST
:
2592 case D3DFILTER_LINEARMIPNEAREST
:
2593 tex_mag
= WINED3D_TEXF_POINT
;
2595 case D3DFILTER_LINEAR
:
2596 case D3DFILTER_MIPLINEAR
:
2597 case D3DFILTER_LINEARMIPLINEAR
:
2598 tex_mag
= WINED3D_TEXF_LINEAR
;
2601 tex_mag
= WINED3D_TEXF_POINT
;
2602 FIXME("Unhandled texture mag %#x.\n", value
);
2606 wined3d_device_set_sampler_state(device
->wined3d_device
, 0, WINED3D_SAMP_MAG_FILTER
, tex_mag
);
2610 case D3DRENDERSTATE_TEXTUREMIN
:
2612 enum wined3d_texture_filter_type tex_min
;
2613 enum wined3d_texture_filter_type tex_mip
;
2617 case D3DFILTER_NEAREST
:
2618 tex_min
= WINED3D_TEXF_POINT
;
2619 tex_mip
= WINED3D_TEXF_NONE
;
2621 case D3DFILTER_LINEAR
:
2622 tex_min
= WINED3D_TEXF_LINEAR
;
2623 tex_mip
= WINED3D_TEXF_NONE
;
2625 case D3DFILTER_MIPNEAREST
:
2626 tex_min
= WINED3D_TEXF_POINT
;
2627 tex_mip
= WINED3D_TEXF_POINT
;
2629 case D3DFILTER_MIPLINEAR
:
2630 tex_min
= WINED3D_TEXF_LINEAR
;
2631 tex_mip
= WINED3D_TEXF_POINT
;
2633 case D3DFILTER_LINEARMIPNEAREST
:
2634 tex_min
= WINED3D_TEXF_POINT
;
2635 tex_mip
= WINED3D_TEXF_LINEAR
;
2637 case D3DFILTER_LINEARMIPLINEAR
:
2638 tex_min
= WINED3D_TEXF_LINEAR
;
2639 tex_mip
= WINED3D_TEXF_LINEAR
;
2643 FIXME("Unhandled texture min %#x.\n",value
);
2644 tex_min
= WINED3D_TEXF_POINT
;
2645 tex_mip
= WINED3D_TEXF_NONE
;
2649 wined3d_device_set_sampler_state(device
->wined3d_device
,
2650 0, WINED3D_SAMP_MIP_FILTER
, tex_mip
);
2651 wined3d_device_set_sampler_state(device
->wined3d_device
,
2652 0, WINED3D_SAMP_MIN_FILTER
, tex_min
);
2656 case D3DRENDERSTATE_TEXTUREADDRESS
:
2657 wined3d_device_set_sampler_state(device
->wined3d_device
,
2658 0, WINED3D_SAMP_ADDRESS_V
, value
);
2660 case D3DRENDERSTATE_TEXTUREADDRESSU
:
2661 wined3d_device_set_sampler_state(device
->wined3d_device
,
2662 0, WINED3D_SAMP_ADDRESS_U
, value
);
2664 case D3DRENDERSTATE_TEXTUREADDRESSV
:
2665 wined3d_device_set_sampler_state(device
->wined3d_device
,
2666 0, WINED3D_SAMP_ADDRESS_V
, value
);
2669 case D3DRENDERSTATE_BORDERCOLOR
:
2670 /* This should probably just forward to the corresponding sampler
2671 * state. Needs tests. */
2672 FIXME("Unhandled render state D3DRENDERSTATE_BORDERCOLOR.\n");
2676 case D3DRENDERSTATE_TEXTUREHANDLE
:
2677 case D3DRENDERSTATE_TEXTUREMAPBLEND
:
2678 WARN("Render state %#x is invalid in d3d7.\n", state
);
2679 hr
= DDERR_INVALIDPARAMS
;
2682 case D3DRENDERSTATE_ZBIAS
:
2683 wined3d_device_set_render_state(device
->wined3d_device
, WINED3D_RS_DEPTHBIAS
, value
);
2687 if (state
>= D3DRENDERSTATE_STIPPLEPATTERN00
2688 && state
<= D3DRENDERSTATE_STIPPLEPATTERN31
)
2690 FIXME("Unhandled stipple pattern render state (%#x).\n", state
);
2695 wined3d_device_set_render_state(device
->wined3d_device
, state
, value
);
2698 wined3d_mutex_unlock();
2703 static HRESULT WINAPI
d3d_device7_SetRenderState_FPUSetup(IDirect3DDevice7
*iface
,
2704 D3DRENDERSTATETYPE state
, DWORD value
)
2706 return d3d_device7_SetRenderState(iface
, state
, value
);
2709 static HRESULT WINAPI
d3d_device7_SetRenderState_FPUPreserve(IDirect3DDevice7
*iface
,
2710 D3DRENDERSTATETYPE state
, DWORD value
)
2715 old_fpucw
= d3d_fpu_setup();
2716 hr
= d3d_device7_SetRenderState(iface
, state
, value
);
2717 set_fpu_control_word(old_fpucw
);
2722 static HRESULT WINAPI
d3d_device3_SetRenderState(IDirect3DDevice3
*iface
,
2723 D3DRENDERSTATETYPE state
, DWORD value
)
2725 /* Note about D3DRENDERSTATE_TEXTUREMAPBLEND implementation: most of values
2726 for this state can be directly mapped to texture stage colorop and alphaop, but
2727 D3DTBLEND_MODULATE is tricky: it uses alpha from texture when available and alpha
2728 from diffuse otherwise. So changing the texture must be monitored in SetTexture to modify
2729 alphaarg when needed.
2731 Aliens vs Predator 1 depends on accurate D3DTBLEND_MODULATE emulation
2733 Legacy texture blending (TEXTUREMAPBLEND) and texture stage states: directx6 docs state that
2734 TEXTUREMAPBLEND is deprecated, yet can still be used. Games must not use both or results
2735 are undefined. D3DTBLEND_MODULATE mode in particular is dependent on texture pixel format and
2736 requires fixup of stage 0 texture states when texture changes, but this fixup can interfere
2737 with games not using this deprecated state. So a flag 'legacyTextureBlending' has to be kept
2738 in device - TRUE if the app is using TEXTUREMAPBLEND.
2740 Tests show that setting TEXTUREMAPBLEND on native doesn't seem to change values returned by
2741 GetTextureStageState and vice versa. Not so on Wine, but it is 'undefined' anyway so, probably, ok,
2742 unless some broken game will be found that cares. */
2744 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
2747 TRACE("iface %p, state %#x, value %#x.\n", iface
, state
, value
);
2749 if (state
>= D3DSTATE_OVERRIDE_BIAS
)
2751 WARN("Unhandled state %#x.\n", state
);
2752 return DDERR_INVALIDPARAMS
;
2755 wined3d_mutex_lock();
2759 case D3DRENDERSTATE_TEXTUREHANDLE
:
2761 struct ddraw_surface
*surf
;
2765 hr
= wined3d_device_set_texture(device
->wined3d_device
, 0, NULL
);
2769 surf
= ddraw_get_object(&device
->handle_table
, value
- 1, DDRAW_HANDLE_SURFACE
);
2772 WARN("Invalid texture handle.\n");
2773 hr
= DDERR_INVALIDPARAMS
;
2777 hr
= IDirect3DDevice3_SetTexture(iface
, 0, &surf
->IDirect3DTexture2_iface
);
2781 case D3DRENDERSTATE_TEXTUREMAPBLEND
:
2783 device
->legacyTextureBlending
= TRUE
;
2787 case D3DTBLEND_MODULATE
:
2789 struct wined3d_texture
*tex
= NULL
;
2790 BOOL tex_alpha
= FALSE
;
2791 DDPIXELFORMAT ddfmt
;
2793 if ((tex
= wined3d_device_get_texture(device
->wined3d_device
, 0)))
2795 struct wined3d_resource_desc desc
;
2797 wined3d_resource_get_desc(wined3d_texture_get_resource(tex
), &desc
);
2798 ddfmt
.dwSize
= sizeof(ddfmt
);
2799 ddrawformat_from_wined3dformat(&ddfmt
, desc
.format
);
2800 if (ddfmt
.u5
.dwRGBAlphaBitMask
)
2805 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2806 0, WINED3D_TSS_ALPHA_OP
, WINED3D_TOP_SELECT_ARG1
);
2808 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2809 0, WINED3D_TSS_ALPHA_OP
, WINED3D_TOP_SELECT_ARG2
);
2810 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2811 0, WINED3D_TSS_ALPHA_ARG1
, WINED3DTA_TEXTURE
);
2812 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2813 0, WINED3D_TSS_ALPHA_ARG2
, WINED3DTA_CURRENT
);
2814 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2815 0, WINED3D_TSS_COLOR_ARG1
, WINED3DTA_TEXTURE
);
2816 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2817 0, WINED3D_TSS_COLOR_ARG2
, WINED3DTA_CURRENT
);
2818 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2819 0, WINED3D_TSS_COLOR_OP
, WINED3D_TOP_MODULATE
);
2824 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2825 0, WINED3D_TSS_COLOR_OP
, WINED3D_TOP_ADD
);
2826 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2827 0, WINED3D_TSS_COLOR_ARG1
, WINED3DTA_TEXTURE
);
2828 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2829 0, WINED3D_TSS_COLOR_ARG2
, WINED3DTA_CURRENT
);
2830 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2831 0, WINED3D_TSS_ALPHA_OP
, WINED3D_TOP_SELECT_ARG2
);
2832 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2833 0, WINED3D_TSS_ALPHA_ARG2
, WINED3DTA_CURRENT
);
2836 case D3DTBLEND_MODULATEALPHA
:
2837 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2838 0, WINED3D_TSS_COLOR_ARG1
, WINED3DTA_TEXTURE
);
2839 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2840 0, WINED3D_TSS_ALPHA_ARG1
, WINED3DTA_TEXTURE
);
2841 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2842 0, WINED3D_TSS_COLOR_ARG2
, WINED3DTA_CURRENT
);
2843 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2844 0, WINED3D_TSS_ALPHA_ARG2
, WINED3DTA_CURRENT
);
2845 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2846 0, WINED3D_TSS_COLOR_OP
, WINED3D_TOP_MODULATE
);
2847 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2848 0, WINED3D_TSS_ALPHA_OP
, WINED3D_TOP_MODULATE
);
2851 case D3DTBLEND_COPY
:
2852 case D3DTBLEND_DECAL
:
2853 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2854 0, WINED3D_TSS_COLOR_ARG1
, WINED3DTA_TEXTURE
);
2855 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2856 0, WINED3D_TSS_ALPHA_ARG1
, WINED3DTA_TEXTURE
);
2857 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2858 0, WINED3D_TSS_COLOR_OP
, WINED3D_TOP_SELECT_ARG1
);
2859 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2860 0, WINED3D_TSS_ALPHA_OP
, WINED3D_TOP_SELECT_ARG1
);
2863 case D3DTBLEND_DECALALPHA
:
2864 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2865 0, WINED3D_TSS_COLOR_OP
, WINED3D_TOP_BLEND_TEXTURE_ALPHA
);
2866 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2867 0, WINED3D_TSS_COLOR_ARG1
, WINED3DTA_TEXTURE
);
2868 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2869 0, WINED3D_TSS_COLOR_ARG2
, WINED3DTA_CURRENT
);
2870 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2871 0, WINED3D_TSS_ALPHA_OP
, WINED3D_TOP_SELECT_ARG2
);
2872 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2873 0, WINED3D_TSS_ALPHA_ARG2
, WINED3DTA_CURRENT
);
2877 FIXME("Unhandled texture environment %#x.\n", value
);
2884 case D3DRENDERSTATE_LIGHTING
:
2885 case D3DRENDERSTATE_NORMALIZENORMALS
:
2886 case D3DRENDERSTATE_LOCALVIEWER
:
2891 hr
= IDirect3DDevice7_SetRenderState(&device
->IDirect3DDevice7_iface
, state
, value
);
2894 wined3d_mutex_unlock();
2899 static HRESULT WINAPI
d3d_device2_SetRenderState(IDirect3DDevice2
*iface
,
2900 D3DRENDERSTATETYPE state
, DWORD value
)
2902 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
2904 TRACE("iface %p, state %#x, value %#x.\n", iface
, state
, value
);
2906 return IDirect3DDevice3_SetRenderState(&device
->IDirect3DDevice3_iface
, state
, value
);
2909 /*****************************************************************************
2910 * Direct3DDevice3::SetLightState
2912 * Sets a light state for Direct3DDevice3 and Direct3DDevice2. The
2913 * light states are forwarded to Direct3DDevice7 render states
2918 * LightStateType: The light state to change
2919 * Value: The value to assign to that light state
2923 * DDERR_INVALIDPARAMS if the parameters were incorrect
2924 * Also check IDirect3DDevice7::SetRenderState
2926 *****************************************************************************/
2927 static HRESULT WINAPI
d3d_device3_SetLightState(IDirect3DDevice3
*iface
,
2928 D3DLIGHTSTATETYPE state
, DWORD value
)
2930 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
2933 TRACE("iface %p, state %#x, value %#x.\n", iface
, state
, value
);
2935 if (!state
|| (state
> D3DLIGHTSTATE_COLORVERTEX
))
2937 TRACE("Unexpected Light State Type\n");
2938 return DDERR_INVALIDPARAMS
;
2941 wined3d_mutex_lock();
2942 if (state
== D3DLIGHTSTATE_MATERIAL
)
2946 struct d3d_material
*m
;
2948 if (!(m
= ddraw_get_object(&device
->handle_table
, value
- 1, DDRAW_HANDLE_MATERIAL
)))
2950 WARN("Invalid material handle.\n");
2951 wined3d_mutex_unlock();
2952 return DDERR_INVALIDPARAMS
;
2955 material_activate(m
);
2958 device
->material
= value
;
2960 else if (state
== D3DLIGHTSTATE_COLORMODEL
)
2965 ERR("DDCOLOR_MONO should not happen!\n");
2968 /* We are already in this mode */
2969 TRACE("Setting color model to RGB (no-op).\n");
2972 ERR("Unknown color model!\n");
2973 wined3d_mutex_unlock();
2974 return DDERR_INVALIDPARAMS
;
2979 D3DRENDERSTATETYPE rs
;
2982 case D3DLIGHTSTATE_AMBIENT
: /* 2 */
2983 rs
= D3DRENDERSTATE_AMBIENT
;
2985 case D3DLIGHTSTATE_FOGMODE
: /* 4 */
2986 rs
= D3DRENDERSTATE_FOGVERTEXMODE
;
2988 case D3DLIGHTSTATE_FOGSTART
: /* 5 */
2989 rs
= D3DRENDERSTATE_FOGSTART
;
2991 case D3DLIGHTSTATE_FOGEND
: /* 6 */
2992 rs
= D3DRENDERSTATE_FOGEND
;
2994 case D3DLIGHTSTATE_FOGDENSITY
: /* 7 */
2995 rs
= D3DRENDERSTATE_FOGDENSITY
;
2997 case D3DLIGHTSTATE_COLORVERTEX
: /* 8 */
2998 rs
= D3DRENDERSTATE_COLORVERTEX
;
3001 FIXME("Unhandled D3DLIGHTSTATETYPE %#x.\n", state
);
3002 wined3d_mutex_unlock();
3003 return DDERR_INVALIDPARAMS
;
3006 hr
= IDirect3DDevice7_SetRenderState(&device
->IDirect3DDevice7_iface
, rs
, value
);
3007 wined3d_mutex_unlock();
3010 wined3d_mutex_unlock();
3015 static HRESULT WINAPI
d3d_device2_SetLightState(IDirect3DDevice2
*iface
,
3016 D3DLIGHTSTATETYPE state
, DWORD value
)
3018 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
3020 TRACE("iface %p, state %#x, value %#x.\n", iface
, state
, value
);
3022 return d3d_device3_SetLightState(&device
->IDirect3DDevice3_iface
, state
, value
);
3025 /*****************************************************************************
3026 * IDirect3DDevice3::GetLightState
3028 * Returns the current setting of a light state. The state is read from
3029 * the Direct3DDevice7 render state.
3034 * LightStateType: The light state to return
3035 * Value: The address to store the light state setting at
3039 * DDDERR_INVALIDPARAMS if the parameters were incorrect
3040 * Also see IDirect3DDevice7::GetRenderState
3042 *****************************************************************************/
3043 static HRESULT WINAPI
d3d_device3_GetLightState(IDirect3DDevice3
*iface
,
3044 D3DLIGHTSTATETYPE state
, DWORD
*value
)
3046 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
3049 TRACE("iface %p, state %#x, value %p.\n", iface
, state
, value
);
3051 if (!state
|| (state
> D3DLIGHTSTATE_COLORVERTEX
))
3053 TRACE("Unexpected Light State Type\n");
3054 return DDERR_INVALIDPARAMS
;
3058 return DDERR_INVALIDPARAMS
;
3060 wined3d_mutex_lock();
3061 if (state
== D3DLIGHTSTATE_MATERIAL
)
3063 *value
= device
->material
;
3065 else if (state
== D3DLIGHTSTATE_COLORMODEL
)
3067 *value
= D3DCOLOR_RGB
;
3071 D3DRENDERSTATETYPE rs
;
3074 case D3DLIGHTSTATE_AMBIENT
: /* 2 */
3075 rs
= D3DRENDERSTATE_AMBIENT
;
3077 case D3DLIGHTSTATE_FOGMODE
: /* 4 */
3078 rs
= D3DRENDERSTATE_FOGVERTEXMODE
;
3080 case D3DLIGHTSTATE_FOGSTART
: /* 5 */
3081 rs
= D3DRENDERSTATE_FOGSTART
;
3083 case D3DLIGHTSTATE_FOGEND
: /* 6 */
3084 rs
= D3DRENDERSTATE_FOGEND
;
3086 case D3DLIGHTSTATE_FOGDENSITY
: /* 7 */
3087 rs
= D3DRENDERSTATE_FOGDENSITY
;
3089 case D3DLIGHTSTATE_COLORVERTEX
: /* 8 */
3090 rs
= D3DRENDERSTATE_COLORVERTEX
;
3093 FIXME("Unhandled D3DLIGHTSTATETYPE %#x.\n", state
);
3094 wined3d_mutex_unlock();
3095 return DDERR_INVALIDPARAMS
;
3098 hr
= IDirect3DDevice7_GetRenderState(&device
->IDirect3DDevice7_iface
, rs
, value
);
3099 wined3d_mutex_unlock();
3102 wined3d_mutex_unlock();
3107 static HRESULT WINAPI
d3d_device2_GetLightState(IDirect3DDevice2
*iface
,
3108 D3DLIGHTSTATETYPE state
, DWORD
*value
)
3110 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
3112 TRACE("iface %p, state %#x, value %p.\n", iface
, state
, value
);
3114 return d3d_device3_GetLightState(&device
->IDirect3DDevice3_iface
, state
, value
);
3117 /*****************************************************************************
3118 * IDirect3DDevice7::SetTransform
3120 * Assigns a D3DMATRIX to a transform type. The transform types are defined
3121 * in include/d3dtypes.h.
3122 * The D3DTRANSFORMSTATE_WORLD (=1) is translated to D3DTS_WORLDMATRIX(0)
3123 * (=255) for wined3d, because the 1 transform state was removed in d3d8
3124 * and WineD3D already understands the replacement D3DTS_WORLDMATRIX(0)
3126 * Version 2, 3 and 7
3129 * TransformStateType: transform state to set
3130 * Matrix: Matrix to assign to the state
3134 * DDERR_INVALIDPARAMS if Matrix == NULL
3136 *****************************************************************************/
3137 static HRESULT
d3d_device7_SetTransform(IDirect3DDevice7
*iface
,
3138 D3DTRANSFORMSTATETYPE state
, D3DMATRIX
*matrix
)
3140 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
3141 enum wined3d_transform_state wined3d_state
;
3143 TRACE("iface %p, state %#x, matrix %p.\n", iface
, state
, matrix
);
3147 case D3DTRANSFORMSTATE_WORLD
:
3148 wined3d_state
= WINED3D_TS_WORLD_MATRIX(0);
3150 case D3DTRANSFORMSTATE_WORLD1
:
3151 wined3d_state
= WINED3D_TS_WORLD_MATRIX(1);
3153 case D3DTRANSFORMSTATE_WORLD2
:
3154 wined3d_state
= WINED3D_TS_WORLD_MATRIX(2);
3156 case D3DTRANSFORMSTATE_WORLD3
:
3157 wined3d_state
= WINED3D_TS_WORLD_MATRIX(3);
3160 wined3d_state
= state
;
3164 return DDERR_INVALIDPARAMS
;
3166 /* Note: D3DMATRIX is compatible with struct wined3d_matrix. */
3167 wined3d_mutex_lock();
3168 wined3d_device_set_transform(device
->wined3d_device
, wined3d_state
, (struct wined3d_matrix
*)matrix
);
3169 wined3d_mutex_unlock();
3174 static HRESULT WINAPI
d3d_device7_SetTransform_FPUSetup(IDirect3DDevice7
*iface
,
3175 D3DTRANSFORMSTATETYPE state
, D3DMATRIX
*matrix
)
3177 return d3d_device7_SetTransform(iface
, state
, matrix
);
3180 static HRESULT WINAPI
d3d_device7_SetTransform_FPUPreserve(IDirect3DDevice7
*iface
,
3181 D3DTRANSFORMSTATETYPE state
, D3DMATRIX
*matrix
)
3186 old_fpucw
= d3d_fpu_setup();
3187 hr
= d3d_device7_SetTransform(iface
, state
, matrix
);
3188 set_fpu_control_word(old_fpucw
);
3193 static HRESULT WINAPI
d3d_device3_SetTransform(IDirect3DDevice3
*iface
,
3194 D3DTRANSFORMSTATETYPE state
, D3DMATRIX
*matrix
)
3196 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
3198 TRACE("iface %p, state %#x, matrix %p.\n", iface
, state
, matrix
);
3201 return DDERR_INVALIDPARAMS
;
3203 if (state
== D3DTRANSFORMSTATE_PROJECTION
)
3205 D3DMATRIX projection
;
3207 wined3d_mutex_lock();
3208 multiply_matrix(&projection
, &device
->legacy_clipspace
, matrix
);
3209 wined3d_device_set_transform(device
->wined3d_device
,
3210 WINED3D_TS_PROJECTION
, (struct wined3d_matrix
*)&projection
);
3211 device
->legacy_projection
= *matrix
;
3212 wined3d_mutex_unlock();
3217 return IDirect3DDevice7_SetTransform(&device
->IDirect3DDevice7_iface
, state
, matrix
);
3220 static HRESULT WINAPI
d3d_device2_SetTransform(IDirect3DDevice2
*iface
,
3221 D3DTRANSFORMSTATETYPE state
, D3DMATRIX
*matrix
)
3223 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
3225 TRACE("iface %p, state %#x, matrix %p.\n", iface
, state
, matrix
);
3227 return IDirect3DDevice3_SetTransform(&device
->IDirect3DDevice3_iface
, state
, matrix
);
3230 /*****************************************************************************
3231 * IDirect3DDevice7::GetTransform
3233 * Returns the matrix assigned to a transform state
3234 * D3DTRANSFORMSTATE_WORLD is translated to D3DTS_WORLDMATRIX(0), see
3238 * TransformStateType: State to read the matrix from
3239 * Matrix: Address to store the matrix at
3243 * DDERR_INVALIDPARAMS if Matrix == NULL
3245 *****************************************************************************/
3246 static HRESULT
d3d_device7_GetTransform(IDirect3DDevice7
*iface
,
3247 D3DTRANSFORMSTATETYPE state
, D3DMATRIX
*matrix
)
3249 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
3250 enum wined3d_transform_state wined3d_state
;
3252 TRACE("iface %p, state %#x, matrix %p.\n", iface
, state
, matrix
);
3256 case D3DTRANSFORMSTATE_WORLD
:
3257 wined3d_state
= WINED3D_TS_WORLD_MATRIX(0);
3259 case D3DTRANSFORMSTATE_WORLD1
:
3260 wined3d_state
= WINED3D_TS_WORLD_MATRIX(1);
3262 case D3DTRANSFORMSTATE_WORLD2
:
3263 wined3d_state
= WINED3D_TS_WORLD_MATRIX(2);
3265 case D3DTRANSFORMSTATE_WORLD3
:
3266 wined3d_state
= WINED3D_TS_WORLD_MATRIX(3);
3269 wined3d_state
= state
;
3273 return DDERR_INVALIDPARAMS
;
3275 /* Note: D3DMATRIX is compatible with struct wined3d_matrix. */
3276 wined3d_mutex_lock();
3277 wined3d_device_get_transform(device
->wined3d_device
, wined3d_state
, (struct wined3d_matrix
*)matrix
);
3278 wined3d_mutex_unlock();
3283 static HRESULT WINAPI
d3d_device7_GetTransform_FPUSetup(IDirect3DDevice7
*iface
,
3284 D3DTRANSFORMSTATETYPE state
, D3DMATRIX
*matrix
)
3286 return d3d_device7_GetTransform(iface
, state
, matrix
);
3289 static HRESULT WINAPI
d3d_device7_GetTransform_FPUPreserve(IDirect3DDevice7
*iface
,
3290 D3DTRANSFORMSTATETYPE state
, D3DMATRIX
*matrix
)
3295 old_fpucw
= d3d_fpu_setup();
3296 hr
= d3d_device7_GetTransform(iface
, state
, matrix
);
3297 set_fpu_control_word(old_fpucw
);
3302 static HRESULT WINAPI
d3d_device3_GetTransform(IDirect3DDevice3
*iface
,
3303 D3DTRANSFORMSTATETYPE state
, D3DMATRIX
*matrix
)
3305 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
3307 TRACE("iface %p, state %#x, matrix %p.\n", iface
, state
, matrix
);
3310 return DDERR_INVALIDPARAMS
;
3312 if (state
== D3DTRANSFORMSTATE_PROJECTION
)
3314 wined3d_mutex_lock();
3315 *matrix
= device
->legacy_projection
;
3316 wined3d_mutex_unlock();
3320 return IDirect3DDevice7_GetTransform(&device
->IDirect3DDevice7_iface
, state
, matrix
);
3323 static HRESULT WINAPI
d3d_device2_GetTransform(IDirect3DDevice2
*iface
,
3324 D3DTRANSFORMSTATETYPE state
, D3DMATRIX
*matrix
)
3326 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
3328 TRACE("iface %p, state %#x, matrix %p.\n", iface
, state
, matrix
);
3330 return IDirect3DDevice3_GetTransform(&device
->IDirect3DDevice3_iface
, state
, matrix
);
3333 /*****************************************************************************
3334 * IDirect3DDevice7::MultiplyTransform
3336 * Multiplies the already-set transform matrix of a transform state
3337 * with another matrix. For the world matrix, see SetTransform
3339 * Version 2, 3 and 7
3342 * TransformStateType: Transform state to multiply
3343 * D3DMatrix Matrix to multiply with.
3347 * DDERR_INVALIDPARAMS if D3DMatrix is NULL
3349 *****************************************************************************/
3350 static HRESULT
d3d_device7_MultiplyTransform(IDirect3DDevice7
*iface
,
3351 D3DTRANSFORMSTATETYPE state
, D3DMATRIX
*matrix
)
3353 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
3354 enum wined3d_transform_state wined3d_state
;
3356 TRACE("iface %p, state %#x, matrix %p.\n", iface
, state
, matrix
);
3360 case D3DTRANSFORMSTATE_WORLD
:
3361 wined3d_state
= WINED3D_TS_WORLD_MATRIX(0);
3363 case D3DTRANSFORMSTATE_WORLD1
:
3364 wined3d_state
= WINED3D_TS_WORLD_MATRIX(1);
3366 case D3DTRANSFORMSTATE_WORLD2
:
3367 wined3d_state
= WINED3D_TS_WORLD_MATRIX(2);
3369 case D3DTRANSFORMSTATE_WORLD3
:
3370 wined3d_state
= WINED3D_TS_WORLD_MATRIX(3);
3373 wined3d_state
= state
;
3376 /* Note: D3DMATRIX is compatible with struct wined3d_matrix. */
3377 wined3d_mutex_lock();
3378 wined3d_device_multiply_transform(device
->wined3d_device
,
3379 wined3d_state
, (struct wined3d_matrix
*)matrix
);
3380 wined3d_mutex_unlock();
3385 static HRESULT WINAPI
d3d_device7_MultiplyTransform_FPUSetup(IDirect3DDevice7
*iface
,
3386 D3DTRANSFORMSTATETYPE state
, D3DMATRIX
*matrix
)
3388 return d3d_device7_MultiplyTransform(iface
, state
, matrix
);
3391 static HRESULT WINAPI
d3d_device7_MultiplyTransform_FPUPreserve(IDirect3DDevice7
*iface
,
3392 D3DTRANSFORMSTATETYPE state
, D3DMATRIX
*matrix
)
3397 old_fpucw
= d3d_fpu_setup();
3398 hr
= d3d_device7_MultiplyTransform(iface
, state
, matrix
);
3399 set_fpu_control_word(old_fpucw
);
3404 static HRESULT WINAPI
d3d_device3_MultiplyTransform(IDirect3DDevice3
*iface
,
3405 D3DTRANSFORMSTATETYPE state
, D3DMATRIX
*matrix
)
3407 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
3409 TRACE("iface %p, state %#x, matrix %p.\n", iface
, state
, matrix
);
3411 if (state
== D3DTRANSFORMSTATE_PROJECTION
)
3413 D3DMATRIX projection
, tmp
;
3415 wined3d_mutex_lock();
3416 multiply_matrix(&tmp
, &device
->legacy_projection
, matrix
);
3417 multiply_matrix(&projection
, &device
->legacy_clipspace
, &tmp
);
3418 wined3d_device_set_transform(device
->wined3d_device
,
3419 WINED3D_TS_PROJECTION
, (struct wined3d_matrix
*)&projection
);
3420 device
->legacy_projection
= tmp
;
3421 wined3d_mutex_unlock();
3426 return IDirect3DDevice7_MultiplyTransform(&device
->IDirect3DDevice7_iface
, state
, matrix
);
3429 static HRESULT WINAPI
d3d_device2_MultiplyTransform(IDirect3DDevice2
*iface
,
3430 D3DTRANSFORMSTATETYPE state
, D3DMATRIX
*matrix
)
3432 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
3434 TRACE("iface %p, state %#x, matrix %p.\n", iface
, state
, matrix
);
3436 return IDirect3DDevice3_MultiplyTransform(&device
->IDirect3DDevice3_iface
, state
, matrix
);
3439 /*****************************************************************************
3440 * IDirect3DDevice7::DrawPrimitive
3442 * Draws primitives based on vertices in an application-provided pointer
3444 * Version 2, 3 and 7. The IDirect3DDevice2 thunk converts the fixed vertex type into
3445 * an FVF format for D3D7
3448 * PrimitiveType: The type of the primitives to draw
3449 * Vertex type: Flexible vertex format vertex description
3450 * Vertices: Pointer to the vertex array
3451 * VertexCount: The number of vertices to draw
3452 * Flags: As usual a few flags
3456 * DDERR_INVALIDPARAMS if Vertices is NULL
3458 *****************************************************************************/
3460 /* The caller is responsible for wined3d locking */
3461 static HRESULT
d3d_device_prepare_vertex_buffer(struct d3d_device
*device
, UINT min_size
)
3465 if (device
->vertex_buffer_size
< min_size
|| !device
->vertex_buffer
)
3467 UINT size
= max(device
->vertex_buffer_size
* 2, min_size
);
3468 struct wined3d_buffer
*buffer
;
3470 TRACE("Growing vertex buffer to %u bytes\n", size
);
3472 hr
= wined3d_buffer_create_vb(device
->wined3d_device
, size
, WINED3DUSAGE_DYNAMIC
| WINED3DUSAGE_WRITEONLY
,
3473 WINED3D_POOL_DEFAULT
, NULL
, &ddraw_null_wined3d_parent_ops
, &buffer
);
3476 ERR("(%p) wined3d_buffer_create_vb failed with hr = %08x\n", device
, hr
);
3480 if (device
->vertex_buffer
)
3481 wined3d_buffer_decref(device
->vertex_buffer
);
3483 device
->vertex_buffer
= buffer
;
3484 device
->vertex_buffer_size
= size
;
3485 device
->vertex_buffer_pos
= 0;
3490 static HRESULT
d3d_device7_DrawPrimitive(IDirect3DDevice7
*iface
,
3491 D3DPRIMITIVETYPE primitive_type
, DWORD fvf
, void *vertices
,
3492 DWORD vertex_count
, DWORD flags
)
3494 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
3495 struct wined3d_map_desc wined3d_map_desc
;
3496 struct wined3d_box wined3d_box
= {0};
3497 UINT stride
, vb_pos
, size
, align
;
3498 struct wined3d_resource
*vb
;
3501 TRACE("iface %p, primitive_type %#x, fvf %#x, vertices %p, vertex_count %u, flags %#x.\n",
3502 iface
, primitive_type
, fvf
, vertices
, vertex_count
, flags
);
3506 WARN("0 vertex count.\n");
3510 /* Get the stride */
3511 stride
= get_flexible_vertex_size(fvf
);
3512 size
= vertex_count
* stride
;
3514 wined3d_mutex_lock();
3515 hr
= d3d_device_prepare_vertex_buffer(device
, size
);
3519 vb_pos
= device
->vertex_buffer_pos
;
3520 align
= vb_pos
% stride
;
3521 if (align
) align
= stride
- align
;
3522 if (vb_pos
+ size
+ align
> device
->vertex_buffer_size
)
3527 wined3d_box
.left
= vb_pos
;
3528 wined3d_box
.right
= vb_pos
+ size
;
3529 vb
= wined3d_buffer_get_resource(device
->vertex_buffer
);
3530 if (FAILED(hr
= wined3d_resource_map(vb
, 0, &wined3d_map_desc
, &wined3d_box
,
3531 vb_pos
? WINED3D_MAP_NOOVERWRITE
: WINED3D_MAP_DISCARD
)))
3533 memcpy(wined3d_map_desc
.data
, vertices
, size
);
3534 wined3d_resource_unmap(vb
, 0);
3535 device
->vertex_buffer_pos
= vb_pos
+ size
;
3537 hr
= wined3d_device_set_stream_source(device
->wined3d_device
, 0, device
->vertex_buffer
, 0, stride
);
3541 wined3d_device_set_vertex_declaration(device
->wined3d_device
, ddraw_find_decl(device
->ddraw
, fvf
));
3542 wined3d_device_set_primitive_type(device
->wined3d_device
, primitive_type
);
3543 hr
= wined3d_device_draw_primitive(device
->wined3d_device
, vb_pos
/ stride
, vertex_count
);
3546 wined3d_mutex_unlock();
3550 static HRESULT WINAPI
d3d_device7_DrawPrimitive_FPUSetup(IDirect3DDevice7
*iface
,
3551 D3DPRIMITIVETYPE primitive_type
, DWORD fvf
, void *vertices
,
3552 DWORD vertex_count
, DWORD flags
)
3554 return d3d_device7_DrawPrimitive(iface
, primitive_type
, fvf
, vertices
, vertex_count
, flags
);
3557 static HRESULT WINAPI
d3d_device7_DrawPrimitive_FPUPreserve(IDirect3DDevice7
*iface
,
3558 D3DPRIMITIVETYPE primitive_type
, DWORD fvf
, void *vertices
,
3559 DWORD vertex_count
, DWORD flags
)
3564 old_fpucw
= d3d_fpu_setup();
3565 hr
= d3d_device7_DrawPrimitive(iface
, primitive_type
, fvf
, vertices
, vertex_count
, flags
);
3566 set_fpu_control_word(old_fpucw
);
3571 static void setup_lighting(const struct d3d_device
*device
, DWORD fvf
, DWORD flags
)
3575 /* Ignore the D3DFVF_XYZRHW case here, wined3d takes care of that */
3576 if (!device
->material
|| !(fvf
& D3DFVF_NORMAL
) || (flags
& D3DDP_DONOTLIGHT
))
3579 wined3d_device_set_render_state(device
->wined3d_device
, WINED3D_RS_LIGHTING
, enable
);
3583 static HRESULT WINAPI
d3d_device3_DrawPrimitive(IDirect3DDevice3
*iface
,
3584 D3DPRIMITIVETYPE primitive_type
, DWORD fvf
, void *vertices
, DWORD vertex_count
,
3587 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
3589 TRACE("iface %p, primitive_type %#x, fvf %#x, vertices %p, vertex_count %u, flags %#x.\n",
3590 iface
, primitive_type
, fvf
, vertices
, vertex_count
, flags
);
3592 setup_lighting(device
, fvf
, flags
);
3594 return IDirect3DDevice7_DrawPrimitive(&device
->IDirect3DDevice7_iface
,
3595 primitive_type
, fvf
, vertices
, vertex_count
, flags
);
3598 static HRESULT WINAPI
d3d_device2_DrawPrimitive(IDirect3DDevice2
*iface
,
3599 D3DPRIMITIVETYPE primitive_type
, D3DVERTEXTYPE vertex_type
, void *vertices
,
3600 DWORD vertex_count
, DWORD flags
)
3602 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
3605 TRACE("iface %p, primitive_type %#x, vertex_type %#x, vertices %p, vertex_count %u, flags %#x.\n",
3606 iface
, primitive_type
, vertex_type
, vertices
, vertex_count
, flags
);
3608 switch (vertex_type
)
3610 case D3DVT_VERTEX
: fvf
= D3DFVF_VERTEX
; break;
3611 case D3DVT_LVERTEX
: fvf
= D3DFVF_LVERTEX
; break;
3612 case D3DVT_TLVERTEX
: fvf
= D3DFVF_TLVERTEX
; break;
3614 FIXME("Unhandled vertex type %#x.\n", vertex_type
);
3615 return DDERR_INVALIDPARAMS
; /* Should never happen */
3618 return d3d_device3_DrawPrimitive(&device
->IDirect3DDevice3_iface
,
3619 primitive_type
, fvf
, vertices
, vertex_count
, flags
);
3622 /*****************************************************************************
3623 * IDirect3DDevice7::DrawIndexedPrimitive
3625 * Draws vertices from an application-provided pointer, based on the index
3626 * numbers in a WORD array.
3628 * Version 2, 3 and 7. The version 7 thunk translates the vertex type into
3629 * an FVF format for D3D7
3632 * PrimitiveType: The primitive type to draw
3633 * VertexType: The FVF vertex description
3634 * Vertices: Pointer to the vertex array
3636 * Indices: Pointer to the index array
3637 * IndexCount: Number of indices = Number of vertices to draw
3638 * Flags: As usual, some flags
3642 * DDERR_INVALIDPARAMS if Vertices or Indices is NULL
3644 *****************************************************************************/
3645 /* The caller is responsible for wined3d locking */
3646 static HRESULT
d3d_device_prepare_index_buffer(struct d3d_device
*device
, UINT min_size
)
3650 if (device
->index_buffer_size
< min_size
|| !device
->index_buffer
)
3652 UINT size
= max(device
->index_buffer_size
* 2, min_size
);
3653 struct wined3d_buffer
*buffer
;
3655 TRACE("Growing index buffer to %u bytes\n", size
);
3657 hr
= wined3d_buffer_create_ib(device
->wined3d_device
, size
, WINED3DUSAGE_DYNAMIC
| WINED3DUSAGE_WRITEONLY
,
3658 WINED3D_POOL_DEFAULT
, NULL
, &ddraw_null_wined3d_parent_ops
, &buffer
);
3661 ERR("(%p) wined3d_buffer_create_ib failed with hr = %08x\n", device
, hr
);
3665 if (device
->index_buffer
)
3666 wined3d_buffer_decref(device
->index_buffer
);
3667 device
->index_buffer
= buffer
;
3668 device
->index_buffer_size
= size
;
3669 device
->index_buffer_pos
= 0;
3674 static HRESULT
d3d_device7_DrawIndexedPrimitive(IDirect3DDevice7
*iface
,
3675 D3DPRIMITIVETYPE primitive_type
, DWORD fvf
, void *vertices
, DWORD vertex_count
,
3676 WORD
*indices
, DWORD index_count
, DWORD flags
)
3678 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
3680 UINT stride
= get_flexible_vertex_size(fvf
);
3681 UINT vtx_size
= stride
* vertex_count
, idx_size
= index_count
* sizeof(*indices
);
3682 struct wined3d_map_desc wined3d_map_desc
;
3683 struct wined3d_box wined3d_box
= {0};
3684 struct wined3d_resource
*ib
, *vb
;
3685 UINT vb_pos
, ib_pos
, align
;
3687 TRACE("iface %p, primitive_type %#x, fvf %#x, vertices %p, vertex_count %u, "
3688 "indices %p, index_count %u, flags %#x.\n",
3689 iface
, primitive_type
, fvf
, vertices
, vertex_count
, indices
, index_count
, flags
);
3691 if (!vertex_count
|| !index_count
)
3693 WARN("0 vertex or index count.\n");
3697 /* Set the D3DDevice's FVF */
3698 wined3d_mutex_lock();
3700 hr
= d3d_device_prepare_vertex_buffer(device
, vtx_size
);
3704 vb_pos
= device
->vertex_buffer_pos
;
3705 align
= vb_pos
% stride
;
3706 if (align
) align
= stride
- align
;
3707 if (vb_pos
+ vtx_size
+ align
> device
->vertex_buffer_size
)
3712 wined3d_box
.left
= vb_pos
;
3713 wined3d_box
.right
= vb_pos
+ vtx_size
;
3714 vb
= wined3d_buffer_get_resource(device
->vertex_buffer
);
3715 if (FAILED(hr
= wined3d_resource_map(vb
, 0, &wined3d_map_desc
, &wined3d_box
,
3716 vb_pos
? WINED3D_MAP_NOOVERWRITE
: WINED3D_MAP_DISCARD
)))
3718 memcpy(wined3d_map_desc
.data
, vertices
, vtx_size
);
3719 wined3d_resource_unmap(vb
, 0);
3720 device
->vertex_buffer_pos
= vb_pos
+ vtx_size
;
3722 hr
= d3d_device_prepare_index_buffer(device
, idx_size
);
3725 ib_pos
= device
->index_buffer_pos
;
3726 if (device
->index_buffer_size
- idx_size
< ib_pos
)
3729 wined3d_box
.left
= ib_pos
;
3730 wined3d_box
.right
= ib_pos
+ idx_size
;
3731 ib
= wined3d_buffer_get_resource(device
->index_buffer
);
3732 if (FAILED(hr
= wined3d_resource_map(ib
, 0, &wined3d_map_desc
, &wined3d_box
,
3733 ib_pos
? WINED3D_MAP_NOOVERWRITE
: WINED3D_MAP_DISCARD
)))
3735 memcpy(wined3d_map_desc
.data
, indices
, idx_size
);
3736 wined3d_resource_unmap(ib
, 0);
3737 device
->index_buffer_pos
= ib_pos
+ idx_size
;
3739 hr
= wined3d_device_set_stream_source(device
->wined3d_device
, 0, device
->vertex_buffer
, 0, stride
);
3742 wined3d_device_set_index_buffer(device
->wined3d_device
, device
->index_buffer
, WINED3DFMT_R16_UINT
, 0);
3744 wined3d_device_set_vertex_declaration(device
->wined3d_device
, ddraw_find_decl(device
->ddraw
, fvf
));
3745 wined3d_device_set_primitive_type(device
->wined3d_device
, primitive_type
);
3746 wined3d_device_set_base_vertex_index(device
->wined3d_device
, vb_pos
/ stride
);
3747 hr
= wined3d_device_draw_indexed_primitive(device
->wined3d_device
, ib_pos
/ sizeof(*indices
), index_count
);
3750 wined3d_mutex_unlock();
3754 static HRESULT WINAPI
d3d_device7_DrawIndexedPrimitive_FPUSetup(IDirect3DDevice7
*iface
,
3755 D3DPRIMITIVETYPE primitive_type
, DWORD fvf
, void *vertices
, DWORD vertex_count
,
3756 WORD
*indices
, DWORD index_count
, DWORD flags
)
3758 return d3d_device7_DrawIndexedPrimitive(iface
, primitive_type
, fvf
,
3759 vertices
, vertex_count
, indices
, index_count
, flags
);
3762 static HRESULT WINAPI
d3d_device7_DrawIndexedPrimitive_FPUPreserve(IDirect3DDevice7
*iface
,
3763 D3DPRIMITIVETYPE primitive_type
, DWORD fvf
, void *vertices
, DWORD vertex_count
,
3764 WORD
*indices
, DWORD index_count
, DWORD flags
)
3769 old_fpucw
= d3d_fpu_setup();
3770 hr
= d3d_device7_DrawIndexedPrimitive(iface
, primitive_type
, fvf
,
3771 vertices
, vertex_count
, indices
, index_count
, flags
);
3772 set_fpu_control_word(old_fpucw
);
3777 static HRESULT WINAPI
d3d_device3_DrawIndexedPrimitive(IDirect3DDevice3
*iface
,
3778 D3DPRIMITIVETYPE primitive_type
, DWORD fvf
, void *vertices
, DWORD vertex_count
,
3779 WORD
*indices
, DWORD index_count
, DWORD flags
)
3781 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
3783 TRACE("iface %p, primitive_type %#x, fvf %#x, vertices %p, vertex_count %u, "
3784 "indices %p, index_count %u, flags %#x.\n",
3785 iface
, primitive_type
, fvf
, vertices
, vertex_count
, indices
, index_count
, flags
);
3787 setup_lighting(device
, fvf
, flags
);
3789 return IDirect3DDevice7_DrawIndexedPrimitive(&device
->IDirect3DDevice7_iface
,
3790 primitive_type
, fvf
, vertices
, vertex_count
, indices
, index_count
, flags
);
3793 static HRESULT WINAPI
d3d_device2_DrawIndexedPrimitive(IDirect3DDevice2
*iface
,
3794 D3DPRIMITIVETYPE primitive_type
, D3DVERTEXTYPE vertex_type
, void *vertices
,
3795 DWORD vertex_count
, WORD
*indices
, DWORD index_count
, DWORD flags
)
3797 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
3800 TRACE("iface %p, primitive_type %#x, vertex_type %#x, vertices %p, vertex_count %u, "
3801 "indices %p, index_count %u, flags %#x.\n",
3802 iface
, primitive_type
, vertex_type
, vertices
, vertex_count
, indices
, index_count
, flags
);
3804 switch (vertex_type
)
3806 case D3DVT_VERTEX
: fvf
= D3DFVF_VERTEX
; break;
3807 case D3DVT_LVERTEX
: fvf
= D3DFVF_LVERTEX
; break;
3808 case D3DVT_TLVERTEX
: fvf
= D3DFVF_TLVERTEX
; break;
3810 ERR("Unhandled vertex type %#x.\n", vertex_type
);
3811 return DDERR_INVALIDPARAMS
; /* Should never happen */
3814 return d3d_device3_DrawIndexedPrimitive(&device
->IDirect3DDevice3_iface
,
3815 primitive_type
, fvf
, vertices
, vertex_count
, indices
, index_count
, flags
);
3818 /*****************************************************************************
3819 * IDirect3DDevice3::End
3821 * Ends a draw begun with IDirect3DDevice3::Begin or
3822 * IDirect3DDevice::BeginIndexed. The vertices specified with
3823 * IDirect3DDevice::Vertex or IDirect3DDevice::Index are drawn using
3824 * the IDirect3DDevice3::DrawPrimitive method. So far only
3825 * non-indexed mode is supported
3830 * Flags: Some flags, as usual. Don't know which are defined
3833 * The return value of IDirect3DDevice3::DrawPrimitive
3835 *****************************************************************************/
3836 static HRESULT WINAPI
d3d_device3_End(IDirect3DDevice3
*iface
, DWORD flags
)
3838 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
3840 TRACE("iface %p, flags %#x.\n", iface
, flags
);
3842 return d3d_device3_DrawPrimitive(&device
->IDirect3DDevice3_iface
, device
->primitive_type
,
3843 device
->vertex_type
, device
->sysmem_vertex_buffer
, device
->nb_vertices
, device
->render_flags
);
3846 static HRESULT WINAPI
d3d_device2_End(IDirect3DDevice2
*iface
, DWORD flags
)
3848 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
3850 TRACE("iface %p, flags %#x.\n", iface
, flags
);
3852 return d3d_device3_End(&device
->IDirect3DDevice3_iface
, flags
);
3855 /*****************************************************************************
3856 * IDirect3DDevice7::SetClipStatus
3858 * Sets the clip status. This defines things as clipping conditions and
3859 * the extents of the clipping region.
3861 * Version 2, 3 and 7
3867 * D3D_OK because it's a stub
3868 * (DDERR_INVALIDPARAMS if ClipStatus == NULL)
3870 *****************************************************************************/
3871 static HRESULT WINAPI
d3d_device7_SetClipStatus(IDirect3DDevice7
*iface
, D3DCLIPSTATUS
*clip_status
)
3873 FIXME("iface %p, clip_status %p stub!\n", iface
, clip_status
);
3878 static HRESULT WINAPI
d3d_device3_SetClipStatus(IDirect3DDevice3
*iface
, D3DCLIPSTATUS
*clip_status
)
3880 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
3882 TRACE("iface %p, clip_status %p.\n", iface
, clip_status
);
3884 return IDirect3DDevice7_SetClipStatus(&device
->IDirect3DDevice7_iface
, clip_status
);
3887 static HRESULT WINAPI
d3d_device2_SetClipStatus(IDirect3DDevice2
*iface
, D3DCLIPSTATUS
*clip_status
)
3889 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
3891 TRACE("iface %p, clip_status %p.\n", iface
, clip_status
);
3893 return IDirect3DDevice7_SetClipStatus(&device
->IDirect3DDevice7_iface
, clip_status
);
3896 /*****************************************************************************
3897 * IDirect3DDevice7::GetClipStatus
3899 * Returns the clip status
3902 * ClipStatus: Address to write the clip status to
3905 * D3D_OK because it's a stub
3907 *****************************************************************************/
3908 static HRESULT WINAPI
d3d_device7_GetClipStatus(IDirect3DDevice7
*iface
, D3DCLIPSTATUS
*clip_status
)
3910 FIXME("iface %p, clip_status %p stub!\n", iface
, clip_status
);
3915 static HRESULT WINAPI
d3d_device3_GetClipStatus(IDirect3DDevice3
*iface
, D3DCLIPSTATUS
*clip_status
)
3917 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
3919 TRACE("iface %p, clip_status %p.\n", iface
, clip_status
);
3921 return IDirect3DDevice7_GetClipStatus(&device
->IDirect3DDevice7_iface
, clip_status
);
3924 static HRESULT WINAPI
d3d_device2_GetClipStatus(IDirect3DDevice2
*iface
, D3DCLIPSTATUS
*clip_status
)
3926 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
3928 TRACE("iface %p, clip_status %p.\n", iface
, clip_status
);
3930 return IDirect3DDevice7_GetClipStatus(&device
->IDirect3DDevice7_iface
, clip_status
);
3933 /*****************************************************************************
3934 * IDirect3DDevice::DrawPrimitiveStrided
3936 * Draws vertices described by a D3DDRAWPRIMITIVESTRIDEDDATA structure.
3941 * PrimitiveType: The primitive type to draw
3942 * VertexType: The FVF description of the vertices to draw (for the stride??)
3943 * D3DDrawPrimStrideData: A D3DDRAWPRIMITIVESTRIDEDDATA structure describing
3944 * the vertex data locations
3945 * VertexCount: The number of vertices to draw
3949 * D3D_OK, because it's a stub
3950 * (DDERR_INVALIDPARAMS if D3DDrawPrimStrideData is NULL)
3952 *****************************************************************************/
3953 static void pack_strided_data(BYTE
*dst
, DWORD count
, const D3DDRAWPRIMITIVESTRIDEDDATA
*src
, DWORD fvf
)
3955 DWORD i
, tex
, offset
;
3957 for (i
= 0; i
< count
; i
++)
3959 /* The contents of the strided data are determined by the fvf,
3960 * not by the members set in src. So it's valid
3961 * to have diffuse.lpvData set to 0xdeadbeef if the diffuse flag is
3962 * not set in the fvf. */
3963 if (fvf
& D3DFVF_POSITION_MASK
)
3965 offset
= i
* src
->position
.dwStride
;
3966 if (fvf
& D3DFVF_XYZRHW
)
3968 memcpy(dst
, ((BYTE
*)src
->position
.lpvData
) + offset
, 4 * sizeof(float));
3969 dst
+= 4 * sizeof(float);
3973 memcpy(dst
, ((BYTE
*)src
->position
.lpvData
) + offset
, 3 * sizeof(float));
3974 dst
+= 3 * sizeof(float);
3978 if (fvf
& D3DFVF_NORMAL
)
3980 offset
= i
* src
->normal
.dwStride
;
3981 memcpy(dst
, ((BYTE
*)src
->normal
.lpvData
) + offset
, 3 * sizeof(float));
3982 dst
+= 3 * sizeof(float);
3985 if (fvf
& D3DFVF_DIFFUSE
)
3987 offset
= i
* src
->diffuse
.dwStride
;
3988 memcpy(dst
, ((BYTE
*)src
->diffuse
.lpvData
) + offset
, sizeof(DWORD
));
3989 dst
+= sizeof(DWORD
);
3992 if (fvf
& D3DFVF_SPECULAR
)
3994 offset
= i
* src
->specular
.dwStride
;
3995 memcpy(dst
, ((BYTE
*)src
->specular
.lpvData
) + offset
, sizeof(DWORD
));
3996 dst
+= sizeof(DWORD
);
3999 for (tex
= 0; tex
< GET_TEXCOUNT_FROM_FVF(fvf
); ++tex
)
4001 DWORD attrib_count
= GET_TEXCOORD_SIZE_FROM_FVF(fvf
, tex
);
4002 offset
= i
* src
->textureCoords
[tex
].dwStride
;
4003 memcpy(dst
, ((BYTE
*)src
->textureCoords
[tex
].lpvData
) + offset
, attrib_count
* sizeof(float));
4004 dst
+= attrib_count
* sizeof(float);
4009 static HRESULT
d3d_device7_DrawPrimitiveStrided(IDirect3DDevice7
*iface
, D3DPRIMITIVETYPE primitive_type
,
4010 DWORD fvf
, D3DDRAWPRIMITIVESTRIDEDDATA
*strided_data
, DWORD vertex_count
, DWORD flags
)
4012 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
4014 UINT dst_stride
= get_flexible_vertex_size(fvf
);
4015 UINT dst_size
= dst_stride
* vertex_count
;
4016 struct wined3d_map_desc wined3d_map_desc
;
4017 struct wined3d_box wined3d_box
= {0};
4018 struct wined3d_resource
*vb
;
4021 TRACE("iface %p, primitive_type %#x, fvf %#x, strided_data %p, vertex_count %u, flags %#x.\n",
4022 iface
, primitive_type
, fvf
, strided_data
, vertex_count
, flags
);
4026 WARN("0 vertex count.\n");
4030 wined3d_mutex_lock();
4031 hr
= d3d_device_prepare_vertex_buffer(device
, dst_size
);
4035 vb_pos
= device
->vertex_buffer_pos
;
4036 align
= vb_pos
% dst_stride
;
4037 if (align
) align
= dst_stride
- align
;
4038 if (vb_pos
+ dst_size
+ align
> device
->vertex_buffer_size
)
4043 wined3d_box
.left
= vb_pos
;
4044 wined3d_box
.right
= vb_pos
+ dst_size
;
4045 vb
= wined3d_buffer_get_resource(device
->vertex_buffer
);
4046 if (FAILED(hr
= wined3d_resource_map(vb
, 0, &wined3d_map_desc
, &wined3d_box
,
4047 vb_pos
? WINED3D_MAP_NOOVERWRITE
: WINED3D_MAP_DISCARD
)))
4049 pack_strided_data(wined3d_map_desc
.data
, vertex_count
, strided_data
, fvf
);
4050 wined3d_resource_unmap(vb
, 0);
4051 device
->vertex_buffer_pos
= vb_pos
+ dst_size
;
4053 hr
= wined3d_device_set_stream_source(device
->wined3d_device
, 0, device
->vertex_buffer
, 0, dst_stride
);
4056 wined3d_device_set_vertex_declaration(device
->wined3d_device
, ddraw_find_decl(device
->ddraw
, fvf
));
4058 wined3d_device_set_primitive_type(device
->wined3d_device
, primitive_type
);
4059 hr
= wined3d_device_draw_primitive(device
->wined3d_device
, vb_pos
/ dst_stride
, vertex_count
);
4062 wined3d_mutex_unlock();
4066 static HRESULT WINAPI
d3d_device7_DrawPrimitiveStrided_FPUSetup(IDirect3DDevice7
*iface
,
4067 D3DPRIMITIVETYPE PrimitiveType
, DWORD VertexType
,
4068 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
, DWORD VertexCount
, DWORD Flags
)
4070 return d3d_device7_DrawPrimitiveStrided(iface
, PrimitiveType
,
4071 VertexType
, D3DDrawPrimStrideData
, VertexCount
, Flags
);
4074 static HRESULT WINAPI
d3d_device7_DrawPrimitiveStrided_FPUPreserve(IDirect3DDevice7
*iface
,
4075 D3DPRIMITIVETYPE PrimitiveType
, DWORD VertexType
,
4076 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
, DWORD VertexCount
, DWORD Flags
)
4081 old_fpucw
= d3d_fpu_setup();
4082 hr
= d3d_device7_DrawPrimitiveStrided(iface
, PrimitiveType
,
4083 VertexType
, D3DDrawPrimStrideData
, VertexCount
, Flags
);
4084 set_fpu_control_word(old_fpucw
);
4089 static HRESULT WINAPI
d3d_device3_DrawPrimitiveStrided(IDirect3DDevice3
*iface
,
4090 D3DPRIMITIVETYPE PrimitiveType
, DWORD VertexType
,
4091 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
, DWORD VertexCount
, DWORD Flags
)
4093 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
4095 TRACE("iface %p, primitive_type %#x, FVF %#x, strided_data %p, vertex_count %u, flags %#x.\n",
4096 iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Flags
);
4098 setup_lighting(device
, VertexType
, Flags
);
4100 return IDirect3DDevice7_DrawPrimitiveStrided(&device
->IDirect3DDevice7_iface
,
4101 PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Flags
);
4104 /*****************************************************************************
4105 * IDirect3DDevice7::DrawIndexedPrimitiveStrided
4107 * Draws primitives specified by strided data locations based on indices
4115 * D3D_OK, because it's a stub
4116 * (DDERR_INVALIDPARAMS if D3DDrawPrimStrideData is NULL)
4117 * (DDERR_INVALIDPARAMS if Indices is NULL)
4119 *****************************************************************************/
4120 static HRESULT
d3d_device7_DrawIndexedPrimitiveStrided(IDirect3DDevice7
*iface
,
4121 D3DPRIMITIVETYPE primitive_type
, DWORD fvf
, D3DDRAWPRIMITIVESTRIDEDDATA
*strided_data
,
4122 DWORD vertex_count
, WORD
*indices
, DWORD index_count
, DWORD flags
)
4124 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
4125 UINT vtx_dst_stride
= get_flexible_vertex_size(fvf
);
4126 UINT vtx_dst_size
= vertex_count
* vtx_dst_stride
;
4127 UINT idx_size
= index_count
* sizeof(WORD
);
4128 struct wined3d_map_desc wined3d_map_desc
;
4129 struct wined3d_box wined3d_box
= {0};
4130 struct wined3d_resource
*ib
, *vb
;
4135 TRACE("iface %p, primitive_type %#x, fvf %#x, strided_data %p, "
4136 "vertex_count %u, indices %p, index_count %u, flags %#x.\n",
4137 iface
, primitive_type
, fvf
, strided_data
, vertex_count
, indices
, index_count
, flags
);
4139 if (!vertex_count
|| !index_count
)
4141 WARN("0 vertex or index count.\n");
4145 wined3d_mutex_lock();
4147 hr
= d3d_device_prepare_vertex_buffer(device
, vtx_dst_size
);
4151 vb_pos
= device
->vertex_buffer_pos
;
4152 align
= vb_pos
% vtx_dst_stride
;
4153 if (align
) align
= vtx_dst_stride
- align
;
4154 if (vb_pos
+ vtx_dst_size
+ align
> device
->vertex_buffer_size
)
4159 wined3d_box
.left
= vb_pos
;
4160 wined3d_box
.right
= vb_pos
+ vtx_dst_size
;
4161 vb
= wined3d_buffer_get_resource(device
->vertex_buffer
);
4162 if (FAILED(hr
= wined3d_resource_map(vb
, 0, &wined3d_map_desc
, &wined3d_box
,
4163 vb_pos
? WINED3D_MAP_NOOVERWRITE
: WINED3D_MAP_DISCARD
)))
4165 pack_strided_data(wined3d_map_desc
.data
, vertex_count
, strided_data
, fvf
);
4166 wined3d_resource_unmap(vb
, 0);
4167 device
->vertex_buffer_pos
= vb_pos
+ vtx_dst_size
;
4169 hr
= d3d_device_prepare_index_buffer(device
, idx_size
);
4172 ib_pos
= device
->index_buffer_pos
;
4173 if (device
->index_buffer_size
- idx_size
< ib_pos
)
4176 wined3d_box
.left
= ib_pos
;
4177 wined3d_box
.right
= ib_pos
+ idx_size
;
4178 ib
= wined3d_buffer_get_resource(device
->index_buffer
);
4179 if (FAILED(hr
= wined3d_resource_map(ib
, 0, &wined3d_map_desc
, &wined3d_box
,
4180 ib_pos
? WINED3D_MAP_NOOVERWRITE
: WINED3D_MAP_DISCARD
)))
4182 memcpy(wined3d_map_desc
.data
, indices
, idx_size
);
4183 wined3d_resource_unmap(ib
, 0);
4184 device
->index_buffer_pos
= ib_pos
+ idx_size
;
4186 hr
= wined3d_device_set_stream_source(device
->wined3d_device
, 0, device
->vertex_buffer
, 0, vtx_dst_stride
);
4189 wined3d_device_set_index_buffer(device
->wined3d_device
, device
->index_buffer
, WINED3DFMT_R16_UINT
, 0);
4190 wined3d_device_set_base_vertex_index(device
->wined3d_device
, vb_pos
/ vtx_dst_stride
);
4192 wined3d_device_set_vertex_declaration(device
->wined3d_device
, ddraw_find_decl(device
->ddraw
, fvf
));
4193 wined3d_device_set_primitive_type(device
->wined3d_device
, primitive_type
);
4194 hr
= wined3d_device_draw_indexed_primitive(device
->wined3d_device
, ib_pos
/ sizeof(WORD
), index_count
);
4197 wined3d_mutex_unlock();
4201 static HRESULT WINAPI
d3d_device7_DrawIndexedPrimitiveStrided_FPUSetup(IDirect3DDevice7
*iface
,
4202 D3DPRIMITIVETYPE PrimitiveType
, DWORD VertexType
,
4203 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
, DWORD VertexCount
,
4204 WORD
*Indices
, DWORD IndexCount
, DWORD Flags
)
4206 return d3d_device7_DrawIndexedPrimitiveStrided(iface
, PrimitiveType
, VertexType
,
4207 D3DDrawPrimStrideData
, VertexCount
, Indices
, IndexCount
, Flags
);
4210 static HRESULT WINAPI
d3d_device7_DrawIndexedPrimitiveStrided_FPUPreserve(IDirect3DDevice7
*iface
,
4211 D3DPRIMITIVETYPE PrimitiveType
, DWORD VertexType
,
4212 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
, DWORD VertexCount
,
4213 WORD
*Indices
, DWORD IndexCount
, DWORD Flags
)
4218 old_fpucw
= d3d_fpu_setup();
4219 hr
= d3d_device7_DrawIndexedPrimitiveStrided(iface
, PrimitiveType
, VertexType
,
4220 D3DDrawPrimStrideData
, VertexCount
, Indices
, IndexCount
, Flags
);
4221 set_fpu_control_word(old_fpucw
);
4226 static HRESULT WINAPI
d3d_device3_DrawIndexedPrimitiveStrided(IDirect3DDevice3
*iface
,
4227 D3DPRIMITIVETYPE PrimitiveType
, DWORD VertexType
,
4228 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
, DWORD VertexCount
, WORD
*Indices
,
4229 DWORD IndexCount
, DWORD Flags
)
4231 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
4233 TRACE("iface %p, primitive_type %#x, FVF %#x, strided_data %p, vertex_count %u, indices %p, index_count %u, flags %#x.\n",
4234 iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Indices
, IndexCount
, Flags
);
4236 setup_lighting(device
, VertexType
, Flags
);
4238 return IDirect3DDevice7_DrawIndexedPrimitiveStrided(&device
->IDirect3DDevice7_iface
,
4239 PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Indices
, IndexCount
, Flags
);
4242 /*****************************************************************************
4243 * IDirect3DDevice7::DrawPrimitiveVB
4245 * Draws primitives from a vertex buffer to the screen.
4250 * PrimitiveType: Type of primitive to be rendered.
4251 * D3DVertexBuf: Source Vertex Buffer
4252 * StartVertex: Index of the first vertex from the buffer to be rendered
4253 * NumVertices: Number of vertices to be rendered
4254 * Flags: Can be D3DDP_WAIT to wait until rendering has finished
4258 * DDERR_INVALIDPARAMS if D3DVertexBuf is NULL
4260 *****************************************************************************/
4261 static HRESULT
d3d_device7_DrawPrimitiveVB(IDirect3DDevice7
*iface
, D3DPRIMITIVETYPE primitive_type
,
4262 IDirect3DVertexBuffer7
*vb
, DWORD start_vertex
, DWORD vertex_count
, DWORD flags
)
4264 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
4265 struct d3d_vertex_buffer
*vb_impl
= unsafe_impl_from_IDirect3DVertexBuffer7(vb
);
4269 TRACE("iface %p, primitive_type %#x, vb %p, start_vertex %u, vertex_count %u, flags %#x.\n",
4270 iface
, primitive_type
, vb
, start_vertex
, vertex_count
, flags
);
4274 WARN("0 vertex count.\n");
4278 stride
= get_flexible_vertex_size(vb_impl
->fvf
);
4280 wined3d_mutex_lock();
4281 wined3d_device_set_vertex_declaration(device
->wined3d_device
, vb_impl
->wined3d_declaration
);
4282 if (FAILED(hr
= wined3d_device_set_stream_source(device
->wined3d_device
,
4283 0, vb_impl
->wined3d_buffer
, 0, stride
)))
4285 WARN("Failed to set stream source, hr %#x.\n", hr
);
4286 wined3d_mutex_unlock();
4290 /* Now draw the primitives */
4291 wined3d_device_set_primitive_type(device
->wined3d_device
, primitive_type
);
4292 hr
= wined3d_device_draw_primitive(device
->wined3d_device
, start_vertex
, vertex_count
);
4294 wined3d_mutex_unlock();
4299 static HRESULT WINAPI
d3d_device7_DrawPrimitiveVB_FPUSetup(IDirect3DDevice7
*iface
, D3DPRIMITIVETYPE PrimitiveType
,
4300 IDirect3DVertexBuffer7
*D3DVertexBuf
, DWORD StartVertex
, DWORD NumVertices
, DWORD Flags
)
4302 return d3d_device7_DrawPrimitiveVB(iface
, PrimitiveType
, D3DVertexBuf
, StartVertex
, NumVertices
, Flags
);
4305 static HRESULT WINAPI
d3d_device7_DrawPrimitiveVB_FPUPreserve(IDirect3DDevice7
*iface
, D3DPRIMITIVETYPE PrimitiveType
,
4306 IDirect3DVertexBuffer7
*D3DVertexBuf
, DWORD StartVertex
, DWORD NumVertices
, DWORD Flags
)
4311 old_fpucw
= d3d_fpu_setup();
4312 hr
= d3d_device7_DrawPrimitiveVB(iface
, PrimitiveType
, D3DVertexBuf
, StartVertex
, NumVertices
, Flags
);
4313 set_fpu_control_word(old_fpucw
);
4318 static HRESULT WINAPI
d3d_device3_DrawPrimitiveVB(IDirect3DDevice3
*iface
, D3DPRIMITIVETYPE PrimitiveType
,
4319 IDirect3DVertexBuffer
*D3DVertexBuf
, DWORD StartVertex
, DWORD NumVertices
, DWORD Flags
)
4321 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
4322 struct d3d_vertex_buffer
*vb
= unsafe_impl_from_IDirect3DVertexBuffer7((IDirect3DVertexBuffer7
*)D3DVertexBuf
);
4324 TRACE("iface %p, primitive_type %#x, vb %p, start_vertex %u, vertex_count %u, flags %#x.\n",
4325 iface
, PrimitiveType
, D3DVertexBuf
, StartVertex
, NumVertices
, Flags
);
4327 setup_lighting(device
, vb
->fvf
, Flags
);
4329 return IDirect3DDevice7_DrawPrimitiveVB(&device
->IDirect3DDevice7_iface
,
4330 PrimitiveType
, &vb
->IDirect3DVertexBuffer7_iface
, StartVertex
, NumVertices
, Flags
);
4333 /*****************************************************************************
4334 * IDirect3DDevice7::DrawIndexedPrimitiveVB
4336 * Draws primitives from a vertex buffer to the screen
4339 * PrimitiveType: Type of primitive to be rendered.
4340 * D3DVertexBuf: Source Vertex Buffer
4341 * StartVertex: Index of the first vertex from the buffer to be rendered
4342 * NumVertices: Number of vertices to be rendered
4343 * Indices: Array of DWORDs used to index into the Vertices
4344 * IndexCount: Number of indices in Indices
4345 * Flags: Can be D3DDP_WAIT to wait until rendering has finished
4349 *****************************************************************************/
4350 static HRESULT
d3d_device7_DrawIndexedPrimitiveVB(IDirect3DDevice7
*iface
,
4351 D3DPRIMITIVETYPE primitive_type
, IDirect3DVertexBuffer7
*vb
,
4352 DWORD start_vertex
, DWORD vertex_count
, WORD
*indices
, DWORD index_count
, DWORD flags
)
4354 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
4355 struct d3d_vertex_buffer
*vb_impl
= unsafe_impl_from_IDirect3DVertexBuffer7(vb
);
4356 DWORD stride
= get_flexible_vertex_size(vb_impl
->fvf
);
4357 struct wined3d_map_desc wined3d_map_desc
;
4358 struct wined3d_box wined3d_box
= {0};
4359 struct wined3d_resource
*ib
;
4363 TRACE("iface %p, primitive_type %#x, vb %p, start_vertex %u, "
4364 "vertex_count %u, indices %p, index_count %u, flags %#x.\n",
4365 iface
, primitive_type
, vb
, start_vertex
, vertex_count
, indices
, index_count
, flags
);
4367 if (!vertex_count
|| !index_count
)
4369 WARN("0 vertex or index count.\n");
4374 * 1) Upload the indices to the index buffer
4375 * 2) Set the index source
4376 * 3) Set the Vertex Buffer as the Stream source
4377 * 4) Call wined3d_device_draw_indexed_primitive()
4380 wined3d_mutex_lock();
4382 wined3d_device_set_vertex_declaration(device
->wined3d_device
, vb_impl
->wined3d_declaration
);
4384 hr
= d3d_device_prepare_index_buffer(device
, index_count
* sizeof(WORD
));
4387 wined3d_mutex_unlock();
4390 ib_pos
= device
->index_buffer_pos
;
4392 if (device
->index_buffer_size
- index_count
* sizeof(WORD
) < ib_pos
)
4395 /* Copy the index stream into the index buffer. */
4396 wined3d_box
.left
= ib_pos
;
4397 wined3d_box
.right
= ib_pos
+ index_count
* sizeof(WORD
);
4398 ib
= wined3d_buffer_get_resource(device
->index_buffer
);
4399 if (FAILED(hr
= wined3d_resource_map(ib
, 0, &wined3d_map_desc
, &wined3d_box
,
4400 ib_pos
? WINED3D_MAP_NOOVERWRITE
: WINED3D_MAP_DISCARD
)))
4402 ERR("Failed to map buffer, hr %#x.\n", hr
);
4403 wined3d_mutex_unlock();
4406 memcpy(wined3d_map_desc
.data
, indices
, index_count
* sizeof(WORD
));
4407 wined3d_resource_unmap(ib
, 0);
4408 device
->index_buffer_pos
= ib_pos
+ index_count
* sizeof(WORD
);
4410 /* Set the index stream */
4411 wined3d_device_set_base_vertex_index(device
->wined3d_device
, start_vertex
);
4412 wined3d_device_set_index_buffer(device
->wined3d_device
, device
->index_buffer
, WINED3DFMT_R16_UINT
, 0);
4414 /* Set the vertex stream source */
4415 if (FAILED(hr
= wined3d_device_set_stream_source(device
->wined3d_device
,
4416 0, vb_impl
->wined3d_buffer
, 0, stride
)))
4418 ERR("(%p) IDirect3DDevice::SetStreamSource failed with hr = %08x\n", device
, hr
);
4419 wined3d_mutex_unlock();
4423 wined3d_device_set_primitive_type(device
->wined3d_device
, primitive_type
);
4424 hr
= wined3d_device_draw_indexed_primitive(device
->wined3d_device
, ib_pos
/ sizeof(WORD
), index_count
);
4426 wined3d_mutex_unlock();
4431 static HRESULT WINAPI
d3d_device7_DrawIndexedPrimitiveVB_FPUSetup(IDirect3DDevice7
*iface
,
4432 D3DPRIMITIVETYPE PrimitiveType
, IDirect3DVertexBuffer7
*D3DVertexBuf
,
4433 DWORD StartVertex
, DWORD NumVertices
, WORD
*Indices
, DWORD IndexCount
, DWORD Flags
)
4435 return d3d_device7_DrawIndexedPrimitiveVB(iface
, PrimitiveType
,
4436 D3DVertexBuf
, StartVertex
, NumVertices
, Indices
, IndexCount
, Flags
);
4439 static HRESULT WINAPI
d3d_device7_DrawIndexedPrimitiveVB_FPUPreserve(IDirect3DDevice7
*iface
,
4440 D3DPRIMITIVETYPE PrimitiveType
, IDirect3DVertexBuffer7
*D3DVertexBuf
,
4441 DWORD StartVertex
, DWORD NumVertices
, WORD
*Indices
, DWORD IndexCount
, DWORD Flags
)
4446 old_fpucw
= d3d_fpu_setup();
4447 hr
= d3d_device7_DrawIndexedPrimitiveVB(iface
, PrimitiveType
,
4448 D3DVertexBuf
, StartVertex
, NumVertices
, Indices
, IndexCount
, Flags
);
4449 set_fpu_control_word(old_fpucw
);
4454 static HRESULT WINAPI
d3d_device3_DrawIndexedPrimitiveVB(IDirect3DDevice3
*iface
,
4455 D3DPRIMITIVETYPE PrimitiveType
, IDirect3DVertexBuffer
*D3DVertexBuf
, WORD
*Indices
,
4456 DWORD IndexCount
, DWORD Flags
)
4458 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
4459 struct d3d_vertex_buffer
*vb
= unsafe_impl_from_IDirect3DVertexBuffer7((IDirect3DVertexBuffer7
*)D3DVertexBuf
);
4461 TRACE("iface %p, primitive_type %#x, vb %p, indices %p, index_count %u, flags %#x.\n",
4462 iface
, PrimitiveType
, D3DVertexBuf
, Indices
, IndexCount
, Flags
);
4464 setup_lighting(device
, vb
->fvf
, Flags
);
4466 return IDirect3DDevice7_DrawIndexedPrimitiveVB(&device
->IDirect3DDevice7_iface
, PrimitiveType
,
4467 &vb
->IDirect3DVertexBuffer7_iface
, 0, IndexCount
, Indices
, IndexCount
, Flags
);
4470 /*****************************************************************************
4471 * IDirect3DDevice7::ComputeSphereVisibility
4473 * Calculates the visibility of spheres in the current viewport. The spheres
4474 * are passed in the Centers and Radii arrays, the results are passed back
4475 * in the ReturnValues array. Return values are either completely visible,
4476 * partially visible or completely invisible.
4477 * The return value consists of a combination of D3DCLIP_* flags, or is
4478 * 0 if the sphere is completely visible (according to the SDK, not checked)
4483 * Centers: Array containing the sphere centers
4484 * Radii: Array containing the sphere radii
4485 * NumSpheres: The number of centers and radii in the arrays
4487 * ReturnValues: Array to write the results to
4491 * (DDERR_INVALIDPARAMS if Centers, Radii or ReturnValues are NULL)
4492 * (D3DERR_INVALIDMATRIX if the combined world, view and proj matrix
4495 *****************************************************************************/
4497 static DWORD
in_plane(UINT idx
, struct wined3d_vec4 p
, D3DVECTOR center
, D3DVALUE radius
, BOOL equality
)
4499 float distance
, norm
;
4501 norm
= sqrtf(p
.x
* p
.x
+ p
.y
* p
.y
+ p
.z
* p
.z
);
4502 distance
= (p
.x
* center
.u1
.x
+ p
.y
* center
.u2
.y
+ p
.z
* center
.u3
.z
+ p
.w
) / norm
;
4506 if (fabs(distance
) <= radius
)
4507 return D3DSTATUS_CLIPUNIONLEFT
<< idx
;
4508 if (distance
<= -radius
)
4509 return (D3DSTATUS_CLIPUNIONLEFT
| D3DSTATUS_CLIPINTERSECTIONLEFT
) << idx
;
4513 if (fabs(distance
) < radius
)
4514 return D3DSTATUS_CLIPUNIONLEFT
<< idx
;
4515 if (distance
< -radius
)
4516 return (D3DSTATUS_CLIPUNIONLEFT
| D3DSTATUS_CLIPINTERSECTIONLEFT
) << idx
;
4521 static void prepare_clip_space_planes(struct d3d_device
*device
, struct wined3d_vec4
*plane
)
4525 /* We want the wined3d matrices since those include the legacy viewport
4526 * transformation. */
4527 wined3d_mutex_lock();
4528 wined3d_device_get_transform(device
->wined3d_device
,
4529 WINED3D_TS_WORLD
, (struct wined3d_matrix
*)&m
);
4531 wined3d_device_get_transform(device
->wined3d_device
,
4532 WINED3D_TS_VIEW
, (struct wined3d_matrix
*)&temp
);
4533 multiply_matrix(&m
, &temp
, &m
);
4535 wined3d_device_get_transform(device
->wined3d_device
,
4536 WINED3D_TS_PROJECTION
, (struct wined3d_matrix
*)&temp
);
4537 multiply_matrix(&m
, &temp
, &m
);
4538 wined3d_mutex_unlock();
4541 plane
[0].x
= m
._14
+ m
._11
;
4542 plane
[0].y
= m
._24
+ m
._21
;
4543 plane
[0].z
= m
._34
+ m
._31
;
4544 plane
[0].w
= m
._44
+ m
._41
;
4547 plane
[1].x
= m
._14
- m
._11
;
4548 plane
[1].y
= m
._24
- m
._21
;
4549 plane
[1].z
= m
._34
- m
._31
;
4550 plane
[1].w
= m
._44
- m
._41
;
4553 plane
[2].x
= m
._14
- m
._12
;
4554 plane
[2].y
= m
._24
- m
._22
;
4555 plane
[2].z
= m
._34
- m
._32
;
4556 plane
[2].w
= m
._44
- m
._42
;
4559 plane
[3].x
= m
._14
+ m
._12
;
4560 plane
[3].y
= m
._24
+ m
._22
;
4561 plane
[3].z
= m
._34
+ m
._32
;
4562 plane
[3].w
= m
._44
+ m
._42
;
4571 plane
[5].x
= m
._14
- m
._13
;
4572 plane
[5].y
= m
._24
- m
._23
;
4573 plane
[5].z
= m
._34
- m
._33
;
4574 plane
[5].w
= m
._44
- m
._43
;
4577 static void compute_sphere_visibility(struct wined3d_vec4 plane
[12], DWORD enabled_planes
, BOOL equality
,
4578 D3DVECTOR
*centers
, D3DVALUE
*radii
, DWORD sphere_count
, DWORD
*return_values
)
4582 for (i
= 0; i
< sphere_count
; ++i
)
4584 return_values
[i
] = 0;
4585 for (j
= 0; j
< 12; ++j
)
4586 if (enabled_planes
& 1u << j
)
4587 return_values
[i
] |= in_plane(j
, plane
[j
], centers
[i
], radii
[i
], equality
);
4591 static HRESULT WINAPI
d3d_device7_ComputeSphereVisibility(IDirect3DDevice7
*iface
,
4592 D3DVECTOR
*centers
, D3DVALUE
*radii
, DWORD sphere_count
, DWORD flags
, DWORD
*return_values
)
4594 struct wined3d_vec4 plane
[12];
4595 DWORD enabled_planes
= 0x3f;
4596 DWORD user_clip_planes
;
4599 TRACE("iface %p, centers %p, radii %p, sphere_count %u, flags %#x, return_values %p.\n",
4600 iface
, centers
, radii
, sphere_count
, flags
, return_values
);
4602 prepare_clip_space_planes(impl_from_IDirect3DDevice7(iface
), plane
);
4604 IDirect3DDevice7_GetRenderState(iface
, D3DRENDERSTATE_CLIPPLANEENABLE
, &user_clip_planes
);
4605 enabled_planes
|= user_clip_planes
<< 6;
4606 for (j
= 6; j
< 12; ++j
)
4607 IDirect3DDevice7_GetClipPlane(iface
, j
- 6, (D3DVALUE
*)&plane
[j
]);
4609 compute_sphere_visibility(plane
, enabled_planes
, FALSE
, centers
, radii
, sphere_count
, return_values
);
4613 static HRESULT WINAPI
d3d_device3_ComputeSphereVisibility(IDirect3DDevice3
*iface
,
4614 D3DVECTOR
*centers
, D3DVALUE
*radii
, DWORD sphere_count
, DWORD flags
, DWORD
*return_values
)
4616 static const DWORD enabled_planes
= 0x3f;
4617 struct wined3d_vec4 plane
[6];
4620 TRACE("iface %p, centers %p, radii %p, sphere_count %u, flags %#x, return_values %p.\n",
4621 iface
, centers
, radii
, sphere_count
, flags
, return_values
);
4623 prepare_clip_space_planes(impl_from_IDirect3DDevice3(iface
), plane
);
4625 compute_sphere_visibility(plane
, enabled_planes
, TRUE
, centers
, radii
, sphere_count
, return_values
);
4626 for (i
= 0; i
< sphere_count
; ++i
)
4628 BOOL intersect_frustum
= FALSE
, outside_frustum
= FALSE
;
4629 DWORD d3d7_result
= return_values
[i
];
4631 return_values
[i
] = 0;
4633 for (j
= 0; j
< 6; ++j
)
4635 DWORD clip
= (d3d7_result
>> j
) & (D3DSTATUS_CLIPUNIONLEFT
| D3DSTATUS_CLIPINTERSECTIONLEFT
);
4637 if (clip
== D3DSTATUS_CLIPUNIONLEFT
)
4639 return_values
[i
] |= D3DVIS_INTERSECT_LEFT
<< j
* 2;
4640 intersect_frustum
= TRUE
;
4644 return_values
[i
] |= D3DVIS_OUTSIDE_LEFT
<< j
* 2;
4645 outside_frustum
= TRUE
;
4648 if (outside_frustum
)
4649 return_values
[i
] |= D3DVIS_OUTSIDE_FRUSTUM
;
4650 else if (intersect_frustum
)
4651 return_values
[i
] |= D3DVIS_INTERSECT_FRUSTUM
;
4656 /*****************************************************************************
4657 * IDirect3DDevice7::GetTexture
4659 * Returns the texture interface handle assigned to a texture stage.
4660 * The returned texture is AddRefed. This is taken from old ddraw,
4661 * not checked in Windows.
4666 * Stage: Texture stage to read the texture from
4667 * Texture: Address to store the interface pointer at
4671 * DDERR_INVALIDPARAMS if Texture is NULL
4673 *****************************************************************************/
4674 static HRESULT
d3d_device7_GetTexture(IDirect3DDevice7
*iface
,
4675 DWORD stage
, IDirectDrawSurface7
**texture
)
4677 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
4678 struct wined3d_texture
*wined3d_texture
;
4679 struct ddraw_texture
*ddraw_texture
;
4681 TRACE("iface %p, stage %u, texture %p.\n", iface
, stage
, texture
);
4684 return DDERR_INVALIDPARAMS
;
4686 wined3d_mutex_lock();
4687 if (!(wined3d_texture
= wined3d_device_get_texture(device
->wined3d_device
, stage
)))
4690 wined3d_mutex_unlock();
4694 ddraw_texture
= wined3d_texture_get_parent(wined3d_texture
);
4695 *texture
= &ddraw_texture
->root
->IDirectDrawSurface7_iface
;
4696 IDirectDrawSurface7_AddRef(*texture
);
4697 wined3d_mutex_unlock();
4702 static HRESULT WINAPI
d3d_device7_GetTexture_FPUSetup(IDirect3DDevice7
*iface
,
4703 DWORD stage
, IDirectDrawSurface7
**Texture
)
4705 return d3d_device7_GetTexture(iface
, stage
, Texture
);
4708 static HRESULT WINAPI
d3d_device7_GetTexture_FPUPreserve(IDirect3DDevice7
*iface
,
4709 DWORD stage
, IDirectDrawSurface7
**Texture
)
4714 old_fpucw
= d3d_fpu_setup();
4715 hr
= d3d_device7_GetTexture(iface
, stage
, Texture
);
4716 set_fpu_control_word(old_fpucw
);
4721 static HRESULT WINAPI
d3d_device3_GetTexture(IDirect3DDevice3
*iface
, DWORD stage
, IDirect3DTexture2
**Texture2
)
4723 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
4724 struct ddraw_surface
*ret_val_impl
;
4726 IDirectDrawSurface7
*ret_val
;
4728 TRACE("iface %p, stage %u, texture %p.\n", iface
, stage
, Texture2
);
4730 ret
= IDirect3DDevice7_GetTexture(&device
->IDirect3DDevice7_iface
, stage
, &ret_val
);
4732 ret_val_impl
= unsafe_impl_from_IDirectDrawSurface7(ret_val
);
4733 *Texture2
= ret_val_impl
? &ret_val_impl
->IDirect3DTexture2_iface
: NULL
;
4735 TRACE("Returning texture %p.\n", *Texture2
);
4740 /*****************************************************************************
4741 * IDirect3DDevice7::SetTexture
4743 * Assigns a texture to a texture stage. Is the texture AddRef-ed?
4748 * Stage: The stage to assign the texture to
4749 * Texture: Interface pointer to the texture surface
4754 *****************************************************************************/
4755 static HRESULT
d3d_device7_SetTexture(IDirect3DDevice7
*iface
,
4756 DWORD stage
, IDirectDrawSurface7
*texture
)
4758 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
4759 struct ddraw_surface
*surf
= unsafe_impl_from_IDirectDrawSurface7(texture
);
4760 struct wined3d_texture
*wined3d_texture
= NULL
;
4763 TRACE("iface %p, stage %u, texture %p.\n", iface
, stage
, texture
);
4765 if (surf
&& (surf
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_TEXTURE
))
4766 wined3d_texture
= surf
->wined3d_texture
;
4768 wined3d_mutex_lock();
4769 hr
= wined3d_device_set_texture(device
->wined3d_device
, stage
, wined3d_texture
);
4770 wined3d_mutex_unlock();
4775 static HRESULT WINAPI
d3d_device7_SetTexture_FPUSetup(IDirect3DDevice7
*iface
,
4776 DWORD stage
, IDirectDrawSurface7
*texture
)
4778 return d3d_device7_SetTexture(iface
, stage
, texture
);
4781 static HRESULT WINAPI
d3d_device7_SetTexture_FPUPreserve(IDirect3DDevice7
*iface
,
4782 DWORD stage
, IDirectDrawSurface7
*texture
)
4787 old_fpucw
= d3d_fpu_setup();
4788 hr
= d3d_device7_SetTexture(iface
, stage
, texture
);
4789 set_fpu_control_word(old_fpucw
);
4794 static HRESULT WINAPI
d3d_device3_SetTexture(IDirect3DDevice3
*iface
,
4795 DWORD stage
, IDirect3DTexture2
*texture
)
4797 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
4798 struct ddraw_surface
*tex
= unsafe_impl_from_IDirect3DTexture2(texture
);
4802 TRACE("iface %p, stage %u, texture %p.\n", iface
, stage
, texture
);
4804 wined3d_mutex_lock();
4806 if (device
->legacyTextureBlending
)
4807 IDirect3DDevice3_GetRenderState(iface
, D3DRENDERSTATE_TEXTUREMAPBLEND
, &texmapblend
);
4809 hr
= IDirect3DDevice7_SetTexture(&device
->IDirect3DDevice7_iface
, stage
, &tex
->IDirectDrawSurface7_iface
);
4811 if (device
->legacyTextureBlending
&& texmapblend
== D3DTBLEND_MODULATE
)
4813 /* This fixup is required by the way D3DTBLEND_MODULATE maps to texture stage states.
4814 See d3d_device3_SetRenderState() for details. */
4815 struct wined3d_texture
*tex
= NULL
;
4816 BOOL tex_alpha
= FALSE
;
4817 DDPIXELFORMAT ddfmt
;
4819 if ((tex
= wined3d_device_get_texture(device
->wined3d_device
, 0)))
4821 struct wined3d_resource_desc desc
;
4823 wined3d_resource_get_desc(wined3d_texture_get_resource(tex
), &desc
);
4824 ddfmt
.dwSize
= sizeof(ddfmt
);
4825 ddrawformat_from_wined3dformat(&ddfmt
, desc
.format
);
4826 if (ddfmt
.u5
.dwRGBAlphaBitMask
)
4830 /* Args 1 and 2 are already set to WINED3DTA_TEXTURE/WINED3DTA_CURRENT in case of D3DTBLEND_MODULATE */
4832 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
4833 0, WINED3D_TSS_ALPHA_OP
, WINED3D_TOP_SELECT_ARG1
);
4835 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
4836 0, WINED3D_TSS_ALPHA_OP
, WINED3D_TOP_SELECT_ARG2
);
4839 wined3d_mutex_unlock();
4844 static const struct tss_lookup
4849 enum wined3d_texture_stage_state texture_state
;
4850 enum wined3d_sampler_state sampler_state
;
4855 {FALSE
, {WINED3D_TSS_INVALID
}}, /* 0, unused */
4856 {FALSE
, {WINED3D_TSS_COLOR_OP
}}, /* 1, D3DTSS_COLOROP */
4857 {FALSE
, {WINED3D_TSS_COLOR_ARG1
}}, /* 2, D3DTSS_COLORARG1 */
4858 {FALSE
, {WINED3D_TSS_COLOR_ARG2
}}, /* 3, D3DTSS_COLORARG2 */
4859 {FALSE
, {WINED3D_TSS_ALPHA_OP
}}, /* 4, D3DTSS_ALPHAOP */
4860 {FALSE
, {WINED3D_TSS_ALPHA_ARG1
}}, /* 5, D3DTSS_ALPHAARG1 */
4861 {FALSE
, {WINED3D_TSS_ALPHA_ARG2
}}, /* 6, D3DTSS_ALPHAARG2 */
4862 {FALSE
, {WINED3D_TSS_BUMPENV_MAT00
}}, /* 7, D3DTSS_BUMPENVMAT00 */
4863 {FALSE
, {WINED3D_TSS_BUMPENV_MAT01
}}, /* 8, D3DTSS_BUMPENVMAT01 */
4864 {FALSE
, {WINED3D_TSS_BUMPENV_MAT10
}}, /* 9, D3DTSS_BUMPENVMAT10 */
4865 {FALSE
, {WINED3D_TSS_BUMPENV_MAT11
}}, /* 10, D3DTSS_BUMPENVMAT11 */
4866 {FALSE
, {WINED3D_TSS_TEXCOORD_INDEX
}}, /* 11, D3DTSS_TEXCOORDINDEX */
4867 {TRUE
, {WINED3D_SAMP_ADDRESS_U
}}, /* 12, D3DTSS_ADDRESS */
4868 {TRUE
, {WINED3D_SAMP_ADDRESS_U
}}, /* 13, D3DTSS_ADDRESSU */
4869 {TRUE
, {WINED3D_SAMP_ADDRESS_V
}}, /* 14, D3DTSS_ADDRESSV */
4870 {TRUE
, {WINED3D_SAMP_BORDER_COLOR
}}, /* 15, D3DTSS_BORDERCOLOR */
4871 {TRUE
, {WINED3D_SAMP_MAG_FILTER
}}, /* 16, D3DTSS_MAGFILTER */
4872 {TRUE
, {WINED3D_SAMP_MIN_FILTER
}}, /* 17, D3DTSS_MINFILTER */
4873 {TRUE
, {WINED3D_SAMP_MIP_FILTER
}}, /* 18, D3DTSS_MIPFILTER */
4874 {TRUE
, {WINED3D_SAMP_MIPMAP_LOD_BIAS
}}, /* 19, D3DTSS_MIPMAPLODBIAS */
4875 {TRUE
, {WINED3D_SAMP_MAX_MIP_LEVEL
}}, /* 20, D3DTSS_MAXMIPLEVEL */
4876 {TRUE
, {WINED3D_SAMP_MAX_ANISOTROPY
}}, /* 21, D3DTSS_MAXANISOTROPY */
4877 {FALSE
, {WINED3D_TSS_BUMPENV_LSCALE
}}, /* 22, D3DTSS_BUMPENVLSCALE */
4878 {FALSE
, {WINED3D_TSS_BUMPENV_LOFFSET
}}, /* 23, D3DTSS_BUMPENVLOFFSET */
4879 {FALSE
, {WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS
}}, /* 24, D3DTSS_TEXTURETRANSFORMFLAGS */
4882 /*****************************************************************************
4883 * IDirect3DDevice7::GetTextureStageState
4885 * Retrieves a state from a texture stage.
4890 * Stage: The stage to retrieve the state from
4891 * TexStageStateType: The state type to retrieve
4892 * State: Address to store the state's value at
4896 * DDERR_INVALIDPARAMS if State is NULL
4898 *****************************************************************************/
4899 static HRESULT
d3d_device7_GetTextureStageState(IDirect3DDevice7
*iface
,
4900 DWORD stage
, D3DTEXTURESTAGESTATETYPE state
, DWORD
*value
)
4902 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
4903 const struct tss_lookup
*l
;
4905 TRACE("iface %p, stage %u, state %#x, value %p.\n",
4906 iface
, stage
, state
, value
);
4909 return DDERR_INVALIDPARAMS
;
4911 if (state
> D3DTSS_TEXTURETRANSFORMFLAGS
)
4913 WARN("Invalid state %#x passed.\n", state
);
4917 l
= &tss_lookup
[state
];
4919 wined3d_mutex_lock();
4921 if (l
->sampler_state
)
4923 *value
= wined3d_device_get_sampler_state(device
->wined3d_device
, stage
, l
->u
.sampler_state
);
4927 /* Mipfilter is a sampler state with different values */
4928 case D3DTSS_MIPFILTER
:
4932 case WINED3D_TEXF_NONE
:
4933 *value
= D3DTFP_NONE
;
4935 case WINED3D_TEXF_POINT
:
4936 *value
= D3DTFP_POINT
;
4938 case WINED3D_TEXF_LINEAR
:
4939 *value
= D3DTFP_LINEAR
;
4942 ERR("Unexpected mipfilter value %#x.\n", *value
);
4943 *value
= D3DTFP_NONE
;
4949 /* Magfilter has slightly different values */
4950 case D3DTSS_MAGFILTER
:
4954 case WINED3D_TEXF_POINT
:
4955 *value
= D3DTFG_POINT
;
4957 case WINED3D_TEXF_LINEAR
:
4958 *value
= D3DTFG_LINEAR
;
4960 case WINED3D_TEXF_ANISOTROPIC
:
4961 *value
= D3DTFG_ANISOTROPIC
;
4963 case WINED3D_TEXF_FLAT_CUBIC
:
4964 *value
= D3DTFG_FLATCUBIC
;
4966 case WINED3D_TEXF_GAUSSIAN_CUBIC
:
4967 *value
= D3DTFG_GAUSSIANCUBIC
;
4970 ERR("Unexpected wined3d mag filter value %#x.\n", *value
);
4971 *value
= D3DTFG_POINT
;
4983 *value
= wined3d_device_get_texture_stage_state(device
->wined3d_device
, stage
, l
->u
.texture_state
);
4986 wined3d_mutex_unlock();
4991 static HRESULT WINAPI
d3d_device7_GetTextureStageState_FPUSetup(IDirect3DDevice7
*iface
,
4992 DWORD stage
, D3DTEXTURESTAGESTATETYPE state
, DWORD
*value
)
4994 return d3d_device7_GetTextureStageState(iface
, stage
, state
, value
);
4997 static HRESULT WINAPI
d3d_device7_GetTextureStageState_FPUPreserve(IDirect3DDevice7
*iface
,
4998 DWORD stage
, D3DTEXTURESTAGESTATETYPE state
, DWORD
*value
)
5003 old_fpucw
= d3d_fpu_setup();
5004 hr
= d3d_device7_GetTextureStageState(iface
, stage
, state
, value
);
5005 set_fpu_control_word(old_fpucw
);
5010 static HRESULT WINAPI
d3d_device3_GetTextureStageState(IDirect3DDevice3
*iface
,
5011 DWORD stage
, D3DTEXTURESTAGESTATETYPE state
, DWORD
*value
)
5013 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
5015 TRACE("iface %p, stage %u, state %#x, value %p.\n",
5016 iface
, stage
, state
, value
);
5018 return IDirect3DDevice7_GetTextureStageState(&device
->IDirect3DDevice7_iface
, stage
, state
, value
);
5021 /*****************************************************************************
5022 * IDirect3DDevice7::SetTextureStageState
5024 * Sets a texture stage state. Some stage types need to be handled specially,
5025 * because they do not exist in WineD3D and were moved to another place
5030 * Stage: The stage to modify
5031 * TexStageStateType: The state to change
5032 * State: The new value for the state
5037 *****************************************************************************/
5038 static HRESULT
d3d_device7_SetTextureStageState(IDirect3DDevice7
*iface
,
5039 DWORD stage
, D3DTEXTURESTAGESTATETYPE state
, DWORD value
)
5041 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
5042 const struct tss_lookup
*l
;
5044 TRACE("iface %p, stage %u, state %#x, value %#x.\n",
5045 iface
, stage
, state
, value
);
5047 if (state
> D3DTSS_TEXTURETRANSFORMFLAGS
)
5049 WARN("Invalid state %#x passed.\n", state
);
5053 l
= &tss_lookup
[state
];
5055 wined3d_mutex_lock();
5057 if (l
->sampler_state
)
5061 /* Mipfilter is a sampler state with different values */
5062 case D3DTSS_MIPFILTER
:
5067 value
= WINED3D_TEXF_NONE
;
5070 value
= WINED3D_TEXF_POINT
;
5072 case 0: /* Unchecked */
5074 value
= WINED3D_TEXF_LINEAR
;
5077 ERR("Unexpected mipfilter value %#x.\n", value
);
5078 value
= WINED3D_TEXF_NONE
;
5084 /* Magfilter has slightly different values */
5085 case D3DTSS_MAGFILTER
:
5090 value
= WINED3D_TEXF_POINT
;
5093 value
= WINED3D_TEXF_LINEAR
;
5095 case D3DTFG_FLATCUBIC
:
5096 value
= WINED3D_TEXF_FLAT_CUBIC
;
5098 case D3DTFG_GAUSSIANCUBIC
:
5099 value
= WINED3D_TEXF_GAUSSIAN_CUBIC
;
5101 case D3DTFG_ANISOTROPIC
:
5102 value
= WINED3D_TEXF_ANISOTROPIC
;
5105 ERR("Unexpected d3d7 mag filter value %#x.\n", value
);
5106 value
= WINED3D_TEXF_POINT
;
5112 case D3DTSS_ADDRESS
:
5113 wined3d_device_set_sampler_state(device
->wined3d_device
, stage
, WINED3D_SAMP_ADDRESS_V
, value
);
5120 wined3d_device_set_sampler_state(device
->wined3d_device
, stage
, l
->u
.sampler_state
, value
);
5124 wined3d_device_set_texture_stage_state(device
->wined3d_device
, stage
, l
->u
.texture_state
, value
);
5127 wined3d_mutex_unlock();
5132 static HRESULT WINAPI
d3d_device7_SetTextureStageState_FPUSetup(IDirect3DDevice7
*iface
,
5133 DWORD stage
, D3DTEXTURESTAGESTATETYPE state
, DWORD value
)
5135 return d3d_device7_SetTextureStageState(iface
, stage
, state
, value
);
5138 static HRESULT WINAPI
d3d_device7_SetTextureStageState_FPUPreserve(IDirect3DDevice7
*iface
,
5139 DWORD stage
, D3DTEXTURESTAGESTATETYPE state
, DWORD value
)
5144 old_fpucw
= d3d_fpu_setup();
5145 hr
= d3d_device7_SetTextureStageState(iface
, stage
, state
, value
);
5146 set_fpu_control_word(old_fpucw
);
5151 static HRESULT WINAPI
d3d_device3_SetTextureStageState(IDirect3DDevice3
*iface
,
5152 DWORD stage
, D3DTEXTURESTAGESTATETYPE state
, DWORD value
)
5154 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
5156 TRACE("iface %p, stage %u, state %#x, value %#x.\n",
5157 iface
, stage
, state
, value
);
5159 return IDirect3DDevice7_SetTextureStageState(&device
->IDirect3DDevice7_iface
, stage
, state
, value
);
5162 /*****************************************************************************
5163 * IDirect3DDevice7::ValidateDevice
5165 * SDK: "Reports the device's ability to render the currently set
5166 * texture-blending operations in a single pass". Whatever that means
5172 * NumPasses: Address to write the number of necessary passes for the
5173 * desired effect to.
5178 *****************************************************************************/
5179 static HRESULT
d3d_device7_ValidateDevice(IDirect3DDevice7
*iface
, DWORD
*pass_count
)
5181 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
5184 TRACE("iface %p, pass_count %p.\n", iface
, pass_count
);
5186 wined3d_mutex_lock();
5187 hr
= wined3d_device_validate_device(device
->wined3d_device
, pass_count
);
5188 wined3d_mutex_unlock();
5193 static HRESULT WINAPI
d3d_device7_ValidateDevice_FPUSetup(IDirect3DDevice7
*iface
, DWORD
*pass_count
)
5195 return d3d_device7_ValidateDevice(iface
, pass_count
);
5198 static HRESULT WINAPI
d3d_device7_ValidateDevice_FPUPreserve(IDirect3DDevice7
*iface
, DWORD
*pass_count
)
5203 old_fpucw
= d3d_fpu_setup();
5204 hr
= d3d_device7_ValidateDevice(iface
, pass_count
);
5205 set_fpu_control_word(old_fpucw
);
5210 static HRESULT WINAPI
d3d_device3_ValidateDevice(IDirect3DDevice3
*iface
, DWORD
*pass_count
)
5212 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
5214 TRACE("iface %p, pass_count %p.\n", iface
, pass_count
);
5216 return IDirect3DDevice7_ValidateDevice(&device
->IDirect3DDevice7_iface
, pass_count
);
5219 /*****************************************************************************
5220 * IDirect3DDevice7::Clear
5222 * Fills the render target, the z buffer and the stencil buffer with a
5223 * clear color / value
5228 * Count: Number of rectangles in Rects must be 0 if Rects is NULL
5229 * Rects: Rectangles to clear. If NULL, the whole surface is cleared
5230 * Flags: Some flags, as usual
5231 * Color: Clear color for the render target
5232 * Z: Clear value for the Z buffer
5233 * Stencil: Clear value to store in each stencil buffer entry
5238 *****************************************************************************/
5239 static HRESULT
d3d_device7_Clear(IDirect3DDevice7
*iface
, DWORD count
,
5240 D3DRECT
*rects
, DWORD flags
, D3DCOLOR color
, D3DVALUE z
, DWORD stencil
)
5242 const struct wined3d_color c
=
5244 ((color
>> 16) & 0xff) / 255.0f
,
5245 ((color
>> 8) & 0xff) / 255.0f
,
5246 (color
& 0xff) / 255.0f
,
5247 ((color
>> 24) & 0xff) / 255.0f
,
5249 struct d3d_device
*This
= impl_from_IDirect3DDevice7(iface
);
5252 TRACE("iface %p, count %u, rects %p, flags %#x, color 0x%08x, z %.8e, stencil %#x.\n",
5253 iface
, count
, rects
, flags
, color
, z
, stencil
);
5255 if (count
&& !rects
)
5257 WARN("count %u with NULL rects.\n", count
);
5261 wined3d_mutex_lock();
5262 hr
= wined3d_device_clear(This
->wined3d_device
, count
, (RECT
*)rects
, flags
, &c
, z
, stencil
);
5263 wined3d_mutex_unlock();
5268 static HRESULT WINAPI
d3d_device7_Clear_FPUSetup(IDirect3DDevice7
*iface
, DWORD count
,
5269 D3DRECT
*rects
, DWORD flags
, D3DCOLOR color
, D3DVALUE z
, DWORD stencil
)
5271 return d3d_device7_Clear(iface
, count
, rects
, flags
, color
, z
, stencil
);
5274 static HRESULT WINAPI
d3d_device7_Clear_FPUPreserve(IDirect3DDevice7
*iface
, DWORD count
,
5275 D3DRECT
*rects
, DWORD flags
, D3DCOLOR color
, D3DVALUE z
, DWORD stencil
)
5280 old_fpucw
= d3d_fpu_setup();
5281 hr
= d3d_device7_Clear(iface
, count
, rects
, flags
, color
, z
, stencil
);
5282 set_fpu_control_word(old_fpucw
);
5287 /*****************************************************************************
5288 * IDirect3DDevice7::SetViewport
5290 * Sets the current viewport.
5292 * Version 7 only, but IDirect3DViewport uses this call for older
5296 * Data: The new viewport to set
5300 * DDERR_INVALIDPARAMS if Data is NULL
5302 *****************************************************************************/
5303 static HRESULT
d3d_device7_SetViewport(IDirect3DDevice7
*iface
, D3DVIEWPORT7
*viewport
)
5305 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
5307 TRACE("iface %p, viewport %p.\n", iface
, viewport
);
5310 return DDERR_INVALIDPARAMS
;
5312 /* Note: D3DVIEWPORT7 is compatible with struct wined3d_viewport. */
5313 wined3d_mutex_lock();
5314 wined3d_device_set_viewport(device
->wined3d_device
, (struct wined3d_viewport
*)viewport
);
5315 wined3d_mutex_unlock();
5320 static HRESULT WINAPI
d3d_device7_SetViewport_FPUSetup(IDirect3DDevice7
*iface
, D3DVIEWPORT7
*viewport
)
5322 return d3d_device7_SetViewport(iface
, viewport
);
5325 static HRESULT WINAPI
d3d_device7_SetViewport_FPUPreserve(IDirect3DDevice7
*iface
, D3DVIEWPORT7
*viewport
)
5330 old_fpucw
= d3d_fpu_setup();
5331 hr
= d3d_device7_SetViewport(iface
, viewport
);
5332 set_fpu_control_word(old_fpucw
);
5337 /*****************************************************************************
5338 * IDirect3DDevice::GetViewport
5340 * Returns the current viewport
5345 * Data: D3D7Viewport structure to write the viewport information to
5349 * DDERR_INVALIDPARAMS if Data is NULL
5351 *****************************************************************************/
5352 static HRESULT
d3d_device7_GetViewport(IDirect3DDevice7
*iface
, D3DVIEWPORT7
*viewport
)
5354 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
5356 TRACE("iface %p, viewport %p.\n", iface
, viewport
);
5359 return DDERR_INVALIDPARAMS
;
5361 /* Note: D3DVIEWPORT7 is compatible with struct wined3d_viewport. */
5362 wined3d_mutex_lock();
5363 wined3d_device_get_viewport(device
->wined3d_device
, (struct wined3d_viewport
*)viewport
);
5364 wined3d_mutex_unlock();
5369 static HRESULT WINAPI
d3d_device7_GetViewport_FPUSetup(IDirect3DDevice7
*iface
, D3DVIEWPORT7
*viewport
)
5371 return d3d_device7_GetViewport(iface
, viewport
);
5374 static HRESULT WINAPI
d3d_device7_GetViewport_FPUPreserve(IDirect3DDevice7
*iface
, D3DVIEWPORT7
*viewport
)
5379 old_fpucw
= d3d_fpu_setup();
5380 hr
= d3d_device7_GetViewport(iface
, viewport
);
5381 set_fpu_control_word(old_fpucw
);
5386 /*****************************************************************************
5387 * IDirect3DDevice7::SetMaterial
5394 * Mat: The material to set
5398 * DDERR_INVALIDPARAMS if Mat is NULL.
5400 *****************************************************************************/
5401 static HRESULT
d3d_device7_SetMaterial(IDirect3DDevice7
*iface
, D3DMATERIAL7
*material
)
5403 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
5405 TRACE("iface %p, material %p.\n", iface
, material
);
5408 return DDERR_INVALIDPARAMS
;
5410 wined3d_mutex_lock();
5411 /* Note: D3DMATERIAL7 is compatible with struct wined3d_material. */
5412 wined3d_device_set_material(device
->wined3d_device
, (struct wined3d_material
*)material
);
5413 wined3d_mutex_unlock();
5418 static HRESULT WINAPI
d3d_device7_SetMaterial_FPUSetup(IDirect3DDevice7
*iface
, D3DMATERIAL7
*material
)
5420 return d3d_device7_SetMaterial(iface
, material
);
5423 static HRESULT WINAPI
d3d_device7_SetMaterial_FPUPreserve(IDirect3DDevice7
*iface
, D3DMATERIAL7
*material
)
5428 old_fpucw
= d3d_fpu_setup();
5429 hr
= d3d_device7_SetMaterial(iface
, material
);
5430 set_fpu_control_word(old_fpucw
);
5435 /*****************************************************************************
5436 * IDirect3DDevice7::GetMaterial
5438 * Returns the current material
5443 * Mat: D3DMATERIAL7 structure to write the material parameters to
5447 * DDERR_INVALIDPARAMS if Mat is NULL
5449 *****************************************************************************/
5450 static HRESULT
d3d_device7_GetMaterial(IDirect3DDevice7
*iface
, D3DMATERIAL7
*material
)
5452 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
5454 TRACE("iface %p, material %p.\n", iface
, material
);
5456 wined3d_mutex_lock();
5457 /* Note: D3DMATERIAL7 is compatible with struct wined3d_material. */
5458 wined3d_device_get_material(device
->wined3d_device
, (struct wined3d_material
*)material
);
5459 wined3d_mutex_unlock();
5464 static HRESULT WINAPI
d3d_device7_GetMaterial_FPUSetup(IDirect3DDevice7
*iface
, D3DMATERIAL7
*material
)
5466 return d3d_device7_GetMaterial(iface
, material
);
5469 static HRESULT WINAPI
d3d_device7_GetMaterial_FPUPreserve(IDirect3DDevice7
*iface
, D3DMATERIAL7
*material
)
5474 old_fpucw
= d3d_fpu_setup();
5475 hr
= d3d_device7_GetMaterial(iface
, material
);
5476 set_fpu_control_word(old_fpucw
);
5481 /*****************************************************************************
5482 * IDirect3DDevice7::SetLight
5484 * Assigns a light to a light index, but doesn't activate it yet.
5486 * Version 7, IDirect3DLight uses this method for older versions
5489 * LightIndex: The index of the new light
5490 * Light: A D3DLIGHT7 structure describing the light
5495 *****************************************************************************/
5496 static HRESULT
d3d_device7_SetLight(IDirect3DDevice7
*iface
, DWORD light_idx
, D3DLIGHT7
*light
)
5498 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
5501 TRACE("iface %p, light_idx %u, light %p.\n", iface
, light_idx
, light
);
5503 wined3d_mutex_lock();
5504 /* Note: D3DLIGHT7 is compatible with struct wined3d_light. */
5505 hr
= wined3d_device_set_light(device
->wined3d_device
, light_idx
, (struct wined3d_light
*)light
);
5506 wined3d_mutex_unlock();
5508 return hr_ddraw_from_wined3d(hr
);
5511 static HRESULT WINAPI
d3d_device7_SetLight_FPUSetup(IDirect3DDevice7
*iface
, DWORD light_idx
, D3DLIGHT7
*light
)
5513 return d3d_device7_SetLight(iface
, light_idx
, light
);
5516 static HRESULT WINAPI
d3d_device7_SetLight_FPUPreserve(IDirect3DDevice7
*iface
, DWORD light_idx
, D3DLIGHT7
*light
)
5521 old_fpucw
= d3d_fpu_setup();
5522 hr
= d3d_device7_SetLight(iface
, light_idx
, light
);
5523 set_fpu_control_word(old_fpucw
);
5528 /*****************************************************************************
5529 * IDirect3DDevice7::GetLight
5531 * Returns the light assigned to a light index
5534 * Light: Structure to write the light information to
5538 * DDERR_INVALIDPARAMS if Light is NULL
5540 *****************************************************************************/
5541 static HRESULT
d3d_device7_GetLight(IDirect3DDevice7
*iface
, DWORD light_idx
, D3DLIGHT7
*light
)
5543 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
5546 TRACE("iface %p, light_idx %u, light %p.\n", iface
, light_idx
, light
);
5548 wined3d_mutex_lock();
5549 /* Note: D3DLIGHT7 is compatible with struct wined3d_light. */
5550 rc
= wined3d_device_get_light(device
->wined3d_device
, light_idx
, (struct wined3d_light
*)light
);
5551 wined3d_mutex_unlock();
5553 /* Translate the result. WineD3D returns other values than D3D7 */
5554 return hr_ddraw_from_wined3d(rc
);
5557 static HRESULT WINAPI
d3d_device7_GetLight_FPUSetup(IDirect3DDevice7
*iface
, DWORD light_idx
, D3DLIGHT7
*light
)
5559 return d3d_device7_GetLight(iface
, light_idx
, light
);
5562 static HRESULT WINAPI
d3d_device7_GetLight_FPUPreserve(IDirect3DDevice7
*iface
, DWORD light_idx
, D3DLIGHT7
*light
)
5567 old_fpucw
= d3d_fpu_setup();
5568 hr
= d3d_device7_GetLight(iface
, light_idx
, light
);
5569 set_fpu_control_word(old_fpucw
);
5574 /*****************************************************************************
5575 * IDirect3DDevice7::BeginStateBlock
5577 * Begins recording to a stateblock
5584 *****************************************************************************/
5585 static HRESULT
d3d_device7_BeginStateBlock(IDirect3DDevice7
*iface
)
5587 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
5590 TRACE("iface %p.\n", iface
);
5592 wined3d_mutex_lock();
5593 hr
= wined3d_device_begin_stateblock(device
->wined3d_device
);
5594 wined3d_mutex_unlock();
5596 return hr_ddraw_from_wined3d(hr
);
5599 static HRESULT WINAPI
d3d_device7_BeginStateBlock_FPUSetup(IDirect3DDevice7
*iface
)
5601 return d3d_device7_BeginStateBlock(iface
);
5604 static HRESULT WINAPI
d3d_device7_BeginStateBlock_FPUPreserve(IDirect3DDevice7
*iface
)
5609 old_fpucw
= d3d_fpu_setup();
5610 hr
= d3d_device7_BeginStateBlock(iface
);
5611 set_fpu_control_word(old_fpucw
);
5616 /*****************************************************************************
5617 * IDirect3DDevice7::EndStateBlock
5619 * Stops recording to a state block and returns the created stateblock
5625 * BlockHandle: Address to store the stateblock's handle to
5629 * DDERR_INVALIDPARAMS if BlockHandle is NULL
5631 *****************************************************************************/
5632 static HRESULT
d3d_device7_EndStateBlock(IDirect3DDevice7
*iface
, DWORD
*stateblock
)
5634 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
5635 struct wined3d_stateblock
*wined3d_sb
;
5639 TRACE("iface %p, stateblock %p.\n", iface
, stateblock
);
5642 return DDERR_INVALIDPARAMS
;
5644 wined3d_mutex_lock();
5646 hr
= wined3d_device_end_stateblock(device
->wined3d_device
, &wined3d_sb
);
5649 WARN("Failed to end stateblock, hr %#x.\n", hr
);
5650 wined3d_mutex_unlock();
5652 return hr_ddraw_from_wined3d(hr
);
5655 h
= ddraw_allocate_handle(&device
->handle_table
, wined3d_sb
, DDRAW_HANDLE_STATEBLOCK
);
5656 if (h
== DDRAW_INVALID_HANDLE
)
5658 ERR("Failed to allocate a stateblock handle.\n");
5659 wined3d_stateblock_decref(wined3d_sb
);
5660 wined3d_mutex_unlock();
5662 return DDERR_OUTOFMEMORY
;
5665 wined3d_mutex_unlock();
5666 *stateblock
= h
+ 1;
5668 return hr_ddraw_from_wined3d(hr
);
5671 static HRESULT WINAPI
d3d_device7_EndStateBlock_FPUSetup(IDirect3DDevice7
*iface
, DWORD
*stateblock
)
5673 return d3d_device7_EndStateBlock(iface
, stateblock
);
5676 static HRESULT WINAPI
d3d_device7_EndStateBlock_FPUPreserve(IDirect3DDevice7
*iface
, DWORD
*stateblock
)
5681 old_fpucw
= d3d_fpu_setup();
5682 hr
= d3d_device7_EndStateBlock(iface
, stateblock
);
5683 set_fpu_control_word(old_fpucw
);
5688 /*****************************************************************************
5689 * IDirect3DDevice7::PreLoad
5691 * Allows the app to signal that a texture will be used soon, to allow
5692 * the Direct3DDevice to load it to the video card in the meantime.
5697 * Texture: The texture to preload
5701 * DDERR_INVALIDPARAMS if Texture is NULL
5703 *****************************************************************************/
5704 static HRESULT
d3d_device7_PreLoad(IDirect3DDevice7
*iface
, IDirectDrawSurface7
*texture
)
5706 struct ddraw_surface
*surface
= unsafe_impl_from_IDirectDrawSurface7(texture
);
5708 TRACE("iface %p, texture %p.\n", iface
, texture
);
5711 return DDERR_INVALIDPARAMS
;
5713 wined3d_mutex_lock();
5714 wined3d_resource_preload(wined3d_texture_get_resource(surface
->wined3d_texture
));
5715 wined3d_mutex_unlock();
5720 static HRESULT WINAPI
d3d_device7_PreLoad_FPUSetup(IDirect3DDevice7
*iface
, IDirectDrawSurface7
*texture
)
5722 return d3d_device7_PreLoad(iface
, texture
);
5725 static HRESULT WINAPI
d3d_device7_PreLoad_FPUPreserve(IDirect3DDevice7
*iface
, IDirectDrawSurface7
*texture
)
5730 old_fpucw
= d3d_fpu_setup();
5731 hr
= d3d_device7_PreLoad(iface
, texture
);
5732 set_fpu_control_word(old_fpucw
);
5737 /*****************************************************************************
5738 * IDirect3DDevice7::ApplyStateBlock
5740 * Activates the state stored in a state block handle.
5743 * BlockHandle: The stateblock handle to activate
5747 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is NULL
5749 *****************************************************************************/
5750 static HRESULT
d3d_device7_ApplyStateBlock(IDirect3DDevice7
*iface
, DWORD stateblock
)
5752 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
5753 struct wined3d_stateblock
*wined3d_sb
;
5755 TRACE("iface %p, stateblock %#x.\n", iface
, stateblock
);
5757 wined3d_mutex_lock();
5758 wined3d_sb
= ddraw_get_object(&device
->handle_table
, stateblock
- 1, DDRAW_HANDLE_STATEBLOCK
);
5761 WARN("Invalid stateblock handle.\n");
5762 wined3d_mutex_unlock();
5763 return D3DERR_INVALIDSTATEBLOCK
;
5766 wined3d_stateblock_apply(wined3d_sb
);
5767 wined3d_mutex_unlock();
5772 static HRESULT WINAPI
d3d_device7_ApplyStateBlock_FPUSetup(IDirect3DDevice7
*iface
, DWORD stateblock
)
5774 return d3d_device7_ApplyStateBlock(iface
, stateblock
);
5777 static HRESULT WINAPI
d3d_device7_ApplyStateBlock_FPUPreserve(IDirect3DDevice7
*iface
, DWORD stateblock
)
5782 old_fpucw
= d3d_fpu_setup();
5783 hr
= d3d_device7_ApplyStateBlock(iface
, stateblock
);
5784 set_fpu_control_word(old_fpucw
);
5789 /*****************************************************************************
5790 * IDirect3DDevice7::CaptureStateBlock
5792 * Updates a stateblock's values to the values currently set for the device
5797 * BlockHandle: Stateblock to update
5801 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is NULL
5803 *****************************************************************************/
5804 static HRESULT
d3d_device7_CaptureStateBlock(IDirect3DDevice7
*iface
, DWORD stateblock
)
5806 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
5807 struct wined3d_stateblock
*wined3d_sb
;
5809 TRACE("iface %p, stateblock %#x.\n", iface
, stateblock
);
5811 wined3d_mutex_lock();
5812 wined3d_sb
= ddraw_get_object(&device
->handle_table
, stateblock
- 1, DDRAW_HANDLE_STATEBLOCK
);
5815 WARN("Invalid stateblock handle.\n");
5816 wined3d_mutex_unlock();
5817 return D3DERR_INVALIDSTATEBLOCK
;
5820 wined3d_stateblock_capture(wined3d_sb
);
5821 wined3d_mutex_unlock();
5826 static HRESULT WINAPI
d3d_device7_CaptureStateBlock_FPUSetup(IDirect3DDevice7
*iface
, DWORD stateblock
)
5828 return d3d_device7_CaptureStateBlock(iface
, stateblock
);
5831 static HRESULT WINAPI
d3d_device7_CaptureStateBlock_FPUPreserve(IDirect3DDevice7
*iface
, DWORD stateblock
)
5836 old_fpucw
= d3d_fpu_setup();
5837 hr
= d3d_device7_CaptureStateBlock(iface
, stateblock
);
5838 set_fpu_control_word(old_fpucw
);
5843 /*****************************************************************************
5844 * IDirect3DDevice7::DeleteStateBlock
5846 * Deletes a stateblock handle. This means releasing the WineD3DStateBlock
5851 * BlockHandle: Stateblock handle to delete
5855 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is 0
5857 *****************************************************************************/
5858 static HRESULT
d3d_device7_DeleteStateBlock(IDirect3DDevice7
*iface
, DWORD stateblock
)
5860 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
5861 struct wined3d_stateblock
*wined3d_sb
;
5864 TRACE("iface %p, stateblock %#x.\n", iface
, stateblock
);
5866 wined3d_mutex_lock();
5868 wined3d_sb
= ddraw_free_handle(&device
->handle_table
, stateblock
- 1, DDRAW_HANDLE_STATEBLOCK
);
5871 WARN("Invalid stateblock handle.\n");
5872 wined3d_mutex_unlock();
5873 return D3DERR_INVALIDSTATEBLOCK
;
5876 if ((ref
= wined3d_stateblock_decref(wined3d_sb
)))
5878 ERR("Something is still holding stateblock %p (refcount %u).\n", wined3d_sb
, ref
);
5881 wined3d_mutex_unlock();
5886 static HRESULT WINAPI
d3d_device7_DeleteStateBlock_FPUSetup(IDirect3DDevice7
*iface
, DWORD stateblock
)
5888 return d3d_device7_DeleteStateBlock(iface
, stateblock
);
5891 static HRESULT WINAPI
d3d_device7_DeleteStateBlock_FPUPreserve(IDirect3DDevice7
*iface
, DWORD stateblock
)
5896 old_fpucw
= d3d_fpu_setup();
5897 hr
= d3d_device7_DeleteStateBlock(iface
, stateblock
);
5898 set_fpu_control_word(old_fpucw
);
5903 /*****************************************************************************
5904 * IDirect3DDevice7::CreateStateBlock
5906 * Creates a new state block handle.
5911 * Type: The state block type
5912 * BlockHandle: Address to write the created handle to
5916 * DDERR_INVALIDPARAMS if BlockHandle is NULL
5918 *****************************************************************************/
5919 static HRESULT
d3d_device7_CreateStateBlock(IDirect3DDevice7
*iface
,
5920 D3DSTATEBLOCKTYPE type
, DWORD
*stateblock
)
5922 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
5923 struct wined3d_stateblock
*wined3d_sb
;
5927 TRACE("iface %p, type %#x, stateblock %p.\n", iface
, type
, stateblock
);
5930 return DDERR_INVALIDPARAMS
;
5932 if (type
!= D3DSBT_ALL
5933 && type
!= D3DSBT_PIXELSTATE
5934 && type
!= D3DSBT_VERTEXSTATE
)
5936 WARN("Unexpected stateblock type, returning DDERR_INVALIDPARAMS\n");
5937 return DDERR_INVALIDPARAMS
;
5940 wined3d_mutex_lock();
5942 /* The D3DSTATEBLOCKTYPE enum is fine here. */
5943 hr
= wined3d_stateblock_create(device
->wined3d_device
, type
, &wined3d_sb
);
5946 WARN("Failed to create stateblock, hr %#x.\n", hr
);
5947 wined3d_mutex_unlock();
5948 return hr_ddraw_from_wined3d(hr
);
5951 h
= ddraw_allocate_handle(&device
->handle_table
, wined3d_sb
, DDRAW_HANDLE_STATEBLOCK
);
5952 if (h
== DDRAW_INVALID_HANDLE
)
5954 ERR("Failed to allocate stateblock handle.\n");
5955 wined3d_stateblock_decref(wined3d_sb
);
5956 wined3d_mutex_unlock();
5957 return DDERR_OUTOFMEMORY
;
5960 *stateblock
= h
+ 1;
5961 wined3d_mutex_unlock();
5963 return hr_ddraw_from_wined3d(hr
);
5966 static HRESULT WINAPI
d3d_device7_CreateStateBlock_FPUSetup(IDirect3DDevice7
*iface
,
5967 D3DSTATEBLOCKTYPE type
, DWORD
*stateblock
)
5969 return d3d_device7_CreateStateBlock(iface
, type
, stateblock
);
5972 static HRESULT WINAPI
d3d_device7_CreateStateBlock_FPUPreserve(IDirect3DDevice7
*iface
,
5973 D3DSTATEBLOCKTYPE type
, DWORD
*stateblock
)
5978 old_fpucw
= d3d_fpu_setup();
5979 hr
= d3d_device7_CreateStateBlock(iface
, type
, stateblock
);
5980 set_fpu_control_word(old_fpucw
);
5985 static BOOL
is_mip_level_subset(struct ddraw_surface
*dest
, struct ddraw_surface
*src
)
5987 struct ddraw_surface
*src_level
, *dest_level
;
5988 IDirectDrawSurface7
*temp
;
5989 DDSURFACEDESC2 ddsd
;
5990 BOOL levelFound
; /* at least one suitable sublevel in dest found */
5992 /* To satisfy "destination is mip level subset of source" criteria (regular texture counts as 1 level),
5993 * 1) there must be at least one mip level in destination that matched dimensions of some mip level in source and
5994 * 2) there must be no destination levels that don't match any levels in source. Otherwise it's INVALIDPARAMS.
6001 for (;src_level
&& dest_level
;)
6003 if (src_level
->surface_desc
.dwWidth
== dest_level
->surface_desc
.dwWidth
&&
6004 src_level
->surface_desc
.dwHeight
== dest_level
->surface_desc
.dwHeight
)
6008 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
6009 ddsd
.ddsCaps
.dwCaps2
= DDSCAPS2_MIPMAPSUBLEVEL
;
6010 IDirectDrawSurface7_GetAttachedSurface(&dest_level
->IDirectDrawSurface7_iface
, &ddsd
.ddsCaps
, &temp
);
6012 if (dest_level
!= dest
) IDirectDrawSurface7_Release(&dest_level
->IDirectDrawSurface7_iface
);
6014 dest_level
= unsafe_impl_from_IDirectDrawSurface7(temp
);
6017 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
6018 ddsd
.ddsCaps
.dwCaps2
= DDSCAPS2_MIPMAPSUBLEVEL
;
6019 IDirectDrawSurface7_GetAttachedSurface(&src_level
->IDirectDrawSurface7_iface
, &ddsd
.ddsCaps
, &temp
);
6021 if (src_level
!= src
) IDirectDrawSurface7_Release(&src_level
->IDirectDrawSurface7_iface
);
6023 src_level
= unsafe_impl_from_IDirectDrawSurface7(temp
);
6026 if (src_level
&& src_level
!= src
) IDirectDrawSurface7_Release(&src_level
->IDirectDrawSurface7_iface
);
6027 if (dest_level
&& dest_level
!= dest
) IDirectDrawSurface7_Release(&dest_level
->IDirectDrawSurface7_iface
);
6029 return !dest_level
&& levelFound
;
6032 static void copy_mipmap_chain(struct d3d_device
*device
, struct ddraw_surface
*dst
,
6033 struct ddraw_surface
*src
, const POINT
*DestPoint
, const RECT
*SrcRect
)
6035 struct ddraw_surface
*dst_level
, *src_level
;
6036 IDirectDrawSurface7
*temp
;
6037 DDSURFACEDESC2 ddsd
;
6041 IDirectDrawPalette
*pal
= NULL
, *pal_src
= NULL
;
6045 /* Copy palette, if possible. */
6046 IDirectDrawSurface7_GetPalette(&src
->IDirectDrawSurface7_iface
, &pal_src
);
6047 IDirectDrawSurface7_GetPalette(&dst
->IDirectDrawSurface7_iface
, &pal
);
6049 if (pal_src
!= NULL
&& pal
!= NULL
)
6051 PALETTEENTRY palent
[256];
6053 IDirectDrawPalette_GetEntries(pal_src
, 0, 0, 256, palent
);
6054 IDirectDrawPalette_SetEntries(pal
, 0, 0, 256, palent
);
6057 if (pal
) IDirectDrawPalette_Release(pal
);
6058 if (pal_src
) IDirectDrawPalette_Release(pal_src
);
6060 /* Copy colorkeys, if present. */
6061 for (ckeyflag
= DDCKEY_DESTBLT
; ckeyflag
<= DDCKEY_SRCOVERLAY
; ckeyflag
<<= 1)
6063 hr
= IDirectDrawSurface7_GetColorKey(&src
->IDirectDrawSurface7_iface
, ckeyflag
, &ddckey
);
6067 IDirectDrawSurface7_SetColorKey(&dst
->IDirectDrawSurface7_iface
, ckeyflag
, &ddckey
);
6075 src_rect
= *SrcRect
;
6077 for (;src_level
&& dst_level
;)
6079 if (src_level
->surface_desc
.dwWidth
== dst_level
->surface_desc
.dwWidth
6080 && src_level
->surface_desc
.dwHeight
== dst_level
->surface_desc
.dwHeight
)
6082 UINT src_w
= src_rect
.right
- src_rect
.left
;
6083 UINT src_h
= src_rect
.bottom
- src_rect
.top
;
6084 RECT dst_rect
= {point
.x
, point
.y
, point
.x
+ src_w
, point
.y
+ src_h
};
6086 if (FAILED(hr
= wined3d_texture_blt(dst_level
->wined3d_texture
, dst_level
->sub_resource_idx
, &dst_rect
,
6087 src_level
->wined3d_texture
, src_level
->sub_resource_idx
, &src_rect
, 0, NULL
, WINED3D_TEXF_POINT
)))
6088 ERR("Blit failed, hr %#x.\n", hr
);
6090 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
6091 ddsd
.ddsCaps
.dwCaps2
= DDSCAPS2_MIPMAPSUBLEVEL
;
6092 IDirectDrawSurface7_GetAttachedSurface(&dst_level
->IDirectDrawSurface7_iface
, &ddsd
.ddsCaps
, &temp
);
6094 if (dst_level
!= dst
)
6095 IDirectDrawSurface7_Release(&dst_level
->IDirectDrawSurface7_iface
);
6097 dst_level
= unsafe_impl_from_IDirectDrawSurface7(temp
);
6100 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
6101 ddsd
.ddsCaps
.dwCaps2
= DDSCAPS2_MIPMAPSUBLEVEL
;
6102 IDirectDrawSurface7_GetAttachedSurface(&src_level
->IDirectDrawSurface7_iface
, &ddsd
.ddsCaps
, &temp
);
6104 if (src_level
!= src
) IDirectDrawSurface7_Release(&src_level
->IDirectDrawSurface7_iface
);
6106 src_level
= unsafe_impl_from_IDirectDrawSurface7(temp
);
6113 src_rect
.right
= (src_rect
.right
+ 1) / 2;
6114 src_rect
.bottom
= (src_rect
.bottom
+ 1) / 2;
6117 if (src_level
&& src_level
!= src
)
6118 IDirectDrawSurface7_Release(&src_level
->IDirectDrawSurface7_iface
);
6119 if (dst_level
&& dst_level
!= dst
)
6120 IDirectDrawSurface7_Release(&dst_level
->IDirectDrawSurface7_iface
);
6123 /*****************************************************************************
6124 * IDirect3DDevice7::Load
6126 * Loads a rectangular area from the source into the destination texture.
6127 * It can also copy the source to the faces of a cubic environment map
6132 * DestTex: Destination texture
6133 * DestPoint: Point in the destination where the source image should be
6135 * SrcTex: Source texture
6136 * SrcRect: Source rectangle
6137 * Flags: Cubemap faces to load (DDSCAPS2_CUBEMAP_ALLFACES, DDSCAPS2_CUBEMAP_POSITIVEX,
6138 * DDSCAPS2_CUBEMAP_NEGATIVEX, DDSCAPS2_CUBEMAP_POSITIVEY, DDSCAPS2_CUBEMAP_NEGATIVEY,
6139 * DDSCAPS2_CUBEMAP_POSITIVEZ, DDSCAPS2_CUBEMAP_NEGATIVEZ)
6143 * DDERR_INVALIDPARAMS if dst_texture or src_texture is NULL, broken coordinates or anything unexpected.
6146 *****************************************************************************/
6147 static HRESULT
d3d_device7_Load(IDirect3DDevice7
*iface
, IDirectDrawSurface7
*dst_texture
, POINT
*dst_pos
,
6148 IDirectDrawSurface7
*src_texture
, RECT
*src_rect
, DWORD flags
)
6150 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
6151 struct ddraw_surface
*dest
= unsafe_impl_from_IDirectDrawSurface7(dst_texture
);
6152 struct ddraw_surface
*src
= unsafe_impl_from_IDirectDrawSurface7(src_texture
);
6156 TRACE("iface %p, dst_texture %p, dst_pos %s, src_texture %p, src_rect %s, flags %#x.\n",
6157 iface
, dst_texture
, wine_dbgstr_point(dst_pos
), src_texture
, wine_dbgstr_rect(src_rect
), flags
);
6159 if( (!src
) || (!dest
) )
6160 return DDERR_INVALIDPARAMS
;
6162 wined3d_mutex_lock();
6165 SetRect(&srcrect
, 0, 0, src
->surface_desc
.dwWidth
, src
->surface_desc
.dwHeight
);
6167 srcrect
= *src_rect
;
6170 destpoint
.x
= destpoint
.y
= 0;
6172 destpoint
= *dst_pos
;
6174 /* Check bad dimensions. dst_pos is validated against src, not dest, because
6175 * destination can be a subset of mip levels, in which case actual coordinates used
6176 * for it may be divided. If any dimension of dest is larger than source, it can't be
6177 * mip level subset, so an error can be returned early.
6179 if (IsRectEmpty(&srcrect
) || srcrect
.right
> src
->surface_desc
.dwWidth
||
6180 srcrect
.bottom
> src
->surface_desc
.dwHeight
||
6181 destpoint
.x
+ srcrect
.right
- srcrect
.left
> src
->surface_desc
.dwWidth
||
6182 destpoint
.y
+ srcrect
.bottom
- srcrect
.top
> src
->surface_desc
.dwHeight
||
6183 dest
->surface_desc
.dwWidth
> src
->surface_desc
.dwWidth
||
6184 dest
->surface_desc
.dwHeight
> src
->surface_desc
.dwHeight
)
6186 wined3d_mutex_unlock();
6187 return DDERR_INVALIDPARAMS
;
6190 /* Must be top level surfaces. */
6191 if (src
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_MIPMAPSUBLEVEL
||
6192 dest
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_MIPMAPSUBLEVEL
)
6194 wined3d_mutex_unlock();
6195 return DDERR_INVALIDPARAMS
;
6198 if (src
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_CUBEMAP
)
6200 struct ddraw_surface
*src_face
, *dest_face
;
6201 DWORD src_face_flag
, dest_face_flag
;
6202 IDirectDrawSurface7
*temp
;
6203 DDSURFACEDESC2 ddsd
;
6206 if (!(dest
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_CUBEMAP
))
6208 wined3d_mutex_unlock();
6209 return DDERR_INVALIDPARAMS
;
6212 /* Iterate through cube faces 2 times. First time is just to check INVALIDPARAMS conditions, second
6213 * time it's actual surface loading. */
6214 for (i
= 0; i
< 2; i
++)
6219 for (;dest_face
&& src_face
;)
6221 src_face_flag
= src_face
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_CUBEMAP_ALLFACES
;
6222 dest_face_flag
= dest_face
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_CUBEMAP_ALLFACES
;
6224 if (src_face_flag
== dest_face_flag
)
6228 /* Destination mip levels must be subset of source mip levels. */
6229 if (!is_mip_level_subset(dest_face
, src_face
))
6231 wined3d_mutex_unlock();
6232 return DDERR_INVALIDPARAMS
;
6235 else if (flags
& dest_face_flag
)
6237 copy_mipmap_chain(device
, dest_face
, src_face
, &destpoint
, &srcrect
);
6240 if (src_face_flag
< DDSCAPS2_CUBEMAP_NEGATIVEZ
)
6242 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
6243 ddsd
.ddsCaps
.dwCaps2
= DDSCAPS2_CUBEMAP
| (src_face_flag
<< 1);
6244 IDirectDrawSurface7_GetAttachedSurface(&src
->IDirectDrawSurface7_iface
, &ddsd
.ddsCaps
, &temp
);
6246 if (src_face
!= src
) IDirectDrawSurface7_Release(&src_face
->IDirectDrawSurface7_iface
);
6248 src_face
= unsafe_impl_from_IDirectDrawSurface7(temp
);
6252 if (src_face
!= src
) IDirectDrawSurface7_Release(&src_face
->IDirectDrawSurface7_iface
);
6258 if (dest_face_flag
< DDSCAPS2_CUBEMAP_NEGATIVEZ
)
6260 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
6261 ddsd
.ddsCaps
.dwCaps2
= DDSCAPS2_CUBEMAP
| (dest_face_flag
<< 1);
6262 IDirectDrawSurface7_GetAttachedSurface(&dest
->IDirectDrawSurface7_iface
, &ddsd
.ddsCaps
, &temp
);
6264 if (dest_face
!= dest
) IDirectDrawSurface7_Release(&dest_face
->IDirectDrawSurface7_iface
);
6266 dest_face
= unsafe_impl_from_IDirectDrawSurface7(temp
);
6270 if (dest_face
!= dest
) IDirectDrawSurface7_Release(&dest_face
->IDirectDrawSurface7_iface
);
6278 /* Native returns error if src faces are not subset of dest faces. */
6281 wined3d_mutex_unlock();
6282 return DDERR_INVALIDPARAMS
;
6287 wined3d_mutex_unlock();
6290 else if (dest
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_CUBEMAP
)
6292 wined3d_mutex_unlock();
6293 return DDERR_INVALIDPARAMS
;
6296 /* Handle non cube map textures. */
6298 /* Destination mip levels must be subset of source mip levels. */
6299 if (!is_mip_level_subset(dest
, src
))
6301 wined3d_mutex_unlock();
6302 return DDERR_INVALIDPARAMS
;
6305 copy_mipmap_chain(device
, dest
, src
, &destpoint
, &srcrect
);
6307 wined3d_mutex_unlock();
6312 static HRESULT WINAPI
d3d_device7_Load_FPUSetup(IDirect3DDevice7
*iface
, IDirectDrawSurface7
*dst_texture
,
6313 POINT
*dst_pos
, IDirectDrawSurface7
*src_texture
, RECT
*src_rect
, DWORD flags
)
6315 return d3d_device7_Load(iface
, dst_texture
, dst_pos
, src_texture
, src_rect
, flags
);
6318 static HRESULT WINAPI
d3d_device7_Load_FPUPreserve(IDirect3DDevice7
*iface
, IDirectDrawSurface7
*dst_texture
,
6319 POINT
*dst_pos
, IDirectDrawSurface7
*src_texture
, RECT
*src_rect
, DWORD flags
)
6324 old_fpucw
= d3d_fpu_setup();
6325 hr
= d3d_device7_Load(iface
, dst_texture
, dst_pos
, src_texture
, src_rect
, flags
);
6326 set_fpu_control_word(old_fpucw
);
6331 /*****************************************************************************
6332 * IDirect3DDevice7::LightEnable
6334 * Enables or disables a light
6336 * Version 7, IDirect3DLight uses this method too.
6339 * LightIndex: The index of the light to enable / disable
6340 * Enable: Enable or disable the light
6345 *****************************************************************************/
6346 static HRESULT
d3d_device7_LightEnable(IDirect3DDevice7
*iface
, DWORD light_idx
, BOOL enabled
)
6348 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
6351 TRACE("iface %p, light_idx %u, enabled %#x.\n", iface
, light_idx
, enabled
);
6353 wined3d_mutex_lock();
6354 hr
= wined3d_device_set_light_enable(device
->wined3d_device
, light_idx
, enabled
);
6355 wined3d_mutex_unlock();
6357 return hr_ddraw_from_wined3d(hr
);
6360 static HRESULT WINAPI
d3d_device7_LightEnable_FPUSetup(IDirect3DDevice7
*iface
, DWORD light_idx
, BOOL enabled
)
6362 return d3d_device7_LightEnable(iface
, light_idx
, enabled
);
6365 static HRESULT WINAPI
d3d_device7_LightEnable_FPUPreserve(IDirect3DDevice7
*iface
, DWORD light_idx
, BOOL enabled
)
6370 old_fpucw
= d3d_fpu_setup();
6371 hr
= d3d_device7_LightEnable(iface
, light_idx
, enabled
);
6372 set_fpu_control_word(old_fpucw
);
6377 /*****************************************************************************
6378 * IDirect3DDevice7::GetLightEnable
6380 * Retrieves if the light with the given index is enabled or not
6385 * LightIndex: Index of desired light
6386 * Enable: Pointer to a BOOL which contains the result
6390 * DDERR_INVALIDPARAMS if Enable is NULL
6392 *****************************************************************************/
6393 static HRESULT
d3d_device7_GetLightEnable(IDirect3DDevice7
*iface
, DWORD light_idx
, BOOL
*enabled
)
6395 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
6398 TRACE("iface %p, light_idx %u, enabled %p.\n", iface
, light_idx
, enabled
);
6401 return DDERR_INVALIDPARAMS
;
6403 wined3d_mutex_lock();
6404 hr
= wined3d_device_get_light_enable(device
->wined3d_device
, light_idx
, enabled
);
6405 wined3d_mutex_unlock();
6407 return hr_ddraw_from_wined3d(hr
);
6410 static HRESULT WINAPI
d3d_device7_GetLightEnable_FPUSetup(IDirect3DDevice7
*iface
, DWORD light_idx
, BOOL
*enabled
)
6412 return d3d_device7_GetLightEnable(iface
, light_idx
, enabled
);
6415 static HRESULT WINAPI
d3d_device7_GetLightEnable_FPUPreserve(IDirect3DDevice7
*iface
, DWORD light_idx
, BOOL
*enabled
)
6420 old_fpucw
= d3d_fpu_setup();
6421 hr
= d3d_device7_GetLightEnable(iface
, light_idx
, enabled
);
6422 set_fpu_control_word(old_fpucw
);
6427 /*****************************************************************************
6428 * IDirect3DDevice7::SetClipPlane
6430 * Sets custom clipping plane
6435 * Index: The index of the clipping plane
6436 * PlaneEquation: An equation defining the clipping plane
6440 * DDERR_INVALIDPARAMS if PlaneEquation is NULL
6442 *****************************************************************************/
6443 static HRESULT
d3d_device7_SetClipPlane(IDirect3DDevice7
*iface
, DWORD idx
, D3DVALUE
*plane
)
6445 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
6448 TRACE("iface %p, idx %u, plane %p.\n", iface
, idx
, plane
);
6451 return DDERR_INVALIDPARAMS
;
6453 wined3d_mutex_lock();
6454 hr
= wined3d_device_set_clip_plane(device
->wined3d_device
, idx
, (struct wined3d_vec4
*)plane
);
6455 wined3d_mutex_unlock();
6460 static HRESULT WINAPI
d3d_device7_SetClipPlane_FPUSetup(IDirect3DDevice7
*iface
, DWORD idx
, D3DVALUE
*plane
)
6462 return d3d_device7_SetClipPlane(iface
, idx
, plane
);
6465 static HRESULT WINAPI
d3d_device7_SetClipPlane_FPUPreserve(IDirect3DDevice7
*iface
, DWORD idx
, D3DVALUE
*plane
)
6470 old_fpucw
= d3d_fpu_setup();
6471 hr
= d3d_device7_SetClipPlane(iface
, idx
, plane
);
6472 set_fpu_control_word(old_fpucw
);
6477 /*****************************************************************************
6478 * IDirect3DDevice7::GetClipPlane
6480 * Returns the clipping plane with a specific index
6483 * Index: The index of the desired plane
6484 * PlaneEquation: Address to store the plane equation to
6488 * DDERR_INVALIDPARAMS if PlaneEquation is NULL
6490 *****************************************************************************/
6491 static HRESULT
d3d_device7_GetClipPlane(IDirect3DDevice7
*iface
, DWORD idx
, D3DVALUE
*plane
)
6493 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
6496 TRACE("iface %p, idx %u, plane %p.\n", iface
, idx
, plane
);
6499 return DDERR_INVALIDPARAMS
;
6501 wined3d_mutex_lock();
6502 hr
= wined3d_device_get_clip_plane(device
->wined3d_device
, idx
, (struct wined3d_vec4
*)plane
);
6503 wined3d_mutex_unlock();
6508 static HRESULT WINAPI
d3d_device7_GetClipPlane_FPUSetup(IDirect3DDevice7
*iface
, DWORD idx
, D3DVALUE
*plane
)
6510 return d3d_device7_GetClipPlane(iface
, idx
, plane
);
6513 static HRESULT WINAPI
d3d_device7_GetClipPlane_FPUPreserve(IDirect3DDevice7
*iface
, DWORD idx
, D3DVALUE
*plane
)
6518 old_fpucw
= d3d_fpu_setup();
6519 hr
= d3d_device7_GetClipPlane(iface
, idx
, plane
);
6520 set_fpu_control_word(old_fpucw
);
6525 /*****************************************************************************
6526 * IDirect3DDevice7::GetInfo
6528 * Retrieves some information about the device. The DirectX sdk says that
6529 * this version returns S_FALSE for all retail builds of DirectX, that's what
6530 * this implementation does.
6533 * DevInfoID: Information type requested
6534 * DevInfoStruct: Pointer to a structure to store the info to
6535 * Size: Size of the structure
6538 * S_FALSE, because it's a non-debug driver
6540 *****************************************************************************/
6541 static HRESULT WINAPI
d3d_device7_GetInfo(IDirect3DDevice7
*iface
, DWORD info_id
, void *info
, DWORD info_size
)
6543 TRACE("iface %p, info_id %#x, info %p, info_size %u.\n",
6544 iface
, info_id
, info
, info_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 d3d_device7_QueryInterface
,
6576 d3d_device7_Release
,
6577 /*** IDirect3DDevice7 ***/
6578 d3d_device7_GetCaps_FPUSetup
,
6579 d3d_device7_EnumTextureFormats_FPUSetup
,
6580 d3d_device7_BeginScene_FPUSetup
,
6581 d3d_device7_EndScene_FPUSetup
,
6582 d3d_device7_GetDirect3D
,
6583 d3d_device7_SetRenderTarget_FPUSetup
,
6584 d3d_device7_GetRenderTarget
,
6585 d3d_device7_Clear_FPUSetup
,
6586 d3d_device7_SetTransform_FPUSetup
,
6587 d3d_device7_GetTransform_FPUSetup
,
6588 d3d_device7_SetViewport_FPUSetup
,
6589 d3d_device7_MultiplyTransform_FPUSetup
,
6590 d3d_device7_GetViewport_FPUSetup
,
6591 d3d_device7_SetMaterial_FPUSetup
,
6592 d3d_device7_GetMaterial_FPUSetup
,
6593 d3d_device7_SetLight_FPUSetup
,
6594 d3d_device7_GetLight_FPUSetup
,
6595 d3d_device7_SetRenderState_FPUSetup
,
6596 d3d_device7_GetRenderState_FPUSetup
,
6597 d3d_device7_BeginStateBlock_FPUSetup
,
6598 d3d_device7_EndStateBlock_FPUSetup
,
6599 d3d_device7_PreLoad_FPUSetup
,
6600 d3d_device7_DrawPrimitive_FPUSetup
,
6601 d3d_device7_DrawIndexedPrimitive_FPUSetup
,
6602 d3d_device7_SetClipStatus
,
6603 d3d_device7_GetClipStatus
,
6604 d3d_device7_DrawPrimitiveStrided_FPUSetup
,
6605 d3d_device7_DrawIndexedPrimitiveStrided_FPUSetup
,
6606 d3d_device7_DrawPrimitiveVB_FPUSetup
,
6607 d3d_device7_DrawIndexedPrimitiveVB_FPUSetup
,
6608 d3d_device7_ComputeSphereVisibility
,
6609 d3d_device7_GetTexture_FPUSetup
,
6610 d3d_device7_SetTexture_FPUSetup
,
6611 d3d_device7_GetTextureStageState_FPUSetup
,
6612 d3d_device7_SetTextureStageState_FPUSetup
,
6613 d3d_device7_ValidateDevice_FPUSetup
,
6614 d3d_device7_ApplyStateBlock_FPUSetup
,
6615 d3d_device7_CaptureStateBlock_FPUSetup
,
6616 d3d_device7_DeleteStateBlock_FPUSetup
,
6617 d3d_device7_CreateStateBlock_FPUSetup
,
6618 d3d_device7_Load_FPUSetup
,
6619 d3d_device7_LightEnable_FPUSetup
,
6620 d3d_device7_GetLightEnable_FPUSetup
,
6621 d3d_device7_SetClipPlane_FPUSetup
,
6622 d3d_device7_GetClipPlane_FPUSetup
,
6626 static const struct IDirect3DDevice7Vtbl d3d_device7_fpu_preserve_vtbl
=
6628 /*** IUnknown Methods ***/
6629 d3d_device7_QueryInterface
,
6631 d3d_device7_Release
,
6632 /*** IDirect3DDevice7 ***/
6633 d3d_device7_GetCaps_FPUPreserve
,
6634 d3d_device7_EnumTextureFormats_FPUPreserve
,
6635 d3d_device7_BeginScene_FPUPreserve
,
6636 d3d_device7_EndScene_FPUPreserve
,
6637 d3d_device7_GetDirect3D
,
6638 d3d_device7_SetRenderTarget_FPUPreserve
,
6639 d3d_device7_GetRenderTarget
,
6640 d3d_device7_Clear_FPUPreserve
,
6641 d3d_device7_SetTransform_FPUPreserve
,
6642 d3d_device7_GetTransform_FPUPreserve
,
6643 d3d_device7_SetViewport_FPUPreserve
,
6644 d3d_device7_MultiplyTransform_FPUPreserve
,
6645 d3d_device7_GetViewport_FPUPreserve
,
6646 d3d_device7_SetMaterial_FPUPreserve
,
6647 d3d_device7_GetMaterial_FPUPreserve
,
6648 d3d_device7_SetLight_FPUPreserve
,
6649 d3d_device7_GetLight_FPUPreserve
,
6650 d3d_device7_SetRenderState_FPUPreserve
,
6651 d3d_device7_GetRenderState_FPUPreserve
,
6652 d3d_device7_BeginStateBlock_FPUPreserve
,
6653 d3d_device7_EndStateBlock_FPUPreserve
,
6654 d3d_device7_PreLoad_FPUPreserve
,
6655 d3d_device7_DrawPrimitive_FPUPreserve
,
6656 d3d_device7_DrawIndexedPrimitive_FPUPreserve
,
6657 d3d_device7_SetClipStatus
,
6658 d3d_device7_GetClipStatus
,
6659 d3d_device7_DrawPrimitiveStrided_FPUPreserve
,
6660 d3d_device7_DrawIndexedPrimitiveStrided_FPUPreserve
,
6661 d3d_device7_DrawPrimitiveVB_FPUPreserve
,
6662 d3d_device7_DrawIndexedPrimitiveVB_FPUPreserve
,
6663 d3d_device7_ComputeSphereVisibility
,
6664 d3d_device7_GetTexture_FPUPreserve
,
6665 d3d_device7_SetTexture_FPUPreserve
,
6666 d3d_device7_GetTextureStageState_FPUPreserve
,
6667 d3d_device7_SetTextureStageState_FPUPreserve
,
6668 d3d_device7_ValidateDevice_FPUPreserve
,
6669 d3d_device7_ApplyStateBlock_FPUPreserve
,
6670 d3d_device7_CaptureStateBlock_FPUPreserve
,
6671 d3d_device7_DeleteStateBlock_FPUPreserve
,
6672 d3d_device7_CreateStateBlock_FPUPreserve
,
6673 d3d_device7_Load_FPUPreserve
,
6674 d3d_device7_LightEnable_FPUPreserve
,
6675 d3d_device7_GetLightEnable_FPUPreserve
,
6676 d3d_device7_SetClipPlane_FPUPreserve
,
6677 d3d_device7_GetClipPlane_FPUPreserve
,
6681 static const struct IDirect3DDevice3Vtbl d3d_device3_vtbl
=
6683 /*** IUnknown Methods ***/
6684 d3d_device3_QueryInterface
,
6686 d3d_device3_Release
,
6687 /*** IDirect3DDevice3 ***/
6688 d3d_device3_GetCaps
,
6689 d3d_device3_GetStats
,
6690 d3d_device3_AddViewport
,
6691 d3d_device3_DeleteViewport
,
6692 d3d_device3_NextViewport
,
6693 d3d_device3_EnumTextureFormats
,
6694 d3d_device3_BeginScene
,
6695 d3d_device3_EndScene
,
6696 d3d_device3_GetDirect3D
,
6697 d3d_device3_SetCurrentViewport
,
6698 d3d_device3_GetCurrentViewport
,
6699 d3d_device3_SetRenderTarget
,
6700 d3d_device3_GetRenderTarget
,
6702 d3d_device3_BeginIndexed
,
6706 d3d_device3_GetRenderState
,
6707 d3d_device3_SetRenderState
,
6708 d3d_device3_GetLightState
,
6709 d3d_device3_SetLightState
,
6710 d3d_device3_SetTransform
,
6711 d3d_device3_GetTransform
,
6712 d3d_device3_MultiplyTransform
,
6713 d3d_device3_DrawPrimitive
,
6714 d3d_device3_DrawIndexedPrimitive
,
6715 d3d_device3_SetClipStatus
,
6716 d3d_device3_GetClipStatus
,
6717 d3d_device3_DrawPrimitiveStrided
,
6718 d3d_device3_DrawIndexedPrimitiveStrided
,
6719 d3d_device3_DrawPrimitiveVB
,
6720 d3d_device3_DrawIndexedPrimitiveVB
,
6721 d3d_device3_ComputeSphereVisibility
,
6722 d3d_device3_GetTexture
,
6723 d3d_device3_SetTexture
,
6724 d3d_device3_GetTextureStageState
,
6725 d3d_device3_SetTextureStageState
,
6726 d3d_device3_ValidateDevice
6729 static const struct IDirect3DDevice2Vtbl d3d_device2_vtbl
=
6731 /*** IUnknown Methods ***/
6732 d3d_device2_QueryInterface
,
6734 d3d_device2_Release
,
6735 /*** IDirect3DDevice2 ***/
6736 d3d_device2_GetCaps
,
6737 d3d_device2_SwapTextureHandles
,
6738 d3d_device2_GetStats
,
6739 d3d_device2_AddViewport
,
6740 d3d_device2_DeleteViewport
,
6741 d3d_device2_NextViewport
,
6742 d3d_device2_EnumTextureFormats
,
6743 d3d_device2_BeginScene
,
6744 d3d_device2_EndScene
,
6745 d3d_device2_GetDirect3D
,
6746 d3d_device2_SetCurrentViewport
,
6747 d3d_device2_GetCurrentViewport
,
6748 d3d_device2_SetRenderTarget
,
6749 d3d_device2_GetRenderTarget
,
6751 d3d_device2_BeginIndexed
,
6755 d3d_device2_GetRenderState
,
6756 d3d_device2_SetRenderState
,
6757 d3d_device2_GetLightState
,
6758 d3d_device2_SetLightState
,
6759 d3d_device2_SetTransform
,
6760 d3d_device2_GetTransform
,
6761 d3d_device2_MultiplyTransform
,
6762 d3d_device2_DrawPrimitive
,
6763 d3d_device2_DrawIndexedPrimitive
,
6764 d3d_device2_SetClipStatus
,
6765 d3d_device2_GetClipStatus
6768 static const struct IDirect3DDeviceVtbl d3d_device1_vtbl
=
6770 /*** IUnknown Methods ***/
6771 d3d_device1_QueryInterface
,
6773 d3d_device1_Release
,
6774 /*** IDirect3DDevice1 ***/
6775 d3d_device1_Initialize
,
6776 d3d_device1_GetCaps
,
6777 d3d_device1_SwapTextureHandles
,
6778 d3d_device1_CreateExecuteBuffer
,
6779 d3d_device1_GetStats
,
6780 d3d_device1_Execute
,
6781 d3d_device1_AddViewport
,
6782 d3d_device1_DeleteViewport
,
6783 d3d_device1_NextViewport
,
6785 d3d_device1_GetPickRecords
,
6786 d3d_device1_EnumTextureFormats
,
6787 d3d_device1_CreateMatrix
,
6788 d3d_device1_SetMatrix
,
6789 d3d_device1_GetMatrix
,
6790 d3d_device1_DeleteMatrix
,
6791 d3d_device1_BeginScene
,
6792 d3d_device1_EndScene
,
6793 d3d_device1_GetDirect3D
6796 static const struct IUnknownVtbl d3d_device_inner_vtbl
=
6798 d3d_device_inner_QueryInterface
,
6799 d3d_device_inner_AddRef
,
6800 d3d_device_inner_Release
,
6803 struct d3d_device
*unsafe_impl_from_IDirect3DDevice7(IDirect3DDevice7
*iface
)
6805 if (!iface
) return NULL
;
6806 assert((iface
->lpVtbl
== &d3d_device7_fpu_preserve_vtbl
) || (iface
->lpVtbl
== &d3d_device7_fpu_setup_vtbl
));
6807 return CONTAINING_RECORD(iface
, struct d3d_device
, IDirect3DDevice7_iface
);
6810 struct d3d_device
*unsafe_impl_from_IDirect3DDevice3(IDirect3DDevice3
*iface
)
6812 if (!iface
) return NULL
;
6813 assert(iface
->lpVtbl
== &d3d_device3_vtbl
);
6814 return CONTAINING_RECORD(iface
, struct d3d_device
, IDirect3DDevice3_iface
);
6817 struct d3d_device
*unsafe_impl_from_IDirect3DDevice2(IDirect3DDevice2
*iface
)
6819 if (!iface
) return NULL
;
6820 assert(iface
->lpVtbl
== &d3d_device2_vtbl
);
6821 return CONTAINING_RECORD(iface
, struct d3d_device
, IDirect3DDevice2_iface
);
6824 struct d3d_device
*unsafe_impl_from_IDirect3DDevice(IDirect3DDevice
*iface
)
6826 if (!iface
) return NULL
;
6827 assert(iface
->lpVtbl
== &d3d_device1_vtbl
);
6828 return CONTAINING_RECORD(iface
, struct d3d_device
, IDirect3DDevice_iface
);
6831 enum wined3d_depth_buffer_type
d3d_device_update_depth_stencil(struct d3d_device
*device
)
6833 IDirectDrawSurface7
*depthStencil
= NULL
;
6834 IDirectDrawSurface7
*render_target
;
6835 static DDSCAPS2 depthcaps
= { DDSCAPS_ZBUFFER
, 0, 0, {0} };
6836 struct ddraw_surface
*dsi
;
6838 if (device
->rt_iface
&& SUCCEEDED(IUnknown_QueryInterface(device
->rt_iface
,
6839 &IID_IDirectDrawSurface7
, (void **)&render_target
)))
6841 IDirectDrawSurface7_GetAttachedSurface(render_target
, &depthcaps
, &depthStencil
);
6842 IDirectDrawSurface7_Release(render_target
);
6846 TRACE("Setting wined3d depth stencil to NULL\n");
6847 wined3d_device_set_depth_stencil_view(device
->wined3d_device
, NULL
);
6848 return WINED3D_ZB_FALSE
;
6851 dsi
= impl_from_IDirectDrawSurface7(depthStencil
);
6852 wined3d_device_set_depth_stencil_view(device
->wined3d_device
,
6853 ddraw_surface_get_rendertarget_view(dsi
));
6855 IDirectDrawSurface7_Release(depthStencil
);
6856 return WINED3D_ZB_TRUE
;
6859 static HRESULT
d3d_device_init(struct d3d_device
*device
, struct ddraw
*ddraw
,
6860 struct ddraw_surface
*target
, IUnknown
*rt_iface
, UINT version
, IUnknown
*outer_unknown
)
6862 static const D3DMATRIX ident
=
6864 1.0f
, 0.0f
, 0.0f
, 0.0f
,
6865 0.0f
, 1.0f
, 0.0f
, 0.0f
,
6866 0.0f
, 0.0f
, 1.0f
, 0.0f
,
6867 0.0f
, 0.0f
, 0.0f
, 1.0f
,
6871 if (ddraw
->cooperative_level
& DDSCL_FPUPRESERVE
)
6872 device
->IDirect3DDevice7_iface
.lpVtbl
= &d3d_device7_fpu_preserve_vtbl
;
6874 device
->IDirect3DDevice7_iface
.lpVtbl
= &d3d_device7_fpu_setup_vtbl
;
6876 device
->IDirect3DDevice3_iface
.lpVtbl
= &d3d_device3_vtbl
;
6877 device
->IDirect3DDevice2_iface
.lpVtbl
= &d3d_device2_vtbl
;
6878 device
->IDirect3DDevice_iface
.lpVtbl
= &d3d_device1_vtbl
;
6879 device
->IUnknown_inner
.lpVtbl
= &d3d_device_inner_vtbl
;
6881 device
->version
= version
;
6884 device
->outer_unknown
= outer_unknown
;
6886 device
->outer_unknown
= &device
->IUnknown_inner
;
6888 device
->ddraw
= ddraw
;
6889 list_init(&device
->viewport_list
);
6891 if (!ddraw_handle_table_init(&device
->handle_table
, 64))
6893 ERR("Failed to initialize handle table.\n");
6894 return DDERR_OUTOFMEMORY
;
6897 device
->legacyTextureBlending
= FALSE
;
6898 device
->legacy_projection
= ident
;
6899 device
->legacy_clipspace
= ident
;
6901 /* This is for convenience. */
6902 device
->wined3d_device
= ddraw
->wined3d_device
;
6903 wined3d_device_incref(ddraw
->wined3d_device
);
6905 /* Render to the back buffer */
6906 if (FAILED(hr
= wined3d_device_set_rendertarget_view(ddraw
->wined3d_device
,
6907 0, ddraw_surface_get_rendertarget_view(target
), TRUE
)))
6909 ERR("Failed to set render target, hr %#x.\n", hr
);
6910 ddraw_handle_table_destroy(&device
->handle_table
);
6914 device
->rt_iface
= rt_iface
;
6916 IUnknown_AddRef(device
->rt_iface
);
6918 ddraw
->d3ddevice
= device
;
6920 wined3d_device_set_render_state(ddraw
->wined3d_device
, WINED3D_RS_ZENABLE
,
6921 d3d_device_update_depth_stencil(device
));
6922 if (version
== 1) /* Color keying is initially enabled for version 1 devices. */
6923 wined3d_device_set_render_state(ddraw
->wined3d_device
, WINED3D_RS_COLORKEYENABLE
, TRUE
);
6924 else if (version
== 2)
6925 wined3d_device_set_render_state(ddraw
->wined3d_device
, WINED3D_RS_SPECULARENABLE
, TRUE
);
6927 wined3d_device_set_render_state(ddraw
->wined3d_device
, WINED3D_RS_NORMALIZENORMALS
, TRUE
);
6932 HRESULT
d3d_device_create(struct ddraw
*ddraw
, struct ddraw_surface
*target
, IUnknown
*rt_iface
,
6933 UINT version
, struct d3d_device
**device
, IUnknown
*outer_unknown
)
6935 struct d3d_device
*object
;
6938 TRACE("ddraw %p, target %p, version %u, device %p, outer_unknown %p.\n",
6939 ddraw
, target
, version
, device
, outer_unknown
);
6941 if (!(target
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_3DDEVICE
)
6942 || (target
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_ZBUFFER
))
6944 WARN("Surface %p is not a render target.\n", target
);
6945 return DDERR_INVALIDCAPS
;
6948 if (!validate_surface_palette(target
))
6950 WARN("Surface %p has an indexed pixel format, but no palette.\n", target
);
6951 return DDERR_NOPALETTEATTACHED
;
6954 if (!(target
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_VIDEOMEMORY
))
6956 WARN("Surface %p is not in video memory.\n", target
);
6957 return D3DERR_SURFACENOTINVIDMEM
;
6960 if (ddraw
->flags
& DDRAW_NO3D
)
6962 ERR_(winediag
)("The application wants to create a Direct3D device, "
6963 "but the current DirectDrawRenderer does not support this.\n");
6968 if (ddraw
->d3ddevice
)
6970 FIXME("Only one Direct3D device per DirectDraw object supported.\n");
6971 return DDERR_INVALIDPARAMS
;
6974 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*object
));
6977 ERR("Failed to allocate device memory.\n");
6978 return DDERR_OUTOFMEMORY
;
6981 if (FAILED(hr
= d3d_device_init(object
, ddraw
, target
, rt_iface
, version
, outer_unknown
)))
6983 WARN("Failed to initialize device, hr %#x.\n", hr
);
6984 HeapFree(GetProcessHeap(), 0, object
);
6988 TRACE("Created device %p.\n", object
);