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
30 #include "ddraw_private.h"
32 WINE_DECLARE_DEBUG_CHANNEL(winediag
);
35 const GUID IID_D3DDEVICE_WineD3D
= {
39 { 0xb7,0x98,0xc6,0x8a,0x77,0x2d,0x72,0x2a }
42 static inline void set_fpu_control_word(WORD fpucw
)
44 #if defined(__i386__) && defined(__GNUC__)
45 __asm__
volatile ("fldcw %0" : : "m" (fpucw
));
46 #elif defined(__i386__) && defined(_MSC_VER)
51 static inline WORD
d3d_fpu_setup(void)
55 #if defined(__i386__) && defined(__GNUC__)
56 __asm__
volatile ("fnstcw %0" : "=m" (oldcw
));
57 #elif defined(__i386__) && defined(_MSC_VER)
60 static BOOL warned
= FALSE
;
63 FIXME("FPUPRESERVE not implemented for this platform / compiler\n");
69 set_fpu_control_word(0x37f);
74 static inline struct d3d_device
*impl_from_IUnknown(IUnknown
*iface
)
76 return CONTAINING_RECORD(iface
, struct d3d_device
, IUnknown_inner
);
79 static HRESULT WINAPI
d3d_device_inner_QueryInterface(IUnknown
*iface
, REFIID riid
, void **out
)
81 struct d3d_device
*device
= impl_from_IUnknown(iface
);
83 TRACE("iface %p, riid %s, out %p.\n", iface
, debugstr_guid(riid
), out
);
88 return DDERR_INVALIDPARAMS
;
91 if (IsEqualGUID(&IID_IUnknown
, riid
))
93 IDirect3DDevice7_AddRef(&device
->IDirect3DDevice7_iface
);
94 *out
= &device
->IDirect3DDevice7_iface
;
98 if (device
->version
== 7)
100 if (IsEqualGUID(&IID_IDirect3DDevice7
, riid
))
102 IDirect3DDevice7_AddRef(&device
->IDirect3DDevice7_iface
);
103 *out
= &device
->IDirect3DDevice7_iface
;
109 if (IsEqualGUID(&IID_IDirect3DDevice3
, riid
) && device
->version
== 3)
111 IDirect3DDevice3_AddRef(&device
->IDirect3DDevice3_iface
);
112 *out
= &device
->IDirect3DDevice3_iface
;
116 if (IsEqualGUID(&IID_IDirect3DDevice2
, riid
) && device
->version
>= 2)
118 IDirect3DDevice2_AddRef(&device
->IDirect3DDevice2_iface
);
119 *out
= &device
->IDirect3DDevice2_iface
;
123 if (IsEqualGUID(&IID_IDirect3DDevice
, riid
))
125 IDirect3DDevice_AddRef(&device
->IDirect3DDevice_iface
);
126 *out
= &device
->IDirect3DDevice_iface
;
131 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid
));
134 return E_NOINTERFACE
;
137 static HRESULT WINAPI
d3d_device7_QueryInterface(IDirect3DDevice7
*iface
, REFIID riid
, void **out
)
139 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
141 TRACE("iface %p, riid %s, out %p.\n", iface
, debugstr_guid(riid
), out
);
143 return IUnknown_QueryInterface(device
->outer_unknown
, riid
, out
);
146 static HRESULT WINAPI
d3d_device3_QueryInterface(IDirect3DDevice3
*iface
, REFIID riid
, void **out
)
148 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
150 TRACE("iface %p, riid %s, out %p.\n", iface
, debugstr_guid(riid
), out
);
152 return IUnknown_QueryInterface(device
->outer_unknown
, riid
, out
);
155 static HRESULT WINAPI
d3d_device2_QueryInterface(IDirect3DDevice2
*iface
, REFIID riid
, void **out
)
157 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
159 TRACE("iface %p, riid %s, out %p.\n", iface
, debugstr_guid(riid
), out
);
161 return IUnknown_QueryInterface(device
->outer_unknown
, riid
, out
);
164 static HRESULT WINAPI
d3d_device1_QueryInterface(IDirect3DDevice
*iface
, REFIID riid
, void **out
)
166 struct d3d_device
*device
= impl_from_IDirect3DDevice(iface
);
168 TRACE("iface %p, riid %s, out %p.\n", iface
, debugstr_guid(riid
), out
);
170 return IUnknown_QueryInterface(device
->outer_unknown
, riid
, out
);
173 static ULONG WINAPI
d3d_device_inner_AddRef(IUnknown
*iface
)
175 struct d3d_device
*device
= impl_from_IUnknown(iface
);
176 ULONG ref
= InterlockedIncrement(&device
->ref
);
178 TRACE("%p increasing refcount to %u.\n", device
, ref
);
183 static ULONG WINAPI
d3d_device7_AddRef(IDirect3DDevice7
*iface
)
185 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
187 TRACE("iface %p.\n", iface
);
189 return IUnknown_AddRef(device
->outer_unknown
);
192 static ULONG WINAPI
d3d_device3_AddRef(IDirect3DDevice3
*iface
)
194 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
196 TRACE("iface %p.\n", iface
);
198 return IUnknown_AddRef(device
->outer_unknown
);
201 static ULONG WINAPI
d3d_device2_AddRef(IDirect3DDevice2
*iface
)
203 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
205 TRACE("iface %p.\n", iface
);
207 return IUnknown_AddRef(device
->outer_unknown
);
210 static ULONG WINAPI
d3d_device1_AddRef(IDirect3DDevice
*iface
)
212 struct d3d_device
*device
= impl_from_IDirect3DDevice(iface
);
214 TRACE("iface %p.\n", iface
);
216 return IUnknown_AddRef(device
->outer_unknown
);
219 static ULONG WINAPI
d3d_device_inner_Release(IUnknown
*iface
)
221 struct d3d_device
*This
= impl_from_IUnknown(iface
);
222 ULONG ref
= InterlockedDecrement(&This
->ref
);
225 TRACE("%p decreasing refcount to %u.\n", This
, ref
);
227 /* This method doesn't destroy the wined3d device, because it's still in
228 * use for 2D rendering. IDirectDrawSurface7::Release will destroy the
229 * wined3d device when the render target is released. */
233 struct list
*vp_entry
, *vp_entry2
;
235 wined3d_mutex_lock();
237 /* There is no need to unset any resources here, wined3d will take
238 * care of that on uninit_3d(). */
240 if (This
->index_buffer
)
241 wined3d_buffer_decref(This
->index_buffer
);
242 if (This
->vertex_buffer
)
243 wined3d_buffer_decref(This
->vertex_buffer
);
245 wined3d_device_set_rendertarget_view(This
->wined3d_device
, 0, NULL
, FALSE
);
247 /* Release the wined3d device. This won't destroy it. */
248 if (!wined3d_device_decref(This
->wined3d_device
))
249 ERR("The wined3d device (%p) was destroyed unexpectedly.\n", This
->wined3d_device
);
251 /* The texture handles should be unset by now, but there might be some bits
252 * missing in our reference counting(needs test). Do a sanity check. */
253 for (i
= 0; i
< This
->handle_table
.entry_count
; ++i
)
255 struct ddraw_handle_entry
*entry
= &This
->handle_table
.entries
[i
];
259 case DDRAW_HANDLE_FREE
:
262 case DDRAW_HANDLE_MATERIAL
:
264 struct d3d_material
*m
= entry
->object
;
265 FIXME("Material handle %#x (%p) not unset properly.\n", i
+ 1, m
);
270 case DDRAW_HANDLE_MATRIX
:
272 /* No FIXME here because this might happen because of sloppy applications. */
273 WARN("Leftover matrix handle %#x (%p), deleting.\n", i
+ 1, entry
->object
);
274 IDirect3DDevice_DeleteMatrix(&This
->IDirect3DDevice_iface
, i
+ 1);
278 case DDRAW_HANDLE_STATEBLOCK
:
280 /* No FIXME here because this might happen because of sloppy applications. */
281 WARN("Leftover stateblock handle %#x (%p), deleting.\n", i
+ 1, entry
->object
);
282 IDirect3DDevice7_DeleteStateBlock(&This
->IDirect3DDevice7_iface
, i
+ 1);
286 case DDRAW_HANDLE_SURFACE
:
288 struct ddraw_surface
*surf
= entry
->object
;
289 FIXME("Texture handle %#x (%p) not unset properly.\n", i
+ 1, surf
);
295 FIXME("Handle %#x (%p) has unknown type %#x.\n", i
+ 1, entry
->object
, entry
->type
);
300 ddraw_handle_table_destroy(&This
->handle_table
);
302 LIST_FOR_EACH_SAFE(vp_entry
, vp_entry2
, &This
->viewport_list
)
304 struct d3d_viewport
*vp
= LIST_ENTRY(vp_entry
, struct d3d_viewport
, entry
);
305 IDirect3DDevice3_DeleteViewport(&This
->IDirect3DDevice3_iface
, &vp
->IDirect3DViewport3_iface
);
308 TRACE("Releasing render target %p.\n", This
->rt_iface
);
309 rt_iface
= This
->rt_iface
;
310 This
->rt_iface
= NULL
;
311 if (This
->version
!= 1)
312 IUnknown_Release(rt_iface
);
313 TRACE("Render target release done.\n");
315 /* Releasing the render target above may have released the last
316 * reference to the ddraw object. */
318 This
->ddraw
->d3ddevice
= NULL
;
320 /* Now free the structure */
321 HeapFree(GetProcessHeap(), 0, This
);
322 wined3d_mutex_unlock();
329 static ULONG WINAPI
d3d_device7_Release(IDirect3DDevice7
*iface
)
331 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
333 TRACE("iface %p.\n", iface
);
335 return IUnknown_Release(device
->outer_unknown
);
338 static ULONG WINAPI
d3d_device3_Release(IDirect3DDevice3
*iface
)
340 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
342 TRACE("iface %p.\n", iface
);
344 return IUnknown_Release(device
->outer_unknown
);
347 static ULONG WINAPI
d3d_device2_Release(IDirect3DDevice2
*iface
)
349 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
351 TRACE("iface %p.\n", iface
);
353 return IUnknown_Release(device
->outer_unknown
);
356 static ULONG WINAPI
d3d_device1_Release(IDirect3DDevice
*iface
)
358 struct d3d_device
*device
= impl_from_IDirect3DDevice(iface
);
360 TRACE("iface %p.\n", iface
);
362 return IUnknown_Release(device
->outer_unknown
);
365 /*****************************************************************************
366 * IDirect3DDevice Methods
367 *****************************************************************************/
369 /*****************************************************************************
370 * IDirect3DDevice::Initialize
372 * Initializes a Direct3DDevice. This implementation is a no-op, as all
373 * initialization is done at create time.
375 * Exists in Version 1
378 * No idea what they mean, as the MSDN page is gone
382 *****************************************************************************/
383 static HRESULT WINAPI
d3d_device1_Initialize(IDirect3DDevice
*iface
,
384 IDirect3D
*d3d
, GUID
*guid
, D3DDEVICEDESC
*device_desc
)
386 /* It shouldn't be crucial, but print a FIXME, I'm interested if
387 * any game calls it and when. */
388 FIXME("iface %p, d3d %p, guid %s, device_desc %p nop!\n",
389 iface
, d3d
, debugstr_guid(guid
), device_desc
);
394 static HRESULT
d3d_device7_GetCaps(IDirect3DDevice7
*iface
, D3DDEVICEDESC7
*device_desc
)
396 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
398 TRACE("iface %p, device_desc %p.\n", iface
, device_desc
);
402 WARN("device_desc is NULL, returning DDERR_INVALIDPARAMS.\n");
403 return DDERR_INVALIDPARAMS
;
406 /* Call the same function used by IDirect3D, this saves code */
407 return ddraw_get_d3dcaps(device
->ddraw
, device_desc
);
410 static HRESULT WINAPI
d3d_device7_GetCaps_FPUSetup(IDirect3DDevice7
*iface
, D3DDEVICEDESC7
*desc
)
412 return d3d_device7_GetCaps(iface
, desc
);
415 static HRESULT WINAPI
d3d_device7_GetCaps_FPUPreserve(IDirect3DDevice7
*iface
, D3DDEVICEDESC7
*desc
)
420 old_fpucw
= d3d_fpu_setup();
421 hr
= d3d_device7_GetCaps(iface
, desc
);
422 set_fpu_control_word(old_fpucw
);
426 /*****************************************************************************
427 * IDirect3DDevice3::GetCaps
429 * Retrieves the capabilities of the hardware device and the emulation
430 * device. For Wine, hardware and emulation are the same (it's all HW).
432 * This implementation is used for Version 1, 2, and 3. Version 7 has its own
435 * HWDesc: Structure to fill with the HW caps
436 * HelDesc: Structure to fill with the hardware emulation caps
440 * D3DERR_* if a problem occurs. See WineD3D
442 *****************************************************************************/
444 /* There are 3 versions of D3DDEVICEDESC. All 3 share the same name because
445 * Microsoft just expanded the existing structure without naming them
446 * D3DDEVICEDESC2 and D3DDEVICEDESC3. Which version is used have depends
447 * on the version of the DirectX SDK. DirectX 6+ and Wine use the latest
448 * one with 252 bytes.
450 * All 3 versions are allowed as parameters and only the specified amount of
453 * Note that Direct3D7 and earlier are not available in native Win64
454 * ddraw.dll builds, so possible size differences between 32 bit and
455 * 64 bit are a non-issue.
457 static inline BOOL
check_d3ddevicedesc_size(DWORD size
)
459 if (size
== FIELD_OFFSET(D3DDEVICEDESC
, dwMinTextureWidth
) /* 172 */
460 || size
== FIELD_OFFSET(D3DDEVICEDESC
, dwMaxTextureRepeat
) /* 204 */
461 || size
== sizeof(D3DDEVICEDESC
) /* 252 */) return TRUE
;
465 static HRESULT WINAPI
d3d_device3_GetCaps(IDirect3DDevice3
*iface
,
466 D3DDEVICEDESC
*HWDesc
, D3DDEVICEDESC
*HelDesc
)
468 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
469 D3DDEVICEDESC7 desc7
;
473 TRACE("iface %p, hw_desc %p, hel_desc %p.\n", iface
, HWDesc
, HelDesc
);
477 WARN("HWDesc is NULL, returning DDERR_INVALIDPARAMS.\n");
478 return DDERR_INVALIDPARAMS
;
480 if (!check_d3ddevicedesc_size(HWDesc
->dwSize
))
482 WARN("HWDesc->dwSize is %u, returning DDERR_INVALIDPARAMS.\n", HWDesc
->dwSize
);
483 return DDERR_INVALIDPARAMS
;
487 WARN("HelDesc is NULL, returning DDERR_INVALIDPARAMS.\n");
488 return DDERR_INVALIDPARAMS
;
490 if (!check_d3ddevicedesc_size(HelDesc
->dwSize
))
492 WARN("HelDesc->dwSize is %u, returning DDERR_INVALIDPARAMS.\n", HelDesc
->dwSize
);
493 return DDERR_INVALIDPARAMS
;
496 if (FAILED(hr
= ddraw_get_d3dcaps(device
->ddraw
, &desc7
)))
499 ddraw_d3dcaps1_from_7(&desc1
, &desc7
);
500 DD_STRUCT_COPY_BYSIZE(HWDesc
, &desc1
);
501 DD_STRUCT_COPY_BYSIZE(HelDesc
, &desc1
);
505 static HRESULT WINAPI
d3d_device2_GetCaps(IDirect3DDevice2
*iface
,
506 D3DDEVICEDESC
*hw_desc
, D3DDEVICEDESC
*hel_desc
)
508 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
510 TRACE("iface %p, hw_desc %p, hel_desc %p.\n", iface
, hw_desc
, hel_desc
);
512 return d3d_device3_GetCaps(&device
->IDirect3DDevice3_iface
, hw_desc
, hel_desc
);
515 static HRESULT WINAPI
d3d_device1_GetCaps(IDirect3DDevice
*iface
,
516 D3DDEVICEDESC
*hw_desc
, D3DDEVICEDESC
*hel_desc
)
518 struct d3d_device
*device
= impl_from_IDirect3DDevice(iface
);
520 TRACE("iface %p, hw_desc %p, hel_desc %p.\n", iface
, hw_desc
, hel_desc
);
522 return d3d_device3_GetCaps(&device
->IDirect3DDevice3_iface
, hw_desc
, hel_desc
);
525 /*****************************************************************************
526 * IDirect3DDevice2::SwapTextureHandles
528 * Swaps the texture handles of 2 Texture interfaces. Version 1 and 2
531 * Tex1, Tex2: The 2 Textures to swap
536 *****************************************************************************/
537 static HRESULT WINAPI
d3d_device2_SwapTextureHandles(IDirect3DDevice2
*iface
,
538 IDirect3DTexture2
*tex1
, IDirect3DTexture2
*tex2
)
540 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
541 struct ddraw_surface
*surf1
= unsafe_impl_from_IDirect3DTexture2(tex1
);
542 struct ddraw_surface
*surf2
= unsafe_impl_from_IDirect3DTexture2(tex2
);
545 TRACE("iface %p, tex1 %p, tex2 %p.\n", iface
, tex1
, tex2
);
547 wined3d_mutex_lock();
549 h1
= surf1
->Handle
- 1;
550 h2
= surf2
->Handle
- 1;
551 device
->handle_table
.entries
[h1
].object
= surf2
;
552 device
->handle_table
.entries
[h2
].object
= surf1
;
553 surf2
->Handle
= h1
+ 1;
554 surf1
->Handle
= h2
+ 1;
556 wined3d_mutex_unlock();
561 static HRESULT WINAPI
d3d_device1_SwapTextureHandles(IDirect3DDevice
*iface
,
562 IDirect3DTexture
*tex1
, IDirect3DTexture
*tex2
)
564 struct d3d_device
*device
= impl_from_IDirect3DDevice(iface
);
565 struct ddraw_surface
*surf1
= unsafe_impl_from_IDirect3DTexture(tex1
);
566 struct ddraw_surface
*surf2
= unsafe_impl_from_IDirect3DTexture(tex2
);
567 IDirect3DTexture2
*t1
= surf1
? &surf1
->IDirect3DTexture2_iface
: NULL
;
568 IDirect3DTexture2
*t2
= surf2
? &surf2
->IDirect3DTexture2_iface
: NULL
;
570 TRACE("iface %p, tex1 %p, tex2 %p.\n", iface
, tex1
, tex2
);
572 return d3d_device2_SwapTextureHandles(&device
->IDirect3DDevice2_iface
, t1
, t2
);
575 /*****************************************************************************
576 * IDirect3DDevice3::GetStats
578 * This method seems to retrieve some stats from the device.
579 * The MSDN documentation doesn't exist any more, but the D3DSTATS
580 * structure suggests that the amount of drawn primitives and processed
581 * vertices is returned.
583 * Exists in Version 1, 2 and 3
586 * Stats: Pointer to a D3DSTATS structure to be filled
590 * DDERR_INVALIDPARAMS if Stats == NULL
592 *****************************************************************************/
593 static HRESULT WINAPI
d3d_device3_GetStats(IDirect3DDevice3
*iface
, D3DSTATS
*Stats
)
595 FIXME("iface %p, stats %p stub!\n", iface
, Stats
);
598 return DDERR_INVALIDPARAMS
;
600 /* Fill the Stats with 0 */
601 Stats
->dwTrianglesDrawn
= 0;
602 Stats
->dwLinesDrawn
= 0;
603 Stats
->dwPointsDrawn
= 0;
604 Stats
->dwSpansDrawn
= 0;
605 Stats
->dwVerticesProcessed
= 0;
610 static HRESULT WINAPI
d3d_device2_GetStats(IDirect3DDevice2
*iface
, D3DSTATS
*stats
)
612 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
614 TRACE("iface %p, stats %p.\n", iface
, stats
);
616 return d3d_device3_GetStats(&device
->IDirect3DDevice3_iface
, stats
);
619 static HRESULT WINAPI
d3d_device1_GetStats(IDirect3DDevice
*iface
, D3DSTATS
*stats
)
621 struct d3d_device
*device
= impl_from_IDirect3DDevice(iface
);
623 TRACE("iface %p, stats %p.\n", iface
, stats
);
625 return d3d_device3_GetStats(&device
->IDirect3DDevice3_iface
, stats
);
628 /*****************************************************************************
629 * IDirect3DDevice::CreateExecuteBuffer
631 * Creates an IDirect3DExecuteBuffer, used for rendering with a
637 * Desc: Buffer description
638 * ExecuteBuffer: Address to return the Interface pointer at
639 * UnkOuter: Must be NULL. Basically for aggregation, which ddraw doesn't
643 * CLASS_E_NOAGGREGATION if UnkOuter != NULL
644 * DDERR_OUTOFMEMORY if we ran out of memory
647 *****************************************************************************/
648 static HRESULT WINAPI
d3d_device1_CreateExecuteBuffer(IDirect3DDevice
*iface
,
649 D3DEXECUTEBUFFERDESC
*buffer_desc
, IDirect3DExecuteBuffer
**ExecuteBuffer
, IUnknown
*outer_unknown
)
651 struct d3d_device
*device
= impl_from_IDirect3DDevice(iface
);
652 struct d3d_execute_buffer
*object
;
655 TRACE("iface %p, buffer_desc %p, buffer %p, outer_unknown %p.\n",
656 iface
, buffer_desc
, ExecuteBuffer
, outer_unknown
);
659 return CLASS_E_NOAGGREGATION
;
661 /* Allocate the new Execute Buffer */
662 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*object
));
665 ERR("Failed to allocate execute buffer memory.\n");
666 return DDERR_OUTOFMEMORY
;
669 hr
= d3d_execute_buffer_init(object
, device
, buffer_desc
);
672 WARN("Failed to initialize execute buffer, hr %#x.\n", hr
);
673 HeapFree(GetProcessHeap(), 0, object
);
677 *ExecuteBuffer
= &object
->IDirect3DExecuteBuffer_iface
;
679 TRACE(" Returning IDirect3DExecuteBuffer at %p, implementation is at %p\n", *ExecuteBuffer
, object
);
684 /*****************************************************************************
685 * IDirect3DDevice::Execute
687 * Executes all the stuff in an execute buffer.
690 * ExecuteBuffer: The buffer to execute
691 * Viewport: The viewport used for rendering
695 * DDERR_INVALIDPARAMS if ExecuteBuffer == NULL
698 *****************************************************************************/
699 static HRESULT WINAPI
d3d_device1_Execute(IDirect3DDevice
*iface
,
700 IDirect3DExecuteBuffer
*ExecuteBuffer
, IDirect3DViewport
*viewport
, DWORD flags
)
702 struct d3d_device
*device
= impl_from_IDirect3DDevice(iface
);
703 struct d3d_execute_buffer
*buffer
= unsafe_impl_from_IDirect3DExecuteBuffer(ExecuteBuffer
);
704 struct d3d_viewport
*viewport_impl
= unsafe_impl_from_IDirect3DViewport(viewport
);
707 TRACE("iface %p, buffer %p, viewport %p, flags %#x.\n", iface
, ExecuteBuffer
, viewport
, flags
);
710 return DDERR_INVALIDPARAMS
;
713 wined3d_mutex_lock();
714 hr
= d3d_execute_buffer_execute(buffer
, device
, viewport_impl
);
715 wined3d_mutex_unlock();
720 /*****************************************************************************
721 * IDirect3DDevice3::AddViewport
723 * Add a Direct3DViewport to the device's viewport list. These viewports
724 * are wrapped to IDirect3DDevice7 viewports in viewport.c
726 * Exists in Version 1, 2 and 3. Note that IDirect3DViewport 1, 2 and 3
727 * are the same interfaces.
730 * Viewport: The viewport to add
733 * DDERR_INVALIDPARAMS if Viewport == NULL
736 *****************************************************************************/
737 static HRESULT WINAPI
d3d_device3_AddViewport(IDirect3DDevice3
*iface
, IDirect3DViewport3
*viewport
)
739 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
740 struct d3d_viewport
*vp
= unsafe_impl_from_IDirect3DViewport3(viewport
);
742 TRACE("iface %p, viewport %p.\n", iface
, viewport
);
746 return DDERR_INVALIDPARAMS
;
748 wined3d_mutex_lock();
749 IDirect3DViewport3_AddRef(viewport
);
750 list_add_head(&device
->viewport_list
, &vp
->entry
);
751 /* Viewport must be usable for Clear() after AddViewport, so set active_device here. */
752 vp
->active_device
= device
;
753 wined3d_mutex_unlock();
758 static HRESULT WINAPI
d3d_device2_AddViewport(IDirect3DDevice2
*iface
,
759 IDirect3DViewport2
*viewport
)
761 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
762 struct d3d_viewport
*vp
= unsafe_impl_from_IDirect3DViewport2(viewport
);
764 TRACE("iface %p, viewport %p.\n", iface
, viewport
);
766 return d3d_device3_AddViewport(&device
->IDirect3DDevice3_iface
, &vp
->IDirect3DViewport3_iface
);
769 static HRESULT WINAPI
d3d_device1_AddViewport(IDirect3DDevice
*iface
, IDirect3DViewport
*viewport
)
771 struct d3d_device
*device
= impl_from_IDirect3DDevice(iface
);
772 struct d3d_viewport
*vp
= unsafe_impl_from_IDirect3DViewport(viewport
);
774 TRACE("iface %p, viewport %p.\n", iface
, viewport
);
776 return d3d_device3_AddViewport(&device
->IDirect3DDevice3_iface
, &vp
->IDirect3DViewport3_iface
);
779 /*****************************************************************************
780 * IDirect3DDevice3::DeleteViewport
782 * Deletes a Direct3DViewport from the device's viewport list.
784 * Exists in Version 1, 2 and 3. Note that all Viewport interface versions
788 * Viewport: The viewport to delete
792 * DDERR_INVALIDPARAMS if the viewport wasn't found in the list
794 *****************************************************************************/
795 static HRESULT WINAPI
d3d_device3_DeleteViewport(IDirect3DDevice3
*iface
, IDirect3DViewport3
*viewport
)
797 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
798 struct d3d_viewport
*vp
= unsafe_impl_from_IDirect3DViewport3(viewport
);
800 TRACE("iface %p, viewport %p.\n", iface
, viewport
);
804 WARN("NULL viewport, returning DDERR_INVALIDPARAMS\n");
805 return DDERR_INVALIDPARAMS
;
808 wined3d_mutex_lock();
810 if (vp
->active_device
!= device
)
812 WARN("Viewport %p active device is %p.\n", vp
, vp
->active_device
);
813 wined3d_mutex_unlock();
814 return DDERR_INVALIDPARAMS
;
817 if (device
->current_viewport
== vp
)
819 TRACE("Deleting current viewport, unsetting and releasing\n");
820 IDirect3DViewport3_Release(viewport
);
821 device
->current_viewport
= NULL
;
824 vp
->active_device
= NULL
;
825 list_remove(&vp
->entry
);
827 IDirect3DViewport3_Release(viewport
);
829 wined3d_mutex_unlock();
834 static HRESULT WINAPI
d3d_device2_DeleteViewport(IDirect3DDevice2
*iface
, IDirect3DViewport2
*viewport
)
836 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
837 struct d3d_viewport
*vp
= unsafe_impl_from_IDirect3DViewport2(viewport
);
839 TRACE("iface %p, viewport %p.\n", iface
, viewport
);
841 return d3d_device3_DeleteViewport(&device
->IDirect3DDevice3_iface
,
842 vp
? &vp
->IDirect3DViewport3_iface
: NULL
);
845 static HRESULT WINAPI
d3d_device1_DeleteViewport(IDirect3DDevice
*iface
, IDirect3DViewport
*viewport
)
847 struct d3d_device
*device
= impl_from_IDirect3DDevice(iface
);
848 struct d3d_viewport
*vp
= unsafe_impl_from_IDirect3DViewport(viewport
);
850 TRACE("iface %p, viewport %p.\n", iface
, viewport
);
852 return d3d_device3_DeleteViewport(&device
->IDirect3DDevice3_iface
,
853 vp
? &vp
->IDirect3DViewport3_iface
: NULL
);
856 /*****************************************************************************
857 * IDirect3DDevice3::NextViewport
859 * Returns a viewport from the viewport list, depending on the
860 * passed viewport and the flags.
862 * Exists in Version 1, 2 and 3. Note that all Viewport interface versions
866 * Viewport: Viewport to use for beginning the search
867 * Flags: D3DNEXT_NEXT, D3DNEXT_HEAD or D3DNEXT_TAIL
871 * DDERR_INVALIDPARAMS if the flags were wrong, or Viewport was NULL
873 *****************************************************************************/
874 static HRESULT WINAPI
d3d_device3_NextViewport(IDirect3DDevice3
*iface
,
875 IDirect3DViewport3
*Viewport3
, IDirect3DViewport3
**lplpDirect3DViewport3
, DWORD flags
)
877 struct d3d_device
*This
= impl_from_IDirect3DDevice3(iface
);
878 struct d3d_viewport
*vp
= unsafe_impl_from_IDirect3DViewport3(Viewport3
);
879 struct d3d_viewport
*next
;
882 TRACE("iface %p, viewport %p, next %p, flags %#x.\n",
883 iface
, Viewport3
, lplpDirect3DViewport3
, flags
);
887 *lplpDirect3DViewport3
= NULL
;
888 return DDERR_INVALIDPARAMS
;
892 wined3d_mutex_lock();
896 entry
= list_next(&This
->viewport_list
, &vp
->entry
);
900 entry
= list_head(&This
->viewport_list
);
904 entry
= list_tail(&This
->viewport_list
);
908 WARN("Invalid flags %#x.\n", flags
);
909 *lplpDirect3DViewport3
= NULL
;
910 wined3d_mutex_unlock();
911 return DDERR_INVALIDPARAMS
;
916 next
= LIST_ENTRY(entry
, struct d3d_viewport
, entry
);
917 *lplpDirect3DViewport3
= &next
->IDirect3DViewport3_iface
;
920 *lplpDirect3DViewport3
= NULL
;
922 wined3d_mutex_unlock();
927 static HRESULT WINAPI
d3d_device2_NextViewport(IDirect3DDevice2
*iface
,
928 IDirect3DViewport2
*viewport
, IDirect3DViewport2
**next
, DWORD flags
)
930 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
931 struct d3d_viewport
*vp
= unsafe_impl_from_IDirect3DViewport2(viewport
);
932 IDirect3DViewport3
*res
;
935 TRACE("iface %p, viewport %p, next %p, flags %#x.\n",
936 iface
, viewport
, next
, flags
);
938 hr
= d3d_device3_NextViewport(&device
->IDirect3DDevice3_iface
,
939 &vp
->IDirect3DViewport3_iface
, &res
, flags
);
940 *next
= (IDirect3DViewport2
*)res
;
944 static HRESULT WINAPI
d3d_device1_NextViewport(IDirect3DDevice
*iface
,
945 IDirect3DViewport
*viewport
, IDirect3DViewport
**next
, DWORD flags
)
947 struct d3d_device
*device
= impl_from_IDirect3DDevice(iface
);
948 struct d3d_viewport
*vp
= unsafe_impl_from_IDirect3DViewport(viewport
);
949 IDirect3DViewport3
*res
;
952 TRACE("iface %p, viewport %p, next %p, flags %#x.\n",
953 iface
, viewport
, next
, flags
);
955 hr
= d3d_device3_NextViewport(&device
->IDirect3DDevice3_iface
,
956 &vp
->IDirect3DViewport3_iface
, &res
, flags
);
957 *next
= (IDirect3DViewport
*)res
;
961 /*****************************************************************************
962 * IDirect3DDevice::Pick
964 * Executes an execute buffer without performing rendering. Instead, a
965 * list of primitives that intersect with (x1,y1) of the passed rectangle
966 * is created. IDirect3DDevice::GetPickRecords can be used to retrieve
972 * ExecuteBuffer: Buffer to execute
973 * Viewport: Viewport to use for execution
974 * Flags: None are defined, according to the SDK
975 * Rect: Specifies the coordinates to be picked. Only x1 and y2 are used,
976 * x2 and y2 are ignored.
979 * D3D_OK because it's a stub
981 *****************************************************************************/
982 static HRESULT WINAPI
d3d_device1_Pick(IDirect3DDevice
*iface
, IDirect3DExecuteBuffer
*buffer
,
983 IDirect3DViewport
*viewport
, DWORD flags
, D3DRECT
*rect
)
985 FIXME("iface %p, buffer %p, viewport %p, flags %#x, rect %s stub!\n",
986 iface
, buffer
, viewport
, flags
, wine_dbgstr_rect((RECT
*)rect
));
991 /*****************************************************************************
992 * IDirect3DDevice::GetPickRecords
994 * Retrieves the pick records generated by IDirect3DDevice::GetPickRecords
999 * Count: Pointer to a DWORD containing the numbers of pick records to
1001 * D3DPickRec: Address to store the resulting D3DPICKRECORD array.
1004 * D3D_OK, because it's a stub
1006 *****************************************************************************/
1007 static HRESULT WINAPI
d3d_device1_GetPickRecords(IDirect3DDevice
*iface
,
1008 DWORD
*count
, D3DPICKRECORD
*records
)
1010 FIXME("iface %p, count %p, records %p stub!\n", iface
, count
, records
);
1015 /*****************************************************************************
1016 * IDirect3DDevice7::EnumTextureformats
1018 * Enumerates the supported texture formats. It checks against a list of all possible
1019 * formats to see if WineD3D supports it. If so, then it is passed to the app.
1021 * This is for Version 7 and 3, older versions have a different
1022 * callback function and their own implementation
1025 * Callback: Callback to call for each enumerated format
1026 * Arg: Argument to pass to the callback
1030 * DDERR_INVALIDPARAMS if Callback == NULL
1032 *****************************************************************************/
1033 static HRESULT
d3d_device7_EnumTextureFormats(IDirect3DDevice7
*iface
,
1034 LPD3DENUMPIXELFORMATSCALLBACK callback
, void *context
)
1036 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
1037 struct wined3d_display_mode mode
;
1041 static const enum wined3d_format_id FormatList
[] =
1044 WINED3DFMT_B5G5R5X1_UNORM
,
1045 WINED3DFMT_B5G5R5A1_UNORM
,
1046 WINED3DFMT_B4G4R4A4_UNORM
,
1047 WINED3DFMT_B5G6R5_UNORM
,
1049 WINED3DFMT_B8G8R8X8_UNORM
,
1050 WINED3DFMT_B8G8R8A8_UNORM
,
1052 WINED3DFMT_B2G3R3_UNORM
,
1062 static const enum wined3d_format_id BumpFormatList
[] =
1064 WINED3DFMT_R8G8_SNORM
,
1065 WINED3DFMT_R5G5_SNORM_L6_UNORM
,
1066 WINED3DFMT_R8G8_SNORM_L8X8_UNORM
,
1067 WINED3DFMT_R10G11B11_SNORM
,
1068 WINED3DFMT_R10G10B10_SNORM_A2_UNORM
1071 TRACE("iface %p, callback %p, context %p.\n", iface
, callback
, context
);
1074 return DDERR_INVALIDPARAMS
;
1076 wined3d_mutex_lock();
1078 memset(&mode
, 0, sizeof(mode
));
1079 if (FAILED(hr
= wined3d_get_adapter_display_mode(device
->ddraw
->wined3d
, WINED3DADAPTER_DEFAULT
, &mode
, NULL
)))
1081 wined3d_mutex_unlock();
1082 WARN("Cannot get the current adapter format\n");
1086 for (i
= 0; i
< sizeof(FormatList
) / sizeof(*FormatList
); ++i
)
1088 if (wined3d_check_device_format(device
->ddraw
->wined3d
, WINED3DADAPTER_DEFAULT
, WINED3D_DEVICE_TYPE_HAL
,
1089 mode
.format_id
, WINED3DUSAGE_TEXTURE
, WINED3D_RTYPE_TEXTURE_2D
, FormatList
[i
]) == D3D_OK
)
1091 DDPIXELFORMAT pformat
;
1093 memset(&pformat
, 0, sizeof(pformat
));
1094 pformat
.dwSize
= sizeof(pformat
);
1095 ddrawformat_from_wined3dformat(&pformat
, FormatList
[i
]);
1097 TRACE("Enumerating WineD3DFormat %d\n", FormatList
[i
]);
1098 hr
= callback(&pformat
, context
);
1099 if(hr
!= DDENUMRET_OK
)
1101 TRACE("Format enumeration cancelled by application\n");
1102 wined3d_mutex_unlock();
1108 for (i
= 0; i
< sizeof(BumpFormatList
) / sizeof(*BumpFormatList
); ++i
)
1110 if (wined3d_check_device_format(device
->ddraw
->wined3d
, WINED3DADAPTER_DEFAULT
,
1111 WINED3D_DEVICE_TYPE_HAL
, mode
.format_id
, WINED3DUSAGE_TEXTURE
| WINED3DUSAGE_QUERY_LEGACYBUMPMAP
,
1112 WINED3D_RTYPE_TEXTURE_2D
, BumpFormatList
[i
]) == D3D_OK
)
1114 DDPIXELFORMAT pformat
;
1116 memset(&pformat
, 0, sizeof(pformat
));
1117 pformat
.dwSize
= sizeof(pformat
);
1118 ddrawformat_from_wined3dformat(&pformat
, BumpFormatList
[i
]);
1120 TRACE("Enumerating WineD3DFormat %d\n", BumpFormatList
[i
]);
1121 hr
= callback(&pformat
, context
);
1122 if(hr
!= DDENUMRET_OK
)
1124 TRACE("Format enumeration cancelled by application\n");
1125 wined3d_mutex_unlock();
1130 TRACE("End of enumeration\n");
1131 wined3d_mutex_unlock();
1136 static HRESULT WINAPI
d3d_device7_EnumTextureFormats_FPUSetup(IDirect3DDevice7
*iface
,
1137 LPD3DENUMPIXELFORMATSCALLBACK callback
, void *context
)
1139 return d3d_device7_EnumTextureFormats(iface
, callback
, context
);
1142 static HRESULT WINAPI
d3d_device7_EnumTextureFormats_FPUPreserve(IDirect3DDevice7
*iface
,
1143 LPD3DENUMPIXELFORMATSCALLBACK callback
, void *context
)
1148 old_fpucw
= d3d_fpu_setup();
1149 hr
= d3d_device7_EnumTextureFormats(iface
, callback
, context
);
1150 set_fpu_control_word(old_fpucw
);
1155 static HRESULT WINAPI
d3d_device3_EnumTextureFormats(IDirect3DDevice3
*iface
,
1156 LPD3DENUMPIXELFORMATSCALLBACK callback
, void *context
)
1158 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
1160 TRACE("iface %p, callback %p, context %p.\n", iface
, callback
, context
);
1162 return IDirect3DDevice7_EnumTextureFormats(&device
->IDirect3DDevice7_iface
, callback
, context
);
1165 /*****************************************************************************
1166 * IDirect3DDevice2::EnumTextureformats
1168 * EnumTextureFormats for Version 1 and 2, see
1169 * IDirect3DDevice7::EnumTexureFormats for a more detailed description.
1171 * This version has a different callback and does not enumerate FourCC
1174 *****************************************************************************/
1175 static HRESULT WINAPI
d3d_device2_EnumTextureFormats(IDirect3DDevice2
*iface
,
1176 LPD3DENUMTEXTUREFORMATSCALLBACK callback
, void *context
)
1178 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
1179 struct wined3d_display_mode mode
;
1183 static const enum wined3d_format_id FormatList
[] =
1186 WINED3DFMT_B5G5R5X1_UNORM
,
1187 WINED3DFMT_B5G5R5A1_UNORM
,
1188 WINED3DFMT_B4G4R4A4_UNORM
,
1189 WINED3DFMT_B5G6R5_UNORM
,
1191 WINED3DFMT_B8G8R8X8_UNORM
,
1192 WINED3DFMT_B8G8R8A8_UNORM
,
1194 WINED3DFMT_B2G3R3_UNORM
,
1196 /* FOURCC codes - Not in this version*/
1199 TRACE("iface %p, callback %p, context %p.\n", iface
, callback
, context
);
1202 return DDERR_INVALIDPARAMS
;
1204 wined3d_mutex_lock();
1206 memset(&mode
, 0, sizeof(mode
));
1207 if (FAILED(hr
= wined3d_get_adapter_display_mode(device
->ddraw
->wined3d
, WINED3DADAPTER_DEFAULT
, &mode
, NULL
)))
1209 wined3d_mutex_unlock();
1210 WARN("Cannot get the current adapter format\n");
1214 for (i
= 0; i
< sizeof(FormatList
) / sizeof(*FormatList
); ++i
)
1216 if (wined3d_check_device_format(device
->ddraw
->wined3d
, 0, WINED3D_DEVICE_TYPE_HAL
,
1217 mode
.format_id
, WINED3DUSAGE_TEXTURE
, WINED3D_RTYPE_TEXTURE_2D
, FormatList
[i
]) == D3D_OK
)
1219 DDSURFACEDESC sdesc
;
1221 memset(&sdesc
, 0, sizeof(sdesc
));
1222 sdesc
.dwSize
= sizeof(sdesc
);
1223 sdesc
.dwFlags
= DDSD_PIXELFORMAT
| DDSD_CAPS
;
1224 sdesc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
1225 sdesc
.ddpfPixelFormat
.dwSize
= sizeof(sdesc
.ddpfPixelFormat
);
1226 ddrawformat_from_wined3dformat(&sdesc
.ddpfPixelFormat
, FormatList
[i
]);
1228 TRACE("Enumerating WineD3DFormat %d\n", FormatList
[i
]);
1229 hr
= callback(&sdesc
, context
);
1230 if(hr
!= DDENUMRET_OK
)
1232 TRACE("Format enumeration cancelled by application\n");
1233 wined3d_mutex_unlock();
1238 TRACE("End of enumeration\n");
1239 wined3d_mutex_unlock();
1244 static HRESULT WINAPI
d3d_device1_EnumTextureFormats(IDirect3DDevice
*iface
,
1245 LPD3DENUMTEXTUREFORMATSCALLBACK callback
, void *context
)
1247 struct d3d_device
*device
= impl_from_IDirect3DDevice(iface
);
1249 TRACE("iface %p, callback %p, context %p.\n", iface
, callback
, context
);
1251 return d3d_device2_EnumTextureFormats(&device
->IDirect3DDevice2_iface
, callback
, context
);
1254 /*****************************************************************************
1255 * IDirect3DDevice::CreateMatrix
1257 * Creates a matrix handle. A handle is created and memory for a D3DMATRIX is
1258 * allocated for the handle.
1263 * D3DMatHandle: Address to return the handle at
1267 * DDERR_INVALIDPARAMS if D3DMatHandle = NULL
1269 *****************************************************************************/
1270 static HRESULT WINAPI
d3d_device1_CreateMatrix(IDirect3DDevice
*iface
, D3DMATRIXHANDLE
*D3DMatHandle
)
1272 struct d3d_device
*device
= impl_from_IDirect3DDevice(iface
);
1276 TRACE("iface %p, matrix_handle %p.\n", iface
, D3DMatHandle
);
1279 return DDERR_INVALIDPARAMS
;
1281 Matrix
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(D3DMATRIX
));
1284 ERR("Out of memory when allocating a D3DMATRIX\n");
1285 return DDERR_OUTOFMEMORY
;
1288 wined3d_mutex_lock();
1290 h
= ddraw_allocate_handle(&device
->handle_table
, Matrix
, DDRAW_HANDLE_MATRIX
);
1291 if (h
== DDRAW_INVALID_HANDLE
)
1293 ERR("Failed to allocate a matrix handle.\n");
1294 HeapFree(GetProcessHeap(), 0, Matrix
);
1295 wined3d_mutex_unlock();
1296 return DDERR_OUTOFMEMORY
;
1299 *D3DMatHandle
= h
+ 1;
1301 TRACE(" returning matrix handle %d\n", *D3DMatHandle
);
1303 wined3d_mutex_unlock();
1308 /*****************************************************************************
1309 * IDirect3DDevice::SetMatrix
1311 * Sets a matrix for a matrix handle. The matrix is copied into the memory
1312 * allocated for the handle
1317 * D3DMatHandle: Handle to set the matrix to
1318 * D3DMatrix: Matrix to set
1322 * DDERR_INVALIDPARAMS if the handle of the matrix is invalid or the matrix
1325 *****************************************************************************/
1326 static HRESULT WINAPI
d3d_device1_SetMatrix(IDirect3DDevice
*iface
,
1327 D3DMATRIXHANDLE D3DMatHandle
, D3DMATRIX
*D3DMatrix
)
1329 struct d3d_device
*This
= impl_from_IDirect3DDevice(iface
);
1332 TRACE("iface %p, matrix_handle %#x, matrix %p.\n", iface
, D3DMatHandle
, D3DMatrix
);
1334 if (!D3DMatrix
) return DDERR_INVALIDPARAMS
;
1336 wined3d_mutex_lock();
1338 m
= ddraw_get_object(&This
->handle_table
, D3DMatHandle
- 1, DDRAW_HANDLE_MATRIX
);
1341 WARN("Invalid matrix handle.\n");
1342 wined3d_mutex_unlock();
1343 return DDERR_INVALIDPARAMS
;
1346 if (TRACE_ON(ddraw
))
1347 dump_D3DMATRIX(D3DMatrix
);
1351 if (D3DMatHandle
== This
->world
)
1352 wined3d_device_set_transform(This
->wined3d_device
,
1353 WINED3D_TS_WORLD_MATRIX(0), (struct wined3d_matrix
*)D3DMatrix
);
1355 if (D3DMatHandle
== This
->view
)
1356 wined3d_device_set_transform(This
->wined3d_device
,
1357 WINED3D_TS_VIEW
, (struct wined3d_matrix
*)D3DMatrix
);
1359 if (D3DMatHandle
== This
->proj
)
1360 wined3d_device_set_transform(This
->wined3d_device
,
1361 WINED3D_TS_PROJECTION
, (struct wined3d_matrix
*)D3DMatrix
);
1363 wined3d_mutex_unlock();
1368 /*****************************************************************************
1369 * IDirect3DDevice::GetMatrix
1371 * Returns the content of a D3DMATRIX handle
1376 * D3DMatHandle: Matrix handle to read the content from
1377 * D3DMatrix: Address to store the content at
1381 * DDERR_INVALIDPARAMS if D3DMatHandle is invalid or D3DMatrix is NULL
1383 *****************************************************************************/
1384 static HRESULT WINAPI
d3d_device1_GetMatrix(IDirect3DDevice
*iface
,
1385 D3DMATRIXHANDLE D3DMatHandle
, D3DMATRIX
*D3DMatrix
)
1387 struct d3d_device
*device
= impl_from_IDirect3DDevice(iface
);
1390 TRACE("iface %p, matrix_handle %#x, matrix %p.\n", iface
, D3DMatHandle
, D3DMatrix
);
1392 if (!D3DMatrix
) return DDERR_INVALIDPARAMS
;
1394 wined3d_mutex_lock();
1396 m
= ddraw_get_object(&device
->handle_table
, D3DMatHandle
- 1, DDRAW_HANDLE_MATRIX
);
1399 WARN("Invalid matrix handle.\n");
1400 wined3d_mutex_unlock();
1401 return DDERR_INVALIDPARAMS
;
1406 wined3d_mutex_unlock();
1411 /*****************************************************************************
1412 * IDirect3DDevice::DeleteMatrix
1414 * Destroys a Matrix handle. Frees the memory and unsets the handle data
1419 * D3DMatHandle: Handle to destroy
1423 * DDERR_INVALIDPARAMS if D3DMatHandle is invalid
1425 *****************************************************************************/
1426 static HRESULT WINAPI
d3d_device1_DeleteMatrix(IDirect3DDevice
*iface
, D3DMATRIXHANDLE D3DMatHandle
)
1428 struct d3d_device
*device
= impl_from_IDirect3DDevice(iface
);
1431 TRACE("iface %p, matrix_handle %#x.\n", iface
, D3DMatHandle
);
1433 wined3d_mutex_lock();
1435 m
= ddraw_free_handle(&device
->handle_table
, D3DMatHandle
- 1, DDRAW_HANDLE_MATRIX
);
1438 WARN("Invalid matrix handle.\n");
1439 wined3d_mutex_unlock();
1440 return DDERR_INVALIDPARAMS
;
1443 wined3d_mutex_unlock();
1445 HeapFree(GetProcessHeap(), 0, m
);
1450 /*****************************************************************************
1451 * IDirect3DDevice7::BeginScene
1453 * This method must be called before any rendering is performed.
1454 * IDirect3DDevice::EndScene has to be called after the scene is complete
1456 * Version 1, 2, 3 and 7
1459 * D3D_OK on success,
1460 * D3DERR_SCENE_IN_SCENE if WineD3D returns an error(Only in case of an already
1463 *****************************************************************************/
1464 static HRESULT
d3d_device7_BeginScene(IDirect3DDevice7
*iface
)
1466 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
1469 TRACE("iface %p.\n", iface
);
1471 wined3d_mutex_lock();
1472 hr
= wined3d_device_begin_scene(device
->wined3d_device
);
1473 wined3d_mutex_unlock();
1475 if(hr
== WINED3D_OK
) return D3D_OK
;
1476 else return D3DERR_SCENE_IN_SCENE
; /* TODO: Other possible causes of failure */
1479 static HRESULT WINAPI
d3d_device7_BeginScene_FPUSetup(IDirect3DDevice7
*iface
)
1481 return d3d_device7_BeginScene(iface
);
1484 static HRESULT WINAPI
d3d_device7_BeginScene_FPUPreserve(IDirect3DDevice7
*iface
)
1489 old_fpucw
= d3d_fpu_setup();
1490 hr
= d3d_device7_BeginScene(iface
);
1491 set_fpu_control_word(old_fpucw
);
1496 static HRESULT WINAPI
d3d_device3_BeginScene(IDirect3DDevice3
*iface
)
1498 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
1500 TRACE("iface %p.\n", iface
);
1502 return IDirect3DDevice7_BeginScene(&device
->IDirect3DDevice7_iface
);
1505 static HRESULT WINAPI
d3d_device2_BeginScene(IDirect3DDevice2
*iface
)
1507 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
1509 TRACE("iface %p.\n", iface
);
1511 return IDirect3DDevice7_BeginScene(&device
->IDirect3DDevice7_iface
);
1514 static HRESULT WINAPI
d3d_device1_BeginScene(IDirect3DDevice
*iface
)
1516 struct d3d_device
*device
= impl_from_IDirect3DDevice(iface
);
1518 TRACE("iface %p.\n", iface
);
1520 return IDirect3DDevice7_BeginScene(&device
->IDirect3DDevice7_iface
);
1523 /*****************************************************************************
1524 * IDirect3DDevice7::EndScene
1526 * Ends a scene that has been begun with IDirect3DDevice7::BeginScene.
1527 * This method must be called after rendering is finished.
1529 * Version 1, 2, 3 and 7
1532 * D3D_OK on success,
1533 * D3DERR_SCENE_NOT_IN_SCENE is returned if WineD3D returns an error. It does
1534 * that only if the scene was already ended.
1536 *****************************************************************************/
1537 static HRESULT
d3d_device7_EndScene(IDirect3DDevice7
*iface
)
1539 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
1542 TRACE("iface %p.\n", iface
);
1544 wined3d_mutex_lock();
1545 hr
= wined3d_device_end_scene(device
->wined3d_device
);
1546 wined3d_mutex_unlock();
1548 if(hr
== WINED3D_OK
) return D3D_OK
;
1549 else return D3DERR_SCENE_NOT_IN_SCENE
;
1552 static HRESULT WINAPI DECLSPEC_HOTPATCH
d3d_device7_EndScene_FPUSetup(IDirect3DDevice7
*iface
)
1554 return d3d_device7_EndScene(iface
);
1557 static HRESULT WINAPI DECLSPEC_HOTPATCH
d3d_device7_EndScene_FPUPreserve(IDirect3DDevice7
*iface
)
1562 old_fpucw
= d3d_fpu_setup();
1563 hr
= d3d_device7_EndScene(iface
);
1564 set_fpu_control_word(old_fpucw
);
1569 static HRESULT WINAPI DECLSPEC_HOTPATCH
d3d_device3_EndScene(IDirect3DDevice3
*iface
)
1571 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
1573 TRACE("iface %p.\n", iface
);
1575 return IDirect3DDevice7_EndScene(&device
->IDirect3DDevice7_iface
);
1578 static HRESULT WINAPI DECLSPEC_HOTPATCH
d3d_device2_EndScene(IDirect3DDevice2
*iface
)
1580 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
1582 TRACE("iface %p.\n", iface
);
1584 return IDirect3DDevice7_EndScene(&device
->IDirect3DDevice7_iface
);
1587 static HRESULT WINAPI DECLSPEC_HOTPATCH
d3d_device1_EndScene(IDirect3DDevice
*iface
)
1589 struct d3d_device
*device
= impl_from_IDirect3DDevice(iface
);
1591 TRACE("iface %p.\n", iface
);
1593 return IDirect3DDevice7_EndScene(&device
->IDirect3DDevice7_iface
);
1596 /*****************************************************************************
1597 * IDirect3DDevice7::GetDirect3D
1599 * Returns the IDirect3D(= interface to the DirectDraw object) used to create
1603 * Direct3D7: Address to store the interface pointer at
1607 * DDERR_INVALIDPARAMS if Direct3D7 == NULL
1609 *****************************************************************************/
1610 static HRESULT WINAPI
d3d_device7_GetDirect3D(IDirect3DDevice7
*iface
, IDirect3D7
**d3d
)
1612 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
1614 TRACE("iface %p, d3d %p.\n", iface
, d3d
);
1617 return DDERR_INVALIDPARAMS
;
1619 *d3d
= &device
->ddraw
->IDirect3D7_iface
;
1620 IDirect3D7_AddRef(*d3d
);
1622 TRACE("Returning interface %p.\n", *d3d
);
1626 static HRESULT WINAPI
d3d_device3_GetDirect3D(IDirect3DDevice3
*iface
, IDirect3D3
**d3d
)
1628 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
1630 TRACE("iface %p, d3d %p.\n", iface
, d3d
);
1633 return DDERR_INVALIDPARAMS
;
1635 *d3d
= &device
->ddraw
->IDirect3D3_iface
;
1636 IDirect3D3_AddRef(*d3d
);
1638 TRACE("Returning interface %p.\n", *d3d
);
1642 static HRESULT WINAPI
d3d_device2_GetDirect3D(IDirect3DDevice2
*iface
, IDirect3D2
**d3d
)
1644 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
1646 TRACE("iface %p, d3d %p.\n", iface
, d3d
);
1649 return DDERR_INVALIDPARAMS
;
1651 *d3d
= &device
->ddraw
->IDirect3D2_iface
;
1652 IDirect3D2_AddRef(*d3d
);
1654 TRACE("Returning interface %p.\n", *d3d
);
1658 static HRESULT WINAPI
d3d_device1_GetDirect3D(IDirect3DDevice
*iface
, IDirect3D
**d3d
)
1660 struct d3d_device
*device
= impl_from_IDirect3DDevice(iface
);
1662 TRACE("iface %p, d3d %p.\n", iface
, d3d
);
1665 return DDERR_INVALIDPARAMS
;
1667 *d3d
= &device
->ddraw
->IDirect3D_iface
;
1668 IDirect3D_AddRef(*d3d
);
1670 TRACE("Returning interface %p.\n", *d3d
);
1674 /*****************************************************************************
1675 * IDirect3DDevice3::SetCurrentViewport
1677 * Sets a Direct3DViewport as the current viewport.
1678 * For the thunks note that all viewport interface versions are equal
1681 * Direct3DViewport3: The viewport to set
1687 * (Is a NULL viewport valid?)
1689 *****************************************************************************/
1690 static HRESULT WINAPI
d3d_device3_SetCurrentViewport(IDirect3DDevice3
*iface
, IDirect3DViewport3
*Direct3DViewport3
)
1692 struct d3d_device
*This
= impl_from_IDirect3DDevice3(iface
);
1693 struct d3d_viewport
*vp
= unsafe_impl_from_IDirect3DViewport3(Direct3DViewport3
);
1695 TRACE("iface %p, viewport %p.\n", iface
, Direct3DViewport3
);
1699 WARN("Direct3DViewport3 is NULL, returning DDERR_INVALIDPARAMS\n");
1700 return DDERR_INVALIDPARAMS
;
1703 wined3d_mutex_lock();
1704 /* Do nothing if the specified viewport is the same as the current one */
1705 if (This
->current_viewport
== vp
)
1707 wined3d_mutex_unlock();
1711 if (vp
->active_device
!= This
)
1713 WARN("Viewport %p active device is %p.\n", vp
, vp
->active_device
);
1714 wined3d_mutex_unlock();
1715 return DDERR_INVALIDPARAMS
;
1718 /* Release previous viewport and AddRef the new one */
1719 if (This
->current_viewport
)
1721 TRACE("ViewportImpl is at %p, interface is at %p\n", This
->current_viewport
,
1722 &This
->current_viewport
->IDirect3DViewport3_iface
);
1723 IDirect3DViewport3_Release(&This
->current_viewport
->IDirect3DViewport3_iface
);
1725 IDirect3DViewport3_AddRef(Direct3DViewport3
);
1727 /* Set this viewport as the current viewport */
1728 This
->current_viewport
= vp
;
1730 /* Activate this viewport */
1731 viewport_activate(This
->current_viewport
, FALSE
);
1733 wined3d_mutex_unlock();
1738 static HRESULT WINAPI
d3d_device2_SetCurrentViewport(IDirect3DDevice2
*iface
, IDirect3DViewport2
*viewport
)
1740 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
1741 struct d3d_viewport
*vp
= unsafe_impl_from_IDirect3DViewport2(viewport
);
1743 TRACE("iface %p, viewport %p.\n", iface
, viewport
);
1745 return d3d_device3_SetCurrentViewport(&device
->IDirect3DDevice3_iface
,
1746 vp
? &vp
->IDirect3DViewport3_iface
: NULL
);
1749 /*****************************************************************************
1750 * IDirect3DDevice3::GetCurrentViewport
1752 * Returns the currently active viewport.
1757 * Direct3DViewport3: Address to return the interface pointer at
1761 * DDERR_INVALIDPARAMS if Direct3DViewport == NULL
1763 *****************************************************************************/
1764 static HRESULT WINAPI
d3d_device3_GetCurrentViewport(IDirect3DDevice3
*iface
, IDirect3DViewport3
**viewport
)
1766 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
1768 TRACE("iface %p, viewport %p.\n", iface
, viewport
);
1770 wined3d_mutex_lock();
1771 if (!device
->current_viewport
)
1773 wined3d_mutex_unlock();
1774 WARN("No current viewport, returning D3DERR_NOCURRENTVIEWPORT\n");
1775 return D3DERR_NOCURRENTVIEWPORT
;
1778 *viewport
= &device
->current_viewport
->IDirect3DViewport3_iface
;
1779 IDirect3DViewport3_AddRef(*viewport
);
1781 TRACE("Returning interface %p.\n", *viewport
);
1782 wined3d_mutex_unlock();
1786 static HRESULT WINAPI
d3d_device2_GetCurrentViewport(IDirect3DDevice2
*iface
, IDirect3DViewport2
**viewport
)
1788 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
1790 TRACE("iface %p, viewport %p.\n", iface
, viewport
);
1792 return d3d_device3_GetCurrentViewport(&device
->IDirect3DDevice3_iface
,
1793 (IDirect3DViewport3
**)viewport
);
1796 static BOOL
validate_surface_palette(struct ddraw_surface
*surface
)
1798 return !format_is_paletteindexed(&surface
->surface_desc
.u4
.ddpfPixelFormat
)
1799 || surface
->palette
;
1802 static HRESULT
d3d_device_set_render_target(struct d3d_device
*device
,
1803 struct ddraw_surface
*target
, IUnknown
*rt_iface
)
1807 if (device
->rt_iface
== rt_iface
)
1809 TRACE("No-op SetRenderTarget operation, not doing anything\n");
1814 WARN("Trying to set render target to NULL.\n");
1815 return DDERR_INVALIDPARAMS
;
1818 if (FAILED(hr
= wined3d_device_set_rendertarget_view(device
->wined3d_device
,
1819 0, ddraw_surface_get_rendertarget_view(target
), FALSE
)))
1822 IUnknown_AddRef(rt_iface
);
1823 IUnknown_Release(device
->rt_iface
);
1824 device
->rt_iface
= rt_iface
;
1825 d3d_device_update_depth_stencil(device
);
1830 static HRESULT
d3d_device7_SetRenderTarget(IDirect3DDevice7
*iface
,
1831 IDirectDrawSurface7
*target
, DWORD flags
)
1833 struct ddraw_surface
*target_impl
= unsafe_impl_from_IDirectDrawSurface7(target
);
1834 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
1837 TRACE("iface %p, target %p, flags %#x.\n", iface
, target
, flags
);
1839 wined3d_mutex_lock();
1841 if (!validate_surface_palette(target_impl
))
1843 WARN("Surface %p has an indexed pixel format, but no palette.\n", target_impl
);
1844 wined3d_mutex_unlock();
1845 return DDERR_INVALIDCAPS
;
1848 if (!(target_impl
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_3DDEVICE
))
1850 WARN("Surface %p is not a render target.\n", target_impl
);
1851 wined3d_mutex_unlock();
1852 return DDERR_INVALIDCAPS
;
1855 if (device
->hw
&& !(target_impl
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_VIDEOMEMORY
))
1857 WARN("Surface %p is not in video memory.\n", target_impl
);
1858 wined3d_mutex_unlock();
1859 return DDERR_INVALIDPARAMS
;
1862 if (target_impl
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_ZBUFFER
)
1864 WARN("Surface %p is a depth buffer.\n", target_impl
);
1865 IDirectDrawSurface7_AddRef(target
);
1866 IUnknown_Release(device
->rt_iface
);
1867 device
->rt_iface
= (IUnknown
*)target
;
1868 wined3d_mutex_unlock();
1869 return DDERR_INVALIDPIXELFORMAT
;
1872 hr
= d3d_device_set_render_target(device
, target_impl
, (IUnknown
*)target
);
1873 wined3d_mutex_unlock();
1877 static HRESULT WINAPI
d3d_device7_SetRenderTarget_FPUSetup(IDirect3DDevice7
*iface
,
1878 IDirectDrawSurface7
*NewTarget
, DWORD flags
)
1880 return d3d_device7_SetRenderTarget(iface
, NewTarget
, flags
);
1883 static HRESULT WINAPI
d3d_device7_SetRenderTarget_FPUPreserve(IDirect3DDevice7
*iface
,
1884 IDirectDrawSurface7
*NewTarget
, DWORD flags
)
1889 old_fpucw
= d3d_fpu_setup();
1890 hr
= d3d_device7_SetRenderTarget(iface
, NewTarget
, flags
);
1891 set_fpu_control_word(old_fpucw
);
1896 static HRESULT WINAPI
d3d_device3_SetRenderTarget(IDirect3DDevice3
*iface
,
1897 IDirectDrawSurface4
*target
, DWORD flags
)
1899 struct ddraw_surface
*target_impl
= unsafe_impl_from_IDirectDrawSurface4(target
);
1900 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
1903 TRACE("iface %p, target %p, flags %#x.\n", iface
, target
, flags
);
1905 wined3d_mutex_lock();
1907 if (!validate_surface_palette(target_impl
))
1909 WARN("Surface %p has an indexed pixel format, but no palette.\n", target_impl
);
1910 wined3d_mutex_unlock();
1911 return DDERR_INVALIDCAPS
;
1914 if (!(target_impl
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_3DDEVICE
))
1916 WARN("Surface %p is not a render target.\n", target_impl
);
1917 wined3d_mutex_unlock();
1918 return DDERR_INVALIDCAPS
;
1921 if (target_impl
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_ZBUFFER
)
1923 WARN("Surface %p is a depth buffer.\n", target_impl
);
1924 IDirectDrawSurface4_AddRef(target
);
1925 IUnknown_Release(device
->rt_iface
);
1926 device
->rt_iface
= (IUnknown
*)target
;
1927 wined3d_mutex_unlock();
1928 return DDERR_INVALIDPIXELFORMAT
;
1931 if (device
->hw
&& !(target_impl
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_VIDEOMEMORY
))
1933 WARN("Surface %p is not in video memory.\n", target_impl
);
1934 IDirectDrawSurface4_AddRef(target
);
1935 IUnknown_Release(device
->rt_iface
);
1936 device
->rt_iface
= (IUnknown
*)target
;
1937 wined3d_mutex_unlock();
1941 hr
= d3d_device_set_render_target(device
, target_impl
, (IUnknown
*)target
);
1942 wined3d_mutex_unlock();
1946 static HRESULT WINAPI
d3d_device2_SetRenderTarget(IDirect3DDevice2
*iface
,
1947 IDirectDrawSurface
*target
, DWORD flags
)
1949 struct ddraw_surface
*target_impl
= unsafe_impl_from_IDirectDrawSurface(target
);
1950 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
1953 TRACE("iface %p, target %p, flags %#x.\n", iface
, target
, flags
);
1955 wined3d_mutex_lock();
1957 if (!validate_surface_palette(target_impl
))
1959 WARN("Surface %p has an indexed pixel format, but no palette.\n", target_impl
);
1960 wined3d_mutex_unlock();
1961 return DDERR_INVALIDCAPS
;
1964 if (!(target_impl
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_3DDEVICE
))
1966 WARN("Surface %p is not a render target.\n", target_impl
);
1967 wined3d_mutex_unlock();
1968 return DDERR_INVALIDCAPS
;
1971 if (target_impl
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_ZBUFFER
)
1973 WARN("Surface %p is a depth buffer.\n", target_impl
);
1974 IUnknown_Release(device
->rt_iface
);
1975 device
->rt_iface
= (IUnknown
*)target
;
1976 wined3d_mutex_unlock();
1977 return DDERR_INVALIDPIXELFORMAT
;
1980 if (device
->hw
&& !(target_impl
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_VIDEOMEMORY
))
1982 WARN("Surface %p is not in video memory.\n", target_impl
);
1983 IDirectDrawSurface_AddRef(target
);
1984 IUnknown_Release(device
->rt_iface
);
1985 device
->rt_iface
= (IUnknown
*)target
;
1986 wined3d_mutex_unlock();
1990 hr
= d3d_device_set_render_target(device
, target_impl
, (IUnknown
*)target
);
1991 wined3d_mutex_unlock();
1995 /*****************************************************************************
1996 * IDirect3DDevice7::GetRenderTarget
1998 * Returns the current render target.
1999 * This is handled locally, because the WineD3D render target's parent
2002 * Version 2, 3 and 7
2005 * RenderTarget: Address to store the surface interface pointer
2009 * DDERR_INVALIDPARAMS if RenderTarget == NULL
2011 *****************************************************************************/
2012 static HRESULT WINAPI
d3d_device7_GetRenderTarget(IDirect3DDevice7
*iface
, IDirectDrawSurface7
**RenderTarget
)
2014 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
2017 TRACE("iface %p, target %p.\n", iface
, RenderTarget
);
2020 return DDERR_INVALIDPARAMS
;
2022 wined3d_mutex_lock();
2023 hr
= IUnknown_QueryInterface(device
->rt_iface
, &IID_IDirectDrawSurface7
, (void **)RenderTarget
);
2024 wined3d_mutex_unlock();
2029 static HRESULT WINAPI
d3d_device3_GetRenderTarget(IDirect3DDevice3
*iface
, IDirectDrawSurface4
**RenderTarget
)
2031 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
2032 IDirectDrawSurface7
*RenderTarget7
;
2033 struct ddraw_surface
*RenderTargetImpl
;
2036 TRACE("iface %p, target %p.\n", iface
, RenderTarget
);
2039 return DDERR_INVALIDPARAMS
;
2041 hr
= d3d_device7_GetRenderTarget(&device
->IDirect3DDevice7_iface
, &RenderTarget7
);
2042 if(hr
!= D3D_OK
) return hr
;
2043 RenderTargetImpl
= impl_from_IDirectDrawSurface7(RenderTarget7
);
2044 *RenderTarget
= &RenderTargetImpl
->IDirectDrawSurface4_iface
;
2045 IDirectDrawSurface4_AddRef(*RenderTarget
);
2046 IDirectDrawSurface7_Release(RenderTarget7
);
2050 static HRESULT WINAPI
d3d_device2_GetRenderTarget(IDirect3DDevice2
*iface
, IDirectDrawSurface
**RenderTarget
)
2052 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
2053 IDirectDrawSurface7
*RenderTarget7
;
2054 struct ddraw_surface
*RenderTargetImpl
;
2057 TRACE("iface %p, target %p.\n", iface
, RenderTarget
);
2060 return DDERR_INVALIDPARAMS
;
2062 hr
= d3d_device7_GetRenderTarget(&device
->IDirect3DDevice7_iface
, &RenderTarget7
);
2063 if(hr
!= D3D_OK
) return hr
;
2064 RenderTargetImpl
= impl_from_IDirectDrawSurface7(RenderTarget7
);
2065 *RenderTarget
= &RenderTargetImpl
->IDirectDrawSurface_iface
;
2066 IDirectDrawSurface_AddRef(*RenderTarget
);
2067 IDirectDrawSurface7_Release(RenderTarget7
);
2071 /*****************************************************************************
2072 * IDirect3DDevice3::Begin
2074 * Begins a description block of vertices. This is similar to glBegin()
2075 * and glEnd(). After a call to IDirect3DDevice3::End, the vertices
2076 * described with IDirect3DDevice::Vertex are drawn.
2081 * PrimitiveType: The type of primitives to draw
2082 * VertexTypeDesc: A flexible vertex format description of the vertices
2083 * Flags: Some flags..
2088 *****************************************************************************/
2089 static HRESULT WINAPI
d3d_device3_Begin(IDirect3DDevice3
*iface
,
2090 D3DPRIMITIVETYPE primitive_type
, DWORD fvf
, DWORD flags
)
2092 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
2094 TRACE("iface %p, primitive_type %#x, fvf %#x, flags %#x.\n",
2095 iface
, primitive_type
, fvf
, flags
);
2097 wined3d_mutex_lock();
2098 device
->primitive_type
= primitive_type
;
2099 device
->vertex_type
= fvf
;
2100 device
->render_flags
= flags
;
2101 device
->vertex_size
= get_flexible_vertex_size(device
->vertex_type
);
2102 device
->nb_vertices
= 0;
2103 wined3d_mutex_unlock();
2108 static HRESULT WINAPI
d3d_device2_Begin(IDirect3DDevice2
*iface
,
2109 D3DPRIMITIVETYPE primitive_type
, D3DVERTEXTYPE vertex_type
, DWORD flags
)
2111 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
2114 TRACE("iface %p, primitive_type %#x, vertex_type %#x, flags %#x.\n",
2115 iface
, primitive_type
, vertex_type
, flags
);
2117 switch (vertex_type
)
2119 case D3DVT_VERTEX
: fvf
= D3DFVF_VERTEX
; break;
2120 case D3DVT_LVERTEX
: fvf
= D3DFVF_LVERTEX
; break;
2121 case D3DVT_TLVERTEX
: fvf
= D3DFVF_TLVERTEX
; break;
2123 ERR("Unexpected vertex type %#x.\n", vertex_type
);
2124 return DDERR_INVALIDPARAMS
; /* Should never happen */
2127 return d3d_device3_Begin(&device
->IDirect3DDevice3_iface
, primitive_type
, fvf
, flags
);
2130 /*****************************************************************************
2131 * IDirect3DDevice3::BeginIndexed
2133 * Draws primitives based on vertices in a vertex array which are specified
2139 * PrimitiveType: Primitive type to draw
2140 * VertexType: A FVF description of the vertex format
2141 * Vertices: pointer to an array containing the vertices
2142 * NumVertices: The number of vertices in the vertex array
2143 * Flags: Some flags ...
2146 * D3D_OK, because it's a stub
2148 *****************************************************************************/
2149 static HRESULT WINAPI
d3d_device3_BeginIndexed(IDirect3DDevice3
*iface
,
2150 D3DPRIMITIVETYPE primitive_type
, DWORD fvf
,
2151 void *vertices
, DWORD vertex_count
, DWORD flags
)
2153 FIXME("iface %p, primitive_type %#x, fvf %#x, vertices %p, vertex_count %u, flags %#x stub!\n",
2154 iface
, primitive_type
, fvf
, vertices
, vertex_count
, flags
);
2160 static HRESULT WINAPI
d3d_device2_BeginIndexed(IDirect3DDevice2
*iface
,
2161 D3DPRIMITIVETYPE primitive_type
, D3DVERTEXTYPE vertex_type
,
2162 void *vertices
, DWORD vertex_count
, DWORD flags
)
2164 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
2167 TRACE("iface %p, primitive_type %#x, vertex_type %#x, vertices %p, vertex_count %u, flags %#x stub!\n",
2168 iface
, primitive_type
, vertex_type
, vertices
, vertex_count
, flags
);
2170 switch (vertex_type
)
2172 case D3DVT_VERTEX
: fvf
= D3DFVF_VERTEX
; break;
2173 case D3DVT_LVERTEX
: fvf
= D3DFVF_LVERTEX
; break;
2174 case D3DVT_TLVERTEX
: fvf
= D3DFVF_TLVERTEX
; break;
2176 ERR("Unexpected vertex type %#x.\n", vertex_type
);
2177 return DDERR_INVALIDPARAMS
; /* Should never happen */
2180 return d3d_device3_BeginIndexed(&device
->IDirect3DDevice3_iface
,
2181 primitive_type
, fvf
, vertices
, vertex_count
, flags
);
2184 /*****************************************************************************
2185 * IDirect3DDevice3::Vertex
2187 * Draws a vertex as described by IDirect3DDevice3::Begin. It places all
2188 * drawn vertices in a vertex buffer. If the buffer is too small, its
2189 * size is increased.
2194 * Vertex: Pointer to the vertex
2197 * D3D_OK, on success
2198 * DDERR_INVALIDPARAMS if Vertex is NULL
2200 *****************************************************************************/
2201 static HRESULT WINAPI
d3d_device3_Vertex(IDirect3DDevice3
*iface
, void *vertex
)
2203 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
2205 TRACE("iface %p, vertex %p.\n", iface
, vertex
);
2208 return DDERR_INVALIDPARAMS
;
2210 wined3d_mutex_lock();
2211 if ((device
->nb_vertices
+ 1) * device
->vertex_size
> device
->buffer_size
)
2215 device
->buffer_size
= device
->buffer_size
? device
->buffer_size
* 2 : device
->vertex_size
* 3;
2216 old_buffer
= device
->sysmem_vertex_buffer
;
2217 device
->sysmem_vertex_buffer
= HeapAlloc(GetProcessHeap(), 0, device
->buffer_size
);
2220 memcpy(device
->sysmem_vertex_buffer
, old_buffer
, device
->nb_vertices
* device
->vertex_size
);
2221 HeapFree(GetProcessHeap(), 0, old_buffer
);
2225 memcpy(device
->sysmem_vertex_buffer
+ device
->nb_vertices
++ * device
->vertex_size
, vertex
, device
->vertex_size
);
2226 wined3d_mutex_unlock();
2231 static HRESULT WINAPI
d3d_device2_Vertex(IDirect3DDevice2
*iface
, void *vertex
)
2233 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
2235 TRACE("iface %p, vertex %p.\n", iface
, vertex
);
2237 return d3d_device3_Vertex(&device
->IDirect3DDevice3_iface
, vertex
);
2240 /*****************************************************************************
2241 * IDirect3DDevice3::Index
2243 * Specifies an index to a vertex to be drawn. The vertex array has to
2244 * be specified with BeginIndexed first.
2247 * VertexIndex: The index of the vertex to draw
2250 * D3D_OK because it's a stub
2252 *****************************************************************************/
2253 static HRESULT WINAPI
d3d_device3_Index(IDirect3DDevice3
*iface
, WORD index
)
2255 FIXME("iface %p, index %#x stub!\n", iface
, index
);
2260 static HRESULT WINAPI
d3d_device2_Index(IDirect3DDevice2
*iface
, WORD index
)
2262 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
2264 TRACE("iface %p, index %#x.\n", iface
, index
);
2266 return d3d_device3_Index(&device
->IDirect3DDevice3_iface
, index
);
2269 /*****************************************************************************
2270 * IDirect3DDevice7::GetRenderState
2272 * Returns the value of a render state. The possible render states are
2273 * defined in include/d3dtypes.h
2275 * Version 2, 3 and 7
2278 * RenderStateType: Render state to return the current setting of
2279 * Value: Address to store the value at
2282 * D3D_OK on success,
2283 * DDERR_INVALIDPARAMS if Value == NULL
2285 *****************************************************************************/
2286 static HRESULT
d3d_device7_GetRenderState(IDirect3DDevice7
*iface
,
2287 D3DRENDERSTATETYPE state
, DWORD
*value
)
2289 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
2290 HRESULT hr
= D3D_OK
;
2292 TRACE("iface %p, state %#x, value %p.\n", iface
, state
, value
);
2295 return DDERR_INVALIDPARAMS
;
2297 wined3d_mutex_lock();
2300 case D3DRENDERSTATE_TEXTUREMAG
:
2302 enum wined3d_texture_filter_type tex_mag
;
2304 tex_mag
= wined3d_device_get_sampler_state(device
->wined3d_device
, 0, WINED3D_SAMP_MAG_FILTER
);
2307 case WINED3D_TEXF_POINT
:
2308 *value
= D3DFILTER_NEAREST
;
2310 case WINED3D_TEXF_LINEAR
:
2311 *value
= D3DFILTER_LINEAR
;
2314 ERR("Unhandled texture mag %d !\n",tex_mag
);
2320 case D3DRENDERSTATE_TEXTUREMIN
:
2322 enum wined3d_texture_filter_type tex_min
;
2323 enum wined3d_texture_filter_type tex_mip
;
2325 tex_min
= wined3d_device_get_sampler_state(device
->wined3d_device
, 0, WINED3D_SAMP_MIN_FILTER
);
2326 tex_mip
= wined3d_device_get_sampler_state(device
->wined3d_device
, 0, WINED3D_SAMP_MIP_FILTER
);
2329 case WINED3D_TEXF_POINT
:
2332 case WINED3D_TEXF_NONE
:
2333 *value
= D3DFILTER_NEAREST
;
2335 case WINED3D_TEXF_POINT
:
2336 *value
= D3DFILTER_MIPNEAREST
;
2338 case WINED3D_TEXF_LINEAR
:
2339 *value
= D3DFILTER_LINEARMIPNEAREST
;
2342 ERR("Unhandled mip filter %#x.\n", tex_mip
);
2343 *value
= D3DFILTER_NEAREST
;
2347 case WINED3D_TEXF_LINEAR
:
2350 case WINED3D_TEXF_NONE
:
2351 *value
= D3DFILTER_LINEAR
;
2353 case WINED3D_TEXF_POINT
:
2354 *value
= D3DFILTER_MIPLINEAR
;
2356 case WINED3D_TEXF_LINEAR
:
2357 *value
= D3DFILTER_LINEARMIPLINEAR
;
2360 ERR("Unhandled mip filter %#x.\n", tex_mip
);
2361 *value
= D3DFILTER_LINEAR
;
2366 ERR("Unhandled texture min filter %#x.\n",tex_min
);
2367 *value
= D3DFILTER_NEAREST
;
2373 case D3DRENDERSTATE_TEXTUREADDRESS
:
2374 case D3DRENDERSTATE_TEXTUREADDRESSU
:
2375 *value
= wined3d_device_get_sampler_state(device
->wined3d_device
, 0, WINED3D_SAMP_ADDRESS_U
);
2377 case D3DRENDERSTATE_TEXTUREADDRESSV
:
2378 *value
= wined3d_device_get_sampler_state(device
->wined3d_device
, 0, WINED3D_SAMP_ADDRESS_V
);
2381 case D3DRENDERSTATE_BORDERCOLOR
:
2382 FIXME("Unhandled render state D3DRENDERSTATE_BORDERCOLOR.\n");
2386 case D3DRENDERSTATE_TEXTUREHANDLE
:
2387 case D3DRENDERSTATE_TEXTUREMAPBLEND
:
2388 WARN("Render state %#x is invalid in d3d7.\n", state
);
2389 hr
= DDERR_INVALIDPARAMS
;
2392 case D3DRENDERSTATE_ZBIAS
:
2393 *value
= wined3d_device_get_render_state(device
->wined3d_device
, WINED3D_RS_DEPTHBIAS
);
2397 if (state
>= D3DRENDERSTATE_STIPPLEPATTERN00
2398 && state
<= D3DRENDERSTATE_STIPPLEPATTERN31
)
2400 FIXME("Unhandled stipple pattern render state (%#x).\n", state
);
2404 *value
= wined3d_device_get_render_state(device
->wined3d_device
, state
);
2406 wined3d_mutex_unlock();
2411 static HRESULT WINAPI
d3d_device7_GetRenderState_FPUSetup(IDirect3DDevice7
*iface
,
2412 D3DRENDERSTATETYPE state
, DWORD
*value
)
2414 return d3d_device7_GetRenderState(iface
, state
, value
);
2417 static HRESULT WINAPI
d3d_device7_GetRenderState_FPUPreserve(IDirect3DDevice7
*iface
,
2418 D3DRENDERSTATETYPE state
, DWORD
*value
)
2423 old_fpucw
= d3d_fpu_setup();
2424 hr
= d3d_device7_GetRenderState(iface
, state
, value
);
2425 set_fpu_control_word(old_fpucw
);
2430 static HRESULT WINAPI
d3d_device3_GetRenderState(IDirect3DDevice3
*iface
,
2431 D3DRENDERSTATETYPE state
, DWORD
*value
)
2433 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
2435 TRACE("iface %p, state %#x, value %p.\n", iface
, state
, value
);
2439 case D3DRENDERSTATE_TEXTUREHANDLE
:
2441 /* This state is wrapped to SetTexture in SetRenderState, so
2442 * it has to be wrapped to GetTexture here. */
2443 struct wined3d_texture
*tex
= NULL
;
2446 wined3d_mutex_lock();
2447 if ((tex
= wined3d_device_get_texture(device
->wined3d_device
, 0)))
2449 /* The parent of the texture is the IDirectDrawSurface7
2450 * interface of the ddraw surface. */
2451 struct ddraw_texture
*parent
= wined3d_texture_get_parent(tex
);
2453 *value
= parent
->root
->Handle
;
2455 wined3d_mutex_unlock();
2460 case D3DRENDERSTATE_TEXTUREMAPBLEND
:
2462 /* D3DRENDERSTATE_TEXTUREMAPBLEND is mapped to texture state stages in SetRenderState; reverse
2463 the mapping to get the value. */
2464 DWORD colorop
, colorarg1
, colorarg2
;
2465 DWORD alphaop
, alphaarg1
, alphaarg2
;
2467 wined3d_mutex_lock();
2469 device
->legacyTextureBlending
= TRUE
;
2471 colorop
= wined3d_device_get_texture_stage_state(device
->wined3d_device
, 0, WINED3D_TSS_COLOR_OP
);
2472 colorarg1
= wined3d_device_get_texture_stage_state(device
->wined3d_device
, 0, WINED3D_TSS_COLOR_ARG1
);
2473 colorarg2
= wined3d_device_get_texture_stage_state(device
->wined3d_device
, 0, WINED3D_TSS_COLOR_ARG2
);
2474 alphaop
= wined3d_device_get_texture_stage_state(device
->wined3d_device
, 0, WINED3D_TSS_ALPHA_OP
);
2475 alphaarg1
= wined3d_device_get_texture_stage_state(device
->wined3d_device
, 0, WINED3D_TSS_ALPHA_ARG1
);
2476 alphaarg2
= wined3d_device_get_texture_stage_state(device
->wined3d_device
, 0, WINED3D_TSS_ALPHA_ARG2
);
2478 if (colorop
== WINED3D_TOP_SELECT_ARG1
&& colorarg1
== WINED3DTA_TEXTURE
2479 && alphaop
== WINED3D_TOP_SELECT_ARG1
&& alphaarg1
== WINED3DTA_TEXTURE
)
2480 *value
= D3DTBLEND_DECAL
;
2481 else if (colorop
== WINED3D_TOP_SELECT_ARG1
&& colorarg1
== WINED3DTA_TEXTURE
2482 && alphaop
== WINED3D_TOP_MODULATE
2483 && alphaarg1
== WINED3DTA_TEXTURE
&& alphaarg2
== WINED3DTA_CURRENT
)
2484 *value
= D3DTBLEND_DECALALPHA
;
2485 else if (colorop
== WINED3D_TOP_MODULATE
2486 && colorarg1
== WINED3DTA_TEXTURE
&& colorarg2
== WINED3DTA_CURRENT
2487 && alphaop
== WINED3D_TOP_MODULATE
2488 && alphaarg1
== WINED3DTA_TEXTURE
&& alphaarg2
== WINED3DTA_CURRENT
)
2489 *value
= D3DTBLEND_MODULATEALPHA
;
2492 struct wined3d_texture
*tex
= NULL
;
2493 BOOL tex_alpha
= FALSE
;
2494 DDPIXELFORMAT ddfmt
;
2496 if ((tex
= wined3d_device_get_texture(device
->wined3d_device
, 0)))
2498 struct wined3d_resource_desc desc
;
2500 wined3d_resource_get_desc(wined3d_texture_get_resource(tex
), &desc
);
2501 ddfmt
.dwSize
= sizeof(ddfmt
);
2502 ddrawformat_from_wined3dformat(&ddfmt
, desc
.format
);
2503 if (ddfmt
.u5
.dwRGBAlphaBitMask
)
2507 if (!(colorop
== WINED3D_TOP_MODULATE
2508 && colorarg1
== WINED3DTA_TEXTURE
&& colorarg2
== WINED3DTA_CURRENT
2509 && alphaop
== (tex_alpha
? WINED3D_TOP_SELECT_ARG1
: WINED3D_TOP_SELECT_ARG2
)
2510 && alphaarg1
== WINED3DTA_TEXTURE
&& alphaarg2
== WINED3DTA_CURRENT
))
2511 ERR("Unexpected texture stage state setup, returning D3DTBLEND_MODULATE - likely erroneous.\n");
2513 *value
= D3DTBLEND_MODULATE
;
2516 wined3d_mutex_unlock();
2521 case D3DRENDERSTATE_LIGHTING
:
2522 case D3DRENDERSTATE_NORMALIZENORMALS
:
2523 case D3DRENDERSTATE_LOCALVIEWER
:
2524 *value
= 0xffffffff;
2528 return IDirect3DDevice7_GetRenderState(&device
->IDirect3DDevice7_iface
, state
, value
);
2532 static HRESULT WINAPI
d3d_device2_GetRenderState(IDirect3DDevice2
*iface
,
2533 D3DRENDERSTATETYPE state
, DWORD
*value
)
2535 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
2537 TRACE("iface %p, state %#x, value %p.\n", iface
, state
, value
);
2539 return IDirect3DDevice3_GetRenderState(&device
->IDirect3DDevice3_iface
, state
, value
);
2542 /*****************************************************************************
2543 * IDirect3DDevice7::SetRenderState
2545 * Sets a render state. The possible render states are defined in
2546 * include/d3dtypes.h
2548 * Version 2, 3 and 7
2551 * RenderStateType: State to set
2552 * Value: Value to assign to that state
2554 *****************************************************************************/
2555 static HRESULT
d3d_device7_SetRenderState(IDirect3DDevice7
*iface
,
2556 D3DRENDERSTATETYPE state
, DWORD value
)
2558 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
2559 HRESULT hr
= D3D_OK
;
2561 TRACE("iface %p, state %#x, value %#x.\n", iface
, state
, value
);
2563 wined3d_mutex_lock();
2564 /* Some render states need special care */
2568 * The ddraw texture filter mapping works like this:
2569 * D3DFILTER_NEAREST Point min/mag, no mip
2570 * D3DFILTER_MIPNEAREST Point min/mag, point mip
2571 * D3DFILTER_LINEARMIPNEAREST: Point min/mag, linear mip
2573 * D3DFILTER_LINEAR Linear min/mag, no mip
2574 * D3DFILTER_MIPLINEAR Linear min/mag, point mip
2575 * D3DFILTER_LINEARMIPLINEAR Linear min/mag, linear mip
2577 * This is the opposite of the GL naming convention,
2578 * D3DFILTER_LINEARMIPNEAREST corresponds to GL_NEAREST_MIPMAP_LINEAR.
2580 case D3DRENDERSTATE_TEXTUREMAG
:
2582 enum wined3d_texture_filter_type tex_mag
;
2586 case D3DFILTER_NEAREST
:
2587 case D3DFILTER_MIPNEAREST
:
2588 case D3DFILTER_LINEARMIPNEAREST
:
2589 tex_mag
= WINED3D_TEXF_POINT
;
2591 case D3DFILTER_LINEAR
:
2592 case D3DFILTER_MIPLINEAR
:
2593 case D3DFILTER_LINEARMIPLINEAR
:
2594 tex_mag
= WINED3D_TEXF_LINEAR
;
2597 tex_mag
= WINED3D_TEXF_POINT
;
2598 FIXME("Unhandled texture mag %#x.\n", value
);
2602 wined3d_device_set_sampler_state(device
->wined3d_device
, 0, WINED3D_SAMP_MAG_FILTER
, tex_mag
);
2606 case D3DRENDERSTATE_TEXTUREMIN
:
2608 enum wined3d_texture_filter_type tex_min
;
2609 enum wined3d_texture_filter_type tex_mip
;
2613 case D3DFILTER_NEAREST
:
2614 tex_min
= WINED3D_TEXF_POINT
;
2615 tex_mip
= WINED3D_TEXF_NONE
;
2617 case D3DFILTER_LINEAR
:
2618 tex_min
= WINED3D_TEXF_LINEAR
;
2619 tex_mip
= WINED3D_TEXF_NONE
;
2621 case D3DFILTER_MIPNEAREST
:
2622 tex_min
= WINED3D_TEXF_POINT
;
2623 tex_mip
= WINED3D_TEXF_POINT
;
2625 case D3DFILTER_MIPLINEAR
:
2626 tex_min
= WINED3D_TEXF_LINEAR
;
2627 tex_mip
= WINED3D_TEXF_POINT
;
2629 case D3DFILTER_LINEARMIPNEAREST
:
2630 tex_min
= WINED3D_TEXF_POINT
;
2631 tex_mip
= WINED3D_TEXF_LINEAR
;
2633 case D3DFILTER_LINEARMIPLINEAR
:
2634 tex_min
= WINED3D_TEXF_LINEAR
;
2635 tex_mip
= WINED3D_TEXF_LINEAR
;
2639 FIXME("Unhandled texture min %#x.\n",value
);
2640 tex_min
= WINED3D_TEXF_POINT
;
2641 tex_mip
= WINED3D_TEXF_NONE
;
2645 wined3d_device_set_sampler_state(device
->wined3d_device
,
2646 0, WINED3D_SAMP_MIP_FILTER
, tex_mip
);
2647 wined3d_device_set_sampler_state(device
->wined3d_device
,
2648 0, WINED3D_SAMP_MIN_FILTER
, tex_min
);
2652 case D3DRENDERSTATE_TEXTUREADDRESS
:
2653 wined3d_device_set_sampler_state(device
->wined3d_device
,
2654 0, WINED3D_SAMP_ADDRESS_V
, value
);
2656 case D3DRENDERSTATE_TEXTUREADDRESSU
:
2657 wined3d_device_set_sampler_state(device
->wined3d_device
,
2658 0, WINED3D_SAMP_ADDRESS_U
, value
);
2660 case D3DRENDERSTATE_TEXTUREADDRESSV
:
2661 wined3d_device_set_sampler_state(device
->wined3d_device
,
2662 0, WINED3D_SAMP_ADDRESS_V
, value
);
2665 case D3DRENDERSTATE_BORDERCOLOR
:
2666 /* This should probably just forward to the corresponding sampler
2667 * state. Needs tests. */
2668 FIXME("Unhandled render state D3DRENDERSTATE_BORDERCOLOR.\n");
2672 case D3DRENDERSTATE_TEXTUREHANDLE
:
2673 case D3DRENDERSTATE_TEXTUREMAPBLEND
:
2674 WARN("Render state %#x is invalid in d3d7.\n", state
);
2675 hr
= DDERR_INVALIDPARAMS
;
2678 case D3DRENDERSTATE_ZBIAS
:
2679 wined3d_device_set_render_state(device
->wined3d_device
, WINED3D_RS_DEPTHBIAS
, value
);
2683 if (state
>= D3DRENDERSTATE_STIPPLEPATTERN00
2684 && state
<= D3DRENDERSTATE_STIPPLEPATTERN31
)
2686 FIXME("Unhandled stipple pattern render state (%#x).\n", state
);
2691 wined3d_device_set_render_state(device
->wined3d_device
, state
, value
);
2694 wined3d_mutex_unlock();
2699 static HRESULT WINAPI
d3d_device7_SetRenderState_FPUSetup(IDirect3DDevice7
*iface
,
2700 D3DRENDERSTATETYPE state
, DWORD value
)
2702 return d3d_device7_SetRenderState(iface
, state
, value
);
2705 static HRESULT WINAPI
d3d_device7_SetRenderState_FPUPreserve(IDirect3DDevice7
*iface
,
2706 D3DRENDERSTATETYPE state
, DWORD value
)
2711 old_fpucw
= d3d_fpu_setup();
2712 hr
= d3d_device7_SetRenderState(iface
, state
, value
);
2713 set_fpu_control_word(old_fpucw
);
2718 static HRESULT WINAPI
d3d_device3_SetRenderState(IDirect3DDevice3
*iface
,
2719 D3DRENDERSTATETYPE state
, DWORD value
)
2721 /* Note about D3DRENDERSTATE_TEXTUREMAPBLEND implementation: most of values
2722 for this state can be directly mapped to texture stage colorop and alphaop, but
2723 D3DTBLEND_MODULATE is tricky: it uses alpha from texture when available and alpha
2724 from diffuse otherwise. So changing the texture must be monitored in SetTexture to modify
2725 alphaarg when needed.
2727 Aliens vs Predator 1 depends on accurate D3DTBLEND_MODULATE emulation
2729 Legacy texture blending (TEXTUREMAPBLEND) and texture stage states: directx6 docs state that
2730 TEXTUREMAPBLEND is deprecated, yet can still be used. Games must not use both or results
2731 are undefined. D3DTBLEND_MODULATE mode in particular is dependent on texture pixel format and
2732 requires fixup of stage 0 texture states when texture changes, but this fixup can interfere
2733 with games not using this deprecated state. So a flag 'legacyTextureBlending' has to be kept
2734 in device - TRUE if the app is using TEXTUREMAPBLEND.
2736 Tests show that setting TEXTUREMAPBLEND on native doesn't seem to change values returned by
2737 GetTextureStageState and vice versa. Not so on Wine, but it is 'undefined' anyway so, probably, ok,
2738 unless some broken game will be found that cares. */
2740 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
2743 TRACE("iface %p, state %#x, value %#x.\n", iface
, state
, value
);
2745 if (state
>= D3DSTATE_OVERRIDE_BIAS
)
2747 WARN("Unhandled state %#x.\n", state
);
2748 return DDERR_INVALIDPARAMS
;
2751 wined3d_mutex_lock();
2755 case D3DRENDERSTATE_TEXTUREHANDLE
:
2757 struct ddraw_surface
*surf
;
2761 hr
= wined3d_device_set_texture(device
->wined3d_device
, 0, NULL
);
2765 surf
= ddraw_get_object(&device
->handle_table
, value
- 1, DDRAW_HANDLE_SURFACE
);
2768 WARN("Invalid texture handle.\n");
2769 hr
= DDERR_INVALIDPARAMS
;
2773 hr
= IDirect3DDevice3_SetTexture(iface
, 0, &surf
->IDirect3DTexture2_iface
);
2777 case D3DRENDERSTATE_TEXTUREMAPBLEND
:
2779 device
->legacyTextureBlending
= TRUE
;
2783 case D3DTBLEND_MODULATE
:
2785 struct wined3d_texture
*tex
= NULL
;
2786 BOOL tex_alpha
= FALSE
;
2787 DDPIXELFORMAT ddfmt
;
2789 if ((tex
= wined3d_device_get_texture(device
->wined3d_device
, 0)))
2791 struct wined3d_resource_desc desc
;
2793 wined3d_resource_get_desc(wined3d_texture_get_resource(tex
), &desc
);
2794 ddfmt
.dwSize
= sizeof(ddfmt
);
2795 ddrawformat_from_wined3dformat(&ddfmt
, desc
.format
);
2796 if (ddfmt
.u5
.dwRGBAlphaBitMask
)
2801 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2802 0, WINED3D_TSS_ALPHA_OP
, WINED3D_TOP_SELECT_ARG1
);
2804 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2805 0, WINED3D_TSS_ALPHA_OP
, WINED3D_TOP_SELECT_ARG2
);
2806 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2807 0, WINED3D_TSS_ALPHA_ARG1
, WINED3DTA_TEXTURE
);
2808 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2809 0, WINED3D_TSS_ALPHA_ARG2
, WINED3DTA_CURRENT
);
2810 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2811 0, WINED3D_TSS_COLOR_ARG1
, WINED3DTA_TEXTURE
);
2812 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2813 0, WINED3D_TSS_COLOR_ARG2
, WINED3DTA_CURRENT
);
2814 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2815 0, WINED3D_TSS_COLOR_OP
, WINED3D_TOP_MODULATE
);
2820 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2821 0, WINED3D_TSS_COLOR_OP
, WINED3D_TOP_ADD
);
2822 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2823 0, WINED3D_TSS_COLOR_ARG1
, WINED3DTA_TEXTURE
);
2824 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2825 0, WINED3D_TSS_COLOR_ARG2
, WINED3DTA_CURRENT
);
2826 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2827 0, WINED3D_TSS_ALPHA_OP
, WINED3D_TOP_SELECT_ARG2
);
2828 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2829 0, WINED3D_TSS_ALPHA_ARG2
, WINED3DTA_CURRENT
);
2832 case D3DTBLEND_MODULATEALPHA
:
2833 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2834 0, WINED3D_TSS_COLOR_ARG1
, WINED3DTA_TEXTURE
);
2835 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2836 0, WINED3D_TSS_ALPHA_ARG1
, WINED3DTA_TEXTURE
);
2837 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2838 0, WINED3D_TSS_COLOR_ARG2
, WINED3DTA_CURRENT
);
2839 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2840 0, WINED3D_TSS_ALPHA_ARG2
, WINED3DTA_CURRENT
);
2841 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2842 0, WINED3D_TSS_COLOR_OP
, WINED3D_TOP_MODULATE
);
2843 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2844 0, WINED3D_TSS_ALPHA_OP
, WINED3D_TOP_MODULATE
);
2847 case D3DTBLEND_COPY
:
2848 case D3DTBLEND_DECAL
:
2849 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2850 0, WINED3D_TSS_COLOR_ARG1
, WINED3DTA_TEXTURE
);
2851 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2852 0, WINED3D_TSS_ALPHA_ARG1
, WINED3DTA_TEXTURE
);
2853 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2854 0, WINED3D_TSS_COLOR_OP
, WINED3D_TOP_SELECT_ARG1
);
2855 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2856 0, WINED3D_TSS_ALPHA_OP
, WINED3D_TOP_SELECT_ARG1
);
2859 case D3DTBLEND_DECALALPHA
:
2860 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2861 0, WINED3D_TSS_COLOR_OP
, WINED3D_TOP_BLEND_TEXTURE_ALPHA
);
2862 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2863 0, WINED3D_TSS_COLOR_ARG1
, WINED3DTA_TEXTURE
);
2864 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2865 0, WINED3D_TSS_COLOR_ARG2
, WINED3DTA_CURRENT
);
2866 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2867 0, WINED3D_TSS_ALPHA_OP
, WINED3D_TOP_SELECT_ARG2
);
2868 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2869 0, WINED3D_TSS_ALPHA_ARG2
, WINED3DTA_CURRENT
);
2873 FIXME("Unhandled texture environment %#x.\n", value
);
2880 case D3DRENDERSTATE_LIGHTING
:
2881 case D3DRENDERSTATE_NORMALIZENORMALS
:
2882 case D3DRENDERSTATE_LOCALVIEWER
:
2887 hr
= IDirect3DDevice7_SetRenderState(&device
->IDirect3DDevice7_iface
, state
, value
);
2890 wined3d_mutex_unlock();
2895 static HRESULT WINAPI
d3d_device2_SetRenderState(IDirect3DDevice2
*iface
,
2896 D3DRENDERSTATETYPE state
, DWORD value
)
2898 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
2900 TRACE("iface %p, state %#x, value %#x.\n", iface
, state
, value
);
2902 return IDirect3DDevice3_SetRenderState(&device
->IDirect3DDevice3_iface
, state
, value
);
2905 /*****************************************************************************
2906 * Direct3DDevice3::SetLightState
2908 * Sets a light state for Direct3DDevice3 and Direct3DDevice2. The
2909 * light states are forwarded to Direct3DDevice7 render states
2914 * LightStateType: The light state to change
2915 * Value: The value to assign to that light state
2919 * DDERR_INVALIDPARAMS if the parameters were incorrect
2920 * Also check IDirect3DDevice7::SetRenderState
2922 *****************************************************************************/
2923 static HRESULT WINAPI
d3d_device3_SetLightState(IDirect3DDevice3
*iface
,
2924 D3DLIGHTSTATETYPE state
, DWORD value
)
2926 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
2929 TRACE("iface %p, state %#x, value %#x.\n", iface
, state
, value
);
2931 if (!state
|| (state
> D3DLIGHTSTATE_COLORVERTEX
))
2933 TRACE("Unexpected Light State Type\n");
2934 return DDERR_INVALIDPARAMS
;
2937 wined3d_mutex_lock();
2938 if (state
== D3DLIGHTSTATE_MATERIAL
)
2942 struct d3d_material
*m
;
2944 if (!(m
= ddraw_get_object(&device
->handle_table
, value
- 1, DDRAW_HANDLE_MATERIAL
)))
2946 WARN("Invalid material handle.\n");
2947 wined3d_mutex_unlock();
2948 return DDERR_INVALIDPARAMS
;
2951 material_activate(m
);
2954 device
->material
= value
;
2956 else if (state
== D3DLIGHTSTATE_COLORMODEL
)
2961 ERR("DDCOLOR_MONO should not happen!\n");
2964 /* We are already in this mode */
2965 TRACE("Setting color model to RGB (no-op).\n");
2968 ERR("Unknown color model!\n");
2969 wined3d_mutex_unlock();
2970 return DDERR_INVALIDPARAMS
;
2975 D3DRENDERSTATETYPE rs
;
2978 case D3DLIGHTSTATE_AMBIENT
: /* 2 */
2979 rs
= D3DRENDERSTATE_AMBIENT
;
2981 case D3DLIGHTSTATE_FOGMODE
: /* 4 */
2982 rs
= D3DRENDERSTATE_FOGVERTEXMODE
;
2984 case D3DLIGHTSTATE_FOGSTART
: /* 5 */
2985 rs
= D3DRENDERSTATE_FOGSTART
;
2987 case D3DLIGHTSTATE_FOGEND
: /* 6 */
2988 rs
= D3DRENDERSTATE_FOGEND
;
2990 case D3DLIGHTSTATE_FOGDENSITY
: /* 7 */
2991 rs
= D3DRENDERSTATE_FOGDENSITY
;
2993 case D3DLIGHTSTATE_COLORVERTEX
: /* 8 */
2994 rs
= D3DRENDERSTATE_COLORVERTEX
;
2997 FIXME("Unhandled D3DLIGHTSTATETYPE %#x.\n", state
);
2998 wined3d_mutex_unlock();
2999 return DDERR_INVALIDPARAMS
;
3002 hr
= IDirect3DDevice7_SetRenderState(&device
->IDirect3DDevice7_iface
, rs
, value
);
3003 wined3d_mutex_unlock();
3006 wined3d_mutex_unlock();
3011 static HRESULT WINAPI
d3d_device2_SetLightState(IDirect3DDevice2
*iface
,
3012 D3DLIGHTSTATETYPE state
, DWORD value
)
3014 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
3016 TRACE("iface %p, state %#x, value %#x.\n", iface
, state
, value
);
3018 return d3d_device3_SetLightState(&device
->IDirect3DDevice3_iface
, state
, value
);
3021 /*****************************************************************************
3022 * IDirect3DDevice3::GetLightState
3024 * Returns the current setting of a light state. The state is read from
3025 * the Direct3DDevice7 render state.
3030 * LightStateType: The light state to return
3031 * Value: The address to store the light state setting at
3035 * DDDERR_INVALIDPARAMS if the parameters were incorrect
3036 * Also see IDirect3DDevice7::GetRenderState
3038 *****************************************************************************/
3039 static HRESULT WINAPI
d3d_device3_GetLightState(IDirect3DDevice3
*iface
,
3040 D3DLIGHTSTATETYPE state
, DWORD
*value
)
3042 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
3045 TRACE("iface %p, state %#x, value %p.\n", iface
, state
, value
);
3047 if (!state
|| (state
> D3DLIGHTSTATE_COLORVERTEX
))
3049 TRACE("Unexpected Light State Type\n");
3050 return DDERR_INVALIDPARAMS
;
3054 return DDERR_INVALIDPARAMS
;
3056 wined3d_mutex_lock();
3057 if (state
== D3DLIGHTSTATE_MATERIAL
)
3059 *value
= device
->material
;
3061 else if (state
== D3DLIGHTSTATE_COLORMODEL
)
3063 *value
= D3DCOLOR_RGB
;
3067 D3DRENDERSTATETYPE rs
;
3070 case D3DLIGHTSTATE_AMBIENT
: /* 2 */
3071 rs
= D3DRENDERSTATE_AMBIENT
;
3073 case D3DLIGHTSTATE_FOGMODE
: /* 4 */
3074 rs
= D3DRENDERSTATE_FOGVERTEXMODE
;
3076 case D3DLIGHTSTATE_FOGSTART
: /* 5 */
3077 rs
= D3DRENDERSTATE_FOGSTART
;
3079 case D3DLIGHTSTATE_FOGEND
: /* 6 */
3080 rs
= D3DRENDERSTATE_FOGEND
;
3082 case D3DLIGHTSTATE_FOGDENSITY
: /* 7 */
3083 rs
= D3DRENDERSTATE_FOGDENSITY
;
3085 case D3DLIGHTSTATE_COLORVERTEX
: /* 8 */
3086 rs
= D3DRENDERSTATE_COLORVERTEX
;
3089 FIXME("Unhandled D3DLIGHTSTATETYPE %#x.\n", state
);
3090 wined3d_mutex_unlock();
3091 return DDERR_INVALIDPARAMS
;
3094 hr
= IDirect3DDevice7_GetRenderState(&device
->IDirect3DDevice7_iface
, rs
, value
);
3095 wined3d_mutex_unlock();
3098 wined3d_mutex_unlock();
3103 static HRESULT WINAPI
d3d_device2_GetLightState(IDirect3DDevice2
*iface
,
3104 D3DLIGHTSTATETYPE state
, DWORD
*value
)
3106 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
3108 TRACE("iface %p, state %#x, value %p.\n", iface
, state
, value
);
3110 return d3d_device3_GetLightState(&device
->IDirect3DDevice3_iface
, state
, value
);
3113 /*****************************************************************************
3114 * IDirect3DDevice7::SetTransform
3116 * Assigns a D3DMATRIX to a transform type. The transform types are defined
3117 * in include/d3dtypes.h.
3118 * The D3DTRANSFORMSTATE_WORLD (=1) is translated to D3DTS_WORLDMATRIX(0)
3119 * (=255) for wined3d, because the 1 transform state was removed in d3d8
3120 * and WineD3D already understands the replacement D3DTS_WORLDMATRIX(0)
3122 * Version 2, 3 and 7
3125 * TransformStateType: transform state to set
3126 * Matrix: Matrix to assign to the state
3130 * DDERR_INVALIDPARAMS if Matrix == NULL
3132 *****************************************************************************/
3133 static HRESULT
d3d_device7_SetTransform(IDirect3DDevice7
*iface
,
3134 D3DTRANSFORMSTATETYPE state
, D3DMATRIX
*matrix
)
3136 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
3137 enum wined3d_transform_state wined3d_state
;
3139 TRACE("iface %p, state %#x, matrix %p.\n", iface
, state
, matrix
);
3143 case D3DTRANSFORMSTATE_WORLD
:
3144 wined3d_state
= WINED3D_TS_WORLD_MATRIX(0);
3146 case D3DTRANSFORMSTATE_WORLD1
:
3147 wined3d_state
= WINED3D_TS_WORLD_MATRIX(1);
3149 case D3DTRANSFORMSTATE_WORLD2
:
3150 wined3d_state
= WINED3D_TS_WORLD_MATRIX(2);
3152 case D3DTRANSFORMSTATE_WORLD3
:
3153 wined3d_state
= WINED3D_TS_WORLD_MATRIX(3);
3156 wined3d_state
= state
;
3160 return DDERR_INVALIDPARAMS
;
3162 /* Note: D3DMATRIX is compatible with struct wined3d_matrix. */
3163 wined3d_mutex_lock();
3164 wined3d_device_set_transform(device
->wined3d_device
, wined3d_state
, (struct wined3d_matrix
*)matrix
);
3165 wined3d_mutex_unlock();
3170 static HRESULT WINAPI
d3d_device7_SetTransform_FPUSetup(IDirect3DDevice7
*iface
,
3171 D3DTRANSFORMSTATETYPE state
, D3DMATRIX
*matrix
)
3173 return d3d_device7_SetTransform(iface
, state
, matrix
);
3176 static HRESULT WINAPI
d3d_device7_SetTransform_FPUPreserve(IDirect3DDevice7
*iface
,
3177 D3DTRANSFORMSTATETYPE state
, D3DMATRIX
*matrix
)
3182 old_fpucw
= d3d_fpu_setup();
3183 hr
= d3d_device7_SetTransform(iface
, state
, matrix
);
3184 set_fpu_control_word(old_fpucw
);
3189 static HRESULT WINAPI
d3d_device3_SetTransform(IDirect3DDevice3
*iface
,
3190 D3DTRANSFORMSTATETYPE state
, D3DMATRIX
*matrix
)
3192 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
3194 TRACE("iface %p, state %#x, matrix %p.\n", iface
, state
, matrix
);
3197 return DDERR_INVALIDPARAMS
;
3199 if (state
== D3DTRANSFORMSTATE_PROJECTION
)
3201 D3DMATRIX projection
;
3203 wined3d_mutex_lock();
3204 multiply_matrix(&projection
, &device
->legacy_clipspace
, matrix
);
3205 wined3d_device_set_transform(device
->wined3d_device
,
3206 WINED3D_TS_PROJECTION
, (struct wined3d_matrix
*)&projection
);
3207 device
->legacy_projection
= *matrix
;
3208 wined3d_mutex_unlock();
3213 return IDirect3DDevice7_SetTransform(&device
->IDirect3DDevice7_iface
, state
, matrix
);
3216 static HRESULT WINAPI
d3d_device2_SetTransform(IDirect3DDevice2
*iface
,
3217 D3DTRANSFORMSTATETYPE state
, D3DMATRIX
*matrix
)
3219 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
3221 TRACE("iface %p, state %#x, matrix %p.\n", iface
, state
, matrix
);
3223 return IDirect3DDevice3_SetTransform(&device
->IDirect3DDevice3_iface
, state
, matrix
);
3226 /*****************************************************************************
3227 * IDirect3DDevice7::GetTransform
3229 * Returns the matrix assigned to a transform state
3230 * D3DTRANSFORMSTATE_WORLD is translated to D3DTS_WORLDMATRIX(0), see
3234 * TransformStateType: State to read the matrix from
3235 * Matrix: Address to store the matrix at
3239 * DDERR_INVALIDPARAMS if Matrix == NULL
3241 *****************************************************************************/
3242 static HRESULT
d3d_device7_GetTransform(IDirect3DDevice7
*iface
,
3243 D3DTRANSFORMSTATETYPE state
, D3DMATRIX
*matrix
)
3245 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
3246 enum wined3d_transform_state wined3d_state
;
3248 TRACE("iface %p, state %#x, matrix %p.\n", iface
, state
, matrix
);
3252 case D3DTRANSFORMSTATE_WORLD
:
3253 wined3d_state
= WINED3D_TS_WORLD_MATRIX(0);
3255 case D3DTRANSFORMSTATE_WORLD1
:
3256 wined3d_state
= WINED3D_TS_WORLD_MATRIX(1);
3258 case D3DTRANSFORMSTATE_WORLD2
:
3259 wined3d_state
= WINED3D_TS_WORLD_MATRIX(2);
3261 case D3DTRANSFORMSTATE_WORLD3
:
3262 wined3d_state
= WINED3D_TS_WORLD_MATRIX(3);
3265 wined3d_state
= state
;
3269 return DDERR_INVALIDPARAMS
;
3271 /* Note: D3DMATRIX is compatible with struct wined3d_matrix. */
3272 wined3d_mutex_lock();
3273 wined3d_device_get_transform(device
->wined3d_device
, wined3d_state
, (struct wined3d_matrix
*)matrix
);
3274 wined3d_mutex_unlock();
3279 static HRESULT WINAPI
d3d_device7_GetTransform_FPUSetup(IDirect3DDevice7
*iface
,
3280 D3DTRANSFORMSTATETYPE state
, D3DMATRIX
*matrix
)
3282 return d3d_device7_GetTransform(iface
, state
, matrix
);
3285 static HRESULT WINAPI
d3d_device7_GetTransform_FPUPreserve(IDirect3DDevice7
*iface
,
3286 D3DTRANSFORMSTATETYPE state
, D3DMATRIX
*matrix
)
3291 old_fpucw
= d3d_fpu_setup();
3292 hr
= d3d_device7_GetTransform(iface
, state
, matrix
);
3293 set_fpu_control_word(old_fpucw
);
3298 static HRESULT WINAPI
d3d_device3_GetTransform(IDirect3DDevice3
*iface
,
3299 D3DTRANSFORMSTATETYPE state
, D3DMATRIX
*matrix
)
3301 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
3303 TRACE("iface %p, state %#x, matrix %p.\n", iface
, state
, matrix
);
3306 return DDERR_INVALIDPARAMS
;
3308 if (state
== D3DTRANSFORMSTATE_PROJECTION
)
3310 wined3d_mutex_lock();
3311 *matrix
= device
->legacy_projection
;
3312 wined3d_mutex_unlock();
3316 return IDirect3DDevice7_GetTransform(&device
->IDirect3DDevice7_iface
, state
, matrix
);
3319 static HRESULT WINAPI
d3d_device2_GetTransform(IDirect3DDevice2
*iface
,
3320 D3DTRANSFORMSTATETYPE state
, D3DMATRIX
*matrix
)
3322 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
3324 TRACE("iface %p, state %#x, matrix %p.\n", iface
, state
, matrix
);
3326 return IDirect3DDevice3_GetTransform(&device
->IDirect3DDevice3_iface
, state
, matrix
);
3329 /*****************************************************************************
3330 * IDirect3DDevice7::MultiplyTransform
3332 * Multiplies the already-set transform matrix of a transform state
3333 * with another matrix. For the world matrix, see SetTransform
3335 * Version 2, 3 and 7
3338 * TransformStateType: Transform state to multiply
3339 * D3DMatrix Matrix to multiply with.
3343 * DDERR_INVALIDPARAMS if D3DMatrix is NULL
3345 *****************************************************************************/
3346 static HRESULT
d3d_device7_MultiplyTransform(IDirect3DDevice7
*iface
,
3347 D3DTRANSFORMSTATETYPE state
, D3DMATRIX
*matrix
)
3349 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
3350 enum wined3d_transform_state wined3d_state
;
3352 TRACE("iface %p, state %#x, matrix %p.\n", iface
, state
, matrix
);
3356 case D3DTRANSFORMSTATE_WORLD
:
3357 wined3d_state
= WINED3D_TS_WORLD_MATRIX(0);
3359 case D3DTRANSFORMSTATE_WORLD1
:
3360 wined3d_state
= WINED3D_TS_WORLD_MATRIX(1);
3362 case D3DTRANSFORMSTATE_WORLD2
:
3363 wined3d_state
= WINED3D_TS_WORLD_MATRIX(2);
3365 case D3DTRANSFORMSTATE_WORLD3
:
3366 wined3d_state
= WINED3D_TS_WORLD_MATRIX(3);
3369 wined3d_state
= state
;
3372 /* Note: D3DMATRIX is compatible with struct wined3d_matrix. */
3373 wined3d_mutex_lock();
3374 wined3d_device_multiply_transform(device
->wined3d_device
,
3375 wined3d_state
, (struct wined3d_matrix
*)matrix
);
3376 wined3d_mutex_unlock();
3381 static HRESULT WINAPI
d3d_device7_MultiplyTransform_FPUSetup(IDirect3DDevice7
*iface
,
3382 D3DTRANSFORMSTATETYPE state
, D3DMATRIX
*matrix
)
3384 return d3d_device7_MultiplyTransform(iface
, state
, matrix
);
3387 static HRESULT WINAPI
d3d_device7_MultiplyTransform_FPUPreserve(IDirect3DDevice7
*iface
,
3388 D3DTRANSFORMSTATETYPE state
, D3DMATRIX
*matrix
)
3393 old_fpucw
= d3d_fpu_setup();
3394 hr
= d3d_device7_MultiplyTransform(iface
, state
, matrix
);
3395 set_fpu_control_word(old_fpucw
);
3400 static HRESULT WINAPI
d3d_device3_MultiplyTransform(IDirect3DDevice3
*iface
,
3401 D3DTRANSFORMSTATETYPE state
, D3DMATRIX
*matrix
)
3403 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
3405 TRACE("iface %p, state %#x, matrix %p.\n", iface
, state
, matrix
);
3407 if (state
== D3DTRANSFORMSTATE_PROJECTION
)
3409 D3DMATRIX projection
, tmp
;
3411 wined3d_mutex_lock();
3412 multiply_matrix(&tmp
, &device
->legacy_projection
, matrix
);
3413 multiply_matrix(&projection
, &device
->legacy_clipspace
, &tmp
);
3414 wined3d_device_set_transform(device
->wined3d_device
,
3415 WINED3D_TS_PROJECTION
, (struct wined3d_matrix
*)&projection
);
3416 device
->legacy_projection
= tmp
;
3417 wined3d_mutex_unlock();
3422 return IDirect3DDevice7_MultiplyTransform(&device
->IDirect3DDevice7_iface
, state
, matrix
);
3425 static HRESULT WINAPI
d3d_device2_MultiplyTransform(IDirect3DDevice2
*iface
,
3426 D3DTRANSFORMSTATETYPE state
, D3DMATRIX
*matrix
)
3428 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
3430 TRACE("iface %p, state %#x, matrix %p.\n", iface
, state
, matrix
);
3432 return IDirect3DDevice3_MultiplyTransform(&device
->IDirect3DDevice3_iface
, state
, matrix
);
3435 /*****************************************************************************
3436 * IDirect3DDevice7::DrawPrimitive
3438 * Draws primitives based on vertices in an application-provided pointer
3440 * Version 2, 3 and 7. The IDirect3DDevice2 thunk converts the fixed vertex type into
3441 * an FVF format for D3D7
3444 * PrimitiveType: The type of the primitives to draw
3445 * Vertex type: Flexible vertex format vertex description
3446 * Vertices: Pointer to the vertex array
3447 * VertexCount: The number of vertices to draw
3448 * Flags: As usual a few flags
3452 * DDERR_INVALIDPARAMS if Vertices is NULL
3454 *****************************************************************************/
3456 /* The caller is responsible for wined3d locking */
3457 static HRESULT
d3d_device_prepare_vertex_buffer(struct d3d_device
*device
, UINT min_size
)
3461 if (device
->vertex_buffer_size
< min_size
|| !device
->vertex_buffer
)
3463 UINT size
= max(device
->vertex_buffer_size
* 2, min_size
);
3464 struct wined3d_buffer
*buffer
;
3466 TRACE("Growing vertex buffer to %u bytes\n", size
);
3468 hr
= wined3d_buffer_create_vb(device
->wined3d_device
, size
, WINED3DUSAGE_DYNAMIC
| WINED3DUSAGE_WRITEONLY
,
3469 WINED3D_POOL_DEFAULT
, NULL
, &ddraw_null_wined3d_parent_ops
, &buffer
);
3472 ERR("(%p) wined3d_buffer_create_vb failed with hr = %08x\n", device
, hr
);
3476 if (device
->vertex_buffer
)
3477 wined3d_buffer_decref(device
->vertex_buffer
);
3479 device
->vertex_buffer
= buffer
;
3480 device
->vertex_buffer_size
= size
;
3481 device
->vertex_buffer_pos
= 0;
3486 static HRESULT
d3d_device7_DrawPrimitive(IDirect3DDevice7
*iface
,
3487 D3DPRIMITIVETYPE primitive_type
, DWORD fvf
, void *vertices
,
3488 DWORD vertex_count
, DWORD flags
)
3490 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
3491 struct wined3d_map_desc wined3d_map_desc
;
3492 struct wined3d_box wined3d_box
= {0};
3493 UINT stride
, vb_pos
, size
, align
;
3494 struct wined3d_resource
*vb
;
3497 TRACE("iface %p, primitive_type %#x, fvf %#x, vertices %p, vertex_count %u, flags %#x.\n",
3498 iface
, primitive_type
, fvf
, vertices
, vertex_count
, flags
);
3502 WARN("0 vertex count.\n");
3506 /* Get the stride */
3507 stride
= get_flexible_vertex_size(fvf
);
3508 size
= vertex_count
* stride
;
3510 wined3d_mutex_lock();
3511 hr
= d3d_device_prepare_vertex_buffer(device
, size
);
3515 vb_pos
= device
->vertex_buffer_pos
;
3516 align
= vb_pos
% stride
;
3517 if (align
) align
= stride
- align
;
3518 if (vb_pos
+ size
+ align
> device
->vertex_buffer_size
)
3523 wined3d_box
.left
= vb_pos
;
3524 wined3d_box
.right
= vb_pos
+ size
;
3525 vb
= wined3d_buffer_get_resource(device
->vertex_buffer
);
3526 if (FAILED(hr
= wined3d_resource_map(vb
, 0, &wined3d_map_desc
, &wined3d_box
,
3527 vb_pos
? WINED3D_MAP_NOOVERWRITE
: WINED3D_MAP_DISCARD
)))
3529 memcpy(wined3d_map_desc
.data
, vertices
, size
);
3530 wined3d_resource_unmap(vb
, 0);
3531 device
->vertex_buffer_pos
= vb_pos
+ size
;
3533 hr
= wined3d_device_set_stream_source(device
->wined3d_device
, 0, device
->vertex_buffer
, 0, stride
);
3537 wined3d_device_set_vertex_declaration(device
->wined3d_device
, ddraw_find_decl(device
->ddraw
, fvf
));
3538 wined3d_device_set_primitive_type(device
->wined3d_device
, primitive_type
, 0);
3539 hr
= wined3d_device_draw_primitive(device
->wined3d_device
, vb_pos
/ stride
, vertex_count
);
3542 wined3d_mutex_unlock();
3546 static HRESULT WINAPI
d3d_device7_DrawPrimitive_FPUSetup(IDirect3DDevice7
*iface
,
3547 D3DPRIMITIVETYPE primitive_type
, DWORD fvf
, void *vertices
,
3548 DWORD vertex_count
, DWORD flags
)
3550 return d3d_device7_DrawPrimitive(iface
, primitive_type
, fvf
, vertices
, vertex_count
, flags
);
3553 static HRESULT WINAPI
d3d_device7_DrawPrimitive_FPUPreserve(IDirect3DDevice7
*iface
,
3554 D3DPRIMITIVETYPE primitive_type
, DWORD fvf
, void *vertices
,
3555 DWORD vertex_count
, DWORD flags
)
3560 old_fpucw
= d3d_fpu_setup();
3561 hr
= d3d_device7_DrawPrimitive(iface
, primitive_type
, fvf
, vertices
, vertex_count
, flags
);
3562 set_fpu_control_word(old_fpucw
);
3567 static void setup_lighting(const struct d3d_device
*device
, DWORD fvf
, DWORD flags
)
3571 /* Ignore the D3DFVF_XYZRHW case here, wined3d takes care of that */
3572 if (!device
->material
|| !(fvf
& D3DFVF_NORMAL
) || (flags
& D3DDP_DONOTLIGHT
))
3575 wined3d_device_set_render_state(device
->wined3d_device
, WINED3D_RS_LIGHTING
, enable
);
3579 static HRESULT WINAPI
d3d_device3_DrawPrimitive(IDirect3DDevice3
*iface
,
3580 D3DPRIMITIVETYPE primitive_type
, DWORD fvf
, void *vertices
, DWORD vertex_count
,
3583 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
3585 TRACE("iface %p, primitive_type %#x, fvf %#x, vertices %p, vertex_count %u, flags %#x.\n",
3586 iface
, primitive_type
, fvf
, vertices
, vertex_count
, flags
);
3588 setup_lighting(device
, fvf
, flags
);
3590 return IDirect3DDevice7_DrawPrimitive(&device
->IDirect3DDevice7_iface
,
3591 primitive_type
, fvf
, vertices
, vertex_count
, flags
);
3594 static HRESULT WINAPI
d3d_device2_DrawPrimitive(IDirect3DDevice2
*iface
,
3595 D3DPRIMITIVETYPE primitive_type
, D3DVERTEXTYPE vertex_type
, void *vertices
,
3596 DWORD vertex_count
, DWORD flags
)
3598 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
3601 TRACE("iface %p, primitive_type %#x, vertex_type %#x, vertices %p, vertex_count %u, flags %#x.\n",
3602 iface
, primitive_type
, vertex_type
, vertices
, vertex_count
, flags
);
3604 switch (vertex_type
)
3606 case D3DVT_VERTEX
: fvf
= D3DFVF_VERTEX
; break;
3607 case D3DVT_LVERTEX
: fvf
= D3DFVF_LVERTEX
; break;
3608 case D3DVT_TLVERTEX
: fvf
= D3DFVF_TLVERTEX
; break;
3610 FIXME("Unhandled vertex type %#x.\n", vertex_type
);
3611 return DDERR_INVALIDPARAMS
; /* Should never happen */
3614 return d3d_device3_DrawPrimitive(&device
->IDirect3DDevice3_iface
,
3615 primitive_type
, fvf
, vertices
, vertex_count
, flags
);
3618 /*****************************************************************************
3619 * IDirect3DDevice7::DrawIndexedPrimitive
3621 * Draws vertices from an application-provided pointer, based on the index
3622 * numbers in a WORD array.
3624 * Version 2, 3 and 7. The version 7 thunk translates the vertex type into
3625 * an FVF format for D3D7
3628 * PrimitiveType: The primitive type to draw
3629 * VertexType: The FVF vertex description
3630 * Vertices: Pointer to the vertex array
3632 * Indices: Pointer to the index array
3633 * IndexCount: Number of indices = Number of vertices to draw
3634 * Flags: As usual, some flags
3638 * DDERR_INVALIDPARAMS if Vertices or Indices is NULL
3640 *****************************************************************************/
3641 /* The caller is responsible for wined3d locking */
3642 static HRESULT
d3d_device_prepare_index_buffer(struct d3d_device
*device
, UINT min_size
)
3646 if (device
->index_buffer_size
< min_size
|| !device
->index_buffer
)
3648 UINT size
= max(device
->index_buffer_size
* 2, min_size
);
3649 struct wined3d_buffer
*buffer
;
3651 TRACE("Growing index buffer to %u bytes\n", size
);
3653 hr
= wined3d_buffer_create_ib(device
->wined3d_device
, size
, WINED3DUSAGE_DYNAMIC
| WINED3DUSAGE_WRITEONLY
,
3654 WINED3D_POOL_DEFAULT
, NULL
, &ddraw_null_wined3d_parent_ops
, &buffer
);
3657 ERR("(%p) wined3d_buffer_create_ib failed with hr = %08x\n", device
, hr
);
3661 if (device
->index_buffer
)
3662 wined3d_buffer_decref(device
->index_buffer
);
3663 device
->index_buffer
= buffer
;
3664 device
->index_buffer_size
= size
;
3665 device
->index_buffer_pos
= 0;
3670 static HRESULT
d3d_device7_DrawIndexedPrimitive(IDirect3DDevice7
*iface
,
3671 D3DPRIMITIVETYPE primitive_type
, DWORD fvf
, void *vertices
, DWORD vertex_count
,
3672 WORD
*indices
, DWORD index_count
, DWORD flags
)
3674 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
3676 UINT stride
= get_flexible_vertex_size(fvf
);
3677 UINT vtx_size
= stride
* vertex_count
, idx_size
= index_count
* sizeof(*indices
);
3678 struct wined3d_map_desc wined3d_map_desc
;
3679 struct wined3d_box wined3d_box
= {0};
3680 struct wined3d_resource
*ib
, *vb
;
3681 UINT vb_pos
, ib_pos
, align
;
3683 TRACE("iface %p, primitive_type %#x, fvf %#x, vertices %p, vertex_count %u, "
3684 "indices %p, index_count %u, flags %#x.\n",
3685 iface
, primitive_type
, fvf
, vertices
, vertex_count
, indices
, index_count
, flags
);
3687 if (!vertex_count
|| !index_count
)
3689 WARN("0 vertex or index count.\n");
3693 /* Set the D3DDevice's FVF */
3694 wined3d_mutex_lock();
3696 hr
= d3d_device_prepare_vertex_buffer(device
, vtx_size
);
3700 vb_pos
= device
->vertex_buffer_pos
;
3701 align
= vb_pos
% stride
;
3702 if (align
) align
= stride
- align
;
3703 if (vb_pos
+ vtx_size
+ align
> device
->vertex_buffer_size
)
3708 wined3d_box
.left
= vb_pos
;
3709 wined3d_box
.right
= vb_pos
+ vtx_size
;
3710 vb
= wined3d_buffer_get_resource(device
->vertex_buffer
);
3711 if (FAILED(hr
= wined3d_resource_map(vb
, 0, &wined3d_map_desc
, &wined3d_box
,
3712 vb_pos
? WINED3D_MAP_NOOVERWRITE
: WINED3D_MAP_DISCARD
)))
3714 memcpy(wined3d_map_desc
.data
, vertices
, vtx_size
);
3715 wined3d_resource_unmap(vb
, 0);
3716 device
->vertex_buffer_pos
= vb_pos
+ vtx_size
;
3718 hr
= d3d_device_prepare_index_buffer(device
, idx_size
);
3721 ib_pos
= device
->index_buffer_pos
;
3722 if (device
->index_buffer_size
- idx_size
< ib_pos
)
3725 wined3d_box
.left
= ib_pos
;
3726 wined3d_box
.right
= ib_pos
+ idx_size
;
3727 ib
= wined3d_buffer_get_resource(device
->index_buffer
);
3728 if (FAILED(hr
= wined3d_resource_map(ib
, 0, &wined3d_map_desc
, &wined3d_box
,
3729 ib_pos
? WINED3D_MAP_NOOVERWRITE
: WINED3D_MAP_DISCARD
)))
3731 memcpy(wined3d_map_desc
.data
, indices
, idx_size
);
3732 wined3d_resource_unmap(ib
, 0);
3733 device
->index_buffer_pos
= ib_pos
+ idx_size
;
3735 hr
= wined3d_device_set_stream_source(device
->wined3d_device
, 0, device
->vertex_buffer
, 0, stride
);
3738 wined3d_device_set_index_buffer(device
->wined3d_device
, device
->index_buffer
, WINED3DFMT_R16_UINT
, 0);
3740 wined3d_device_set_vertex_declaration(device
->wined3d_device
, ddraw_find_decl(device
->ddraw
, fvf
));
3741 wined3d_device_set_primitive_type(device
->wined3d_device
, primitive_type
, 0);
3742 wined3d_device_set_base_vertex_index(device
->wined3d_device
, vb_pos
/ stride
);
3743 hr
= wined3d_device_draw_indexed_primitive(device
->wined3d_device
, ib_pos
/ sizeof(*indices
), index_count
);
3746 wined3d_mutex_unlock();
3750 static HRESULT WINAPI
d3d_device7_DrawIndexedPrimitive_FPUSetup(IDirect3DDevice7
*iface
,
3751 D3DPRIMITIVETYPE primitive_type
, DWORD fvf
, void *vertices
, DWORD vertex_count
,
3752 WORD
*indices
, DWORD index_count
, DWORD flags
)
3754 return d3d_device7_DrawIndexedPrimitive(iface
, primitive_type
, fvf
,
3755 vertices
, vertex_count
, indices
, index_count
, flags
);
3758 static HRESULT WINAPI
d3d_device7_DrawIndexedPrimitive_FPUPreserve(IDirect3DDevice7
*iface
,
3759 D3DPRIMITIVETYPE primitive_type
, DWORD fvf
, void *vertices
, DWORD vertex_count
,
3760 WORD
*indices
, DWORD index_count
, DWORD flags
)
3765 old_fpucw
= d3d_fpu_setup();
3766 hr
= d3d_device7_DrawIndexedPrimitive(iface
, primitive_type
, fvf
,
3767 vertices
, vertex_count
, indices
, index_count
, flags
);
3768 set_fpu_control_word(old_fpucw
);
3773 static HRESULT WINAPI
d3d_device3_DrawIndexedPrimitive(IDirect3DDevice3
*iface
,
3774 D3DPRIMITIVETYPE primitive_type
, DWORD fvf
, void *vertices
, DWORD vertex_count
,
3775 WORD
*indices
, DWORD index_count
, DWORD flags
)
3777 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
3779 TRACE("iface %p, primitive_type %#x, fvf %#x, vertices %p, vertex_count %u, "
3780 "indices %p, index_count %u, flags %#x.\n",
3781 iface
, primitive_type
, fvf
, vertices
, vertex_count
, indices
, index_count
, flags
);
3783 setup_lighting(device
, fvf
, flags
);
3785 return IDirect3DDevice7_DrawIndexedPrimitive(&device
->IDirect3DDevice7_iface
,
3786 primitive_type
, fvf
, vertices
, vertex_count
, indices
, index_count
, flags
);
3789 static HRESULT WINAPI
d3d_device2_DrawIndexedPrimitive(IDirect3DDevice2
*iface
,
3790 D3DPRIMITIVETYPE primitive_type
, D3DVERTEXTYPE vertex_type
, void *vertices
,
3791 DWORD vertex_count
, WORD
*indices
, DWORD index_count
, DWORD flags
)
3793 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
3796 TRACE("iface %p, primitive_type %#x, vertex_type %#x, vertices %p, vertex_count %u, "
3797 "indices %p, index_count %u, flags %#x.\n",
3798 iface
, primitive_type
, vertex_type
, vertices
, vertex_count
, indices
, index_count
, flags
);
3800 switch (vertex_type
)
3802 case D3DVT_VERTEX
: fvf
= D3DFVF_VERTEX
; break;
3803 case D3DVT_LVERTEX
: fvf
= D3DFVF_LVERTEX
; break;
3804 case D3DVT_TLVERTEX
: fvf
= D3DFVF_TLVERTEX
; break;
3806 ERR("Unhandled vertex type %#x.\n", vertex_type
);
3807 return DDERR_INVALIDPARAMS
; /* Should never happen */
3810 return d3d_device3_DrawIndexedPrimitive(&device
->IDirect3DDevice3_iface
,
3811 primitive_type
, fvf
, vertices
, vertex_count
, indices
, index_count
, flags
);
3814 /*****************************************************************************
3815 * IDirect3DDevice3::End
3817 * Ends a draw begun with IDirect3DDevice3::Begin or
3818 * IDirect3DDevice::BeginIndexed. The vertices specified with
3819 * IDirect3DDevice::Vertex or IDirect3DDevice::Index are drawn using
3820 * the IDirect3DDevice3::DrawPrimitive method. So far only
3821 * non-indexed mode is supported
3826 * Flags: Some flags, as usual. Don't know which are defined
3829 * The return value of IDirect3DDevice3::DrawPrimitive
3831 *****************************************************************************/
3832 static HRESULT WINAPI
d3d_device3_End(IDirect3DDevice3
*iface
, DWORD flags
)
3834 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
3836 TRACE("iface %p, flags %#x.\n", iface
, flags
);
3838 return d3d_device3_DrawPrimitive(&device
->IDirect3DDevice3_iface
, device
->primitive_type
,
3839 device
->vertex_type
, device
->sysmem_vertex_buffer
, device
->nb_vertices
, device
->render_flags
);
3842 static HRESULT WINAPI
d3d_device2_End(IDirect3DDevice2
*iface
, DWORD flags
)
3844 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
3846 TRACE("iface %p, flags %#x.\n", iface
, flags
);
3848 return d3d_device3_End(&device
->IDirect3DDevice3_iface
, flags
);
3851 /*****************************************************************************
3852 * IDirect3DDevice7::SetClipStatus
3854 * Sets the clip status. This defines things as clipping conditions and
3855 * the extents of the clipping region.
3857 * Version 2, 3 and 7
3863 * D3D_OK because it's a stub
3864 * (DDERR_INVALIDPARAMS if ClipStatus == NULL)
3866 *****************************************************************************/
3867 static HRESULT WINAPI
d3d_device7_SetClipStatus(IDirect3DDevice7
*iface
, D3DCLIPSTATUS
*clip_status
)
3869 FIXME("iface %p, clip_status %p stub!\n", iface
, clip_status
);
3874 static HRESULT WINAPI
d3d_device3_SetClipStatus(IDirect3DDevice3
*iface
, D3DCLIPSTATUS
*clip_status
)
3876 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
3878 TRACE("iface %p, clip_status %p.\n", iface
, clip_status
);
3880 return IDirect3DDevice7_SetClipStatus(&device
->IDirect3DDevice7_iface
, clip_status
);
3883 static HRESULT WINAPI
d3d_device2_SetClipStatus(IDirect3DDevice2
*iface
, D3DCLIPSTATUS
*clip_status
)
3885 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
3887 TRACE("iface %p, clip_status %p.\n", iface
, clip_status
);
3889 return IDirect3DDevice7_SetClipStatus(&device
->IDirect3DDevice7_iface
, clip_status
);
3892 /*****************************************************************************
3893 * IDirect3DDevice7::GetClipStatus
3895 * Returns the clip status
3898 * ClipStatus: Address to write the clip status to
3901 * D3D_OK because it's a stub
3903 *****************************************************************************/
3904 static HRESULT WINAPI
d3d_device7_GetClipStatus(IDirect3DDevice7
*iface
, D3DCLIPSTATUS
*clip_status
)
3906 FIXME("iface %p, clip_status %p stub!\n", iface
, clip_status
);
3911 static HRESULT WINAPI
d3d_device3_GetClipStatus(IDirect3DDevice3
*iface
, D3DCLIPSTATUS
*clip_status
)
3913 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
3915 TRACE("iface %p, clip_status %p.\n", iface
, clip_status
);
3917 return IDirect3DDevice7_GetClipStatus(&device
->IDirect3DDevice7_iface
, clip_status
);
3920 static HRESULT WINAPI
d3d_device2_GetClipStatus(IDirect3DDevice2
*iface
, D3DCLIPSTATUS
*clip_status
)
3922 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
3924 TRACE("iface %p, clip_status %p.\n", iface
, clip_status
);
3926 return IDirect3DDevice7_GetClipStatus(&device
->IDirect3DDevice7_iface
, clip_status
);
3929 /*****************************************************************************
3930 * IDirect3DDevice::DrawPrimitiveStrided
3932 * Draws vertices described by a D3DDRAWPRIMITIVESTRIDEDDATA structure.
3937 * PrimitiveType: The primitive type to draw
3938 * VertexType: The FVF description of the vertices to draw (for the stride??)
3939 * D3DDrawPrimStrideData: A D3DDRAWPRIMITIVESTRIDEDDATA structure describing
3940 * the vertex data locations
3941 * VertexCount: The number of vertices to draw
3945 * D3D_OK, because it's a stub
3946 * (DDERR_INVALIDPARAMS if D3DDrawPrimStrideData is NULL)
3948 *****************************************************************************/
3949 static void pack_strided_data(BYTE
*dst
, DWORD count
, const D3DDRAWPRIMITIVESTRIDEDDATA
*src
, DWORD fvf
)
3951 DWORD i
, tex
, offset
;
3953 for (i
= 0; i
< count
; i
++)
3955 /* The contents of the strided data are determined by the fvf,
3956 * not by the members set in src. So it's valid
3957 * to have diffuse.lpvData set to 0xdeadbeef if the diffuse flag is
3958 * not set in the fvf. */
3959 if (fvf
& D3DFVF_POSITION_MASK
)
3961 offset
= i
* src
->position
.dwStride
;
3962 if (fvf
& D3DFVF_XYZRHW
)
3964 memcpy(dst
, ((BYTE
*)src
->position
.lpvData
) + offset
, 4 * sizeof(float));
3965 dst
+= 4 * sizeof(float);
3969 memcpy(dst
, ((BYTE
*)src
->position
.lpvData
) + offset
, 3 * sizeof(float));
3970 dst
+= 3 * sizeof(float);
3974 if (fvf
& D3DFVF_NORMAL
)
3976 offset
= i
* src
->normal
.dwStride
;
3977 memcpy(dst
, ((BYTE
*)src
->normal
.lpvData
) + offset
, 3 * sizeof(float));
3978 dst
+= 3 * sizeof(float);
3981 if (fvf
& D3DFVF_DIFFUSE
)
3983 offset
= i
* src
->diffuse
.dwStride
;
3984 memcpy(dst
, ((BYTE
*)src
->diffuse
.lpvData
) + offset
, sizeof(DWORD
));
3985 dst
+= sizeof(DWORD
);
3988 if (fvf
& D3DFVF_SPECULAR
)
3990 offset
= i
* src
->specular
.dwStride
;
3991 memcpy(dst
, ((BYTE
*)src
->specular
.lpvData
) + offset
, sizeof(DWORD
));
3992 dst
+= sizeof(DWORD
);
3995 for (tex
= 0; tex
< GET_TEXCOUNT_FROM_FVF(fvf
); ++tex
)
3997 DWORD attrib_count
= GET_TEXCOORD_SIZE_FROM_FVF(fvf
, tex
);
3998 offset
= i
* src
->textureCoords
[tex
].dwStride
;
3999 memcpy(dst
, ((BYTE
*)src
->textureCoords
[tex
].lpvData
) + offset
, attrib_count
* sizeof(float));
4000 dst
+= attrib_count
* sizeof(float);
4005 static HRESULT
d3d_device7_DrawPrimitiveStrided(IDirect3DDevice7
*iface
, D3DPRIMITIVETYPE primitive_type
,
4006 DWORD fvf
, D3DDRAWPRIMITIVESTRIDEDDATA
*strided_data
, DWORD vertex_count
, DWORD flags
)
4008 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
4010 UINT dst_stride
= get_flexible_vertex_size(fvf
);
4011 UINT dst_size
= dst_stride
* vertex_count
;
4012 struct wined3d_map_desc wined3d_map_desc
;
4013 struct wined3d_box wined3d_box
= {0};
4014 struct wined3d_resource
*vb
;
4017 TRACE("iface %p, primitive_type %#x, fvf %#x, strided_data %p, vertex_count %u, flags %#x.\n",
4018 iface
, primitive_type
, fvf
, strided_data
, vertex_count
, flags
);
4022 WARN("0 vertex count.\n");
4026 wined3d_mutex_lock();
4027 hr
= d3d_device_prepare_vertex_buffer(device
, dst_size
);
4031 vb_pos
= device
->vertex_buffer_pos
;
4032 align
= vb_pos
% dst_stride
;
4033 if (align
) align
= dst_stride
- align
;
4034 if (vb_pos
+ dst_size
+ align
> device
->vertex_buffer_size
)
4039 wined3d_box
.left
= vb_pos
;
4040 wined3d_box
.right
= vb_pos
+ dst_size
;
4041 vb
= wined3d_buffer_get_resource(device
->vertex_buffer
);
4042 if (FAILED(hr
= wined3d_resource_map(vb
, 0, &wined3d_map_desc
, &wined3d_box
,
4043 vb_pos
? WINED3D_MAP_NOOVERWRITE
: WINED3D_MAP_DISCARD
)))
4045 pack_strided_data(wined3d_map_desc
.data
, vertex_count
, strided_data
, fvf
);
4046 wined3d_resource_unmap(vb
, 0);
4047 device
->vertex_buffer_pos
= vb_pos
+ dst_size
;
4049 hr
= wined3d_device_set_stream_source(device
->wined3d_device
, 0, device
->vertex_buffer
, 0, dst_stride
);
4052 wined3d_device_set_vertex_declaration(device
->wined3d_device
, ddraw_find_decl(device
->ddraw
, fvf
));
4054 wined3d_device_set_primitive_type(device
->wined3d_device
, primitive_type
, 0);
4055 hr
= wined3d_device_draw_primitive(device
->wined3d_device
, vb_pos
/ dst_stride
, vertex_count
);
4058 wined3d_mutex_unlock();
4062 static HRESULT WINAPI
d3d_device7_DrawPrimitiveStrided_FPUSetup(IDirect3DDevice7
*iface
,
4063 D3DPRIMITIVETYPE PrimitiveType
, DWORD VertexType
,
4064 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
, DWORD VertexCount
, DWORD Flags
)
4066 return d3d_device7_DrawPrimitiveStrided(iface
, PrimitiveType
,
4067 VertexType
, D3DDrawPrimStrideData
, VertexCount
, Flags
);
4070 static HRESULT WINAPI
d3d_device7_DrawPrimitiveStrided_FPUPreserve(IDirect3DDevice7
*iface
,
4071 D3DPRIMITIVETYPE PrimitiveType
, DWORD VertexType
,
4072 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
, DWORD VertexCount
, DWORD Flags
)
4077 old_fpucw
= d3d_fpu_setup();
4078 hr
= d3d_device7_DrawPrimitiveStrided(iface
, PrimitiveType
,
4079 VertexType
, D3DDrawPrimStrideData
, VertexCount
, Flags
);
4080 set_fpu_control_word(old_fpucw
);
4085 static HRESULT WINAPI
d3d_device3_DrawPrimitiveStrided(IDirect3DDevice3
*iface
,
4086 D3DPRIMITIVETYPE PrimitiveType
, DWORD VertexType
,
4087 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
, DWORD VertexCount
, DWORD Flags
)
4089 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
4091 TRACE("iface %p, primitive_type %#x, FVF %#x, strided_data %p, vertex_count %u, flags %#x.\n",
4092 iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Flags
);
4094 setup_lighting(device
, VertexType
, Flags
);
4096 return IDirect3DDevice7_DrawPrimitiveStrided(&device
->IDirect3DDevice7_iface
,
4097 PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Flags
);
4100 /*****************************************************************************
4101 * IDirect3DDevice7::DrawIndexedPrimitiveStrided
4103 * Draws primitives specified by strided data locations based on indices
4111 * D3D_OK, because it's a stub
4112 * (DDERR_INVALIDPARAMS if D3DDrawPrimStrideData is NULL)
4113 * (DDERR_INVALIDPARAMS if Indices is NULL)
4115 *****************************************************************************/
4116 static HRESULT
d3d_device7_DrawIndexedPrimitiveStrided(IDirect3DDevice7
*iface
,
4117 D3DPRIMITIVETYPE primitive_type
, DWORD fvf
, D3DDRAWPRIMITIVESTRIDEDDATA
*strided_data
,
4118 DWORD vertex_count
, WORD
*indices
, DWORD index_count
, DWORD flags
)
4120 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
4121 UINT vtx_dst_stride
= get_flexible_vertex_size(fvf
);
4122 UINT vtx_dst_size
= vertex_count
* vtx_dst_stride
;
4123 UINT idx_size
= index_count
* sizeof(WORD
);
4124 struct wined3d_map_desc wined3d_map_desc
;
4125 struct wined3d_box wined3d_box
= {0};
4126 struct wined3d_resource
*ib
, *vb
;
4131 TRACE("iface %p, primitive_type %#x, fvf %#x, strided_data %p, "
4132 "vertex_count %u, indices %p, index_count %u, flags %#x.\n",
4133 iface
, primitive_type
, fvf
, strided_data
, vertex_count
, indices
, index_count
, flags
);
4135 if (!vertex_count
|| !index_count
)
4137 WARN("0 vertex or index count.\n");
4141 wined3d_mutex_lock();
4143 hr
= d3d_device_prepare_vertex_buffer(device
, vtx_dst_size
);
4147 vb_pos
= device
->vertex_buffer_pos
;
4148 align
= vb_pos
% vtx_dst_stride
;
4149 if (align
) align
= vtx_dst_stride
- align
;
4150 if (vb_pos
+ vtx_dst_size
+ align
> device
->vertex_buffer_size
)
4155 wined3d_box
.left
= vb_pos
;
4156 wined3d_box
.right
= vb_pos
+ vtx_dst_size
;
4157 vb
= wined3d_buffer_get_resource(device
->vertex_buffer
);
4158 if (FAILED(hr
= wined3d_resource_map(vb
, 0, &wined3d_map_desc
, &wined3d_box
,
4159 vb_pos
? WINED3D_MAP_NOOVERWRITE
: WINED3D_MAP_DISCARD
)))
4161 pack_strided_data(wined3d_map_desc
.data
, vertex_count
, strided_data
, fvf
);
4162 wined3d_resource_unmap(vb
, 0);
4163 device
->vertex_buffer_pos
= vb_pos
+ vtx_dst_size
;
4165 hr
= d3d_device_prepare_index_buffer(device
, idx_size
);
4168 ib_pos
= device
->index_buffer_pos
;
4169 if (device
->index_buffer_size
- idx_size
< ib_pos
)
4172 wined3d_box
.left
= ib_pos
;
4173 wined3d_box
.right
= ib_pos
+ idx_size
;
4174 ib
= wined3d_buffer_get_resource(device
->index_buffer
);
4175 if (FAILED(hr
= wined3d_resource_map(ib
, 0, &wined3d_map_desc
, &wined3d_box
,
4176 ib_pos
? WINED3D_MAP_NOOVERWRITE
: WINED3D_MAP_DISCARD
)))
4178 memcpy(wined3d_map_desc
.data
, indices
, idx_size
);
4179 wined3d_resource_unmap(ib
, 0);
4180 device
->index_buffer_pos
= ib_pos
+ idx_size
;
4182 hr
= wined3d_device_set_stream_source(device
->wined3d_device
, 0, device
->vertex_buffer
, 0, vtx_dst_stride
);
4185 wined3d_device_set_index_buffer(device
->wined3d_device
, device
->index_buffer
, WINED3DFMT_R16_UINT
, 0);
4186 wined3d_device_set_base_vertex_index(device
->wined3d_device
, vb_pos
/ vtx_dst_stride
);
4188 wined3d_device_set_vertex_declaration(device
->wined3d_device
, ddraw_find_decl(device
->ddraw
, fvf
));
4189 wined3d_device_set_primitive_type(device
->wined3d_device
, primitive_type
, 0);
4190 hr
= wined3d_device_draw_indexed_primitive(device
->wined3d_device
, ib_pos
/ sizeof(WORD
), index_count
);
4193 wined3d_mutex_unlock();
4197 static HRESULT WINAPI
d3d_device7_DrawIndexedPrimitiveStrided_FPUSetup(IDirect3DDevice7
*iface
,
4198 D3DPRIMITIVETYPE PrimitiveType
, DWORD VertexType
,
4199 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
, DWORD VertexCount
,
4200 WORD
*Indices
, DWORD IndexCount
, DWORD Flags
)
4202 return d3d_device7_DrawIndexedPrimitiveStrided(iface
, PrimitiveType
, VertexType
,
4203 D3DDrawPrimStrideData
, VertexCount
, Indices
, IndexCount
, Flags
);
4206 static HRESULT WINAPI
d3d_device7_DrawIndexedPrimitiveStrided_FPUPreserve(IDirect3DDevice7
*iface
,
4207 D3DPRIMITIVETYPE PrimitiveType
, DWORD VertexType
,
4208 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
, DWORD VertexCount
,
4209 WORD
*Indices
, DWORD IndexCount
, DWORD Flags
)
4214 old_fpucw
= d3d_fpu_setup();
4215 hr
= d3d_device7_DrawIndexedPrimitiveStrided(iface
, PrimitiveType
, VertexType
,
4216 D3DDrawPrimStrideData
, VertexCount
, Indices
, IndexCount
, Flags
);
4217 set_fpu_control_word(old_fpucw
);
4222 static HRESULT WINAPI
d3d_device3_DrawIndexedPrimitiveStrided(IDirect3DDevice3
*iface
,
4223 D3DPRIMITIVETYPE PrimitiveType
, DWORD VertexType
,
4224 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
, DWORD VertexCount
, WORD
*Indices
,
4225 DWORD IndexCount
, DWORD Flags
)
4227 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
4229 TRACE("iface %p, primitive_type %#x, FVF %#x, strided_data %p, vertex_count %u, indices %p, index_count %u, flags %#x.\n",
4230 iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Indices
, IndexCount
, Flags
);
4232 setup_lighting(device
, VertexType
, Flags
);
4234 return IDirect3DDevice7_DrawIndexedPrimitiveStrided(&device
->IDirect3DDevice7_iface
,
4235 PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Indices
, IndexCount
, Flags
);
4238 /*****************************************************************************
4239 * IDirect3DDevice7::DrawPrimitiveVB
4241 * Draws primitives from a vertex buffer to the screen.
4246 * PrimitiveType: Type of primitive to be rendered.
4247 * D3DVertexBuf: Source Vertex Buffer
4248 * StartVertex: Index of the first vertex from the buffer to be rendered
4249 * NumVertices: Number of vertices to be rendered
4250 * Flags: Can be D3DDP_WAIT to wait until rendering has finished
4254 * DDERR_INVALIDPARAMS if D3DVertexBuf is NULL
4256 *****************************************************************************/
4257 static HRESULT
d3d_device7_DrawPrimitiveVB(IDirect3DDevice7
*iface
, D3DPRIMITIVETYPE primitive_type
,
4258 IDirect3DVertexBuffer7
*vb
, DWORD start_vertex
, DWORD vertex_count
, DWORD flags
)
4260 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
4261 struct d3d_vertex_buffer
*vb_impl
= unsafe_impl_from_IDirect3DVertexBuffer7(vb
);
4265 TRACE("iface %p, primitive_type %#x, vb %p, start_vertex %u, vertex_count %u, flags %#x.\n",
4266 iface
, primitive_type
, vb
, start_vertex
, vertex_count
, flags
);
4270 WARN("0 vertex count.\n");
4274 stride
= get_flexible_vertex_size(vb_impl
->fvf
);
4276 wined3d_mutex_lock();
4277 wined3d_device_set_vertex_declaration(device
->wined3d_device
, vb_impl
->wined3d_declaration
);
4278 if (FAILED(hr
= wined3d_device_set_stream_source(device
->wined3d_device
,
4279 0, vb_impl
->wined3d_buffer
, 0, stride
)))
4281 WARN("Failed to set stream source, hr %#x.\n", hr
);
4282 wined3d_mutex_unlock();
4286 /* Now draw the primitives */
4287 wined3d_device_set_primitive_type(device
->wined3d_device
, primitive_type
, 0);
4288 hr
= wined3d_device_draw_primitive(device
->wined3d_device
, start_vertex
, vertex_count
);
4290 wined3d_mutex_unlock();
4295 static HRESULT WINAPI
d3d_device7_DrawPrimitiveVB_FPUSetup(IDirect3DDevice7
*iface
, D3DPRIMITIVETYPE PrimitiveType
,
4296 IDirect3DVertexBuffer7
*D3DVertexBuf
, DWORD StartVertex
, DWORD NumVertices
, DWORD Flags
)
4298 return d3d_device7_DrawPrimitiveVB(iface
, PrimitiveType
, D3DVertexBuf
, StartVertex
, NumVertices
, Flags
);
4301 static HRESULT WINAPI
d3d_device7_DrawPrimitiveVB_FPUPreserve(IDirect3DDevice7
*iface
, D3DPRIMITIVETYPE PrimitiveType
,
4302 IDirect3DVertexBuffer7
*D3DVertexBuf
, DWORD StartVertex
, DWORD NumVertices
, DWORD Flags
)
4307 old_fpucw
= d3d_fpu_setup();
4308 hr
= d3d_device7_DrawPrimitiveVB(iface
, PrimitiveType
, D3DVertexBuf
, StartVertex
, NumVertices
, Flags
);
4309 set_fpu_control_word(old_fpucw
);
4314 static HRESULT WINAPI
d3d_device3_DrawPrimitiveVB(IDirect3DDevice3
*iface
, D3DPRIMITIVETYPE PrimitiveType
,
4315 IDirect3DVertexBuffer
*D3DVertexBuf
, DWORD StartVertex
, DWORD NumVertices
, DWORD Flags
)
4317 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
4318 struct d3d_vertex_buffer
*vb
= unsafe_impl_from_IDirect3DVertexBuffer7((IDirect3DVertexBuffer7
*)D3DVertexBuf
);
4320 TRACE("iface %p, primitive_type %#x, vb %p, start_vertex %u, vertex_count %u, flags %#x.\n",
4321 iface
, PrimitiveType
, D3DVertexBuf
, StartVertex
, NumVertices
, Flags
);
4323 setup_lighting(device
, vb
->fvf
, Flags
);
4325 return IDirect3DDevice7_DrawPrimitiveVB(&device
->IDirect3DDevice7_iface
,
4326 PrimitiveType
, &vb
->IDirect3DVertexBuffer7_iface
, StartVertex
, NumVertices
, Flags
);
4329 /*****************************************************************************
4330 * IDirect3DDevice7::DrawIndexedPrimitiveVB
4332 * Draws primitives from a vertex buffer to the screen
4335 * PrimitiveType: Type of primitive to be rendered.
4336 * D3DVertexBuf: Source Vertex Buffer
4337 * StartVertex: Index of the first vertex from the buffer to be rendered
4338 * NumVertices: Number of vertices to be rendered
4339 * Indices: Array of DWORDs used to index into the Vertices
4340 * IndexCount: Number of indices in Indices
4341 * Flags: Can be D3DDP_WAIT to wait until rendering has finished
4345 *****************************************************************************/
4346 static HRESULT
d3d_device7_DrawIndexedPrimitiveVB(IDirect3DDevice7
*iface
,
4347 D3DPRIMITIVETYPE primitive_type
, IDirect3DVertexBuffer7
*vb
,
4348 DWORD start_vertex
, DWORD vertex_count
, WORD
*indices
, DWORD index_count
, DWORD flags
)
4350 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
4351 struct d3d_vertex_buffer
*vb_impl
= unsafe_impl_from_IDirect3DVertexBuffer7(vb
);
4352 DWORD stride
= get_flexible_vertex_size(vb_impl
->fvf
);
4353 struct wined3d_map_desc wined3d_map_desc
;
4354 struct wined3d_box wined3d_box
= {0};
4355 struct wined3d_resource
*ib
;
4359 TRACE("iface %p, primitive_type %#x, vb %p, start_vertex %u, "
4360 "vertex_count %u, indices %p, index_count %u, flags %#x.\n",
4361 iface
, primitive_type
, vb
, start_vertex
, vertex_count
, indices
, index_count
, flags
);
4363 if (!vertex_count
|| !index_count
)
4365 WARN("0 vertex or index count.\n");
4370 * 1) Upload the indices to the index buffer
4371 * 2) Set the index source
4372 * 3) Set the Vertex Buffer as the Stream source
4373 * 4) Call wined3d_device_draw_indexed_primitive()
4376 wined3d_mutex_lock();
4378 wined3d_device_set_vertex_declaration(device
->wined3d_device
, vb_impl
->wined3d_declaration
);
4380 hr
= d3d_device_prepare_index_buffer(device
, index_count
* sizeof(WORD
));
4383 wined3d_mutex_unlock();
4386 ib_pos
= device
->index_buffer_pos
;
4388 if (device
->index_buffer_size
- index_count
* sizeof(WORD
) < ib_pos
)
4391 /* Copy the index stream into the index buffer. */
4392 wined3d_box
.left
= ib_pos
;
4393 wined3d_box
.right
= ib_pos
+ index_count
* sizeof(WORD
);
4394 ib
= wined3d_buffer_get_resource(device
->index_buffer
);
4395 if (FAILED(hr
= wined3d_resource_map(ib
, 0, &wined3d_map_desc
, &wined3d_box
,
4396 ib_pos
? WINED3D_MAP_NOOVERWRITE
: WINED3D_MAP_DISCARD
)))
4398 ERR("Failed to map buffer, hr %#x.\n", hr
);
4399 wined3d_mutex_unlock();
4402 memcpy(wined3d_map_desc
.data
, indices
, index_count
* sizeof(WORD
));
4403 wined3d_resource_unmap(ib
, 0);
4404 device
->index_buffer_pos
= ib_pos
+ index_count
* sizeof(WORD
);
4406 /* Set the index stream */
4407 wined3d_device_set_base_vertex_index(device
->wined3d_device
, start_vertex
);
4408 wined3d_device_set_index_buffer(device
->wined3d_device
, device
->index_buffer
, WINED3DFMT_R16_UINT
, 0);
4410 /* Set the vertex stream source */
4411 if (FAILED(hr
= wined3d_device_set_stream_source(device
->wined3d_device
,
4412 0, vb_impl
->wined3d_buffer
, 0, stride
)))
4414 ERR("(%p) IDirect3DDevice::SetStreamSource failed with hr = %08x\n", device
, hr
);
4415 wined3d_mutex_unlock();
4419 wined3d_device_set_primitive_type(device
->wined3d_device
, primitive_type
, 0);
4420 hr
= wined3d_device_draw_indexed_primitive(device
->wined3d_device
, ib_pos
/ sizeof(WORD
), index_count
);
4422 wined3d_mutex_unlock();
4427 static HRESULT WINAPI
d3d_device7_DrawIndexedPrimitiveVB_FPUSetup(IDirect3DDevice7
*iface
,
4428 D3DPRIMITIVETYPE PrimitiveType
, IDirect3DVertexBuffer7
*D3DVertexBuf
,
4429 DWORD StartVertex
, DWORD NumVertices
, WORD
*Indices
, DWORD IndexCount
, DWORD Flags
)
4431 return d3d_device7_DrawIndexedPrimitiveVB(iface
, PrimitiveType
,
4432 D3DVertexBuf
, StartVertex
, NumVertices
, Indices
, IndexCount
, Flags
);
4435 static HRESULT WINAPI
d3d_device7_DrawIndexedPrimitiveVB_FPUPreserve(IDirect3DDevice7
*iface
,
4436 D3DPRIMITIVETYPE PrimitiveType
, IDirect3DVertexBuffer7
*D3DVertexBuf
,
4437 DWORD StartVertex
, DWORD NumVertices
, WORD
*Indices
, DWORD IndexCount
, DWORD Flags
)
4442 old_fpucw
= d3d_fpu_setup();
4443 hr
= d3d_device7_DrawIndexedPrimitiveVB(iface
, PrimitiveType
,
4444 D3DVertexBuf
, StartVertex
, NumVertices
, Indices
, IndexCount
, Flags
);
4445 set_fpu_control_word(old_fpucw
);
4450 static HRESULT WINAPI
d3d_device3_DrawIndexedPrimitiveVB(IDirect3DDevice3
*iface
,
4451 D3DPRIMITIVETYPE PrimitiveType
, IDirect3DVertexBuffer
*D3DVertexBuf
, WORD
*Indices
,
4452 DWORD IndexCount
, DWORD Flags
)
4454 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
4455 struct d3d_vertex_buffer
*vb
= unsafe_impl_from_IDirect3DVertexBuffer7((IDirect3DVertexBuffer7
*)D3DVertexBuf
);
4457 TRACE("iface %p, primitive_type %#x, vb %p, indices %p, index_count %u, flags %#x.\n",
4458 iface
, PrimitiveType
, D3DVertexBuf
, Indices
, IndexCount
, Flags
);
4460 setup_lighting(device
, vb
->fvf
, Flags
);
4462 return IDirect3DDevice7_DrawIndexedPrimitiveVB(&device
->IDirect3DDevice7_iface
, PrimitiveType
,
4463 &vb
->IDirect3DVertexBuffer7_iface
, 0, IndexCount
, Indices
, IndexCount
, Flags
);
4466 /*****************************************************************************
4467 * IDirect3DDevice7::ComputeSphereVisibility
4469 * Calculates the visibility of spheres in the current viewport. The spheres
4470 * are passed in the Centers and Radii arrays, the results are passed back
4471 * in the ReturnValues array. Return values are either completely visible,
4472 * partially visible or completely invisible.
4473 * The return value consists of a combination of D3DCLIP_* flags, or is
4474 * 0 if the sphere is completely visible (according to the SDK, not checked)
4479 * Centers: Array containing the sphere centers
4480 * Radii: Array containing the sphere radii
4481 * NumSpheres: The number of centers and radii in the arrays
4483 * ReturnValues: Array to write the results to
4487 * (DDERR_INVALIDPARAMS if Centers, Radii or ReturnValues are NULL)
4488 * (D3DERR_INVALIDMATRIX if the combined world, view and proj matrix
4491 *****************************************************************************/
4493 static DWORD
in_plane(UINT idx
, struct wined3d_vec4 p
, D3DVECTOR center
, D3DVALUE radius
, BOOL equality
)
4495 float distance
, norm
;
4497 norm
= sqrtf(p
.x
* p
.x
+ p
.y
* p
.y
+ p
.z
* p
.z
);
4498 distance
= (p
.x
* center
.u1
.x
+ p
.y
* center
.u2
.y
+ p
.z
* center
.u3
.z
+ p
.w
) / norm
;
4502 if (fabs(distance
) <= radius
)
4503 return D3DSTATUS_CLIPUNIONLEFT
<< idx
;
4504 if (distance
<= -radius
)
4505 return (D3DSTATUS_CLIPUNIONLEFT
| D3DSTATUS_CLIPINTERSECTIONLEFT
) << idx
;
4509 if (fabs(distance
) < radius
)
4510 return D3DSTATUS_CLIPUNIONLEFT
<< idx
;
4511 if (distance
< -radius
)
4512 return (D3DSTATUS_CLIPUNIONLEFT
| D3DSTATUS_CLIPINTERSECTIONLEFT
) << idx
;
4517 static void prepare_clip_space_planes(struct d3d_device
*device
, struct wined3d_vec4
*plane
)
4521 /* We want the wined3d matrices since those include the legacy viewport
4522 * transformation. */
4523 wined3d_mutex_lock();
4524 wined3d_device_get_transform(device
->wined3d_device
,
4525 WINED3D_TS_WORLD
, (struct wined3d_matrix
*)&m
);
4527 wined3d_device_get_transform(device
->wined3d_device
,
4528 WINED3D_TS_VIEW
, (struct wined3d_matrix
*)&temp
);
4529 multiply_matrix(&m
, &temp
, &m
);
4531 wined3d_device_get_transform(device
->wined3d_device
,
4532 WINED3D_TS_PROJECTION
, (struct wined3d_matrix
*)&temp
);
4533 multiply_matrix(&m
, &temp
, &m
);
4534 wined3d_mutex_unlock();
4537 plane
[0].x
= m
._14
+ m
._11
;
4538 plane
[0].y
= m
._24
+ m
._21
;
4539 plane
[0].z
= m
._34
+ m
._31
;
4540 plane
[0].w
= m
._44
+ m
._41
;
4543 plane
[1].x
= m
._14
- m
._11
;
4544 plane
[1].y
= m
._24
- m
._21
;
4545 plane
[1].z
= m
._34
- m
._31
;
4546 plane
[1].w
= m
._44
- m
._41
;
4549 plane
[2].x
= m
._14
- m
._12
;
4550 plane
[2].y
= m
._24
- m
._22
;
4551 plane
[2].z
= m
._34
- m
._32
;
4552 plane
[2].w
= m
._44
- m
._42
;
4555 plane
[3].x
= m
._14
+ m
._12
;
4556 plane
[3].y
= m
._24
+ m
._22
;
4557 plane
[3].z
= m
._34
+ m
._32
;
4558 plane
[3].w
= m
._44
+ m
._42
;
4567 plane
[5].x
= m
._14
- m
._13
;
4568 plane
[5].y
= m
._24
- m
._23
;
4569 plane
[5].z
= m
._34
- m
._33
;
4570 plane
[5].w
= m
._44
- m
._43
;
4573 static void compute_sphere_visibility(struct wined3d_vec4 plane
[12], DWORD enabled_planes
, BOOL equality
,
4574 D3DVECTOR
*centers
, D3DVALUE
*radii
, DWORD sphere_count
, DWORD
*return_values
)
4578 for (i
= 0; i
< sphere_count
; ++i
)
4580 return_values
[i
] = 0;
4581 for (j
= 0; j
< 12; ++j
)
4582 if (enabled_planes
& 1u << j
)
4583 return_values
[i
] |= in_plane(j
, plane
[j
], centers
[i
], radii
[i
], equality
);
4587 static HRESULT WINAPI
d3d_device7_ComputeSphereVisibility(IDirect3DDevice7
*iface
,
4588 D3DVECTOR
*centers
, D3DVALUE
*radii
, DWORD sphere_count
, DWORD flags
, DWORD
*return_values
)
4590 struct wined3d_vec4 plane
[12];
4591 DWORD enabled_planes
= 0x3f;
4592 DWORD user_clip_planes
;
4595 TRACE("iface %p, centers %p, radii %p, sphere_count %u, flags %#x, return_values %p.\n",
4596 iface
, centers
, radii
, sphere_count
, flags
, return_values
);
4598 prepare_clip_space_planes(impl_from_IDirect3DDevice7(iface
), plane
);
4600 IDirect3DDevice7_GetRenderState(iface
, D3DRENDERSTATE_CLIPPLANEENABLE
, &user_clip_planes
);
4601 enabled_planes
|= user_clip_planes
<< 6;
4602 for (j
= 6; j
< 12; ++j
)
4603 IDirect3DDevice7_GetClipPlane(iface
, j
- 6, (D3DVALUE
*)&plane
[j
]);
4605 compute_sphere_visibility(plane
, enabled_planes
, FALSE
, centers
, radii
, sphere_count
, return_values
);
4609 static HRESULT WINAPI
d3d_device3_ComputeSphereVisibility(IDirect3DDevice3
*iface
,
4610 D3DVECTOR
*centers
, D3DVALUE
*radii
, DWORD sphere_count
, DWORD flags
, DWORD
*return_values
)
4612 static const DWORD enabled_planes
= 0x3f;
4613 struct wined3d_vec4 plane
[6];
4616 TRACE("iface %p, centers %p, radii %p, sphere_count %u, flags %#x, return_values %p.\n",
4617 iface
, centers
, radii
, sphere_count
, flags
, return_values
);
4619 prepare_clip_space_planes(impl_from_IDirect3DDevice3(iface
), plane
);
4621 compute_sphere_visibility(plane
, enabled_planes
, TRUE
, centers
, radii
, sphere_count
, return_values
);
4622 for (i
= 0; i
< sphere_count
; ++i
)
4624 BOOL intersect_frustum
= FALSE
, outside_frustum
= FALSE
;
4625 DWORD d3d7_result
= return_values
[i
];
4627 return_values
[i
] = 0;
4629 for (j
= 0; j
< 6; ++j
)
4631 DWORD clip
= (d3d7_result
>> j
) & (D3DSTATUS_CLIPUNIONLEFT
| D3DSTATUS_CLIPINTERSECTIONLEFT
);
4633 if (clip
== D3DSTATUS_CLIPUNIONLEFT
)
4635 return_values
[i
] |= D3DVIS_INTERSECT_LEFT
<< j
* 2;
4636 intersect_frustum
= TRUE
;
4640 return_values
[i
] |= D3DVIS_OUTSIDE_LEFT
<< j
* 2;
4641 outside_frustum
= TRUE
;
4644 if (outside_frustum
)
4645 return_values
[i
] |= D3DVIS_OUTSIDE_FRUSTUM
;
4646 else if (intersect_frustum
)
4647 return_values
[i
] |= D3DVIS_INTERSECT_FRUSTUM
;
4652 /*****************************************************************************
4653 * IDirect3DDevice7::GetTexture
4655 * Returns the texture interface handle assigned to a texture stage.
4656 * The returned texture is AddRefed. This is taken from old ddraw,
4657 * not checked in Windows.
4662 * Stage: Texture stage to read the texture from
4663 * Texture: Address to store the interface pointer at
4667 * DDERR_INVALIDPARAMS if Texture is NULL
4669 *****************************************************************************/
4670 static HRESULT
d3d_device7_GetTexture(IDirect3DDevice7
*iface
,
4671 DWORD stage
, IDirectDrawSurface7
**texture
)
4673 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
4674 struct wined3d_texture
*wined3d_texture
;
4675 struct ddraw_texture
*ddraw_texture
;
4677 TRACE("iface %p, stage %u, texture %p.\n", iface
, stage
, texture
);
4680 return DDERR_INVALIDPARAMS
;
4682 wined3d_mutex_lock();
4683 if (!(wined3d_texture
= wined3d_device_get_texture(device
->wined3d_device
, stage
)))
4686 wined3d_mutex_unlock();
4690 ddraw_texture
= wined3d_texture_get_parent(wined3d_texture
);
4691 *texture
= &ddraw_texture
->root
->IDirectDrawSurface7_iface
;
4692 IDirectDrawSurface7_AddRef(*texture
);
4693 wined3d_mutex_unlock();
4698 static HRESULT WINAPI
d3d_device7_GetTexture_FPUSetup(IDirect3DDevice7
*iface
,
4699 DWORD stage
, IDirectDrawSurface7
**Texture
)
4701 return d3d_device7_GetTexture(iface
, stage
, Texture
);
4704 static HRESULT WINAPI
d3d_device7_GetTexture_FPUPreserve(IDirect3DDevice7
*iface
,
4705 DWORD stage
, IDirectDrawSurface7
**Texture
)
4710 old_fpucw
= d3d_fpu_setup();
4711 hr
= d3d_device7_GetTexture(iface
, stage
, Texture
);
4712 set_fpu_control_word(old_fpucw
);
4717 static HRESULT WINAPI
d3d_device3_GetTexture(IDirect3DDevice3
*iface
, DWORD stage
, IDirect3DTexture2
**Texture2
)
4719 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
4720 struct ddraw_surface
*ret_val_impl
;
4722 IDirectDrawSurface7
*ret_val
;
4724 TRACE("iface %p, stage %u, texture %p.\n", iface
, stage
, Texture2
);
4726 ret
= IDirect3DDevice7_GetTexture(&device
->IDirect3DDevice7_iface
, stage
, &ret_val
);
4728 ret_val_impl
= unsafe_impl_from_IDirectDrawSurface7(ret_val
);
4729 *Texture2
= ret_val_impl
? &ret_val_impl
->IDirect3DTexture2_iface
: NULL
;
4731 TRACE("Returning texture %p.\n", *Texture2
);
4736 /*****************************************************************************
4737 * IDirect3DDevice7::SetTexture
4739 * Assigns a texture to a texture stage. Is the texture AddRef-ed?
4744 * Stage: The stage to assign the texture to
4745 * Texture: Interface pointer to the texture surface
4750 *****************************************************************************/
4751 static HRESULT
d3d_device7_SetTexture(IDirect3DDevice7
*iface
,
4752 DWORD stage
, IDirectDrawSurface7
*texture
)
4754 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
4755 struct ddraw_surface
*surf
= unsafe_impl_from_IDirectDrawSurface7(texture
);
4756 struct wined3d_texture
*wined3d_texture
= NULL
;
4759 TRACE("iface %p, stage %u, texture %p.\n", iface
, stage
, texture
);
4761 if (surf
&& (surf
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_TEXTURE
))
4762 wined3d_texture
= surf
->wined3d_texture
;
4764 wined3d_mutex_lock();
4765 hr
= wined3d_device_set_texture(device
->wined3d_device
, stage
, wined3d_texture
);
4766 wined3d_mutex_unlock();
4771 static HRESULT WINAPI
d3d_device7_SetTexture_FPUSetup(IDirect3DDevice7
*iface
,
4772 DWORD stage
, IDirectDrawSurface7
*texture
)
4774 return d3d_device7_SetTexture(iface
, stage
, texture
);
4777 static HRESULT WINAPI
d3d_device7_SetTexture_FPUPreserve(IDirect3DDevice7
*iface
,
4778 DWORD stage
, IDirectDrawSurface7
*texture
)
4783 old_fpucw
= d3d_fpu_setup();
4784 hr
= d3d_device7_SetTexture(iface
, stage
, texture
);
4785 set_fpu_control_word(old_fpucw
);
4790 static HRESULT WINAPI
d3d_device3_SetTexture(IDirect3DDevice3
*iface
,
4791 DWORD stage
, IDirect3DTexture2
*texture
)
4793 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
4794 struct ddraw_surface
*tex
= unsafe_impl_from_IDirect3DTexture2(texture
);
4798 TRACE("iface %p, stage %u, texture %p.\n", iface
, stage
, texture
);
4800 wined3d_mutex_lock();
4802 if (device
->legacyTextureBlending
)
4803 IDirect3DDevice3_GetRenderState(iface
, D3DRENDERSTATE_TEXTUREMAPBLEND
, &texmapblend
);
4805 hr
= IDirect3DDevice7_SetTexture(&device
->IDirect3DDevice7_iface
, stage
, &tex
->IDirectDrawSurface7_iface
);
4807 if (device
->legacyTextureBlending
&& texmapblend
== D3DTBLEND_MODULATE
)
4809 /* This fixup is required by the way D3DTBLEND_MODULATE maps to texture stage states.
4810 See d3d_device3_SetRenderState() for details. */
4811 struct wined3d_texture
*tex
= NULL
;
4812 BOOL tex_alpha
= FALSE
;
4813 DDPIXELFORMAT ddfmt
;
4815 if ((tex
= wined3d_device_get_texture(device
->wined3d_device
, 0)))
4817 struct wined3d_resource_desc desc
;
4819 wined3d_resource_get_desc(wined3d_texture_get_resource(tex
), &desc
);
4820 ddfmt
.dwSize
= sizeof(ddfmt
);
4821 ddrawformat_from_wined3dformat(&ddfmt
, desc
.format
);
4822 if (ddfmt
.u5
.dwRGBAlphaBitMask
)
4826 /* Args 1 and 2 are already set to WINED3DTA_TEXTURE/WINED3DTA_CURRENT in case of D3DTBLEND_MODULATE */
4828 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
4829 0, WINED3D_TSS_ALPHA_OP
, WINED3D_TOP_SELECT_ARG1
);
4831 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
4832 0, WINED3D_TSS_ALPHA_OP
, WINED3D_TOP_SELECT_ARG2
);
4835 wined3d_mutex_unlock();
4840 static const struct tss_lookup
4845 enum wined3d_texture_stage_state texture_state
;
4846 enum wined3d_sampler_state sampler_state
;
4851 {FALSE
, {WINED3D_TSS_INVALID
}}, /* 0, unused */
4852 {FALSE
, {WINED3D_TSS_COLOR_OP
}}, /* 1, D3DTSS_COLOROP */
4853 {FALSE
, {WINED3D_TSS_COLOR_ARG1
}}, /* 2, D3DTSS_COLORARG1 */
4854 {FALSE
, {WINED3D_TSS_COLOR_ARG2
}}, /* 3, D3DTSS_COLORARG2 */
4855 {FALSE
, {WINED3D_TSS_ALPHA_OP
}}, /* 4, D3DTSS_ALPHAOP */
4856 {FALSE
, {WINED3D_TSS_ALPHA_ARG1
}}, /* 5, D3DTSS_ALPHAARG1 */
4857 {FALSE
, {WINED3D_TSS_ALPHA_ARG2
}}, /* 6, D3DTSS_ALPHAARG2 */
4858 {FALSE
, {WINED3D_TSS_BUMPENV_MAT00
}}, /* 7, D3DTSS_BUMPENVMAT00 */
4859 {FALSE
, {WINED3D_TSS_BUMPENV_MAT01
}}, /* 8, D3DTSS_BUMPENVMAT01 */
4860 {FALSE
, {WINED3D_TSS_BUMPENV_MAT10
}}, /* 9, D3DTSS_BUMPENVMAT10 */
4861 {FALSE
, {WINED3D_TSS_BUMPENV_MAT11
}}, /* 10, D3DTSS_BUMPENVMAT11 */
4862 {FALSE
, {WINED3D_TSS_TEXCOORD_INDEX
}}, /* 11, D3DTSS_TEXCOORDINDEX */
4863 {TRUE
, {WINED3D_SAMP_ADDRESS_U
}}, /* 12, D3DTSS_ADDRESS */
4864 {TRUE
, {WINED3D_SAMP_ADDRESS_U
}}, /* 13, D3DTSS_ADDRESSU */
4865 {TRUE
, {WINED3D_SAMP_ADDRESS_V
}}, /* 14, D3DTSS_ADDRESSV */
4866 {TRUE
, {WINED3D_SAMP_BORDER_COLOR
}}, /* 15, D3DTSS_BORDERCOLOR */
4867 {TRUE
, {WINED3D_SAMP_MAG_FILTER
}}, /* 16, D3DTSS_MAGFILTER */
4868 {TRUE
, {WINED3D_SAMP_MIN_FILTER
}}, /* 17, D3DTSS_MINFILTER */
4869 {TRUE
, {WINED3D_SAMP_MIP_FILTER
}}, /* 18, D3DTSS_MIPFILTER */
4870 {TRUE
, {WINED3D_SAMP_MIPMAP_LOD_BIAS
}}, /* 19, D3DTSS_MIPMAPLODBIAS */
4871 {TRUE
, {WINED3D_SAMP_MAX_MIP_LEVEL
}}, /* 20, D3DTSS_MAXMIPLEVEL */
4872 {TRUE
, {WINED3D_SAMP_MAX_ANISOTROPY
}}, /* 21, D3DTSS_MAXANISOTROPY */
4873 {FALSE
, {WINED3D_TSS_BUMPENV_LSCALE
}}, /* 22, D3DTSS_BUMPENVLSCALE */
4874 {FALSE
, {WINED3D_TSS_BUMPENV_LOFFSET
}}, /* 23, D3DTSS_BUMPENVLOFFSET */
4875 {FALSE
, {WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS
}}, /* 24, D3DTSS_TEXTURETRANSFORMFLAGS */
4878 /*****************************************************************************
4879 * IDirect3DDevice7::GetTextureStageState
4881 * Retrieves a state from a texture stage.
4886 * Stage: The stage to retrieve the state from
4887 * TexStageStateType: The state type to retrieve
4888 * State: Address to store the state's value at
4892 * DDERR_INVALIDPARAMS if State is NULL
4894 *****************************************************************************/
4895 static HRESULT
d3d_device7_GetTextureStageState(IDirect3DDevice7
*iface
,
4896 DWORD stage
, D3DTEXTURESTAGESTATETYPE state
, DWORD
*value
)
4898 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
4899 const struct tss_lookup
*l
;
4901 TRACE("iface %p, stage %u, state %#x, value %p.\n",
4902 iface
, stage
, state
, value
);
4905 return DDERR_INVALIDPARAMS
;
4907 if (state
> D3DTSS_TEXTURETRANSFORMFLAGS
)
4909 WARN("Invalid state %#x passed.\n", state
);
4913 l
= &tss_lookup
[state
];
4915 wined3d_mutex_lock();
4917 if (l
->sampler_state
)
4919 *value
= wined3d_device_get_sampler_state(device
->wined3d_device
, stage
, l
->u
.sampler_state
);
4923 /* Mipfilter is a sampler state with different values */
4924 case D3DTSS_MIPFILTER
:
4928 case WINED3D_TEXF_NONE
:
4929 *value
= D3DTFP_NONE
;
4931 case WINED3D_TEXF_POINT
:
4932 *value
= D3DTFP_POINT
;
4934 case WINED3D_TEXF_LINEAR
:
4935 *value
= D3DTFP_LINEAR
;
4938 ERR("Unexpected mipfilter value %#x.\n", *value
);
4939 *value
= D3DTFP_NONE
;
4945 /* Magfilter has slightly different values */
4946 case D3DTSS_MAGFILTER
:
4950 case WINED3D_TEXF_POINT
:
4951 *value
= D3DTFG_POINT
;
4953 case WINED3D_TEXF_LINEAR
:
4954 *value
= D3DTFG_LINEAR
;
4956 case WINED3D_TEXF_ANISOTROPIC
:
4957 *value
= D3DTFG_ANISOTROPIC
;
4959 case WINED3D_TEXF_FLAT_CUBIC
:
4960 *value
= D3DTFG_FLATCUBIC
;
4962 case WINED3D_TEXF_GAUSSIAN_CUBIC
:
4963 *value
= D3DTFG_GAUSSIANCUBIC
;
4966 ERR("Unexpected wined3d mag filter value %#x.\n", *value
);
4967 *value
= D3DTFG_POINT
;
4979 *value
= wined3d_device_get_texture_stage_state(device
->wined3d_device
, stage
, l
->u
.texture_state
);
4982 wined3d_mutex_unlock();
4987 static HRESULT WINAPI
d3d_device7_GetTextureStageState_FPUSetup(IDirect3DDevice7
*iface
,
4988 DWORD stage
, D3DTEXTURESTAGESTATETYPE state
, DWORD
*value
)
4990 return d3d_device7_GetTextureStageState(iface
, stage
, state
, value
);
4993 static HRESULT WINAPI
d3d_device7_GetTextureStageState_FPUPreserve(IDirect3DDevice7
*iface
,
4994 DWORD stage
, D3DTEXTURESTAGESTATETYPE state
, DWORD
*value
)
4999 old_fpucw
= d3d_fpu_setup();
5000 hr
= d3d_device7_GetTextureStageState(iface
, stage
, state
, value
);
5001 set_fpu_control_word(old_fpucw
);
5006 static HRESULT WINAPI
d3d_device3_GetTextureStageState(IDirect3DDevice3
*iface
,
5007 DWORD stage
, D3DTEXTURESTAGESTATETYPE state
, DWORD
*value
)
5009 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
5011 TRACE("iface %p, stage %u, state %#x, value %p.\n",
5012 iface
, stage
, state
, value
);
5014 return IDirect3DDevice7_GetTextureStageState(&device
->IDirect3DDevice7_iface
, stage
, state
, value
);
5017 /*****************************************************************************
5018 * IDirect3DDevice7::SetTextureStageState
5020 * Sets a texture stage state. Some stage types need to be handled specially,
5021 * because they do not exist in WineD3D and were moved to another place
5026 * Stage: The stage to modify
5027 * TexStageStateType: The state to change
5028 * State: The new value for the state
5033 *****************************************************************************/
5034 static HRESULT
d3d_device7_SetTextureStageState(IDirect3DDevice7
*iface
,
5035 DWORD stage
, D3DTEXTURESTAGESTATETYPE state
, DWORD value
)
5037 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
5038 const struct tss_lookup
*l
;
5040 TRACE("iface %p, stage %u, state %#x, value %#x.\n",
5041 iface
, stage
, state
, value
);
5043 if (state
> D3DTSS_TEXTURETRANSFORMFLAGS
)
5045 WARN("Invalid state %#x passed.\n", state
);
5049 l
= &tss_lookup
[state
];
5051 wined3d_mutex_lock();
5053 if (l
->sampler_state
)
5057 /* Mipfilter is a sampler state with different values */
5058 case D3DTSS_MIPFILTER
:
5063 value
= WINED3D_TEXF_NONE
;
5066 value
= WINED3D_TEXF_POINT
;
5068 case 0: /* Unchecked */
5070 value
= WINED3D_TEXF_LINEAR
;
5073 ERR("Unexpected mipfilter value %#x.\n", value
);
5074 value
= WINED3D_TEXF_NONE
;
5080 /* Magfilter has slightly different values */
5081 case D3DTSS_MAGFILTER
:
5086 value
= WINED3D_TEXF_POINT
;
5089 value
= WINED3D_TEXF_LINEAR
;
5091 case D3DTFG_FLATCUBIC
:
5092 value
= WINED3D_TEXF_FLAT_CUBIC
;
5094 case D3DTFG_GAUSSIANCUBIC
:
5095 value
= WINED3D_TEXF_GAUSSIAN_CUBIC
;
5097 case D3DTFG_ANISOTROPIC
:
5098 value
= WINED3D_TEXF_ANISOTROPIC
;
5101 ERR("Unexpected d3d7 mag filter value %#x.\n", value
);
5102 value
= WINED3D_TEXF_POINT
;
5108 case D3DTSS_ADDRESS
:
5109 wined3d_device_set_sampler_state(device
->wined3d_device
, stage
, WINED3D_SAMP_ADDRESS_V
, value
);
5116 wined3d_device_set_sampler_state(device
->wined3d_device
, stage
, l
->u
.sampler_state
, value
);
5120 wined3d_device_set_texture_stage_state(device
->wined3d_device
, stage
, l
->u
.texture_state
, value
);
5123 wined3d_mutex_unlock();
5128 static HRESULT WINAPI
d3d_device7_SetTextureStageState_FPUSetup(IDirect3DDevice7
*iface
,
5129 DWORD stage
, D3DTEXTURESTAGESTATETYPE state
, DWORD value
)
5131 return d3d_device7_SetTextureStageState(iface
, stage
, state
, value
);
5134 static HRESULT WINAPI
d3d_device7_SetTextureStageState_FPUPreserve(IDirect3DDevice7
*iface
,
5135 DWORD stage
, D3DTEXTURESTAGESTATETYPE state
, DWORD value
)
5140 old_fpucw
= d3d_fpu_setup();
5141 hr
= d3d_device7_SetTextureStageState(iface
, stage
, state
, value
);
5142 set_fpu_control_word(old_fpucw
);
5147 static HRESULT WINAPI
d3d_device3_SetTextureStageState(IDirect3DDevice3
*iface
,
5148 DWORD stage
, D3DTEXTURESTAGESTATETYPE state
, DWORD value
)
5150 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
5152 TRACE("iface %p, stage %u, state %#x, value %#x.\n",
5153 iface
, stage
, state
, value
);
5155 return IDirect3DDevice7_SetTextureStageState(&device
->IDirect3DDevice7_iface
, stage
, state
, value
);
5158 /*****************************************************************************
5159 * IDirect3DDevice7::ValidateDevice
5161 * SDK: "Reports the device's ability to render the currently set
5162 * texture-blending operations in a single pass". Whatever that means
5168 * NumPasses: Address to write the number of necessary passes for the
5169 * desired effect to.
5174 *****************************************************************************/
5175 static HRESULT
d3d_device7_ValidateDevice(IDirect3DDevice7
*iface
, DWORD
*pass_count
)
5177 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
5180 TRACE("iface %p, pass_count %p.\n", iface
, pass_count
);
5182 wined3d_mutex_lock();
5183 hr
= wined3d_device_validate_device(device
->wined3d_device
, pass_count
);
5184 wined3d_mutex_unlock();
5189 static HRESULT WINAPI
d3d_device7_ValidateDevice_FPUSetup(IDirect3DDevice7
*iface
, DWORD
*pass_count
)
5191 return d3d_device7_ValidateDevice(iface
, pass_count
);
5194 static HRESULT WINAPI
d3d_device7_ValidateDevice_FPUPreserve(IDirect3DDevice7
*iface
, DWORD
*pass_count
)
5199 old_fpucw
= d3d_fpu_setup();
5200 hr
= d3d_device7_ValidateDevice(iface
, pass_count
);
5201 set_fpu_control_word(old_fpucw
);
5206 static HRESULT WINAPI
d3d_device3_ValidateDevice(IDirect3DDevice3
*iface
, DWORD
*pass_count
)
5208 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
5210 TRACE("iface %p, pass_count %p.\n", iface
, pass_count
);
5212 return IDirect3DDevice7_ValidateDevice(&device
->IDirect3DDevice7_iface
, pass_count
);
5215 /*****************************************************************************
5216 * IDirect3DDevice7::Clear
5218 * Fills the render target, the z buffer and the stencil buffer with a
5219 * clear color / value
5224 * Count: Number of rectangles in Rects must be 0 if Rects is NULL
5225 * Rects: Rectangles to clear. If NULL, the whole surface is cleared
5226 * Flags: Some flags, as usual
5227 * Color: Clear color for the render target
5228 * Z: Clear value for the Z buffer
5229 * Stencil: Clear value to store in each stencil buffer entry
5234 *****************************************************************************/
5235 static HRESULT
d3d_device7_Clear(IDirect3DDevice7
*iface
, DWORD count
,
5236 D3DRECT
*rects
, DWORD flags
, D3DCOLOR color
, D3DVALUE z
, DWORD stencil
)
5238 const struct wined3d_color c
=
5240 ((color
>> 16) & 0xff) / 255.0f
,
5241 ((color
>> 8) & 0xff) / 255.0f
,
5242 (color
& 0xff) / 255.0f
,
5243 ((color
>> 24) & 0xff) / 255.0f
,
5245 struct d3d_device
*This
= impl_from_IDirect3DDevice7(iface
);
5248 TRACE("iface %p, count %u, rects %p, flags %#x, color 0x%08x, z %.8e, stencil %#x.\n",
5249 iface
, count
, rects
, flags
, color
, z
, stencil
);
5251 if (count
&& !rects
)
5253 WARN("count %u with NULL rects.\n", count
);
5257 wined3d_mutex_lock();
5258 hr
= wined3d_device_clear(This
->wined3d_device
, count
, (RECT
*)rects
, flags
, &c
, z
, stencil
);
5259 wined3d_mutex_unlock();
5264 static HRESULT WINAPI
d3d_device7_Clear_FPUSetup(IDirect3DDevice7
*iface
, DWORD count
,
5265 D3DRECT
*rects
, DWORD flags
, D3DCOLOR color
, D3DVALUE z
, DWORD stencil
)
5267 return d3d_device7_Clear(iface
, count
, rects
, flags
, color
, z
, stencil
);
5270 static HRESULT WINAPI
d3d_device7_Clear_FPUPreserve(IDirect3DDevice7
*iface
, DWORD count
,
5271 D3DRECT
*rects
, DWORD flags
, D3DCOLOR color
, D3DVALUE z
, DWORD stencil
)
5276 old_fpucw
= d3d_fpu_setup();
5277 hr
= d3d_device7_Clear(iface
, count
, rects
, flags
, color
, z
, stencil
);
5278 set_fpu_control_word(old_fpucw
);
5283 /*****************************************************************************
5284 * IDirect3DDevice7::SetViewport
5286 * Sets the current viewport.
5288 * Version 7 only, but IDirect3DViewport uses this call for older
5292 * Data: The new viewport to set
5296 * DDERR_INVALIDPARAMS if Data is NULL
5298 *****************************************************************************/
5299 static HRESULT
d3d_device7_SetViewport(IDirect3DDevice7
*iface
, D3DVIEWPORT7
*viewport
)
5301 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
5302 struct wined3d_viewport vp
;
5304 TRACE("iface %p, viewport %p.\n", iface
, viewport
);
5307 return DDERR_INVALIDPARAMS
;
5309 vp
.x
= viewport
->dwX
;
5310 vp
.y
= viewport
->dwY
;
5311 vp
.width
= viewport
->dwWidth
;
5312 vp
.height
= viewport
->dwHeight
;
5313 vp
.min_z
= viewport
->dvMinZ
;
5314 vp
.max_z
= viewport
->dvMaxZ
;
5316 wined3d_mutex_lock();
5317 wined3d_device_set_viewport(device
->wined3d_device
, &vp
);
5318 wined3d_mutex_unlock();
5323 static HRESULT WINAPI
d3d_device7_SetViewport_FPUSetup(IDirect3DDevice7
*iface
, D3DVIEWPORT7
*viewport
)
5325 return d3d_device7_SetViewport(iface
, viewport
);
5328 static HRESULT WINAPI
d3d_device7_SetViewport_FPUPreserve(IDirect3DDevice7
*iface
, D3DVIEWPORT7
*viewport
)
5333 old_fpucw
= d3d_fpu_setup();
5334 hr
= d3d_device7_SetViewport(iface
, viewport
);
5335 set_fpu_control_word(old_fpucw
);
5340 /*****************************************************************************
5341 * IDirect3DDevice::GetViewport
5343 * Returns the current viewport
5348 * Data: D3D7Viewport structure to write the viewport information to
5352 * DDERR_INVALIDPARAMS if Data is NULL
5354 *****************************************************************************/
5355 static HRESULT
d3d_device7_GetViewport(IDirect3DDevice7
*iface
, D3DVIEWPORT7
*viewport
)
5357 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
5358 struct wined3d_viewport wined3d_viewport
;
5360 TRACE("iface %p, viewport %p.\n", iface
, viewport
);
5363 return DDERR_INVALIDPARAMS
;
5365 wined3d_mutex_lock();
5366 wined3d_device_get_viewport(device
->wined3d_device
, &wined3d_viewport
);
5367 wined3d_mutex_unlock();
5369 viewport
->dwX
= wined3d_viewport
.x
;
5370 viewport
->dwY
= wined3d_viewport
.y
;
5371 viewport
->dwWidth
= wined3d_viewport
.width
;
5372 viewport
->dwHeight
= wined3d_viewport
.height
;
5373 viewport
->dvMinZ
= wined3d_viewport
.min_z
;
5374 viewport
->dvMaxZ
= wined3d_viewport
.max_z
;
5379 static HRESULT WINAPI
d3d_device7_GetViewport_FPUSetup(IDirect3DDevice7
*iface
, D3DVIEWPORT7
*viewport
)
5381 return d3d_device7_GetViewport(iface
, viewport
);
5384 static HRESULT WINAPI
d3d_device7_GetViewport_FPUPreserve(IDirect3DDevice7
*iface
, D3DVIEWPORT7
*viewport
)
5389 old_fpucw
= d3d_fpu_setup();
5390 hr
= d3d_device7_GetViewport(iface
, viewport
);
5391 set_fpu_control_word(old_fpucw
);
5396 /*****************************************************************************
5397 * IDirect3DDevice7::SetMaterial
5404 * Mat: The material to set
5408 * DDERR_INVALIDPARAMS if Mat is NULL.
5410 *****************************************************************************/
5411 static HRESULT
d3d_device7_SetMaterial(IDirect3DDevice7
*iface
, D3DMATERIAL7
*material
)
5413 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
5415 TRACE("iface %p, material %p.\n", iface
, material
);
5418 return DDERR_INVALIDPARAMS
;
5420 wined3d_mutex_lock();
5421 /* Note: D3DMATERIAL7 is compatible with struct wined3d_material. */
5422 wined3d_device_set_material(device
->wined3d_device
, (struct wined3d_material
*)material
);
5423 wined3d_mutex_unlock();
5428 static HRESULT WINAPI
d3d_device7_SetMaterial_FPUSetup(IDirect3DDevice7
*iface
, D3DMATERIAL7
*material
)
5430 return d3d_device7_SetMaterial(iface
, material
);
5433 static HRESULT WINAPI
d3d_device7_SetMaterial_FPUPreserve(IDirect3DDevice7
*iface
, D3DMATERIAL7
*material
)
5438 old_fpucw
= d3d_fpu_setup();
5439 hr
= d3d_device7_SetMaterial(iface
, material
);
5440 set_fpu_control_word(old_fpucw
);
5445 /*****************************************************************************
5446 * IDirect3DDevice7::GetMaterial
5448 * Returns the current material
5453 * Mat: D3DMATERIAL7 structure to write the material parameters to
5457 * DDERR_INVALIDPARAMS if Mat is NULL
5459 *****************************************************************************/
5460 static HRESULT
d3d_device7_GetMaterial(IDirect3DDevice7
*iface
, D3DMATERIAL7
*material
)
5462 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
5464 TRACE("iface %p, material %p.\n", iface
, material
);
5466 wined3d_mutex_lock();
5467 /* Note: D3DMATERIAL7 is compatible with struct wined3d_material. */
5468 wined3d_device_get_material(device
->wined3d_device
, (struct wined3d_material
*)material
);
5469 wined3d_mutex_unlock();
5474 static HRESULT WINAPI
d3d_device7_GetMaterial_FPUSetup(IDirect3DDevice7
*iface
, D3DMATERIAL7
*material
)
5476 return d3d_device7_GetMaterial(iface
, material
);
5479 static HRESULT WINAPI
d3d_device7_GetMaterial_FPUPreserve(IDirect3DDevice7
*iface
, D3DMATERIAL7
*material
)
5484 old_fpucw
= d3d_fpu_setup();
5485 hr
= d3d_device7_GetMaterial(iface
, material
);
5486 set_fpu_control_word(old_fpucw
);
5491 /*****************************************************************************
5492 * IDirect3DDevice7::SetLight
5494 * Assigns a light to a light index, but doesn't activate it yet.
5496 * Version 7, IDirect3DLight uses this method for older versions
5499 * LightIndex: The index of the new light
5500 * Light: A D3DLIGHT7 structure describing the light
5505 *****************************************************************************/
5506 static HRESULT
d3d_device7_SetLight(IDirect3DDevice7
*iface
, DWORD light_idx
, D3DLIGHT7
*light
)
5508 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
5511 TRACE("iface %p, light_idx %u, light %p.\n", iface
, light_idx
, light
);
5513 wined3d_mutex_lock();
5514 /* Note: D3DLIGHT7 is compatible with struct wined3d_light. */
5515 hr
= wined3d_device_set_light(device
->wined3d_device
, light_idx
, (struct wined3d_light
*)light
);
5516 wined3d_mutex_unlock();
5518 return hr_ddraw_from_wined3d(hr
);
5521 static HRESULT WINAPI
d3d_device7_SetLight_FPUSetup(IDirect3DDevice7
*iface
, DWORD light_idx
, D3DLIGHT7
*light
)
5523 return d3d_device7_SetLight(iface
, light_idx
, light
);
5526 static HRESULT WINAPI
d3d_device7_SetLight_FPUPreserve(IDirect3DDevice7
*iface
, DWORD light_idx
, D3DLIGHT7
*light
)
5531 old_fpucw
= d3d_fpu_setup();
5532 hr
= d3d_device7_SetLight(iface
, light_idx
, light
);
5533 set_fpu_control_word(old_fpucw
);
5538 /*****************************************************************************
5539 * IDirect3DDevice7::GetLight
5541 * Returns the light assigned to a light index
5544 * Light: Structure to write the light information to
5548 * DDERR_INVALIDPARAMS if Light is NULL
5550 *****************************************************************************/
5551 static HRESULT
d3d_device7_GetLight(IDirect3DDevice7
*iface
, DWORD light_idx
, D3DLIGHT7
*light
)
5553 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
5556 TRACE("iface %p, light_idx %u, light %p.\n", iface
, light_idx
, light
);
5558 wined3d_mutex_lock();
5559 /* Note: D3DLIGHT7 is compatible with struct wined3d_light. */
5560 rc
= wined3d_device_get_light(device
->wined3d_device
, light_idx
, (struct wined3d_light
*)light
);
5561 wined3d_mutex_unlock();
5563 /* Translate the result. WineD3D returns other values than D3D7 */
5564 return hr_ddraw_from_wined3d(rc
);
5567 static HRESULT WINAPI
d3d_device7_GetLight_FPUSetup(IDirect3DDevice7
*iface
, DWORD light_idx
, D3DLIGHT7
*light
)
5569 return d3d_device7_GetLight(iface
, light_idx
, light
);
5572 static HRESULT WINAPI
d3d_device7_GetLight_FPUPreserve(IDirect3DDevice7
*iface
, DWORD light_idx
, D3DLIGHT7
*light
)
5577 old_fpucw
= d3d_fpu_setup();
5578 hr
= d3d_device7_GetLight(iface
, light_idx
, light
);
5579 set_fpu_control_word(old_fpucw
);
5584 /*****************************************************************************
5585 * IDirect3DDevice7::BeginStateBlock
5587 * Begins recording to a stateblock
5594 *****************************************************************************/
5595 static HRESULT
d3d_device7_BeginStateBlock(IDirect3DDevice7
*iface
)
5597 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
5600 TRACE("iface %p.\n", iface
);
5602 wined3d_mutex_lock();
5603 hr
= wined3d_device_begin_stateblock(device
->wined3d_device
);
5604 wined3d_mutex_unlock();
5606 return hr_ddraw_from_wined3d(hr
);
5609 static HRESULT WINAPI
d3d_device7_BeginStateBlock_FPUSetup(IDirect3DDevice7
*iface
)
5611 return d3d_device7_BeginStateBlock(iface
);
5614 static HRESULT WINAPI
d3d_device7_BeginStateBlock_FPUPreserve(IDirect3DDevice7
*iface
)
5619 old_fpucw
= d3d_fpu_setup();
5620 hr
= d3d_device7_BeginStateBlock(iface
);
5621 set_fpu_control_word(old_fpucw
);
5626 /*****************************************************************************
5627 * IDirect3DDevice7::EndStateBlock
5629 * Stops recording to a state block and returns the created stateblock
5635 * BlockHandle: Address to store the stateblock's handle to
5639 * DDERR_INVALIDPARAMS if BlockHandle is NULL
5641 *****************************************************************************/
5642 static HRESULT
d3d_device7_EndStateBlock(IDirect3DDevice7
*iface
, DWORD
*stateblock
)
5644 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
5645 struct wined3d_stateblock
*wined3d_sb
;
5649 TRACE("iface %p, stateblock %p.\n", iface
, stateblock
);
5652 return DDERR_INVALIDPARAMS
;
5654 wined3d_mutex_lock();
5656 hr
= wined3d_device_end_stateblock(device
->wined3d_device
, &wined3d_sb
);
5659 WARN("Failed to end stateblock, hr %#x.\n", hr
);
5660 wined3d_mutex_unlock();
5662 return hr_ddraw_from_wined3d(hr
);
5665 h
= ddraw_allocate_handle(&device
->handle_table
, wined3d_sb
, DDRAW_HANDLE_STATEBLOCK
);
5666 if (h
== DDRAW_INVALID_HANDLE
)
5668 ERR("Failed to allocate a stateblock handle.\n");
5669 wined3d_stateblock_decref(wined3d_sb
);
5670 wined3d_mutex_unlock();
5672 return DDERR_OUTOFMEMORY
;
5675 wined3d_mutex_unlock();
5676 *stateblock
= h
+ 1;
5678 return hr_ddraw_from_wined3d(hr
);
5681 static HRESULT WINAPI
d3d_device7_EndStateBlock_FPUSetup(IDirect3DDevice7
*iface
, DWORD
*stateblock
)
5683 return d3d_device7_EndStateBlock(iface
, stateblock
);
5686 static HRESULT WINAPI
d3d_device7_EndStateBlock_FPUPreserve(IDirect3DDevice7
*iface
, DWORD
*stateblock
)
5691 old_fpucw
= d3d_fpu_setup();
5692 hr
= d3d_device7_EndStateBlock(iface
, stateblock
);
5693 set_fpu_control_word(old_fpucw
);
5698 /*****************************************************************************
5699 * IDirect3DDevice7::PreLoad
5701 * Allows the app to signal that a texture will be used soon, to allow
5702 * the Direct3DDevice to load it to the video card in the meantime.
5707 * Texture: The texture to preload
5711 * DDERR_INVALIDPARAMS if Texture is NULL
5713 *****************************************************************************/
5714 static HRESULT
d3d_device7_PreLoad(IDirect3DDevice7
*iface
, IDirectDrawSurface7
*texture
)
5716 struct ddraw_surface
*surface
= unsafe_impl_from_IDirectDrawSurface7(texture
);
5718 TRACE("iface %p, texture %p.\n", iface
, texture
);
5721 return DDERR_INVALIDPARAMS
;
5723 wined3d_mutex_lock();
5724 wined3d_resource_preload(wined3d_texture_get_resource(surface
->wined3d_texture
));
5725 wined3d_mutex_unlock();
5730 static HRESULT WINAPI
d3d_device7_PreLoad_FPUSetup(IDirect3DDevice7
*iface
, IDirectDrawSurface7
*texture
)
5732 return d3d_device7_PreLoad(iface
, texture
);
5735 static HRESULT WINAPI
d3d_device7_PreLoad_FPUPreserve(IDirect3DDevice7
*iface
, IDirectDrawSurface7
*texture
)
5740 old_fpucw
= d3d_fpu_setup();
5741 hr
= d3d_device7_PreLoad(iface
, texture
);
5742 set_fpu_control_word(old_fpucw
);
5747 /*****************************************************************************
5748 * IDirect3DDevice7::ApplyStateBlock
5750 * Activates the state stored in a state block handle.
5753 * BlockHandle: The stateblock handle to activate
5757 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is NULL
5759 *****************************************************************************/
5760 static HRESULT
d3d_device7_ApplyStateBlock(IDirect3DDevice7
*iface
, DWORD stateblock
)
5762 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
5763 struct wined3d_stateblock
*wined3d_sb
;
5765 TRACE("iface %p, stateblock %#x.\n", iface
, stateblock
);
5767 wined3d_mutex_lock();
5768 wined3d_sb
= ddraw_get_object(&device
->handle_table
, stateblock
- 1, DDRAW_HANDLE_STATEBLOCK
);
5771 WARN("Invalid stateblock handle.\n");
5772 wined3d_mutex_unlock();
5773 return D3DERR_INVALIDSTATEBLOCK
;
5776 wined3d_stateblock_apply(wined3d_sb
);
5777 wined3d_mutex_unlock();
5782 static HRESULT WINAPI
d3d_device7_ApplyStateBlock_FPUSetup(IDirect3DDevice7
*iface
, DWORD stateblock
)
5784 return d3d_device7_ApplyStateBlock(iface
, stateblock
);
5787 static HRESULT WINAPI
d3d_device7_ApplyStateBlock_FPUPreserve(IDirect3DDevice7
*iface
, DWORD stateblock
)
5792 old_fpucw
= d3d_fpu_setup();
5793 hr
= d3d_device7_ApplyStateBlock(iface
, stateblock
);
5794 set_fpu_control_word(old_fpucw
);
5799 /*****************************************************************************
5800 * IDirect3DDevice7::CaptureStateBlock
5802 * Updates a stateblock's values to the values currently set for the device
5807 * BlockHandle: Stateblock to update
5811 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is NULL
5813 *****************************************************************************/
5814 static HRESULT
d3d_device7_CaptureStateBlock(IDirect3DDevice7
*iface
, DWORD stateblock
)
5816 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
5817 struct wined3d_stateblock
*wined3d_sb
;
5819 TRACE("iface %p, stateblock %#x.\n", iface
, stateblock
);
5821 wined3d_mutex_lock();
5822 wined3d_sb
= ddraw_get_object(&device
->handle_table
, stateblock
- 1, DDRAW_HANDLE_STATEBLOCK
);
5825 WARN("Invalid stateblock handle.\n");
5826 wined3d_mutex_unlock();
5827 return D3DERR_INVALIDSTATEBLOCK
;
5830 wined3d_stateblock_capture(wined3d_sb
);
5831 wined3d_mutex_unlock();
5836 static HRESULT WINAPI
d3d_device7_CaptureStateBlock_FPUSetup(IDirect3DDevice7
*iface
, DWORD stateblock
)
5838 return d3d_device7_CaptureStateBlock(iface
, stateblock
);
5841 static HRESULT WINAPI
d3d_device7_CaptureStateBlock_FPUPreserve(IDirect3DDevice7
*iface
, DWORD stateblock
)
5846 old_fpucw
= d3d_fpu_setup();
5847 hr
= d3d_device7_CaptureStateBlock(iface
, stateblock
);
5848 set_fpu_control_word(old_fpucw
);
5853 /*****************************************************************************
5854 * IDirect3DDevice7::DeleteStateBlock
5856 * Deletes a stateblock handle. This means releasing the WineD3DStateBlock
5861 * BlockHandle: Stateblock handle to delete
5865 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is 0
5867 *****************************************************************************/
5868 static HRESULT
d3d_device7_DeleteStateBlock(IDirect3DDevice7
*iface
, DWORD stateblock
)
5870 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
5871 struct wined3d_stateblock
*wined3d_sb
;
5874 TRACE("iface %p, stateblock %#x.\n", iface
, stateblock
);
5876 wined3d_mutex_lock();
5878 wined3d_sb
= ddraw_free_handle(&device
->handle_table
, stateblock
- 1, DDRAW_HANDLE_STATEBLOCK
);
5881 WARN("Invalid stateblock handle.\n");
5882 wined3d_mutex_unlock();
5883 return D3DERR_INVALIDSTATEBLOCK
;
5886 if ((ref
= wined3d_stateblock_decref(wined3d_sb
)))
5888 ERR("Something is still holding stateblock %p (refcount %u).\n", wined3d_sb
, ref
);
5891 wined3d_mutex_unlock();
5896 static HRESULT WINAPI
d3d_device7_DeleteStateBlock_FPUSetup(IDirect3DDevice7
*iface
, DWORD stateblock
)
5898 return d3d_device7_DeleteStateBlock(iface
, stateblock
);
5901 static HRESULT WINAPI
d3d_device7_DeleteStateBlock_FPUPreserve(IDirect3DDevice7
*iface
, DWORD stateblock
)
5906 old_fpucw
= d3d_fpu_setup();
5907 hr
= d3d_device7_DeleteStateBlock(iface
, stateblock
);
5908 set_fpu_control_word(old_fpucw
);
5913 /*****************************************************************************
5914 * IDirect3DDevice7::CreateStateBlock
5916 * Creates a new state block handle.
5921 * Type: The state block type
5922 * BlockHandle: Address to write the created handle to
5926 * DDERR_INVALIDPARAMS if BlockHandle is NULL
5928 *****************************************************************************/
5929 static HRESULT
d3d_device7_CreateStateBlock(IDirect3DDevice7
*iface
,
5930 D3DSTATEBLOCKTYPE type
, DWORD
*stateblock
)
5932 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
5933 struct wined3d_stateblock
*wined3d_sb
;
5937 TRACE("iface %p, type %#x, stateblock %p.\n", iface
, type
, stateblock
);
5940 return DDERR_INVALIDPARAMS
;
5942 if (type
!= D3DSBT_ALL
5943 && type
!= D3DSBT_PIXELSTATE
5944 && type
!= D3DSBT_VERTEXSTATE
)
5946 WARN("Unexpected stateblock type, returning DDERR_INVALIDPARAMS\n");
5947 return DDERR_INVALIDPARAMS
;
5950 wined3d_mutex_lock();
5952 /* The D3DSTATEBLOCKTYPE enum is fine here. */
5953 hr
= wined3d_stateblock_create(device
->wined3d_device
, type
, &wined3d_sb
);
5956 WARN("Failed to create stateblock, hr %#x.\n", hr
);
5957 wined3d_mutex_unlock();
5958 return hr_ddraw_from_wined3d(hr
);
5961 h
= ddraw_allocate_handle(&device
->handle_table
, wined3d_sb
, DDRAW_HANDLE_STATEBLOCK
);
5962 if (h
== DDRAW_INVALID_HANDLE
)
5964 ERR("Failed to allocate stateblock handle.\n");
5965 wined3d_stateblock_decref(wined3d_sb
);
5966 wined3d_mutex_unlock();
5967 return DDERR_OUTOFMEMORY
;
5970 *stateblock
= h
+ 1;
5971 wined3d_mutex_unlock();
5973 return hr_ddraw_from_wined3d(hr
);
5976 static HRESULT WINAPI
d3d_device7_CreateStateBlock_FPUSetup(IDirect3DDevice7
*iface
,
5977 D3DSTATEBLOCKTYPE type
, DWORD
*stateblock
)
5979 return d3d_device7_CreateStateBlock(iface
, type
, stateblock
);
5982 static HRESULT WINAPI
d3d_device7_CreateStateBlock_FPUPreserve(IDirect3DDevice7
*iface
,
5983 D3DSTATEBLOCKTYPE type
, DWORD
*stateblock
)
5988 old_fpucw
= d3d_fpu_setup();
5989 hr
= d3d_device7_CreateStateBlock(iface
, type
, stateblock
);
5990 set_fpu_control_word(old_fpucw
);
5995 static BOOL
is_mip_level_subset(struct ddraw_surface
*dest
, struct ddraw_surface
*src
)
5997 struct ddraw_surface
*src_level
, *dest_level
;
5998 IDirectDrawSurface7
*temp
;
5999 DDSURFACEDESC2 ddsd
;
6000 BOOL levelFound
; /* at least one suitable sublevel in dest found */
6002 /* To satisfy "destination is mip level subset of source" criteria (regular texture counts as 1 level),
6003 * 1) there must be at least one mip level in destination that matched dimensions of some mip level in source and
6004 * 2) there must be no destination levels that don't match any levels in source. Otherwise it's INVALIDPARAMS.
6011 for (;src_level
&& dest_level
;)
6013 if (src_level
->surface_desc
.dwWidth
== dest_level
->surface_desc
.dwWidth
&&
6014 src_level
->surface_desc
.dwHeight
== dest_level
->surface_desc
.dwHeight
)
6018 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
6019 ddsd
.ddsCaps
.dwCaps2
= DDSCAPS2_MIPMAPSUBLEVEL
;
6020 IDirectDrawSurface7_GetAttachedSurface(&dest_level
->IDirectDrawSurface7_iface
, &ddsd
.ddsCaps
, &temp
);
6022 if (dest_level
!= dest
) IDirectDrawSurface7_Release(&dest_level
->IDirectDrawSurface7_iface
);
6024 dest_level
= unsafe_impl_from_IDirectDrawSurface7(temp
);
6027 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
6028 ddsd
.ddsCaps
.dwCaps2
= DDSCAPS2_MIPMAPSUBLEVEL
;
6029 IDirectDrawSurface7_GetAttachedSurface(&src_level
->IDirectDrawSurface7_iface
, &ddsd
.ddsCaps
, &temp
);
6031 if (src_level
!= src
) IDirectDrawSurface7_Release(&src_level
->IDirectDrawSurface7_iface
);
6033 src_level
= unsafe_impl_from_IDirectDrawSurface7(temp
);
6036 if (src_level
&& src_level
!= src
) IDirectDrawSurface7_Release(&src_level
->IDirectDrawSurface7_iface
);
6037 if (dest_level
&& dest_level
!= dest
) IDirectDrawSurface7_Release(&dest_level
->IDirectDrawSurface7_iface
);
6039 return !dest_level
&& levelFound
;
6042 static void copy_mipmap_chain(struct d3d_device
*device
, struct ddraw_surface
*dst
,
6043 struct ddraw_surface
*src
, const POINT
*DestPoint
, const RECT
*SrcRect
)
6045 struct ddraw_surface
*dst_level
, *src_level
;
6046 IDirectDrawSurface7
*temp
;
6047 DDSURFACEDESC2 ddsd
;
6051 IDirectDrawPalette
*pal
= NULL
, *pal_src
= NULL
;
6055 /* Copy palette, if possible. */
6056 IDirectDrawSurface7_GetPalette(&src
->IDirectDrawSurface7_iface
, &pal_src
);
6057 IDirectDrawSurface7_GetPalette(&dst
->IDirectDrawSurface7_iface
, &pal
);
6059 if (pal_src
!= NULL
&& pal
!= NULL
)
6061 PALETTEENTRY palent
[256];
6063 IDirectDrawPalette_GetEntries(pal_src
, 0, 0, 256, palent
);
6064 IDirectDrawPalette_SetEntries(pal
, 0, 0, 256, palent
);
6067 if (pal
) IDirectDrawPalette_Release(pal
);
6068 if (pal_src
) IDirectDrawPalette_Release(pal_src
);
6070 /* Copy colorkeys, if present. */
6071 for (ckeyflag
= DDCKEY_DESTBLT
; ckeyflag
<= DDCKEY_SRCOVERLAY
; ckeyflag
<<= 1)
6073 hr
= IDirectDrawSurface7_GetColorKey(&src
->IDirectDrawSurface7_iface
, ckeyflag
, &ddckey
);
6077 IDirectDrawSurface7_SetColorKey(&dst
->IDirectDrawSurface7_iface
, ckeyflag
, &ddckey
);
6085 src_rect
= *SrcRect
;
6087 for (;src_level
&& dst_level
;)
6089 if (src_level
->surface_desc
.dwWidth
== dst_level
->surface_desc
.dwWidth
6090 && src_level
->surface_desc
.dwHeight
== dst_level
->surface_desc
.dwHeight
)
6092 UINT src_w
= src_rect
.right
- src_rect
.left
;
6093 UINT src_h
= src_rect
.bottom
- src_rect
.top
;
6094 RECT dst_rect
= {point
.x
, point
.y
, point
.x
+ src_w
, point
.y
+ src_h
};
6096 if (FAILED(hr
= wined3d_texture_blt(dst_level
->wined3d_texture
, dst_level
->sub_resource_idx
, &dst_rect
,
6097 src_level
->wined3d_texture
, src_level
->sub_resource_idx
, &src_rect
, 0, NULL
, WINED3D_TEXF_POINT
)))
6098 ERR("Blit failed, hr %#x.\n", hr
);
6100 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
6101 ddsd
.ddsCaps
.dwCaps2
= DDSCAPS2_MIPMAPSUBLEVEL
;
6102 IDirectDrawSurface7_GetAttachedSurface(&dst_level
->IDirectDrawSurface7_iface
, &ddsd
.ddsCaps
, &temp
);
6104 if (dst_level
!= dst
)
6105 IDirectDrawSurface7_Release(&dst_level
->IDirectDrawSurface7_iface
);
6107 dst_level
= unsafe_impl_from_IDirectDrawSurface7(temp
);
6110 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
6111 ddsd
.ddsCaps
.dwCaps2
= DDSCAPS2_MIPMAPSUBLEVEL
;
6112 IDirectDrawSurface7_GetAttachedSurface(&src_level
->IDirectDrawSurface7_iface
, &ddsd
.ddsCaps
, &temp
);
6114 if (src_level
!= src
) IDirectDrawSurface7_Release(&src_level
->IDirectDrawSurface7_iface
);
6116 src_level
= unsafe_impl_from_IDirectDrawSurface7(temp
);
6123 src_rect
.right
= (src_rect
.right
+ 1) / 2;
6124 src_rect
.bottom
= (src_rect
.bottom
+ 1) / 2;
6127 if (src_level
&& src_level
!= src
)
6128 IDirectDrawSurface7_Release(&src_level
->IDirectDrawSurface7_iface
);
6129 if (dst_level
&& dst_level
!= dst
)
6130 IDirectDrawSurface7_Release(&dst_level
->IDirectDrawSurface7_iface
);
6133 /*****************************************************************************
6134 * IDirect3DDevice7::Load
6136 * Loads a rectangular area from the source into the destination texture.
6137 * It can also copy the source to the faces of a cubic environment map
6142 * DestTex: Destination texture
6143 * DestPoint: Point in the destination where the source image should be
6145 * SrcTex: Source texture
6146 * SrcRect: Source rectangle
6147 * Flags: Cubemap faces to load (DDSCAPS2_CUBEMAP_ALLFACES, DDSCAPS2_CUBEMAP_POSITIVEX,
6148 * DDSCAPS2_CUBEMAP_NEGATIVEX, DDSCAPS2_CUBEMAP_POSITIVEY, DDSCAPS2_CUBEMAP_NEGATIVEY,
6149 * DDSCAPS2_CUBEMAP_POSITIVEZ, DDSCAPS2_CUBEMAP_NEGATIVEZ)
6153 * DDERR_INVALIDPARAMS if dst_texture or src_texture is NULL, broken coordinates or anything unexpected.
6156 *****************************************************************************/
6157 static HRESULT
d3d_device7_Load(IDirect3DDevice7
*iface
, IDirectDrawSurface7
*dst_texture
, POINT
*dst_pos
,
6158 IDirectDrawSurface7
*src_texture
, RECT
*src_rect
, DWORD flags
)
6160 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
6161 struct ddraw_surface
*dest
= unsafe_impl_from_IDirectDrawSurface7(dst_texture
);
6162 struct ddraw_surface
*src
= unsafe_impl_from_IDirectDrawSurface7(src_texture
);
6166 TRACE("iface %p, dst_texture %p, dst_pos %s, src_texture %p, src_rect %s, flags %#x.\n",
6167 iface
, dst_texture
, wine_dbgstr_point(dst_pos
), src_texture
, wine_dbgstr_rect(src_rect
), flags
);
6169 if( (!src
) || (!dest
) )
6170 return DDERR_INVALIDPARAMS
;
6172 wined3d_mutex_lock();
6175 SetRect(&srcrect
, 0, 0, src
->surface_desc
.dwWidth
, src
->surface_desc
.dwHeight
);
6177 srcrect
= *src_rect
;
6180 destpoint
.x
= destpoint
.y
= 0;
6182 destpoint
= *dst_pos
;
6184 /* Check bad dimensions. dst_pos is validated against src, not dest, because
6185 * destination can be a subset of mip levels, in which case actual coordinates used
6186 * for it may be divided. If any dimension of dest is larger than source, it can't be
6187 * mip level subset, so an error can be returned early.
6189 if (IsRectEmpty(&srcrect
) || srcrect
.right
> src
->surface_desc
.dwWidth
||
6190 srcrect
.bottom
> src
->surface_desc
.dwHeight
||
6191 destpoint
.x
+ srcrect
.right
- srcrect
.left
> src
->surface_desc
.dwWidth
||
6192 destpoint
.y
+ srcrect
.bottom
- srcrect
.top
> src
->surface_desc
.dwHeight
||
6193 dest
->surface_desc
.dwWidth
> src
->surface_desc
.dwWidth
||
6194 dest
->surface_desc
.dwHeight
> src
->surface_desc
.dwHeight
)
6196 wined3d_mutex_unlock();
6197 return DDERR_INVALIDPARAMS
;
6200 /* Must be top level surfaces. */
6201 if (src
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_MIPMAPSUBLEVEL
||
6202 dest
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_MIPMAPSUBLEVEL
)
6204 wined3d_mutex_unlock();
6205 return DDERR_INVALIDPARAMS
;
6208 if (src
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_CUBEMAP
)
6210 struct ddraw_surface
*src_face
, *dest_face
;
6211 DWORD src_face_flag
, dest_face_flag
;
6212 IDirectDrawSurface7
*temp
;
6213 DDSURFACEDESC2 ddsd
;
6216 if (!(dest
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_CUBEMAP
))
6218 wined3d_mutex_unlock();
6219 return DDERR_INVALIDPARAMS
;
6222 /* Iterate through cube faces 2 times. First time is just to check INVALIDPARAMS conditions, second
6223 * time it's actual surface loading. */
6224 for (i
= 0; i
< 2; i
++)
6229 for (;dest_face
&& src_face
;)
6231 src_face_flag
= src_face
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_CUBEMAP_ALLFACES
;
6232 dest_face_flag
= dest_face
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_CUBEMAP_ALLFACES
;
6234 if (src_face_flag
== dest_face_flag
)
6238 /* Destination mip levels must be subset of source mip levels. */
6239 if (!is_mip_level_subset(dest_face
, src_face
))
6241 wined3d_mutex_unlock();
6242 return DDERR_INVALIDPARAMS
;
6245 else if (flags
& dest_face_flag
)
6247 copy_mipmap_chain(device
, dest_face
, src_face
, &destpoint
, &srcrect
);
6250 if (src_face_flag
< DDSCAPS2_CUBEMAP_NEGATIVEZ
)
6252 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
6253 ddsd
.ddsCaps
.dwCaps2
= DDSCAPS2_CUBEMAP
| (src_face_flag
<< 1);
6254 IDirectDrawSurface7_GetAttachedSurface(&src
->IDirectDrawSurface7_iface
, &ddsd
.ddsCaps
, &temp
);
6256 if (src_face
!= src
) IDirectDrawSurface7_Release(&src_face
->IDirectDrawSurface7_iface
);
6258 src_face
= unsafe_impl_from_IDirectDrawSurface7(temp
);
6262 if (src_face
!= src
) IDirectDrawSurface7_Release(&src_face
->IDirectDrawSurface7_iface
);
6268 if (dest_face_flag
< DDSCAPS2_CUBEMAP_NEGATIVEZ
)
6270 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
6271 ddsd
.ddsCaps
.dwCaps2
= DDSCAPS2_CUBEMAP
| (dest_face_flag
<< 1);
6272 IDirectDrawSurface7_GetAttachedSurface(&dest
->IDirectDrawSurface7_iface
, &ddsd
.ddsCaps
, &temp
);
6274 if (dest_face
!= dest
) IDirectDrawSurface7_Release(&dest_face
->IDirectDrawSurface7_iface
);
6276 dest_face
= unsafe_impl_from_IDirectDrawSurface7(temp
);
6280 if (dest_face
!= dest
) IDirectDrawSurface7_Release(&dest_face
->IDirectDrawSurface7_iface
);
6288 /* Native returns error if src faces are not subset of dest faces. */
6291 wined3d_mutex_unlock();
6292 return DDERR_INVALIDPARAMS
;
6297 wined3d_mutex_unlock();
6300 else if (dest
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_CUBEMAP
)
6302 wined3d_mutex_unlock();
6303 return DDERR_INVALIDPARAMS
;
6306 /* Handle non cube map textures. */
6308 /* Destination mip levels must be subset of source mip levels. */
6309 if (!is_mip_level_subset(dest
, src
))
6311 wined3d_mutex_unlock();
6312 return DDERR_INVALIDPARAMS
;
6315 copy_mipmap_chain(device
, dest
, src
, &destpoint
, &srcrect
);
6317 wined3d_mutex_unlock();
6322 static HRESULT WINAPI
d3d_device7_Load_FPUSetup(IDirect3DDevice7
*iface
, IDirectDrawSurface7
*dst_texture
,
6323 POINT
*dst_pos
, IDirectDrawSurface7
*src_texture
, RECT
*src_rect
, DWORD flags
)
6325 return d3d_device7_Load(iface
, dst_texture
, dst_pos
, src_texture
, src_rect
, flags
);
6328 static HRESULT WINAPI
d3d_device7_Load_FPUPreserve(IDirect3DDevice7
*iface
, IDirectDrawSurface7
*dst_texture
,
6329 POINT
*dst_pos
, IDirectDrawSurface7
*src_texture
, RECT
*src_rect
, DWORD flags
)
6334 old_fpucw
= d3d_fpu_setup();
6335 hr
= d3d_device7_Load(iface
, dst_texture
, dst_pos
, src_texture
, src_rect
, flags
);
6336 set_fpu_control_word(old_fpucw
);
6341 /*****************************************************************************
6342 * IDirect3DDevice7::LightEnable
6344 * Enables or disables a light
6346 * Version 7, IDirect3DLight uses this method too.
6349 * LightIndex: The index of the light to enable / disable
6350 * Enable: Enable or disable the light
6355 *****************************************************************************/
6356 static HRESULT
d3d_device7_LightEnable(IDirect3DDevice7
*iface
, DWORD light_idx
, BOOL enabled
)
6358 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
6361 TRACE("iface %p, light_idx %u, enabled %#x.\n", iface
, light_idx
, enabled
);
6363 wined3d_mutex_lock();
6364 hr
= wined3d_device_set_light_enable(device
->wined3d_device
, light_idx
, enabled
);
6365 wined3d_mutex_unlock();
6367 return hr_ddraw_from_wined3d(hr
);
6370 static HRESULT WINAPI
d3d_device7_LightEnable_FPUSetup(IDirect3DDevice7
*iface
, DWORD light_idx
, BOOL enabled
)
6372 return d3d_device7_LightEnable(iface
, light_idx
, enabled
);
6375 static HRESULT WINAPI
d3d_device7_LightEnable_FPUPreserve(IDirect3DDevice7
*iface
, DWORD light_idx
, BOOL enabled
)
6380 old_fpucw
= d3d_fpu_setup();
6381 hr
= d3d_device7_LightEnable(iface
, light_idx
, enabled
);
6382 set_fpu_control_word(old_fpucw
);
6387 /*****************************************************************************
6388 * IDirect3DDevice7::GetLightEnable
6390 * Retrieves if the light with the given index is enabled or not
6395 * LightIndex: Index of desired light
6396 * Enable: Pointer to a BOOL which contains the result
6400 * DDERR_INVALIDPARAMS if Enable is NULL
6402 *****************************************************************************/
6403 static HRESULT
d3d_device7_GetLightEnable(IDirect3DDevice7
*iface
, DWORD light_idx
, BOOL
*enabled
)
6405 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
6408 TRACE("iface %p, light_idx %u, enabled %p.\n", iface
, light_idx
, enabled
);
6411 return DDERR_INVALIDPARAMS
;
6413 wined3d_mutex_lock();
6414 hr
= wined3d_device_get_light_enable(device
->wined3d_device
, light_idx
, enabled
);
6415 wined3d_mutex_unlock();
6417 return hr_ddraw_from_wined3d(hr
);
6420 static HRESULT WINAPI
d3d_device7_GetLightEnable_FPUSetup(IDirect3DDevice7
*iface
, DWORD light_idx
, BOOL
*enabled
)
6422 return d3d_device7_GetLightEnable(iface
, light_idx
, enabled
);
6425 static HRESULT WINAPI
d3d_device7_GetLightEnable_FPUPreserve(IDirect3DDevice7
*iface
, DWORD light_idx
, BOOL
*enabled
)
6430 old_fpucw
= d3d_fpu_setup();
6431 hr
= d3d_device7_GetLightEnable(iface
, light_idx
, enabled
);
6432 set_fpu_control_word(old_fpucw
);
6437 /*****************************************************************************
6438 * IDirect3DDevice7::SetClipPlane
6440 * Sets custom clipping plane
6445 * Index: The index of the clipping plane
6446 * PlaneEquation: An equation defining the clipping plane
6450 * DDERR_INVALIDPARAMS if PlaneEquation is NULL
6452 *****************************************************************************/
6453 static HRESULT
d3d_device7_SetClipPlane(IDirect3DDevice7
*iface
, DWORD idx
, D3DVALUE
*plane
)
6455 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
6458 TRACE("iface %p, idx %u, plane %p.\n", iface
, idx
, plane
);
6461 return DDERR_INVALIDPARAMS
;
6463 wined3d_mutex_lock();
6464 hr
= wined3d_device_set_clip_plane(device
->wined3d_device
, idx
, (struct wined3d_vec4
*)plane
);
6465 wined3d_mutex_unlock();
6470 static HRESULT WINAPI
d3d_device7_SetClipPlane_FPUSetup(IDirect3DDevice7
*iface
, DWORD idx
, D3DVALUE
*plane
)
6472 return d3d_device7_SetClipPlane(iface
, idx
, plane
);
6475 static HRESULT WINAPI
d3d_device7_SetClipPlane_FPUPreserve(IDirect3DDevice7
*iface
, DWORD idx
, D3DVALUE
*plane
)
6480 old_fpucw
= d3d_fpu_setup();
6481 hr
= d3d_device7_SetClipPlane(iface
, idx
, plane
);
6482 set_fpu_control_word(old_fpucw
);
6487 /*****************************************************************************
6488 * IDirect3DDevice7::GetClipPlane
6490 * Returns the clipping plane with a specific index
6493 * Index: The index of the desired plane
6494 * PlaneEquation: Address to store the plane equation to
6498 * DDERR_INVALIDPARAMS if PlaneEquation is NULL
6500 *****************************************************************************/
6501 static HRESULT
d3d_device7_GetClipPlane(IDirect3DDevice7
*iface
, DWORD idx
, D3DVALUE
*plane
)
6503 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
6506 TRACE("iface %p, idx %u, plane %p.\n", iface
, idx
, plane
);
6509 return DDERR_INVALIDPARAMS
;
6511 wined3d_mutex_lock();
6512 hr
= wined3d_device_get_clip_plane(device
->wined3d_device
, idx
, (struct wined3d_vec4
*)plane
);
6513 wined3d_mutex_unlock();
6518 static HRESULT WINAPI
d3d_device7_GetClipPlane_FPUSetup(IDirect3DDevice7
*iface
, DWORD idx
, D3DVALUE
*plane
)
6520 return d3d_device7_GetClipPlane(iface
, idx
, plane
);
6523 static HRESULT WINAPI
d3d_device7_GetClipPlane_FPUPreserve(IDirect3DDevice7
*iface
, DWORD idx
, D3DVALUE
*plane
)
6528 old_fpucw
= d3d_fpu_setup();
6529 hr
= d3d_device7_GetClipPlane(iface
, idx
, plane
);
6530 set_fpu_control_word(old_fpucw
);
6535 /*****************************************************************************
6536 * IDirect3DDevice7::GetInfo
6538 * Retrieves some information about the device. The DirectX sdk says that
6539 * this version returns S_FALSE for all retail builds of DirectX, that's what
6540 * this implementation does.
6543 * DevInfoID: Information type requested
6544 * DevInfoStruct: Pointer to a structure to store the info to
6545 * Size: Size of the structure
6548 * S_FALSE, because it's a non-debug driver
6550 *****************************************************************************/
6551 static HRESULT WINAPI
d3d_device7_GetInfo(IDirect3DDevice7
*iface
, DWORD info_id
, void *info
, DWORD info_size
)
6553 TRACE("iface %p, info_id %#x, info %p, info_size %u.\n",
6554 iface
, info_id
, info
, info_size
);
6556 if (TRACE_ON(ddraw
))
6558 TRACE(" info requested : ");
6561 case D3DDEVINFOID_TEXTUREMANAGER
: TRACE("D3DDEVINFOID_TEXTUREMANAGER\n"); break;
6562 case D3DDEVINFOID_D3DTEXTUREMANAGER
: TRACE("D3DDEVINFOID_D3DTEXTUREMANAGER\n"); break;
6563 case D3DDEVINFOID_TEXTURING
: TRACE("D3DDEVINFOID_TEXTURING\n"); break;
6564 default: ERR(" invalid flag !!!\n"); return DDERR_INVALIDPARAMS
;
6568 return S_FALSE
; /* According to MSDN, this is valid for a non-debug driver */
6571 /* For performance optimization, devices created in FPUSETUP and FPUPRESERVE modes
6572 * have separate vtables. Simple functions where this doesn't matter like GetDirect3D
6573 * are not duplicated.
6575 * Device created with DDSCL_FPUSETUP (d3d7 default) - device methods assume that FPU
6576 * has already been setup for optimal d3d operation.
6578 * Device created with DDSCL_FPUPRESERVE - resets and restores FPU mode when necessary in
6579 * d3d calls (FPU may be in a mode non-suitable for d3d when the app calls d3d). Required
6580 * by Sacrifice (game). */
6581 static const struct IDirect3DDevice7Vtbl d3d_device7_fpu_setup_vtbl
=
6583 /*** IUnknown Methods ***/
6584 d3d_device7_QueryInterface
,
6586 d3d_device7_Release
,
6587 /*** IDirect3DDevice7 ***/
6588 d3d_device7_GetCaps_FPUSetup
,
6589 d3d_device7_EnumTextureFormats_FPUSetup
,
6590 d3d_device7_BeginScene_FPUSetup
,
6591 d3d_device7_EndScene_FPUSetup
,
6592 d3d_device7_GetDirect3D
,
6593 d3d_device7_SetRenderTarget_FPUSetup
,
6594 d3d_device7_GetRenderTarget
,
6595 d3d_device7_Clear_FPUSetup
,
6596 d3d_device7_SetTransform_FPUSetup
,
6597 d3d_device7_GetTransform_FPUSetup
,
6598 d3d_device7_SetViewport_FPUSetup
,
6599 d3d_device7_MultiplyTransform_FPUSetup
,
6600 d3d_device7_GetViewport_FPUSetup
,
6601 d3d_device7_SetMaterial_FPUSetup
,
6602 d3d_device7_GetMaterial_FPUSetup
,
6603 d3d_device7_SetLight_FPUSetup
,
6604 d3d_device7_GetLight_FPUSetup
,
6605 d3d_device7_SetRenderState_FPUSetup
,
6606 d3d_device7_GetRenderState_FPUSetup
,
6607 d3d_device7_BeginStateBlock_FPUSetup
,
6608 d3d_device7_EndStateBlock_FPUSetup
,
6609 d3d_device7_PreLoad_FPUSetup
,
6610 d3d_device7_DrawPrimitive_FPUSetup
,
6611 d3d_device7_DrawIndexedPrimitive_FPUSetup
,
6612 d3d_device7_SetClipStatus
,
6613 d3d_device7_GetClipStatus
,
6614 d3d_device7_DrawPrimitiveStrided_FPUSetup
,
6615 d3d_device7_DrawIndexedPrimitiveStrided_FPUSetup
,
6616 d3d_device7_DrawPrimitiveVB_FPUSetup
,
6617 d3d_device7_DrawIndexedPrimitiveVB_FPUSetup
,
6618 d3d_device7_ComputeSphereVisibility
,
6619 d3d_device7_GetTexture_FPUSetup
,
6620 d3d_device7_SetTexture_FPUSetup
,
6621 d3d_device7_GetTextureStageState_FPUSetup
,
6622 d3d_device7_SetTextureStageState_FPUSetup
,
6623 d3d_device7_ValidateDevice_FPUSetup
,
6624 d3d_device7_ApplyStateBlock_FPUSetup
,
6625 d3d_device7_CaptureStateBlock_FPUSetup
,
6626 d3d_device7_DeleteStateBlock_FPUSetup
,
6627 d3d_device7_CreateStateBlock_FPUSetup
,
6628 d3d_device7_Load_FPUSetup
,
6629 d3d_device7_LightEnable_FPUSetup
,
6630 d3d_device7_GetLightEnable_FPUSetup
,
6631 d3d_device7_SetClipPlane_FPUSetup
,
6632 d3d_device7_GetClipPlane_FPUSetup
,
6636 static const struct IDirect3DDevice7Vtbl d3d_device7_fpu_preserve_vtbl
=
6638 /*** IUnknown Methods ***/
6639 d3d_device7_QueryInterface
,
6641 d3d_device7_Release
,
6642 /*** IDirect3DDevice7 ***/
6643 d3d_device7_GetCaps_FPUPreserve
,
6644 d3d_device7_EnumTextureFormats_FPUPreserve
,
6645 d3d_device7_BeginScene_FPUPreserve
,
6646 d3d_device7_EndScene_FPUPreserve
,
6647 d3d_device7_GetDirect3D
,
6648 d3d_device7_SetRenderTarget_FPUPreserve
,
6649 d3d_device7_GetRenderTarget
,
6650 d3d_device7_Clear_FPUPreserve
,
6651 d3d_device7_SetTransform_FPUPreserve
,
6652 d3d_device7_GetTransform_FPUPreserve
,
6653 d3d_device7_SetViewport_FPUPreserve
,
6654 d3d_device7_MultiplyTransform_FPUPreserve
,
6655 d3d_device7_GetViewport_FPUPreserve
,
6656 d3d_device7_SetMaterial_FPUPreserve
,
6657 d3d_device7_GetMaterial_FPUPreserve
,
6658 d3d_device7_SetLight_FPUPreserve
,
6659 d3d_device7_GetLight_FPUPreserve
,
6660 d3d_device7_SetRenderState_FPUPreserve
,
6661 d3d_device7_GetRenderState_FPUPreserve
,
6662 d3d_device7_BeginStateBlock_FPUPreserve
,
6663 d3d_device7_EndStateBlock_FPUPreserve
,
6664 d3d_device7_PreLoad_FPUPreserve
,
6665 d3d_device7_DrawPrimitive_FPUPreserve
,
6666 d3d_device7_DrawIndexedPrimitive_FPUPreserve
,
6667 d3d_device7_SetClipStatus
,
6668 d3d_device7_GetClipStatus
,
6669 d3d_device7_DrawPrimitiveStrided_FPUPreserve
,
6670 d3d_device7_DrawIndexedPrimitiveStrided_FPUPreserve
,
6671 d3d_device7_DrawPrimitiveVB_FPUPreserve
,
6672 d3d_device7_DrawIndexedPrimitiveVB_FPUPreserve
,
6673 d3d_device7_ComputeSphereVisibility
,
6674 d3d_device7_GetTexture_FPUPreserve
,
6675 d3d_device7_SetTexture_FPUPreserve
,
6676 d3d_device7_GetTextureStageState_FPUPreserve
,
6677 d3d_device7_SetTextureStageState_FPUPreserve
,
6678 d3d_device7_ValidateDevice_FPUPreserve
,
6679 d3d_device7_ApplyStateBlock_FPUPreserve
,
6680 d3d_device7_CaptureStateBlock_FPUPreserve
,
6681 d3d_device7_DeleteStateBlock_FPUPreserve
,
6682 d3d_device7_CreateStateBlock_FPUPreserve
,
6683 d3d_device7_Load_FPUPreserve
,
6684 d3d_device7_LightEnable_FPUPreserve
,
6685 d3d_device7_GetLightEnable_FPUPreserve
,
6686 d3d_device7_SetClipPlane_FPUPreserve
,
6687 d3d_device7_GetClipPlane_FPUPreserve
,
6691 static const struct IDirect3DDevice3Vtbl d3d_device3_vtbl
=
6693 /*** IUnknown Methods ***/
6694 d3d_device3_QueryInterface
,
6696 d3d_device3_Release
,
6697 /*** IDirect3DDevice3 ***/
6698 d3d_device3_GetCaps
,
6699 d3d_device3_GetStats
,
6700 d3d_device3_AddViewport
,
6701 d3d_device3_DeleteViewport
,
6702 d3d_device3_NextViewport
,
6703 d3d_device3_EnumTextureFormats
,
6704 d3d_device3_BeginScene
,
6705 d3d_device3_EndScene
,
6706 d3d_device3_GetDirect3D
,
6707 d3d_device3_SetCurrentViewport
,
6708 d3d_device3_GetCurrentViewport
,
6709 d3d_device3_SetRenderTarget
,
6710 d3d_device3_GetRenderTarget
,
6712 d3d_device3_BeginIndexed
,
6716 d3d_device3_GetRenderState
,
6717 d3d_device3_SetRenderState
,
6718 d3d_device3_GetLightState
,
6719 d3d_device3_SetLightState
,
6720 d3d_device3_SetTransform
,
6721 d3d_device3_GetTransform
,
6722 d3d_device3_MultiplyTransform
,
6723 d3d_device3_DrawPrimitive
,
6724 d3d_device3_DrawIndexedPrimitive
,
6725 d3d_device3_SetClipStatus
,
6726 d3d_device3_GetClipStatus
,
6727 d3d_device3_DrawPrimitiveStrided
,
6728 d3d_device3_DrawIndexedPrimitiveStrided
,
6729 d3d_device3_DrawPrimitiveVB
,
6730 d3d_device3_DrawIndexedPrimitiveVB
,
6731 d3d_device3_ComputeSphereVisibility
,
6732 d3d_device3_GetTexture
,
6733 d3d_device3_SetTexture
,
6734 d3d_device3_GetTextureStageState
,
6735 d3d_device3_SetTextureStageState
,
6736 d3d_device3_ValidateDevice
6739 static const struct IDirect3DDevice2Vtbl d3d_device2_vtbl
=
6741 /*** IUnknown Methods ***/
6742 d3d_device2_QueryInterface
,
6744 d3d_device2_Release
,
6745 /*** IDirect3DDevice2 ***/
6746 d3d_device2_GetCaps
,
6747 d3d_device2_SwapTextureHandles
,
6748 d3d_device2_GetStats
,
6749 d3d_device2_AddViewport
,
6750 d3d_device2_DeleteViewport
,
6751 d3d_device2_NextViewport
,
6752 d3d_device2_EnumTextureFormats
,
6753 d3d_device2_BeginScene
,
6754 d3d_device2_EndScene
,
6755 d3d_device2_GetDirect3D
,
6756 d3d_device2_SetCurrentViewport
,
6757 d3d_device2_GetCurrentViewport
,
6758 d3d_device2_SetRenderTarget
,
6759 d3d_device2_GetRenderTarget
,
6761 d3d_device2_BeginIndexed
,
6765 d3d_device2_GetRenderState
,
6766 d3d_device2_SetRenderState
,
6767 d3d_device2_GetLightState
,
6768 d3d_device2_SetLightState
,
6769 d3d_device2_SetTransform
,
6770 d3d_device2_GetTransform
,
6771 d3d_device2_MultiplyTransform
,
6772 d3d_device2_DrawPrimitive
,
6773 d3d_device2_DrawIndexedPrimitive
,
6774 d3d_device2_SetClipStatus
,
6775 d3d_device2_GetClipStatus
6778 static const struct IDirect3DDeviceVtbl d3d_device1_vtbl
=
6780 /*** IUnknown Methods ***/
6781 d3d_device1_QueryInterface
,
6783 d3d_device1_Release
,
6784 /*** IDirect3DDevice1 ***/
6785 d3d_device1_Initialize
,
6786 d3d_device1_GetCaps
,
6787 d3d_device1_SwapTextureHandles
,
6788 d3d_device1_CreateExecuteBuffer
,
6789 d3d_device1_GetStats
,
6790 d3d_device1_Execute
,
6791 d3d_device1_AddViewport
,
6792 d3d_device1_DeleteViewport
,
6793 d3d_device1_NextViewport
,
6795 d3d_device1_GetPickRecords
,
6796 d3d_device1_EnumTextureFormats
,
6797 d3d_device1_CreateMatrix
,
6798 d3d_device1_SetMatrix
,
6799 d3d_device1_GetMatrix
,
6800 d3d_device1_DeleteMatrix
,
6801 d3d_device1_BeginScene
,
6802 d3d_device1_EndScene
,
6803 d3d_device1_GetDirect3D
6806 static const struct IUnknownVtbl d3d_device_inner_vtbl
=
6808 d3d_device_inner_QueryInterface
,
6809 d3d_device_inner_AddRef
,
6810 d3d_device_inner_Release
,
6813 struct d3d_device
*unsafe_impl_from_IDirect3DDevice7(IDirect3DDevice7
*iface
)
6815 if (!iface
) return NULL
;
6816 assert((iface
->lpVtbl
== &d3d_device7_fpu_preserve_vtbl
) || (iface
->lpVtbl
== &d3d_device7_fpu_setup_vtbl
));
6817 return CONTAINING_RECORD(iface
, struct d3d_device
, IDirect3DDevice7_iface
);
6820 struct d3d_device
*unsafe_impl_from_IDirect3DDevice3(IDirect3DDevice3
*iface
)
6822 if (!iface
) return NULL
;
6823 assert(iface
->lpVtbl
== &d3d_device3_vtbl
);
6824 return CONTAINING_RECORD(iface
, struct d3d_device
, IDirect3DDevice3_iface
);
6827 struct d3d_device
*unsafe_impl_from_IDirect3DDevice2(IDirect3DDevice2
*iface
)
6829 if (!iface
) return NULL
;
6830 assert(iface
->lpVtbl
== &d3d_device2_vtbl
);
6831 return CONTAINING_RECORD(iface
, struct d3d_device
, IDirect3DDevice2_iface
);
6834 struct d3d_device
*unsafe_impl_from_IDirect3DDevice(IDirect3DDevice
*iface
)
6836 if (!iface
) return NULL
;
6837 assert(iface
->lpVtbl
== &d3d_device1_vtbl
);
6838 return CONTAINING_RECORD(iface
, struct d3d_device
, IDirect3DDevice_iface
);
6841 enum wined3d_depth_buffer_type
d3d_device_update_depth_stencil(struct d3d_device
*device
)
6843 IDirectDrawSurface7
*depthStencil
= NULL
;
6844 IDirectDrawSurface7
*render_target
;
6845 static DDSCAPS2 depthcaps
= { DDSCAPS_ZBUFFER
, 0, 0, {0} };
6846 struct ddraw_surface
*dsi
;
6848 if (device
->rt_iface
&& SUCCEEDED(IUnknown_QueryInterface(device
->rt_iface
,
6849 &IID_IDirectDrawSurface7
, (void **)&render_target
)))
6851 IDirectDrawSurface7_GetAttachedSurface(render_target
, &depthcaps
, &depthStencil
);
6852 IDirectDrawSurface7_Release(render_target
);
6856 TRACE("Setting wined3d depth stencil to NULL\n");
6857 wined3d_device_set_depth_stencil_view(device
->wined3d_device
, NULL
);
6858 return WINED3D_ZB_FALSE
;
6861 dsi
= impl_from_IDirectDrawSurface7(depthStencil
);
6862 wined3d_device_set_depth_stencil_view(device
->wined3d_device
,
6863 ddraw_surface_get_rendertarget_view(dsi
));
6865 IDirectDrawSurface7_Release(depthStencil
);
6866 return WINED3D_ZB_TRUE
;
6869 static HRESULT
d3d_device_init(struct d3d_device
*device
, struct ddraw
*ddraw
, BOOL hw
,
6870 struct ddraw_surface
*target
, IUnknown
*rt_iface
, UINT version
, IUnknown
*outer_unknown
)
6872 static const D3DMATRIX ident
=
6874 1.0f
, 0.0f
, 0.0f
, 0.0f
,
6875 0.0f
, 1.0f
, 0.0f
, 0.0f
,
6876 0.0f
, 0.0f
, 1.0f
, 0.0f
,
6877 0.0f
, 0.0f
, 0.0f
, 1.0f
,
6881 if (ddraw
->cooperative_level
& DDSCL_FPUPRESERVE
)
6882 device
->IDirect3DDevice7_iface
.lpVtbl
= &d3d_device7_fpu_preserve_vtbl
;
6884 device
->IDirect3DDevice7_iface
.lpVtbl
= &d3d_device7_fpu_setup_vtbl
;
6886 device
->IDirect3DDevice3_iface
.lpVtbl
= &d3d_device3_vtbl
;
6887 device
->IDirect3DDevice2_iface
.lpVtbl
= &d3d_device2_vtbl
;
6888 device
->IDirect3DDevice_iface
.lpVtbl
= &d3d_device1_vtbl
;
6889 device
->IUnknown_inner
.lpVtbl
= &d3d_device_inner_vtbl
;
6891 device
->version
= version
;
6895 device
->outer_unknown
= outer_unknown
;
6897 device
->outer_unknown
= &device
->IUnknown_inner
;
6899 device
->ddraw
= ddraw
;
6900 list_init(&device
->viewport_list
);
6902 if (!ddraw_handle_table_init(&device
->handle_table
, 64))
6904 ERR("Failed to initialize handle table.\n");
6905 return DDERR_OUTOFMEMORY
;
6908 device
->legacyTextureBlending
= FALSE
;
6909 device
->legacy_projection
= ident
;
6910 device
->legacy_clipspace
= ident
;
6912 /* This is for convenience. */
6913 device
->wined3d_device
= ddraw
->wined3d_device
;
6914 wined3d_device_incref(ddraw
->wined3d_device
);
6916 /* Render to the back buffer */
6917 if (FAILED(hr
= wined3d_device_set_rendertarget_view(ddraw
->wined3d_device
,
6918 0, ddraw_surface_get_rendertarget_view(target
), TRUE
)))
6920 ERR("Failed to set render target, hr %#x.\n", hr
);
6921 ddraw_handle_table_destroy(&device
->handle_table
);
6925 device
->rt_iface
= rt_iface
;
6927 IUnknown_AddRef(device
->rt_iface
);
6929 ddraw
->d3ddevice
= device
;
6931 wined3d_device_set_render_state(ddraw
->wined3d_device
, WINED3D_RS_ZENABLE
,
6932 d3d_device_update_depth_stencil(device
));
6933 if (version
== 1) /* Color keying is initially enabled for version 1 devices. */
6934 wined3d_device_set_render_state(ddraw
->wined3d_device
, WINED3D_RS_COLORKEYENABLE
, TRUE
);
6935 else if (version
== 2)
6936 wined3d_device_set_render_state(ddraw
->wined3d_device
, WINED3D_RS_SPECULARENABLE
, TRUE
);
6938 wined3d_device_set_render_state(ddraw
->wined3d_device
, WINED3D_RS_NORMALIZENORMALS
, TRUE
);
6943 HRESULT
d3d_device_create(struct ddraw
*ddraw
, const GUID
*guid
, struct ddraw_surface
*target
, IUnknown
*rt_iface
,
6944 UINT version
, struct d3d_device
**device
, IUnknown
*outer_unknown
)
6946 struct d3d_device
*object
;
6950 TRACE("ddraw %p, guid %s, target %p, version %u, device %p, outer_unknown %p.\n",
6951 ddraw
, debugstr_guid(guid
), target
, version
, device
, outer_unknown
);
6953 if (IsEqualGUID(guid
, &IID_IDirect3DRGBDevice
))
6956 if (!(target
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_3DDEVICE
)
6957 || (target
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_ZBUFFER
))
6959 WARN("Surface %p is not a render target.\n", target
);
6960 return DDERR_INVALIDCAPS
;
6963 if (!validate_surface_palette(target
))
6965 WARN("Surface %p has an indexed pixel format, but no palette.\n", target
);
6966 return DDERR_NOPALETTEATTACHED
;
6969 if (hw
&& !(target
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_VIDEOMEMORY
))
6971 WARN("Surface %p is not in video memory.\n", target
);
6972 return D3DERR_SURFACENOTINVIDMEM
;
6975 if (ddraw
->flags
& DDRAW_NO3D
)
6977 ERR_(winediag
)("The application wants to create a Direct3D device, "
6978 "but the current DirectDrawRenderer does not support this.\n");
6983 if (ddraw
->d3ddevice
)
6985 FIXME("Only one Direct3D device per DirectDraw object supported.\n");
6986 return DDERR_INVALIDPARAMS
;
6989 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*object
));
6992 ERR("Failed to allocate device memory.\n");
6993 return DDERR_OUTOFMEMORY
;
6996 if (FAILED(hr
= d3d_device_init(object
, ddraw
, hw
, target
, rt_iface
, version
, outer_unknown
)))
6998 WARN("Failed to initialize device, hr %#x.\n", hr
);
6999 HeapFree(GetProcessHeap(), 0, object
);
7003 TRACE("Created device %p.\n", object
);