2 * Copyright (c) 1998-2004 Lionel Ulmer
3 * Copyright (c) 2002-2005 Christian Costa
4 * Copyright (c) 2006-2009, 2011-2013 Stefan Dösinger
5 * Copyright (c) 2008 Alexander Dorofeyev
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 * IDirect3DDevice implementation, version 1, 2, 3 and 7. Rendering is relayed
22 * to WineD3D, some minimal DirectDraw specific management is handled here.
23 * The Direct3DDevice is NOT the parent of the WineD3DDevice, because d3d
24 * is initialized when DirectDraw creates the primary surface.
25 * Some type management is necessary, because some D3D types changed between
31 #include "wine/port.h"
33 #include "ddraw_private.h"
35 WINE_DEFAULT_DEBUG_CHANNEL(ddraw
);
36 WINE_DECLARE_DEBUG_CHANNEL(winediag
);
39 const GUID IID_D3DDEVICE_WineD3D
= {
43 { 0xb7,0x98,0xc6,0x8a,0x77,0x2d,0x72,0x2a }
46 static inline void set_fpu_control_word(WORD fpucw
)
48 #if defined(__i386__) && defined(__GNUC__)
49 __asm__
volatile ("fldcw %0" : : "m" (fpucw
));
50 #elif defined(__i386__) && defined(_MSC_VER)
55 static inline WORD
d3d_fpu_setup(void)
59 #if defined(__i386__) && defined(__GNUC__)
60 __asm__
volatile ("fnstcw %0" : "=m" (oldcw
));
61 #elif defined(__i386__) && defined(_MSC_VER)
64 static BOOL warned
= FALSE
;
67 FIXME("FPUPRESERVE not implemented for this platform / compiler\n");
73 set_fpu_control_word(0x37f);
78 static inline struct d3d_device
*impl_from_IUnknown(IUnknown
*iface
)
80 return CONTAINING_RECORD(iface
, struct d3d_device
, IUnknown_inner
);
83 static HRESULT WINAPI
d3d_device_inner_QueryInterface(IUnknown
*iface
, REFIID riid
, void **out
)
85 struct d3d_device
*device
= impl_from_IUnknown(iface
);
87 TRACE("iface %p, riid %s, out %p.\n", iface
, debugstr_guid(riid
), out
);
92 return DDERR_INVALIDPARAMS
;
95 if (IsEqualGUID(&IID_IUnknown
, riid
))
97 IDirect3DDevice7_AddRef(&device
->IDirect3DDevice7_iface
);
98 *out
= &device
->IDirect3DDevice7_iface
;
102 if (device
->version
== 7)
104 if (IsEqualGUID(&IID_IDirect3DDevice7
, riid
))
106 IDirect3DDevice7_AddRef(&device
->IDirect3DDevice7_iface
);
107 *out
= &device
->IDirect3DDevice7_iface
;
113 if (IsEqualGUID(&IID_IDirect3DDevice3
, riid
) && device
->version
== 3)
115 IDirect3DDevice3_AddRef(&device
->IDirect3DDevice3_iface
);
116 *out
= &device
->IDirect3DDevice3_iface
;
120 if (IsEqualGUID(&IID_IDirect3DDevice2
, riid
) && device
->version
>= 2)
122 IDirect3DDevice2_AddRef(&device
->IDirect3DDevice2_iface
);
123 *out
= &device
->IDirect3DDevice2_iface
;
127 if (IsEqualGUID(&IID_IDirect3DDevice
, riid
))
129 IDirect3DDevice_AddRef(&device
->IDirect3DDevice_iface
);
130 *out
= &device
->IDirect3DDevice_iface
;
135 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid
));
138 return E_NOINTERFACE
;
141 static HRESULT WINAPI
d3d_device7_QueryInterface(IDirect3DDevice7
*iface
, REFIID riid
, void **out
)
143 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
145 TRACE("iface %p, riid %s, out %p.\n", iface
, debugstr_guid(riid
), out
);
147 return IUnknown_QueryInterface(device
->outer_unknown
, riid
, out
);
150 static HRESULT WINAPI
d3d_device3_QueryInterface(IDirect3DDevice3
*iface
, REFIID riid
, void **out
)
152 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
154 TRACE("iface %p, riid %s, out %p.\n", iface
, debugstr_guid(riid
), out
);
156 return IUnknown_QueryInterface(device
->outer_unknown
, riid
, out
);
159 static HRESULT WINAPI
d3d_device2_QueryInterface(IDirect3DDevice2
*iface
, REFIID riid
, void **out
)
161 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
163 TRACE("iface %p, riid %s, out %p.\n", iface
, debugstr_guid(riid
), out
);
165 return IUnknown_QueryInterface(device
->outer_unknown
, riid
, out
);
168 static HRESULT WINAPI
d3d_device1_QueryInterface(IDirect3DDevice
*iface
, REFIID riid
, void **out
)
170 struct d3d_device
*device
= impl_from_IDirect3DDevice(iface
);
172 TRACE("iface %p, riid %s, out %p.\n", iface
, debugstr_guid(riid
), out
);
174 return IUnknown_QueryInterface(device
->outer_unknown
, riid
, out
);
177 static ULONG WINAPI
d3d_device_inner_AddRef(IUnknown
*iface
)
179 struct d3d_device
*device
= impl_from_IUnknown(iface
);
180 ULONG ref
= InterlockedIncrement(&device
->ref
);
182 TRACE("%p increasing refcount to %u.\n", device
, ref
);
187 static ULONG WINAPI
d3d_device7_AddRef(IDirect3DDevice7
*iface
)
189 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
191 TRACE("iface %p.\n", iface
);
193 return IUnknown_AddRef(device
->outer_unknown
);
196 static ULONG WINAPI
d3d_device3_AddRef(IDirect3DDevice3
*iface
)
198 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
200 TRACE("iface %p.\n", iface
);
202 return IUnknown_AddRef(device
->outer_unknown
);
205 static ULONG WINAPI
d3d_device2_AddRef(IDirect3DDevice2
*iface
)
207 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
209 TRACE("iface %p.\n", iface
);
211 return IUnknown_AddRef(device
->outer_unknown
);
214 static ULONG WINAPI
d3d_device1_AddRef(IDirect3DDevice
*iface
)
216 struct d3d_device
*device
= impl_from_IDirect3DDevice(iface
);
218 TRACE("iface %p.\n", iface
);
220 return IUnknown_AddRef(device
->outer_unknown
);
223 static ULONG WINAPI
d3d_device_inner_Release(IUnknown
*iface
)
225 struct d3d_device
*This
= impl_from_IUnknown(iface
);
226 ULONG ref
= InterlockedDecrement(&This
->ref
);
229 TRACE("%p decreasing refcount to %u.\n", This
, ref
);
231 /* This method doesn't destroy the wined3d device, because it's still in
232 * use for 2D rendering. IDirectDrawSurface7::Release will destroy the
233 * wined3d device when the render target is released. */
237 struct list
*vp_entry
, *vp_entry2
;
239 wined3d_mutex_lock();
241 /* There is no need to unset any resources here, wined3d will take
242 * care of that on uninit_3d(). */
244 if (This
->index_buffer
)
245 wined3d_buffer_decref(This
->index_buffer
);
246 if (This
->vertex_buffer
)
247 wined3d_buffer_decref(This
->vertex_buffer
);
249 wined3d_device_set_rendertarget_view(This
->wined3d_device
, 0, NULL
, FALSE
);
251 /* Release the wined3d device. This won't destroy it. */
252 if (!wined3d_device_decref(This
->wined3d_device
))
253 ERR("The wined3d device (%p) was destroyed unexpectedly.\n", This
->wined3d_device
);
255 /* The texture handles should be unset by now, but there might be some bits
256 * missing in our reference counting(needs test). Do a sanity check. */
257 for (i
= 0; i
< This
->handle_table
.entry_count
; ++i
)
259 struct ddraw_handle_entry
*entry
= &This
->handle_table
.entries
[i
];
263 case DDRAW_HANDLE_FREE
:
266 case DDRAW_HANDLE_MATERIAL
:
268 struct d3d_material
*m
= entry
->object
;
269 FIXME("Material handle %#x (%p) not unset properly.\n", i
+ 1, m
);
274 case DDRAW_HANDLE_MATRIX
:
276 /* No FIXME here because this might happen because of sloppy applications. */
277 WARN("Leftover matrix handle %#x (%p), deleting.\n", i
+ 1, entry
->object
);
278 IDirect3DDevice_DeleteMatrix(&This
->IDirect3DDevice_iface
, i
+ 1);
282 case DDRAW_HANDLE_STATEBLOCK
:
284 /* No FIXME here because this might happen because of sloppy applications. */
285 WARN("Leftover stateblock handle %#x (%p), deleting.\n", i
+ 1, entry
->object
);
286 IDirect3DDevice7_DeleteStateBlock(&This
->IDirect3DDevice7_iface
, i
+ 1);
290 case DDRAW_HANDLE_SURFACE
:
292 struct ddraw_surface
*surf
= entry
->object
;
293 FIXME("Texture handle %#x (%p) not unset properly.\n", i
+ 1, surf
);
299 FIXME("Handle %#x (%p) has unknown type %#x.\n", i
+ 1, entry
->object
, entry
->type
);
304 ddraw_handle_table_destroy(&This
->handle_table
);
306 LIST_FOR_EACH_SAFE(vp_entry
, vp_entry2
, &This
->viewport_list
)
308 struct d3d_viewport
*vp
= LIST_ENTRY(vp_entry
, struct d3d_viewport
, entry
);
309 IDirect3DDevice3_DeleteViewport(&This
->IDirect3DDevice3_iface
, &vp
->IDirect3DViewport3_iface
);
312 TRACE("Releasing render target %p.\n", This
->rt_iface
);
313 rt_iface
= This
->rt_iface
;
314 This
->rt_iface
= NULL
;
315 if (This
->version
!= 1)
316 IUnknown_Release(rt_iface
);
317 TRACE("Render target release done.\n");
319 This
->ddraw
->d3ddevice
= NULL
;
321 /* Now free the structure */
322 HeapFree(GetProcessHeap(), 0, This
);
323 wined3d_mutex_unlock();
330 static ULONG WINAPI
d3d_device7_Release(IDirect3DDevice7
*iface
)
332 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
334 TRACE("iface %p.\n", iface
);
336 return IUnknown_Release(device
->outer_unknown
);
339 static ULONG WINAPI
d3d_device3_Release(IDirect3DDevice3
*iface
)
341 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
343 TRACE("iface %p.\n", iface
);
345 return IUnknown_Release(device
->outer_unknown
);
348 static ULONG WINAPI
d3d_device2_Release(IDirect3DDevice2
*iface
)
350 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
352 TRACE("iface %p.\n", iface
);
354 return IUnknown_Release(device
->outer_unknown
);
357 static ULONG WINAPI
d3d_device1_Release(IDirect3DDevice
*iface
)
359 struct d3d_device
*device
= impl_from_IDirect3DDevice(iface
);
361 TRACE("iface %p.\n", iface
);
363 return IUnknown_Release(device
->outer_unknown
);
366 /*****************************************************************************
367 * IDirect3DDevice Methods
368 *****************************************************************************/
370 /*****************************************************************************
371 * IDirect3DDevice::Initialize
373 * Initializes a Direct3DDevice. This implementation is a no-op, as all
374 * initialization is done at create time.
376 * Exists in Version 1
379 * No idea what they mean, as the MSDN page is gone
383 *****************************************************************************/
384 static HRESULT WINAPI
d3d_device1_Initialize(IDirect3DDevice
*iface
,
385 IDirect3D
*d3d
, GUID
*guid
, D3DDEVICEDESC
*device_desc
)
387 /* It shouldn't be crucial, but print a FIXME, I'm interested if
388 * any game calls it and when. */
389 FIXME("iface %p, d3d %p, guid %s, device_desc %p nop!\n",
390 iface
, d3d
, debugstr_guid(guid
), device_desc
);
395 static HRESULT
d3d_device7_GetCaps(IDirect3DDevice7
*iface
, D3DDEVICEDESC7
*device_desc
)
397 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
399 TRACE("iface %p, device_desc %p.\n", iface
, device_desc
);
403 WARN("device_desc is NULL, returning DDERR_INVALIDPARAMS.\n");
404 return DDERR_INVALIDPARAMS
;
407 /* Call the same function used by IDirect3D, this saves code */
408 return ddraw_get_d3dcaps(device
->ddraw
, device_desc
);
411 static HRESULT WINAPI
d3d_device7_GetCaps_FPUSetup(IDirect3DDevice7
*iface
, D3DDEVICEDESC7
*desc
)
413 return d3d_device7_GetCaps(iface
, desc
);
416 static HRESULT WINAPI
d3d_device7_GetCaps_FPUPreserve(IDirect3DDevice7
*iface
, D3DDEVICEDESC7
*desc
)
421 old_fpucw
= d3d_fpu_setup();
422 hr
= d3d_device7_GetCaps(iface
, desc
);
423 set_fpu_control_word(old_fpucw
);
427 /*****************************************************************************
428 * IDirect3DDevice3::GetCaps
430 * Retrieves the capabilities of the hardware device and the emulation
431 * device. For Wine, hardware and emulation are the same (it's all HW).
433 * This implementation is used for Version 1, 2, and 3. Version 7 has its own
436 * HWDesc: Structure to fill with the HW caps
437 * HelDesc: Structure to fill with the hardware emulation caps
441 * D3DERR_* if a problem occurs. See WineD3D
443 *****************************************************************************/
445 /* There are 3 versions of D3DDEVICEDESC. All 3 share the same name because
446 * Microsoft just expanded the existing structure without naming them
447 * D3DDEVICEDESC2 and D3DDEVICEDESC3. Which version is used have depends
448 * on the version of the DirectX SDK. DirectX 6+ and Wine use the latest
449 * one with 252 bytes.
451 * All 3 versions are allowed as parameters and only the specified amount of
454 * Note that Direct3D7 and earlier are not available in native Win64
455 * ddraw.dll builds, so possible size differences between 32 bit and
456 * 64 bit are a non-issue.
458 static inline BOOL
check_d3ddevicedesc_size(DWORD size
)
460 if (size
== FIELD_OFFSET(D3DDEVICEDESC
, dwMinTextureWidth
) /* 172 */
461 || size
== FIELD_OFFSET(D3DDEVICEDESC
, dwMaxTextureRepeat
) /* 204 */
462 || size
== sizeof(D3DDEVICEDESC
) /* 252 */) return TRUE
;
466 static HRESULT WINAPI
d3d_device3_GetCaps(IDirect3DDevice3
*iface
,
467 D3DDEVICEDESC
*HWDesc
, D3DDEVICEDESC
*HelDesc
)
469 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
470 D3DDEVICEDESC7 desc7
;
474 TRACE("iface %p, hw_desc %p, hel_desc %p.\n", iface
, HWDesc
, HelDesc
);
478 WARN("HWDesc is NULL, returning DDERR_INVALIDPARAMS.\n");
479 return DDERR_INVALIDPARAMS
;
481 if (!check_d3ddevicedesc_size(HWDesc
->dwSize
))
483 WARN("HWDesc->dwSize is %u, returning DDERR_INVALIDPARAMS.\n", HWDesc
->dwSize
);
484 return DDERR_INVALIDPARAMS
;
488 WARN("HelDesc is NULL, returning DDERR_INVALIDPARAMS.\n");
489 return DDERR_INVALIDPARAMS
;
491 if (!check_d3ddevicedesc_size(HelDesc
->dwSize
))
493 WARN("HelDesc->dwSize is %u, returning DDERR_INVALIDPARAMS.\n", HelDesc
->dwSize
);
494 return DDERR_INVALIDPARAMS
;
497 if (FAILED(hr
= ddraw_get_d3dcaps(device
->ddraw
, &desc7
)))
500 ddraw_d3dcaps1_from_7(&desc1
, &desc7
);
501 DD_STRUCT_COPY_BYSIZE(HWDesc
, &desc1
);
502 DD_STRUCT_COPY_BYSIZE(HelDesc
, &desc1
);
506 static HRESULT WINAPI
d3d_device2_GetCaps(IDirect3DDevice2
*iface
,
507 D3DDEVICEDESC
*hw_desc
, D3DDEVICEDESC
*hel_desc
)
509 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
511 TRACE("iface %p, hw_desc %p, hel_desc %p.\n", iface
, hw_desc
, hel_desc
);
513 return d3d_device3_GetCaps(&device
->IDirect3DDevice3_iface
, hw_desc
, hel_desc
);
516 static HRESULT WINAPI
d3d_device1_GetCaps(IDirect3DDevice
*iface
,
517 D3DDEVICEDESC
*hw_desc
, D3DDEVICEDESC
*hel_desc
)
519 struct d3d_device
*device
= impl_from_IDirect3DDevice(iface
);
521 TRACE("iface %p, hw_desc %p, hel_desc %p.\n", iface
, hw_desc
, hel_desc
);
523 return d3d_device3_GetCaps(&device
->IDirect3DDevice3_iface
, hw_desc
, hel_desc
);
526 /*****************************************************************************
527 * IDirect3DDevice2::SwapTextureHandles
529 * Swaps the texture handles of 2 Texture interfaces. Version 1 and 2
532 * Tex1, Tex2: The 2 Textures to swap
537 *****************************************************************************/
538 static HRESULT WINAPI
d3d_device2_SwapTextureHandles(IDirect3DDevice2
*iface
,
539 IDirect3DTexture2
*tex1
, IDirect3DTexture2
*tex2
)
541 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
542 struct ddraw_surface
*surf1
= unsafe_impl_from_IDirect3DTexture2(tex1
);
543 struct ddraw_surface
*surf2
= unsafe_impl_from_IDirect3DTexture2(tex2
);
546 TRACE("iface %p, tex1 %p, tex2 %p.\n", iface
, tex1
, tex2
);
548 wined3d_mutex_lock();
550 h1
= surf1
->Handle
- 1;
551 h2
= surf2
->Handle
- 1;
552 device
->handle_table
.entries
[h1
].object
= surf2
;
553 device
->handle_table
.entries
[h2
].object
= surf1
;
554 surf2
->Handle
= h1
+ 1;
555 surf1
->Handle
= h2
+ 1;
557 wined3d_mutex_unlock();
562 static HRESULT WINAPI
d3d_device1_SwapTextureHandles(IDirect3DDevice
*iface
,
563 IDirect3DTexture
*tex1
, IDirect3DTexture
*tex2
)
565 struct d3d_device
*device
= impl_from_IDirect3DDevice(iface
);
566 struct ddraw_surface
*surf1
= unsafe_impl_from_IDirect3DTexture(tex1
);
567 struct ddraw_surface
*surf2
= unsafe_impl_from_IDirect3DTexture(tex2
);
568 IDirect3DTexture2
*t1
= surf1
? &surf1
->IDirect3DTexture2_iface
: NULL
;
569 IDirect3DTexture2
*t2
= surf2
? &surf2
->IDirect3DTexture2_iface
: NULL
;
571 TRACE("iface %p, tex1 %p, tex2 %p.\n", iface
, tex1
, tex2
);
573 return d3d_device2_SwapTextureHandles(&device
->IDirect3DDevice2_iface
, t1
, t2
);
576 /*****************************************************************************
577 * IDirect3DDevice3::GetStats
579 * This method seems to retrieve some stats from the device.
580 * The MSDN documentation doesn't exist any more, but the D3DSTATS
581 * structure suggests that the amount of drawn primitives and processed
582 * vertices is returned.
584 * Exists in Version 1, 2 and 3
587 * Stats: Pointer to a D3DSTATS structure to be filled
591 * DDERR_INVALIDPARAMS if Stats == NULL
593 *****************************************************************************/
594 static HRESULT WINAPI
d3d_device3_GetStats(IDirect3DDevice3
*iface
, D3DSTATS
*Stats
)
596 FIXME("iface %p, stats %p stub!\n", iface
, Stats
);
599 return DDERR_INVALIDPARAMS
;
601 /* Fill the Stats with 0 */
602 Stats
->dwTrianglesDrawn
= 0;
603 Stats
->dwLinesDrawn
= 0;
604 Stats
->dwPointsDrawn
= 0;
605 Stats
->dwSpansDrawn
= 0;
606 Stats
->dwVerticesProcessed
= 0;
611 static HRESULT WINAPI
d3d_device2_GetStats(IDirect3DDevice2
*iface
, D3DSTATS
*stats
)
613 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
615 TRACE("iface %p, stats %p.\n", iface
, stats
);
617 return d3d_device3_GetStats(&device
->IDirect3DDevice3_iface
, stats
);
620 static HRESULT WINAPI
d3d_device1_GetStats(IDirect3DDevice
*iface
, D3DSTATS
*stats
)
622 struct d3d_device
*device
= impl_from_IDirect3DDevice(iface
);
624 TRACE("iface %p, stats %p.\n", iface
, stats
);
626 return d3d_device3_GetStats(&device
->IDirect3DDevice3_iface
, stats
);
629 /*****************************************************************************
630 * IDirect3DDevice::CreateExecuteBuffer
632 * Creates an IDirect3DExecuteBuffer, used for rendering with a
638 * Desc: Buffer description
639 * ExecuteBuffer: Address to return the Interface pointer at
640 * UnkOuter: Must be NULL. Basically for aggregation, which ddraw doesn't
644 * CLASS_E_NOAGGREGATION if UnkOuter != NULL
645 * DDERR_OUTOFMEMORY if we ran out of memory
648 *****************************************************************************/
649 static HRESULT WINAPI
d3d_device1_CreateExecuteBuffer(IDirect3DDevice
*iface
,
650 D3DEXECUTEBUFFERDESC
*buffer_desc
, IDirect3DExecuteBuffer
**ExecuteBuffer
, IUnknown
*outer_unknown
)
652 struct d3d_device
*device
= impl_from_IDirect3DDevice(iface
);
653 struct d3d_execute_buffer
*object
;
656 TRACE("iface %p, buffer_desc %p, buffer %p, outer_unknown %p.\n",
657 iface
, buffer_desc
, ExecuteBuffer
, outer_unknown
);
660 return CLASS_E_NOAGGREGATION
;
662 /* Allocate the new Execute Buffer */
663 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*object
));
666 ERR("Failed to allocate execute buffer memory.\n");
667 return DDERR_OUTOFMEMORY
;
670 hr
= d3d_execute_buffer_init(object
, device
, buffer_desc
);
673 WARN("Failed to initialize execute buffer, hr %#x.\n", hr
);
674 HeapFree(GetProcessHeap(), 0, object
);
678 *ExecuteBuffer
= &object
->IDirect3DExecuteBuffer_iface
;
680 TRACE(" Returning IDirect3DExecuteBuffer at %p, implementation is at %p\n", *ExecuteBuffer
, object
);
685 /*****************************************************************************
686 * IDirect3DDevice::Execute
688 * Executes all the stuff in an execute buffer.
691 * ExecuteBuffer: The buffer to execute
692 * Viewport: The viewport used for rendering
696 * DDERR_INVALIDPARAMS if ExecuteBuffer == NULL
699 *****************************************************************************/
700 static HRESULT WINAPI
d3d_device1_Execute(IDirect3DDevice
*iface
,
701 IDirect3DExecuteBuffer
*ExecuteBuffer
, IDirect3DViewport
*viewport
, DWORD flags
)
703 struct d3d_device
*device
= impl_from_IDirect3DDevice(iface
);
704 struct d3d_execute_buffer
*buffer
= unsafe_impl_from_IDirect3DExecuteBuffer(ExecuteBuffer
);
705 struct d3d_viewport
*viewport_impl
= unsafe_impl_from_IDirect3DViewport(viewport
);
708 TRACE("iface %p, buffer %p, viewport %p, flags %#x.\n", iface
, ExecuteBuffer
, viewport
, flags
);
711 return DDERR_INVALIDPARAMS
;
714 wined3d_mutex_lock();
715 hr
= d3d_execute_buffer_execute(buffer
, device
, viewport_impl
);
716 wined3d_mutex_unlock();
721 /*****************************************************************************
722 * IDirect3DDevice3::AddViewport
724 * Add a Direct3DViewport to the device's viewport list. These viewports
725 * are wrapped to IDirect3DDevice7 viewports in viewport.c
727 * Exists in Version 1, 2 and 3. Note that IDirect3DViewport 1, 2 and 3
728 * are the same interfaces.
731 * Viewport: The viewport to add
734 * DDERR_INVALIDPARAMS if Viewport == NULL
737 *****************************************************************************/
738 static HRESULT WINAPI
d3d_device3_AddViewport(IDirect3DDevice3
*iface
, IDirect3DViewport3
*viewport
)
740 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
741 struct d3d_viewport
*vp
= unsafe_impl_from_IDirect3DViewport3(viewport
);
743 TRACE("iface %p, viewport %p.\n", iface
, viewport
);
747 return DDERR_INVALIDPARAMS
;
749 wined3d_mutex_lock();
750 IDirect3DViewport3_AddRef(viewport
);
751 list_add_head(&device
->viewport_list
, &vp
->entry
);
752 /* Viewport must be usable for Clear() after AddViewport, so set active_device here. */
753 vp
->active_device
= device
;
754 wined3d_mutex_unlock();
759 static HRESULT WINAPI
d3d_device2_AddViewport(IDirect3DDevice2
*iface
,
760 IDirect3DViewport2
*viewport
)
762 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
763 struct d3d_viewport
*vp
= unsafe_impl_from_IDirect3DViewport2(viewport
);
765 TRACE("iface %p, viewport %p.\n", iface
, viewport
);
767 return d3d_device3_AddViewport(&device
->IDirect3DDevice3_iface
, &vp
->IDirect3DViewport3_iface
);
770 static HRESULT WINAPI
d3d_device1_AddViewport(IDirect3DDevice
*iface
, IDirect3DViewport
*viewport
)
772 struct d3d_device
*device
= impl_from_IDirect3DDevice(iface
);
773 struct d3d_viewport
*vp
= unsafe_impl_from_IDirect3DViewport(viewport
);
775 TRACE("iface %p, viewport %p.\n", iface
, viewport
);
777 return d3d_device3_AddViewport(&device
->IDirect3DDevice3_iface
, &vp
->IDirect3DViewport3_iface
);
780 /*****************************************************************************
781 * IDirect3DDevice3::DeleteViewport
783 * Deletes a Direct3DViewport from the device's viewport list.
785 * Exists in Version 1, 2 and 3. Note that all Viewport interface versions
789 * Viewport: The viewport to delete
793 * DDERR_INVALIDPARAMS if the viewport wasn't found in the list
795 *****************************************************************************/
796 static HRESULT WINAPI
d3d_device3_DeleteViewport(IDirect3DDevice3
*iface
, IDirect3DViewport3
*viewport
)
798 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
799 struct d3d_viewport
*vp
= unsafe_impl_from_IDirect3DViewport3(viewport
);
801 TRACE("iface %p, viewport %p.\n", iface
, viewport
);
805 WARN("NULL viewport, returning DDERR_INVALIDPARAMS\n");
806 return DDERR_INVALIDPARAMS
;
809 wined3d_mutex_lock();
811 if (vp
->active_device
!= device
)
813 WARN("Viewport %p active device is %p.\n", vp
, vp
->active_device
);
814 wined3d_mutex_unlock();
815 return DDERR_INVALIDPARAMS
;
818 if (device
->current_viewport
== vp
)
820 TRACE("Deleting current viewport, unsetting and releasing\n");
821 IDirect3DViewport3_Release(viewport
);
822 device
->current_viewport
= NULL
;
825 vp
->active_device
= NULL
;
826 list_remove(&vp
->entry
);
828 IDirect3DViewport3_Release(viewport
);
830 wined3d_mutex_unlock();
835 static HRESULT WINAPI
d3d_device2_DeleteViewport(IDirect3DDevice2
*iface
, IDirect3DViewport2
*viewport
)
837 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
838 struct d3d_viewport
*vp
= unsafe_impl_from_IDirect3DViewport2(viewport
);
840 TRACE("iface %p, viewport %p.\n", iface
, viewport
);
842 return d3d_device3_DeleteViewport(&device
->IDirect3DDevice3_iface
,
843 vp
? &vp
->IDirect3DViewport3_iface
: NULL
);
846 static HRESULT WINAPI
d3d_device1_DeleteViewport(IDirect3DDevice
*iface
, IDirect3DViewport
*viewport
)
848 struct d3d_device
*device
= impl_from_IDirect3DDevice(iface
);
849 struct d3d_viewport
*vp
= unsafe_impl_from_IDirect3DViewport(viewport
);
851 TRACE("iface %p, viewport %p.\n", iface
, viewport
);
853 return d3d_device3_DeleteViewport(&device
->IDirect3DDevice3_iface
,
854 vp
? &vp
->IDirect3DViewport3_iface
: NULL
);
857 /*****************************************************************************
858 * IDirect3DDevice3::NextViewport
860 * Returns a viewport from the viewport list, depending on the
861 * passed viewport and the flags.
863 * Exists in Version 1, 2 and 3. Note that all Viewport interface versions
867 * Viewport: Viewport to use for beginning the search
868 * Flags: D3DNEXT_NEXT, D3DNEXT_HEAD or D3DNEXT_TAIL
872 * DDERR_INVALIDPARAMS if the flags were wrong, or Viewport was NULL
874 *****************************************************************************/
875 static HRESULT WINAPI
d3d_device3_NextViewport(IDirect3DDevice3
*iface
,
876 IDirect3DViewport3
*Viewport3
, IDirect3DViewport3
**lplpDirect3DViewport3
, DWORD flags
)
878 struct d3d_device
*This
= impl_from_IDirect3DDevice3(iface
);
879 struct d3d_viewport
*vp
= unsafe_impl_from_IDirect3DViewport3(Viewport3
);
880 struct d3d_viewport
*next
;
883 TRACE("iface %p, viewport %p, next %p, flags %#x.\n",
884 iface
, Viewport3
, lplpDirect3DViewport3
, flags
);
888 *lplpDirect3DViewport3
= NULL
;
889 return DDERR_INVALIDPARAMS
;
893 wined3d_mutex_lock();
897 entry
= list_next(&This
->viewport_list
, &vp
->entry
);
901 entry
= list_head(&This
->viewport_list
);
905 entry
= list_tail(&This
->viewport_list
);
909 WARN("Invalid flags %#x.\n", flags
);
910 *lplpDirect3DViewport3
= NULL
;
911 wined3d_mutex_unlock();
912 return DDERR_INVALIDPARAMS
;
917 next
= LIST_ENTRY(entry
, struct d3d_viewport
, entry
);
918 *lplpDirect3DViewport3
= &next
->IDirect3DViewport3_iface
;
921 *lplpDirect3DViewport3
= NULL
;
923 wined3d_mutex_unlock();
928 static HRESULT WINAPI
d3d_device2_NextViewport(IDirect3DDevice2
*iface
,
929 IDirect3DViewport2
*viewport
, IDirect3DViewport2
**next
, DWORD flags
)
931 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
932 struct d3d_viewport
*vp
= unsafe_impl_from_IDirect3DViewport2(viewport
);
933 IDirect3DViewport3
*res
;
936 TRACE("iface %p, viewport %p, next %p, flags %#x.\n",
937 iface
, viewport
, next
, flags
);
939 hr
= d3d_device3_NextViewport(&device
->IDirect3DDevice3_iface
,
940 &vp
->IDirect3DViewport3_iface
, &res
, flags
);
941 *next
= (IDirect3DViewport2
*)res
;
945 static HRESULT WINAPI
d3d_device1_NextViewport(IDirect3DDevice
*iface
,
946 IDirect3DViewport
*viewport
, IDirect3DViewport
**next
, DWORD flags
)
948 struct d3d_device
*device
= impl_from_IDirect3DDevice(iface
);
949 struct d3d_viewport
*vp
= unsafe_impl_from_IDirect3DViewport(viewport
);
950 IDirect3DViewport3
*res
;
953 TRACE("iface %p, viewport %p, next %p, flags %#x.\n",
954 iface
, viewport
, next
, flags
);
956 hr
= d3d_device3_NextViewport(&device
->IDirect3DDevice3_iface
,
957 &vp
->IDirect3DViewport3_iface
, &res
, flags
);
958 *next
= (IDirect3DViewport
*)res
;
962 /*****************************************************************************
963 * IDirect3DDevice::Pick
965 * Executes an execute buffer without performing rendering. Instead, a
966 * list of primitives that intersect with (x1,y1) of the passed rectangle
967 * is created. IDirect3DDevice::GetPickRecords can be used to retrieve
973 * ExecuteBuffer: Buffer to execute
974 * Viewport: Viewport to use for execution
975 * Flags: None are defined, according to the SDK
976 * Rect: Specifies the coordinates to be picked. Only x1 and y2 are used,
977 * x2 and y2 are ignored.
980 * D3D_OK because it's a stub
982 *****************************************************************************/
983 static HRESULT WINAPI
d3d_device1_Pick(IDirect3DDevice
*iface
, IDirect3DExecuteBuffer
*buffer
,
984 IDirect3DViewport
*viewport
, DWORD flags
, D3DRECT
*rect
)
986 FIXME("iface %p, buffer %p, viewport %p, flags %#x, rect %s stub!\n",
987 iface
, buffer
, viewport
, flags
, wine_dbgstr_rect((RECT
*)rect
));
992 /*****************************************************************************
993 * IDirect3DDevice::GetPickRecords
995 * Retrieves the pick records generated by IDirect3DDevice::GetPickRecords
1000 * Count: Pointer to a DWORD containing the numbers of pick records to
1002 * D3DPickRec: Address to store the resulting D3DPICKRECORD array.
1005 * D3D_OK, because it's a stub
1007 *****************************************************************************/
1008 static HRESULT WINAPI
d3d_device1_GetPickRecords(IDirect3DDevice
*iface
,
1009 DWORD
*count
, D3DPICKRECORD
*records
)
1011 FIXME("iface %p, count %p, records %p stub!\n", iface
, count
, records
);
1016 /*****************************************************************************
1017 * IDirect3DDevice7::EnumTextureformats
1019 * Enumerates the supported texture formats. It has a list of all possible
1020 * formats and calls IWineD3D::CheckDeviceFormat for each format to see if
1021 * WineD3D supports it. If so, then it is passed to the app.
1023 * This is for Version 7 and 3, older versions have a different
1024 * callback function and their own implementation
1027 * Callback: Callback to call for each enumerated format
1028 * Arg: Argument to pass to the callback
1032 * DDERR_INVALIDPARAMS if Callback == NULL
1034 *****************************************************************************/
1035 static HRESULT
d3d_device7_EnumTextureFormats(IDirect3DDevice7
*iface
,
1036 LPD3DENUMPIXELFORMATSCALLBACK callback
, void *context
)
1038 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
1039 struct wined3d_display_mode mode
;
1043 static const enum wined3d_format_id FormatList
[] =
1046 WINED3DFMT_B5G5R5X1_UNORM
,
1047 WINED3DFMT_B5G5R5A1_UNORM
,
1048 WINED3DFMT_B4G4R4A4_UNORM
,
1049 WINED3DFMT_B5G6R5_UNORM
,
1051 WINED3DFMT_B8G8R8X8_UNORM
,
1052 WINED3DFMT_B8G8R8A8_UNORM
,
1054 WINED3DFMT_B2G3R3_UNORM
,
1064 static const enum wined3d_format_id BumpFormatList
[] =
1066 WINED3DFMT_R8G8_SNORM
,
1067 WINED3DFMT_R5G5_SNORM_L6_UNORM
,
1068 WINED3DFMT_R8G8_SNORM_L8X8_UNORM
,
1069 WINED3DFMT_R10G11B11_SNORM
,
1070 WINED3DFMT_R10G10B10_SNORM_A2_UNORM
1073 TRACE("iface %p, callback %p, context %p.\n", iface
, callback
, context
);
1076 return DDERR_INVALIDPARAMS
;
1078 wined3d_mutex_lock();
1080 memset(&mode
, 0, sizeof(mode
));
1081 if (FAILED(hr
= wined3d_get_adapter_display_mode(device
->ddraw
->wined3d
, WINED3DADAPTER_DEFAULT
, &mode
, NULL
)))
1083 wined3d_mutex_unlock();
1084 WARN("Cannot get the current adapter format\n");
1088 for (i
= 0; i
< sizeof(FormatList
) / sizeof(*FormatList
); ++i
)
1090 if (wined3d_check_device_format(device
->ddraw
->wined3d
, WINED3DADAPTER_DEFAULT
, WINED3D_DEVICE_TYPE_HAL
,
1091 mode
.format_id
, 0, WINED3D_RTYPE_TEXTURE
, FormatList
[i
]) == D3D_OK
)
1093 DDPIXELFORMAT pformat
;
1095 memset(&pformat
, 0, sizeof(pformat
));
1096 pformat
.dwSize
= sizeof(pformat
);
1097 ddrawformat_from_wined3dformat(&pformat
, FormatList
[i
]);
1099 TRACE("Enumerating WineD3DFormat %d\n", FormatList
[i
]);
1100 hr
= callback(&pformat
, context
);
1101 if(hr
!= DDENUMRET_OK
)
1103 TRACE("Format enumeration cancelled by application\n");
1104 wined3d_mutex_unlock();
1110 for (i
= 0; i
< sizeof(BumpFormatList
) / sizeof(*BumpFormatList
); ++i
)
1112 if (wined3d_check_device_format(device
->ddraw
->wined3d
, WINED3DADAPTER_DEFAULT
,
1113 WINED3D_DEVICE_TYPE_HAL
, mode
.format_id
, WINED3DUSAGE_QUERY_LEGACYBUMPMAP
,
1114 WINED3D_RTYPE_TEXTURE
, BumpFormatList
[i
]) == D3D_OK
)
1116 DDPIXELFORMAT pformat
;
1118 memset(&pformat
, 0, sizeof(pformat
));
1119 pformat
.dwSize
= sizeof(pformat
);
1120 ddrawformat_from_wined3dformat(&pformat
, BumpFormatList
[i
]);
1122 TRACE("Enumerating WineD3DFormat %d\n", BumpFormatList
[i
]);
1123 hr
= callback(&pformat
, context
);
1124 if(hr
!= DDENUMRET_OK
)
1126 TRACE("Format enumeration cancelled by application\n");
1127 wined3d_mutex_unlock();
1132 TRACE("End of enumeration\n");
1133 wined3d_mutex_unlock();
1138 static HRESULT WINAPI
d3d_device7_EnumTextureFormats_FPUSetup(IDirect3DDevice7
*iface
,
1139 LPD3DENUMPIXELFORMATSCALLBACK callback
, void *context
)
1141 return d3d_device7_EnumTextureFormats(iface
, callback
, context
);
1144 static HRESULT WINAPI
d3d_device7_EnumTextureFormats_FPUPreserve(IDirect3DDevice7
*iface
,
1145 LPD3DENUMPIXELFORMATSCALLBACK callback
, void *context
)
1150 old_fpucw
= d3d_fpu_setup();
1151 hr
= d3d_device7_EnumTextureFormats(iface
, callback
, context
);
1152 set_fpu_control_word(old_fpucw
);
1157 static HRESULT WINAPI
d3d_device3_EnumTextureFormats(IDirect3DDevice3
*iface
,
1158 LPD3DENUMPIXELFORMATSCALLBACK callback
, void *context
)
1160 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
1162 TRACE("iface %p, callback %p, context %p.\n", iface
, callback
, context
);
1164 return IDirect3DDevice7_EnumTextureFormats(&device
->IDirect3DDevice7_iface
, callback
, context
);
1167 /*****************************************************************************
1168 * IDirect3DDevice2::EnumTextureformats
1170 * EnumTextureFormats for Version 1 and 2, see
1171 * IDirect3DDevice7::EnumTexureFormats for a more detailed description.
1173 * This version has a different callback and does not enumerate FourCC
1176 *****************************************************************************/
1177 static HRESULT WINAPI
d3d_device2_EnumTextureFormats(IDirect3DDevice2
*iface
,
1178 LPD3DENUMTEXTUREFORMATSCALLBACK callback
, void *context
)
1180 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
1181 struct wined3d_display_mode mode
;
1185 static const enum wined3d_format_id FormatList
[] =
1188 WINED3DFMT_B5G5R5X1_UNORM
,
1189 WINED3DFMT_B5G5R5A1_UNORM
,
1190 WINED3DFMT_B4G4R4A4_UNORM
,
1191 WINED3DFMT_B5G6R5_UNORM
,
1193 WINED3DFMT_B8G8R8X8_UNORM
,
1194 WINED3DFMT_B8G8R8A8_UNORM
,
1196 WINED3DFMT_B2G3R3_UNORM
,
1198 /* FOURCC codes - Not in this version*/
1201 TRACE("iface %p, callback %p, context %p.\n", iface
, callback
, context
);
1204 return DDERR_INVALIDPARAMS
;
1206 wined3d_mutex_lock();
1208 memset(&mode
, 0, sizeof(mode
));
1209 if (FAILED(hr
= wined3d_get_adapter_display_mode(device
->ddraw
->wined3d
, WINED3DADAPTER_DEFAULT
, &mode
, NULL
)))
1211 wined3d_mutex_unlock();
1212 WARN("Cannot get the current adapter format\n");
1216 for (i
= 0; i
< sizeof(FormatList
) / sizeof(*FormatList
); ++i
)
1218 if (wined3d_check_device_format(device
->ddraw
->wined3d
, 0, WINED3D_DEVICE_TYPE_HAL
,
1219 mode
.format_id
, 0, WINED3D_RTYPE_TEXTURE
, FormatList
[i
]) == D3D_OK
)
1221 DDSURFACEDESC sdesc
;
1223 memset(&sdesc
, 0, sizeof(sdesc
));
1224 sdesc
.dwSize
= sizeof(sdesc
);
1225 sdesc
.dwFlags
= DDSD_PIXELFORMAT
| DDSD_CAPS
;
1226 sdesc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
1227 sdesc
.ddpfPixelFormat
.dwSize
= sizeof(sdesc
.ddpfPixelFormat
);
1228 ddrawformat_from_wined3dformat(&sdesc
.ddpfPixelFormat
, FormatList
[i
]);
1230 TRACE("Enumerating WineD3DFormat %d\n", FormatList
[i
]);
1231 hr
= callback(&sdesc
, context
);
1232 if(hr
!= DDENUMRET_OK
)
1234 TRACE("Format enumeration cancelled by application\n");
1235 wined3d_mutex_unlock();
1240 TRACE("End of enumeration\n");
1241 wined3d_mutex_unlock();
1246 static HRESULT WINAPI
d3d_device1_EnumTextureFormats(IDirect3DDevice
*iface
,
1247 LPD3DENUMTEXTUREFORMATSCALLBACK callback
, void *context
)
1249 struct d3d_device
*device
= impl_from_IDirect3DDevice(iface
);
1251 TRACE("iface %p, callback %p, context %p.\n", iface
, callback
, context
);
1253 return d3d_device2_EnumTextureFormats(&device
->IDirect3DDevice2_iface
, callback
, context
);
1256 /*****************************************************************************
1257 * IDirect3DDevice::CreateMatrix
1259 * Creates a matrix handle. A handle is created and memory for a D3DMATRIX is
1260 * allocated for the handle.
1265 * D3DMatHandle: Address to return the handle at
1269 * DDERR_INVALIDPARAMS if D3DMatHandle = NULL
1271 *****************************************************************************/
1272 static HRESULT WINAPI
d3d_device1_CreateMatrix(IDirect3DDevice
*iface
, D3DMATRIXHANDLE
*D3DMatHandle
)
1274 struct d3d_device
*device
= impl_from_IDirect3DDevice(iface
);
1278 TRACE("iface %p, matrix_handle %p.\n", iface
, D3DMatHandle
);
1281 return DDERR_INVALIDPARAMS
;
1283 Matrix
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(D3DMATRIX
));
1286 ERR("Out of memory when allocating a D3DMATRIX\n");
1287 return DDERR_OUTOFMEMORY
;
1290 wined3d_mutex_lock();
1292 h
= ddraw_allocate_handle(&device
->handle_table
, Matrix
, DDRAW_HANDLE_MATRIX
);
1293 if (h
== DDRAW_INVALID_HANDLE
)
1295 ERR("Failed to allocate a matrix handle.\n");
1296 HeapFree(GetProcessHeap(), 0, Matrix
);
1297 wined3d_mutex_unlock();
1298 return DDERR_OUTOFMEMORY
;
1301 *D3DMatHandle
= h
+ 1;
1303 TRACE(" returning matrix handle %d\n", *D3DMatHandle
);
1305 wined3d_mutex_unlock();
1310 /*****************************************************************************
1311 * IDirect3DDevice::SetMatrix
1313 * Sets a matrix for a matrix handle. The matrix is copied into the memory
1314 * allocated for the handle
1319 * D3DMatHandle: Handle to set the matrix to
1320 * D3DMatrix: Matrix to set
1324 * DDERR_INVALIDPARAMS if the handle of the matrix is invalid or the matrix
1327 *****************************************************************************/
1328 static HRESULT WINAPI
d3d_device1_SetMatrix(IDirect3DDevice
*iface
,
1329 D3DMATRIXHANDLE D3DMatHandle
, D3DMATRIX
*D3DMatrix
)
1331 struct d3d_device
*This
= impl_from_IDirect3DDevice(iface
);
1334 TRACE("iface %p, matrix_handle %#x, matrix %p.\n", iface
, D3DMatHandle
, D3DMatrix
);
1336 if (!D3DMatrix
) return DDERR_INVALIDPARAMS
;
1338 wined3d_mutex_lock();
1340 m
= ddraw_get_object(&This
->handle_table
, D3DMatHandle
- 1, DDRAW_HANDLE_MATRIX
);
1343 WARN("Invalid matrix handle.\n");
1344 wined3d_mutex_unlock();
1345 return DDERR_INVALIDPARAMS
;
1348 if (TRACE_ON(ddraw
))
1349 dump_D3DMATRIX(D3DMatrix
);
1353 if (D3DMatHandle
== This
->world
)
1354 wined3d_device_set_transform(This
->wined3d_device
,
1355 WINED3D_TS_WORLD_MATRIX(0), (struct wined3d_matrix
*)D3DMatrix
);
1357 if (D3DMatHandle
== This
->view
)
1358 wined3d_device_set_transform(This
->wined3d_device
,
1359 WINED3D_TS_VIEW
, (struct wined3d_matrix
*)D3DMatrix
);
1361 if (D3DMatHandle
== This
->proj
)
1362 wined3d_device_set_transform(This
->wined3d_device
,
1363 WINED3D_TS_PROJECTION
, (struct wined3d_matrix
*)D3DMatrix
);
1365 wined3d_mutex_unlock();
1370 /*****************************************************************************
1371 * IDirect3DDevice::GetMatrix
1373 * Returns the content of a D3DMATRIX handle
1378 * D3DMatHandle: Matrix handle to read the content from
1379 * D3DMatrix: Address to store the content at
1383 * DDERR_INVALIDPARAMS if D3DMatHandle is invalid or D3DMatrix is NULL
1385 *****************************************************************************/
1386 static HRESULT WINAPI
d3d_device1_GetMatrix(IDirect3DDevice
*iface
,
1387 D3DMATRIXHANDLE D3DMatHandle
, D3DMATRIX
*D3DMatrix
)
1389 struct d3d_device
*device
= impl_from_IDirect3DDevice(iface
);
1392 TRACE("iface %p, matrix_handle %#x, matrix %p.\n", iface
, D3DMatHandle
, D3DMatrix
);
1394 if (!D3DMatrix
) return DDERR_INVALIDPARAMS
;
1396 wined3d_mutex_lock();
1398 m
= ddraw_get_object(&device
->handle_table
, D3DMatHandle
- 1, DDRAW_HANDLE_MATRIX
);
1401 WARN("Invalid matrix handle.\n");
1402 wined3d_mutex_unlock();
1403 return DDERR_INVALIDPARAMS
;
1408 wined3d_mutex_unlock();
1413 /*****************************************************************************
1414 * IDirect3DDevice::DeleteMatrix
1416 * Destroys a Matrix handle. Frees the memory and unsets the handle data
1421 * D3DMatHandle: Handle to destroy
1425 * DDERR_INVALIDPARAMS if D3DMatHandle is invalid
1427 *****************************************************************************/
1428 static HRESULT WINAPI
d3d_device1_DeleteMatrix(IDirect3DDevice
*iface
, D3DMATRIXHANDLE D3DMatHandle
)
1430 struct d3d_device
*device
= impl_from_IDirect3DDevice(iface
);
1433 TRACE("iface %p, matrix_handle %#x.\n", iface
, D3DMatHandle
);
1435 wined3d_mutex_lock();
1437 m
= ddraw_free_handle(&device
->handle_table
, D3DMatHandle
- 1, DDRAW_HANDLE_MATRIX
);
1440 WARN("Invalid matrix handle.\n");
1441 wined3d_mutex_unlock();
1442 return DDERR_INVALIDPARAMS
;
1445 wined3d_mutex_unlock();
1447 HeapFree(GetProcessHeap(), 0, m
);
1452 /*****************************************************************************
1453 * IDirect3DDevice7::BeginScene
1455 * This method must be called before any rendering is performed.
1456 * IDirect3DDevice::EndScene has to be called after the scene is complete
1458 * Version 1, 2, 3 and 7
1461 * D3D_OK on success, for details see IWineD3DDevice::BeginScene
1462 * D3DERR_SCENE_IN_SCENE if WineD3D returns an error(Only in case of an already
1465 *****************************************************************************/
1466 static HRESULT
d3d_device7_BeginScene(IDirect3DDevice7
*iface
)
1468 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
1471 TRACE("iface %p.\n", iface
);
1473 wined3d_mutex_lock();
1474 hr
= wined3d_device_begin_scene(device
->wined3d_device
);
1475 wined3d_mutex_unlock();
1477 if(hr
== WINED3D_OK
) return D3D_OK
;
1478 else return D3DERR_SCENE_IN_SCENE
; /* TODO: Other possible causes of failure */
1481 static HRESULT WINAPI
d3d_device7_BeginScene_FPUSetup(IDirect3DDevice7
*iface
)
1483 return d3d_device7_BeginScene(iface
);
1486 static HRESULT WINAPI
d3d_device7_BeginScene_FPUPreserve(IDirect3DDevice7
*iface
)
1491 old_fpucw
= d3d_fpu_setup();
1492 hr
= d3d_device7_BeginScene(iface
);
1493 set_fpu_control_word(old_fpucw
);
1498 static HRESULT WINAPI
d3d_device3_BeginScene(IDirect3DDevice3
*iface
)
1500 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
1502 TRACE("iface %p.\n", iface
);
1504 return IDirect3DDevice7_BeginScene(&device
->IDirect3DDevice7_iface
);
1507 static HRESULT WINAPI
d3d_device2_BeginScene(IDirect3DDevice2
*iface
)
1509 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
1511 TRACE("iface %p.\n", iface
);
1513 return IDirect3DDevice7_BeginScene(&device
->IDirect3DDevice7_iface
);
1516 static HRESULT WINAPI
d3d_device1_BeginScene(IDirect3DDevice
*iface
)
1518 struct d3d_device
*device
= impl_from_IDirect3DDevice(iface
);
1520 TRACE("iface %p.\n", iface
);
1522 return IDirect3DDevice7_BeginScene(&device
->IDirect3DDevice7_iface
);
1525 /*****************************************************************************
1526 * IDirect3DDevice7::EndScene
1528 * Ends a scene that has been begun with IDirect3DDevice7::BeginScene.
1529 * This method must be called after rendering is finished.
1531 * Version 1, 2, 3 and 7
1534 * D3D_OK on success, for details see IWineD3DDevice::EndScene
1535 * D3DERR_SCENE_NOT_IN_SCENE is returned if WineD3D returns an error. It does
1536 * that only if the scene was already ended.
1538 *****************************************************************************/
1539 static HRESULT
d3d_device7_EndScene(IDirect3DDevice7
*iface
)
1541 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
1544 TRACE("iface %p.\n", iface
);
1546 wined3d_mutex_lock();
1547 hr
= wined3d_device_end_scene(device
->wined3d_device
);
1548 wined3d_mutex_unlock();
1550 if(hr
== WINED3D_OK
) return D3D_OK
;
1551 else return D3DERR_SCENE_NOT_IN_SCENE
;
1554 static HRESULT WINAPI DECLSPEC_HOTPATCH
d3d_device7_EndScene_FPUSetup(IDirect3DDevice7
*iface
)
1556 return d3d_device7_EndScene(iface
);
1559 static HRESULT WINAPI DECLSPEC_HOTPATCH
d3d_device7_EndScene_FPUPreserve(IDirect3DDevice7
*iface
)
1564 old_fpucw
= d3d_fpu_setup();
1565 hr
= d3d_device7_EndScene(iface
);
1566 set_fpu_control_word(old_fpucw
);
1571 static HRESULT WINAPI DECLSPEC_HOTPATCH
d3d_device3_EndScene(IDirect3DDevice3
*iface
)
1573 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
1575 TRACE("iface %p.\n", iface
);
1577 return IDirect3DDevice7_EndScene(&device
->IDirect3DDevice7_iface
);
1580 static HRESULT WINAPI DECLSPEC_HOTPATCH
d3d_device2_EndScene(IDirect3DDevice2
*iface
)
1582 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
1584 TRACE("iface %p.\n", iface
);
1586 return IDirect3DDevice7_EndScene(&device
->IDirect3DDevice7_iface
);
1589 static HRESULT WINAPI DECLSPEC_HOTPATCH
d3d_device1_EndScene(IDirect3DDevice
*iface
)
1591 struct d3d_device
*device
= impl_from_IDirect3DDevice(iface
);
1593 TRACE("iface %p.\n", iface
);
1595 return IDirect3DDevice7_EndScene(&device
->IDirect3DDevice7_iface
);
1598 /*****************************************************************************
1599 * IDirect3DDevice7::GetDirect3D
1601 * Returns the IDirect3D(= interface to the DirectDraw object) used to create
1605 * Direct3D7: Address to store the interface pointer at
1609 * DDERR_INVALIDPARAMS if Direct3D7 == NULL
1611 *****************************************************************************/
1612 static HRESULT WINAPI
d3d_device7_GetDirect3D(IDirect3DDevice7
*iface
, IDirect3D7
**d3d
)
1614 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
1616 TRACE("iface %p, d3d %p.\n", iface
, d3d
);
1619 return DDERR_INVALIDPARAMS
;
1621 *d3d
= &device
->ddraw
->IDirect3D7_iface
;
1622 IDirect3D7_AddRef(*d3d
);
1624 TRACE("Returning interface %p.\n", *d3d
);
1628 static HRESULT WINAPI
d3d_device3_GetDirect3D(IDirect3DDevice3
*iface
, IDirect3D3
**d3d
)
1630 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
1632 TRACE("iface %p, d3d %p.\n", iface
, d3d
);
1635 return DDERR_INVALIDPARAMS
;
1637 *d3d
= &device
->ddraw
->IDirect3D3_iface
;
1638 IDirect3D3_AddRef(*d3d
);
1640 TRACE("Returning interface %p.\n", *d3d
);
1644 static HRESULT WINAPI
d3d_device2_GetDirect3D(IDirect3DDevice2
*iface
, IDirect3D2
**d3d
)
1646 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
1648 TRACE("iface %p, d3d %p.\n", iface
, d3d
);
1651 return DDERR_INVALIDPARAMS
;
1653 *d3d
= &device
->ddraw
->IDirect3D2_iface
;
1654 IDirect3D2_AddRef(*d3d
);
1656 TRACE("Returning interface %p.\n", *d3d
);
1660 static HRESULT WINAPI
d3d_device1_GetDirect3D(IDirect3DDevice
*iface
, IDirect3D
**d3d
)
1662 struct d3d_device
*device
= impl_from_IDirect3DDevice(iface
);
1664 TRACE("iface %p, d3d %p.\n", iface
, d3d
);
1667 return DDERR_INVALIDPARAMS
;
1669 *d3d
= &device
->ddraw
->IDirect3D_iface
;
1670 IDirect3D_AddRef(*d3d
);
1672 TRACE("Returning interface %p.\n", *d3d
);
1676 /*****************************************************************************
1677 * IDirect3DDevice3::SetCurrentViewport
1679 * Sets a Direct3DViewport as the current viewport.
1680 * For the thunks note that all viewport interface versions are equal
1683 * Direct3DViewport3: The viewport to set
1689 * (Is a NULL viewport valid?)
1691 *****************************************************************************/
1692 static HRESULT WINAPI
d3d_device3_SetCurrentViewport(IDirect3DDevice3
*iface
, IDirect3DViewport3
*Direct3DViewport3
)
1694 struct d3d_device
*This
= impl_from_IDirect3DDevice3(iface
);
1695 struct d3d_viewport
*vp
= unsafe_impl_from_IDirect3DViewport3(Direct3DViewport3
);
1697 TRACE("iface %p, viewport %p.\n", iface
, Direct3DViewport3
);
1701 WARN("Direct3DViewport3 is NULL, returning DDERR_INVALIDPARAMS\n");
1702 return DDERR_INVALIDPARAMS
;
1705 wined3d_mutex_lock();
1706 /* Do nothing if the specified viewport is the same as the current one */
1707 if (This
->current_viewport
== vp
)
1709 wined3d_mutex_unlock();
1713 if (vp
->active_device
!= This
)
1715 WARN("Viewport %p active device is %p.\n", vp
, vp
->active_device
);
1716 wined3d_mutex_unlock();
1717 return DDERR_INVALIDPARAMS
;
1720 /* Release previous viewport and AddRef the new one */
1721 if (This
->current_viewport
)
1723 TRACE("ViewportImpl is at %p, interface is at %p\n", This
->current_viewport
,
1724 &This
->current_viewport
->IDirect3DViewport3_iface
);
1725 IDirect3DViewport3_Release(&This
->current_viewport
->IDirect3DViewport3_iface
);
1727 IDirect3DViewport3_AddRef(Direct3DViewport3
);
1729 /* Set this viewport as the current viewport */
1730 This
->current_viewport
= vp
;
1732 /* Activate this viewport */
1733 viewport_activate(This
->current_viewport
, FALSE
);
1735 wined3d_mutex_unlock();
1740 static HRESULT WINAPI
d3d_device2_SetCurrentViewport(IDirect3DDevice2
*iface
, IDirect3DViewport2
*viewport
)
1742 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
1743 struct d3d_viewport
*vp
= unsafe_impl_from_IDirect3DViewport2(viewport
);
1745 TRACE("iface %p, viewport %p.\n", iface
, viewport
);
1747 return d3d_device3_SetCurrentViewport(&device
->IDirect3DDevice3_iface
,
1748 vp
? &vp
->IDirect3DViewport3_iface
: NULL
);
1751 /*****************************************************************************
1752 * IDirect3DDevice3::GetCurrentViewport
1754 * Returns the currently active viewport.
1759 * Direct3DViewport3: Address to return the interface pointer at
1763 * DDERR_INVALIDPARAMS if Direct3DViewport == NULL
1765 *****************************************************************************/
1766 static HRESULT WINAPI
d3d_device3_GetCurrentViewport(IDirect3DDevice3
*iface
, IDirect3DViewport3
**viewport
)
1768 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
1770 TRACE("iface %p, viewport %p.\n", iface
, viewport
);
1772 wined3d_mutex_lock();
1773 if (!device
->current_viewport
)
1775 wined3d_mutex_unlock();
1776 WARN("No current viewport, returning D3DERR_NOCURRENTVIEWPORT\n");
1777 return D3DERR_NOCURRENTVIEWPORT
;
1780 *viewport
= &device
->current_viewport
->IDirect3DViewport3_iface
;
1781 IDirect3DViewport3_AddRef(*viewport
);
1783 TRACE("Returning interface %p.\n", *viewport
);
1784 wined3d_mutex_unlock();
1788 static HRESULT WINAPI
d3d_device2_GetCurrentViewport(IDirect3DDevice2
*iface
, IDirect3DViewport2
**viewport
)
1790 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
1792 TRACE("iface %p, viewport %p.\n", iface
, viewport
);
1794 return d3d_device3_GetCurrentViewport(&device
->IDirect3DDevice3_iface
,
1795 (IDirect3DViewport3
**)viewport
);
1798 static BOOL
validate_surface_palette(struct ddraw_surface
*surface
)
1800 return !format_is_paletteindexed(&surface
->surface_desc
.u4
.ddpfPixelFormat
)
1801 || surface
->palette
;
1804 static HRESULT
d3d_device_set_render_target(struct d3d_device
*device
,
1805 struct ddraw_surface
*target
, IUnknown
*rt_iface
)
1809 if (device
->rt_iface
== rt_iface
)
1811 TRACE("No-op SetRenderTarget operation, not doing anything\n");
1816 WARN("Trying to set render target to NULL.\n");
1817 return DDERR_INVALIDPARAMS
;
1820 if (FAILED(hr
= wined3d_device_set_rendertarget_view(device
->wined3d_device
,
1821 0, ddraw_surface_get_rendertarget_view(target
), FALSE
)))
1824 IUnknown_AddRef(rt_iface
);
1825 IUnknown_Release(device
->rt_iface
);
1826 device
->rt_iface
= rt_iface
;
1827 d3d_device_update_depth_stencil(device
);
1832 static HRESULT
d3d_device7_SetRenderTarget(IDirect3DDevice7
*iface
,
1833 IDirectDrawSurface7
*target
, DWORD flags
)
1835 struct ddraw_surface
*target_impl
= unsafe_impl_from_IDirectDrawSurface7(target
);
1836 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
1839 TRACE("iface %p, target %p, flags %#x.\n", iface
, target
, flags
);
1841 wined3d_mutex_lock();
1843 if (!validate_surface_palette(target_impl
))
1845 WARN("Surface %p has an indexed pixel format, but no palette.\n", target_impl
);
1846 wined3d_mutex_unlock();
1847 return DDERR_INVALIDCAPS
;
1850 if (!(target_impl
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_3DDEVICE
))
1852 WARN("Surface %p is not a render target.\n", target_impl
);
1853 wined3d_mutex_unlock();
1854 return DDERR_INVALIDCAPS
;
1857 if (!(target_impl
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_VIDEOMEMORY
))
1859 WARN("Surface %p is not in video memory.\n", target_impl
);
1860 wined3d_mutex_unlock();
1861 return DDERR_INVALIDPARAMS
;
1864 if (target_impl
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_ZBUFFER
)
1866 WARN("Surface %p is a depth buffer.\n", target_impl
);
1867 IDirectDrawSurface7_AddRef(target
);
1868 IUnknown_Release(device
->rt_iface
);
1869 device
->rt_iface
= (IUnknown
*)target
;
1870 wined3d_mutex_unlock();
1871 return DDERR_INVALIDPIXELFORMAT
;
1874 hr
= d3d_device_set_render_target(device
, target_impl
, (IUnknown
*)target
);
1875 wined3d_mutex_unlock();
1879 static HRESULT WINAPI
d3d_device7_SetRenderTarget_FPUSetup(IDirect3DDevice7
*iface
,
1880 IDirectDrawSurface7
*NewTarget
, DWORD flags
)
1882 return d3d_device7_SetRenderTarget(iface
, NewTarget
, flags
);
1885 static HRESULT WINAPI
d3d_device7_SetRenderTarget_FPUPreserve(IDirect3DDevice7
*iface
,
1886 IDirectDrawSurface7
*NewTarget
, DWORD flags
)
1891 old_fpucw
= d3d_fpu_setup();
1892 hr
= d3d_device7_SetRenderTarget(iface
, NewTarget
, flags
);
1893 set_fpu_control_word(old_fpucw
);
1898 static HRESULT WINAPI
d3d_device3_SetRenderTarget(IDirect3DDevice3
*iface
,
1899 IDirectDrawSurface4
*target
, DWORD flags
)
1901 struct ddraw_surface
*target_impl
= unsafe_impl_from_IDirectDrawSurface4(target
);
1902 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
1905 TRACE("iface %p, target %p, flags %#x.\n", iface
, target
, flags
);
1907 wined3d_mutex_lock();
1909 if (!validate_surface_palette(target_impl
))
1911 WARN("Surface %p has an indexed pixel format, but no palette.\n", target_impl
);
1912 wined3d_mutex_unlock();
1913 return DDERR_INVALIDCAPS
;
1916 if (!(target_impl
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_3DDEVICE
))
1918 WARN("Surface %p is not a render target.\n", target_impl
);
1919 wined3d_mutex_unlock();
1920 return DDERR_INVALIDCAPS
;
1923 if (target_impl
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_ZBUFFER
)
1925 WARN("Surface %p is a depth buffer.\n", target_impl
);
1926 IDirectDrawSurface4_AddRef(target
);
1927 IUnknown_Release(device
->rt_iface
);
1928 device
->rt_iface
= (IUnknown
*)target
;
1929 wined3d_mutex_unlock();
1930 return DDERR_INVALIDPIXELFORMAT
;
1933 if (!(target_impl
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_VIDEOMEMORY
))
1935 WARN("Surface %p is not in video memory.\n", target_impl
);
1936 IDirectDrawSurface4_AddRef(target
);
1937 IUnknown_Release(device
->rt_iface
);
1938 device
->rt_iface
= (IUnknown
*)target
;
1939 wined3d_mutex_unlock();
1943 hr
= d3d_device_set_render_target(device
, target_impl
, (IUnknown
*)target
);
1944 wined3d_mutex_unlock();
1948 static HRESULT WINAPI
d3d_device2_SetRenderTarget(IDirect3DDevice2
*iface
,
1949 IDirectDrawSurface
*target
, DWORD flags
)
1951 struct ddraw_surface
*target_impl
= unsafe_impl_from_IDirectDrawSurface(target
);
1952 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
1955 TRACE("iface %p, target %p, flags %#x.\n", iface
, target
, flags
);
1957 wined3d_mutex_lock();
1959 if (!validate_surface_palette(target_impl
))
1961 WARN("Surface %p has an indexed pixel format, but no palette.\n", target_impl
);
1962 wined3d_mutex_unlock();
1963 return DDERR_INVALIDCAPS
;
1966 if (!(target_impl
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_3DDEVICE
))
1968 WARN("Surface %p is not a render target.\n", target_impl
);
1969 wined3d_mutex_unlock();
1970 return DDERR_INVALIDCAPS
;
1973 if (target_impl
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_ZBUFFER
)
1975 WARN("Surface %p is a depth buffer.\n", target_impl
);
1976 IUnknown_Release(device
->rt_iface
);
1977 device
->rt_iface
= (IUnknown
*)target
;
1978 wined3d_mutex_unlock();
1979 return DDERR_INVALIDPIXELFORMAT
;
1982 if (!(target_impl
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_VIDEOMEMORY
))
1984 WARN("Surface %p is not in video memory.\n", target_impl
);
1985 IDirectDrawSurface_AddRef(target
);
1986 IUnknown_Release(device
->rt_iface
);
1987 device
->rt_iface
= (IUnknown
*)target
;
1988 wined3d_mutex_unlock();
1992 hr
= d3d_device_set_render_target(device
, target_impl
, (IUnknown
*)target
);
1993 wined3d_mutex_unlock();
1997 /*****************************************************************************
1998 * IDirect3DDevice7::GetRenderTarget
2000 * Returns the current render target.
2001 * This is handled locally, because the WineD3D render target's parent
2004 * Version 2, 3 and 7
2007 * RenderTarget: Address to store the surface interface pointer
2011 * DDERR_INVALIDPARAMS if RenderTarget == NULL
2013 *****************************************************************************/
2014 static HRESULT WINAPI
d3d_device7_GetRenderTarget(IDirect3DDevice7
*iface
, IDirectDrawSurface7
**RenderTarget
)
2016 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
2019 TRACE("iface %p, target %p.\n", iface
, RenderTarget
);
2022 return DDERR_INVALIDPARAMS
;
2024 wined3d_mutex_lock();
2025 hr
= IUnknown_QueryInterface(device
->rt_iface
, &IID_IDirectDrawSurface7
, (void **)RenderTarget
);
2026 wined3d_mutex_unlock();
2031 static HRESULT WINAPI
d3d_device3_GetRenderTarget(IDirect3DDevice3
*iface
, IDirectDrawSurface4
**RenderTarget
)
2033 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
2034 IDirectDrawSurface7
*RenderTarget7
;
2035 struct ddraw_surface
*RenderTargetImpl
;
2038 TRACE("iface %p, target %p.\n", iface
, RenderTarget
);
2041 return DDERR_INVALIDPARAMS
;
2043 hr
= d3d_device7_GetRenderTarget(&device
->IDirect3DDevice7_iface
, &RenderTarget7
);
2044 if(hr
!= D3D_OK
) return hr
;
2045 RenderTargetImpl
= impl_from_IDirectDrawSurface7(RenderTarget7
);
2046 *RenderTarget
= &RenderTargetImpl
->IDirectDrawSurface4_iface
;
2047 IDirectDrawSurface4_AddRef(*RenderTarget
);
2048 IDirectDrawSurface7_Release(RenderTarget7
);
2052 static HRESULT WINAPI
d3d_device2_GetRenderTarget(IDirect3DDevice2
*iface
, IDirectDrawSurface
**RenderTarget
)
2054 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
2055 IDirectDrawSurface7
*RenderTarget7
;
2056 struct ddraw_surface
*RenderTargetImpl
;
2059 TRACE("iface %p, target %p.\n", iface
, RenderTarget
);
2062 return DDERR_INVALIDPARAMS
;
2064 hr
= d3d_device7_GetRenderTarget(&device
->IDirect3DDevice7_iface
, &RenderTarget7
);
2065 if(hr
!= D3D_OK
) return hr
;
2066 RenderTargetImpl
= impl_from_IDirectDrawSurface7(RenderTarget7
);
2067 *RenderTarget
= &RenderTargetImpl
->IDirectDrawSurface_iface
;
2068 IDirectDrawSurface_AddRef(*RenderTarget
);
2069 IDirectDrawSurface7_Release(RenderTarget7
);
2073 /*****************************************************************************
2074 * IDirect3DDevice3::Begin
2076 * Begins a description block of vertices. This is similar to glBegin()
2077 * and glEnd(). After a call to IDirect3DDevice3::End, the vertices
2078 * described with IDirect3DDevice::Vertex are drawn.
2083 * PrimitiveType: The type of primitives to draw
2084 * VertexTypeDesc: A flexible vertex format description of the vertices
2085 * Flags: Some flags..
2090 *****************************************************************************/
2091 static HRESULT WINAPI
d3d_device3_Begin(IDirect3DDevice3
*iface
,
2092 D3DPRIMITIVETYPE primitive_type
, DWORD fvf
, DWORD flags
)
2094 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
2096 TRACE("iface %p, primitive_type %#x, fvf %#x, flags %#x.\n",
2097 iface
, primitive_type
, fvf
, flags
);
2099 wined3d_mutex_lock();
2100 device
->primitive_type
= primitive_type
;
2101 device
->vertex_type
= fvf
;
2102 device
->render_flags
= flags
;
2103 device
->vertex_size
= get_flexible_vertex_size(device
->vertex_type
);
2104 device
->nb_vertices
= 0;
2105 wined3d_mutex_unlock();
2110 static HRESULT WINAPI
d3d_device2_Begin(IDirect3DDevice2
*iface
,
2111 D3DPRIMITIVETYPE primitive_type
, D3DVERTEXTYPE vertex_type
, DWORD flags
)
2113 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
2116 TRACE("iface %p, primitive_type %#x, vertex_type %#x, flags %#x.\n",
2117 iface
, primitive_type
, vertex_type
, flags
);
2119 switch (vertex_type
)
2121 case D3DVT_VERTEX
: fvf
= D3DFVF_VERTEX
; break;
2122 case D3DVT_LVERTEX
: fvf
= D3DFVF_LVERTEX
; break;
2123 case D3DVT_TLVERTEX
: fvf
= D3DFVF_TLVERTEX
; break;
2125 ERR("Unexpected vertex type %#x.\n", vertex_type
);
2126 return DDERR_INVALIDPARAMS
; /* Should never happen */
2129 return d3d_device3_Begin(&device
->IDirect3DDevice3_iface
, primitive_type
, fvf
, flags
);
2132 /*****************************************************************************
2133 * IDirect3DDevice3::BeginIndexed
2135 * Draws primitives based on vertices in a vertex array which are specified
2141 * PrimitiveType: Primitive type to draw
2142 * VertexType: A FVF description of the vertex format
2143 * Vertices: pointer to an array containing the vertices
2144 * NumVertices: The number of vertices in the vertex array
2145 * Flags: Some flags ...
2148 * D3D_OK, because it's a stub
2150 *****************************************************************************/
2151 static HRESULT WINAPI
d3d_device3_BeginIndexed(IDirect3DDevice3
*iface
,
2152 D3DPRIMITIVETYPE primitive_type
, DWORD fvf
,
2153 void *vertices
, DWORD vertex_count
, DWORD flags
)
2155 FIXME("iface %p, primitive_type %#x, fvf %#x, vertices %p, vertex_count %u, flags %#x stub!\n",
2156 iface
, primitive_type
, fvf
, vertices
, vertex_count
, flags
);
2162 static HRESULT WINAPI
d3d_device2_BeginIndexed(IDirect3DDevice2
*iface
,
2163 D3DPRIMITIVETYPE primitive_type
, D3DVERTEXTYPE vertex_type
,
2164 void *vertices
, DWORD vertex_count
, DWORD flags
)
2166 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
2169 TRACE("iface %p, primitive_type %#x, vertex_type %#x, vertices %p, vertex_count %u, flags %#x stub!\n",
2170 iface
, primitive_type
, vertex_type
, vertices
, vertex_count
, flags
);
2172 switch (vertex_type
)
2174 case D3DVT_VERTEX
: fvf
= D3DFVF_VERTEX
; break;
2175 case D3DVT_LVERTEX
: fvf
= D3DFVF_LVERTEX
; break;
2176 case D3DVT_TLVERTEX
: fvf
= D3DFVF_TLVERTEX
; break;
2178 ERR("Unexpected vertex type %#x.\n", vertex_type
);
2179 return DDERR_INVALIDPARAMS
; /* Should never happen */
2182 return d3d_device3_BeginIndexed(&device
->IDirect3DDevice3_iface
,
2183 primitive_type
, fvf
, vertices
, vertex_count
, flags
);
2186 /*****************************************************************************
2187 * IDirect3DDevice3::Vertex
2189 * Draws a vertex as described by IDirect3DDevice3::Begin. It places all
2190 * drawn vertices in a vertex buffer. If the buffer is too small, its
2191 * size is increased.
2196 * Vertex: Pointer to the vertex
2199 * D3D_OK, on success
2200 * DDERR_INVALIDPARAMS if Vertex is NULL
2202 *****************************************************************************/
2203 static HRESULT WINAPI
d3d_device3_Vertex(IDirect3DDevice3
*iface
, void *vertex
)
2205 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
2207 TRACE("iface %p, vertex %p.\n", iface
, vertex
);
2210 return DDERR_INVALIDPARAMS
;
2212 wined3d_mutex_lock();
2213 if ((device
->nb_vertices
+ 1) * device
->vertex_size
> device
->buffer_size
)
2217 device
->buffer_size
= device
->buffer_size
? device
->buffer_size
* 2 : device
->vertex_size
* 3;
2218 old_buffer
= device
->sysmem_vertex_buffer
;
2219 device
->sysmem_vertex_buffer
= HeapAlloc(GetProcessHeap(), 0, device
->buffer_size
);
2222 memcpy(device
->sysmem_vertex_buffer
, old_buffer
, device
->nb_vertices
* device
->vertex_size
);
2223 HeapFree(GetProcessHeap(), 0, old_buffer
);
2227 memcpy(device
->sysmem_vertex_buffer
+ device
->nb_vertices
++ * device
->vertex_size
, vertex
, device
->vertex_size
);
2228 wined3d_mutex_unlock();
2233 static HRESULT WINAPI
d3d_device2_Vertex(IDirect3DDevice2
*iface
, void *vertex
)
2235 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
2237 TRACE("iface %p, vertex %p.\n", iface
, vertex
);
2239 return d3d_device3_Vertex(&device
->IDirect3DDevice3_iface
, vertex
);
2242 /*****************************************************************************
2243 * IDirect3DDevice3::Index
2245 * Specifies an index to a vertex to be drawn. The vertex array has to
2246 * be specified with BeginIndexed first.
2249 * VertexIndex: The index of the vertex to draw
2252 * D3D_OK because it's a stub
2254 *****************************************************************************/
2255 static HRESULT WINAPI
d3d_device3_Index(IDirect3DDevice3
*iface
, WORD index
)
2257 FIXME("iface %p, index %#x stub!\n", iface
, index
);
2262 static HRESULT WINAPI
d3d_device2_Index(IDirect3DDevice2
*iface
, WORD index
)
2264 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
2266 TRACE("iface %p, index %#x.\n", iface
, index
);
2268 return d3d_device3_Index(&device
->IDirect3DDevice3_iface
, index
);
2271 /*****************************************************************************
2272 * IDirect3DDevice7::GetRenderState
2274 * Returns the value of a render state. The possible render states are
2275 * defined in include/d3dtypes.h
2277 * Version 2, 3 and 7
2280 * RenderStateType: Render state to return the current setting of
2281 * Value: Address to store the value at
2284 * D3D_OK on success, for details see IWineD3DDevice::GetRenderState
2285 * DDERR_INVALIDPARAMS if Value == NULL
2287 *****************************************************************************/
2288 static HRESULT
d3d_device7_GetRenderState(IDirect3DDevice7
*iface
,
2289 D3DRENDERSTATETYPE state
, DWORD
*value
)
2291 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
2292 HRESULT hr
= D3D_OK
;
2294 TRACE("iface %p, state %#x, value %p.\n", iface
, state
, value
);
2297 return DDERR_INVALIDPARAMS
;
2299 wined3d_mutex_lock();
2302 case D3DRENDERSTATE_TEXTUREMAG
:
2304 enum wined3d_texture_filter_type tex_mag
;
2306 tex_mag
= wined3d_device_get_sampler_state(device
->wined3d_device
, 0, WINED3D_SAMP_MAG_FILTER
);
2309 case WINED3D_TEXF_POINT
:
2310 *value
= D3DFILTER_NEAREST
;
2312 case WINED3D_TEXF_LINEAR
:
2313 *value
= D3DFILTER_LINEAR
;
2316 ERR("Unhandled texture mag %d !\n",tex_mag
);
2322 case D3DRENDERSTATE_TEXTUREMIN
:
2324 enum wined3d_texture_filter_type tex_min
;
2325 enum wined3d_texture_filter_type tex_mip
;
2327 tex_min
= wined3d_device_get_sampler_state(device
->wined3d_device
, 0, WINED3D_SAMP_MIN_FILTER
);
2328 tex_mip
= wined3d_device_get_sampler_state(device
->wined3d_device
, 0, WINED3D_SAMP_MIP_FILTER
);
2331 case WINED3D_TEXF_POINT
:
2334 case WINED3D_TEXF_NONE
:
2335 *value
= D3DFILTER_NEAREST
;
2337 case WINED3D_TEXF_POINT
:
2338 *value
= D3DFILTER_MIPNEAREST
;
2340 case WINED3D_TEXF_LINEAR
:
2341 *value
= D3DFILTER_LINEARMIPNEAREST
;
2344 ERR("Unhandled mip filter %#x.\n", tex_mip
);
2345 *value
= D3DFILTER_NEAREST
;
2349 case WINED3D_TEXF_LINEAR
:
2352 case WINED3D_TEXF_NONE
:
2353 *value
= D3DFILTER_LINEAR
;
2355 case WINED3D_TEXF_POINT
:
2356 *value
= D3DFILTER_MIPLINEAR
;
2358 case WINED3D_TEXF_LINEAR
:
2359 *value
= D3DFILTER_LINEARMIPLINEAR
;
2362 ERR("Unhandled mip filter %#x.\n", tex_mip
);
2363 *value
= D3DFILTER_LINEAR
;
2368 ERR("Unhandled texture min filter %#x.\n",tex_min
);
2369 *value
= D3DFILTER_NEAREST
;
2375 case D3DRENDERSTATE_TEXTUREADDRESS
:
2376 case D3DRENDERSTATE_TEXTUREADDRESSU
:
2377 *value
= wined3d_device_get_sampler_state(device
->wined3d_device
, 0, WINED3D_SAMP_ADDRESS_U
);
2379 case D3DRENDERSTATE_TEXTUREADDRESSV
:
2380 *value
= wined3d_device_get_sampler_state(device
->wined3d_device
, 0, WINED3D_SAMP_ADDRESS_V
);
2383 case D3DRENDERSTATE_BORDERCOLOR
:
2384 FIXME("Unhandled render state D3DRENDERSTATE_BORDERCOLOR.\n");
2388 case D3DRENDERSTATE_TEXTUREHANDLE
:
2389 case D3DRENDERSTATE_TEXTUREMAPBLEND
:
2390 WARN("Render state %#x is invalid in d3d7.\n", state
);
2391 hr
= DDERR_INVALIDPARAMS
;
2394 case D3DRENDERSTATE_ZBIAS
:
2395 *value
= wined3d_device_get_render_state(device
->wined3d_device
, WINED3D_RS_DEPTHBIAS
);
2399 if (state
>= D3DRENDERSTATE_STIPPLEPATTERN00
2400 && state
<= D3DRENDERSTATE_STIPPLEPATTERN31
)
2402 FIXME("Unhandled stipple pattern render state (%#x).\n", state
);
2406 *value
= wined3d_device_get_render_state(device
->wined3d_device
, state
);
2408 wined3d_mutex_unlock();
2413 static HRESULT WINAPI
d3d_device7_GetRenderState_FPUSetup(IDirect3DDevice7
*iface
,
2414 D3DRENDERSTATETYPE state
, DWORD
*value
)
2416 return d3d_device7_GetRenderState(iface
, state
, value
);
2419 static HRESULT WINAPI
d3d_device7_GetRenderState_FPUPreserve(IDirect3DDevice7
*iface
,
2420 D3DRENDERSTATETYPE state
, DWORD
*value
)
2425 old_fpucw
= d3d_fpu_setup();
2426 hr
= d3d_device7_GetRenderState(iface
, state
, value
);
2427 set_fpu_control_word(old_fpucw
);
2432 static HRESULT WINAPI
d3d_device3_GetRenderState(IDirect3DDevice3
*iface
,
2433 D3DRENDERSTATETYPE state
, DWORD
*value
)
2435 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
2437 TRACE("iface %p, state %#x, value %p.\n", iface
, state
, value
);
2441 case D3DRENDERSTATE_TEXTUREHANDLE
:
2443 /* This state is wrapped to SetTexture in SetRenderState, so
2444 * it has to be wrapped to GetTexture here. */
2445 struct wined3d_texture
*tex
= NULL
;
2448 wined3d_mutex_lock();
2449 if ((tex
= wined3d_device_get_texture(device
->wined3d_device
, 0)))
2451 /* The parent of the texture is the IDirectDrawSurface7
2452 * interface of the ddraw surface. */
2453 struct ddraw_texture
*parent
= wined3d_texture_get_parent(tex
);
2455 *value
= parent
->root
->Handle
;
2457 wined3d_mutex_unlock();
2462 case D3DRENDERSTATE_TEXTUREMAPBLEND
:
2464 /* D3DRENDERSTATE_TEXTUREMAPBLEND is mapped to texture state stages in SetRenderState; reverse
2465 the mapping to get the value. */
2466 DWORD colorop
, colorarg1
, colorarg2
;
2467 DWORD alphaop
, alphaarg1
, alphaarg2
;
2469 wined3d_mutex_lock();
2471 device
->legacyTextureBlending
= TRUE
;
2473 colorop
= wined3d_device_get_texture_stage_state(device
->wined3d_device
, 0, WINED3D_TSS_COLOR_OP
);
2474 colorarg1
= wined3d_device_get_texture_stage_state(device
->wined3d_device
, 0, WINED3D_TSS_COLOR_ARG1
);
2475 colorarg2
= wined3d_device_get_texture_stage_state(device
->wined3d_device
, 0, WINED3D_TSS_COLOR_ARG2
);
2476 alphaop
= wined3d_device_get_texture_stage_state(device
->wined3d_device
, 0, WINED3D_TSS_ALPHA_OP
);
2477 alphaarg1
= wined3d_device_get_texture_stage_state(device
->wined3d_device
, 0, WINED3D_TSS_ALPHA_ARG1
);
2478 alphaarg2
= wined3d_device_get_texture_stage_state(device
->wined3d_device
, 0, WINED3D_TSS_ALPHA_ARG2
);
2480 if (colorop
== WINED3D_TOP_SELECT_ARG1
&& colorarg1
== WINED3DTA_TEXTURE
2481 && alphaop
== WINED3D_TOP_SELECT_ARG1
&& alphaarg1
== WINED3DTA_TEXTURE
)
2482 *value
= D3DTBLEND_DECAL
;
2483 else if (colorop
== WINED3D_TOP_SELECT_ARG1
&& colorarg1
== WINED3DTA_TEXTURE
2484 && alphaop
== WINED3D_TOP_MODULATE
2485 && alphaarg1
== WINED3DTA_TEXTURE
&& alphaarg2
== WINED3DTA_CURRENT
)
2486 *value
= D3DTBLEND_DECALALPHA
;
2487 else if (colorop
== WINED3D_TOP_MODULATE
2488 && colorarg1
== WINED3DTA_TEXTURE
&& colorarg2
== WINED3DTA_CURRENT
2489 && alphaop
== WINED3D_TOP_MODULATE
2490 && alphaarg1
== WINED3DTA_TEXTURE
&& alphaarg2
== WINED3DTA_CURRENT
)
2491 *value
= D3DTBLEND_MODULATEALPHA
;
2494 struct wined3d_texture
*tex
= NULL
;
2495 BOOL tex_alpha
= FALSE
;
2496 DDPIXELFORMAT ddfmt
;
2498 if ((tex
= wined3d_device_get_texture(device
->wined3d_device
, 0)))
2500 struct wined3d_resource
*sub_resource
;
2502 if ((sub_resource
= wined3d_texture_get_sub_resource(tex
, 0)))
2504 struct wined3d_resource_desc desc
;
2506 wined3d_resource_get_desc(sub_resource
, &desc
);
2507 ddfmt
.dwSize
= sizeof(ddfmt
);
2508 ddrawformat_from_wined3dformat(&ddfmt
, desc
.format
);
2509 if (ddfmt
.u5
.dwRGBAlphaBitMask
) tex_alpha
= TRUE
;
2513 if (!(colorop
== WINED3D_TOP_MODULATE
2514 && colorarg1
== WINED3DTA_TEXTURE
&& colorarg2
== WINED3DTA_CURRENT
2515 && alphaop
== (tex_alpha
? WINED3D_TOP_SELECT_ARG1
: WINED3D_TOP_SELECT_ARG2
)
2516 && alphaarg1
== WINED3DTA_TEXTURE
&& alphaarg2
== WINED3DTA_CURRENT
))
2517 ERR("Unexpected texture stage state setup, returning D3DTBLEND_MODULATE - likely erroneous.\n");
2519 *value
= D3DTBLEND_MODULATE
;
2522 wined3d_mutex_unlock();
2527 case D3DRENDERSTATE_LIGHTING
:
2528 *value
= 0xffffffff;
2532 return IDirect3DDevice7_GetRenderState(&device
->IDirect3DDevice7_iface
, state
, value
);
2536 static HRESULT WINAPI
d3d_device2_GetRenderState(IDirect3DDevice2
*iface
,
2537 D3DRENDERSTATETYPE state
, DWORD
*value
)
2539 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
2541 TRACE("iface %p, state %#x, value %p.\n", iface
, state
, value
);
2543 return IDirect3DDevice3_GetRenderState(&device
->IDirect3DDevice3_iface
, state
, value
);
2546 /*****************************************************************************
2547 * IDirect3DDevice7::SetRenderState
2549 * Sets a render state. The possible render states are defined in
2550 * include/d3dtypes.h
2552 * Version 2, 3 and 7
2555 * RenderStateType: State to set
2556 * Value: Value to assign to that state
2559 * D3D_OK on success,
2560 * for details see IWineD3DDevice::SetRenderState
2562 *****************************************************************************/
2563 static HRESULT
d3d_device7_SetRenderState(IDirect3DDevice7
*iface
,
2564 D3DRENDERSTATETYPE state
, DWORD value
)
2566 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
2567 HRESULT hr
= D3D_OK
;
2569 TRACE("iface %p, state %#x, value %#x.\n", iface
, state
, value
);
2571 wined3d_mutex_lock();
2572 /* Some render states need special care */
2576 * The ddraw texture filter mapping works like this:
2577 * D3DFILTER_NEAREST Point min/mag, no mip
2578 * D3DFILTER_MIPNEAREST Point min/mag, point mip
2579 * D3DFILTER_LINEARMIPNEAREST: Point min/mag, linear mip
2581 * D3DFILTER_LINEAR Linear min/mag, no mip
2582 * D3DFILTER_MIPLINEAR Linear min/mag, point mip
2583 * D3DFILTER_LINEARMIPLINEAR Linear min/mag, linear mip
2585 * This is the opposite of the GL naming convention,
2586 * D3DFILTER_LINEARMIPNEAREST corresponds to GL_NEAREST_MIPMAP_LINEAR.
2588 case D3DRENDERSTATE_TEXTUREMAG
:
2590 enum wined3d_texture_filter_type tex_mag
;
2594 case D3DFILTER_NEAREST
:
2595 case D3DFILTER_MIPNEAREST
:
2596 case D3DFILTER_LINEARMIPNEAREST
:
2597 tex_mag
= WINED3D_TEXF_POINT
;
2599 case D3DFILTER_LINEAR
:
2600 case D3DFILTER_MIPLINEAR
:
2601 case D3DFILTER_LINEARMIPLINEAR
:
2602 tex_mag
= WINED3D_TEXF_LINEAR
;
2605 tex_mag
= WINED3D_TEXF_POINT
;
2606 FIXME("Unhandled texture mag %#x.\n", value
);
2610 wined3d_device_set_sampler_state(device
->wined3d_device
, 0, WINED3D_SAMP_MAG_FILTER
, tex_mag
);
2614 case D3DRENDERSTATE_TEXTUREMIN
:
2616 enum wined3d_texture_filter_type tex_min
;
2617 enum wined3d_texture_filter_type tex_mip
;
2621 case D3DFILTER_NEAREST
:
2622 tex_min
= WINED3D_TEXF_POINT
;
2623 tex_mip
= WINED3D_TEXF_NONE
;
2625 case D3DFILTER_LINEAR
:
2626 tex_min
= WINED3D_TEXF_LINEAR
;
2627 tex_mip
= WINED3D_TEXF_NONE
;
2629 case D3DFILTER_MIPNEAREST
:
2630 tex_min
= WINED3D_TEXF_POINT
;
2631 tex_mip
= WINED3D_TEXF_POINT
;
2633 case D3DFILTER_MIPLINEAR
:
2634 tex_min
= WINED3D_TEXF_LINEAR
;
2635 tex_mip
= WINED3D_TEXF_POINT
;
2637 case D3DFILTER_LINEARMIPNEAREST
:
2638 tex_min
= WINED3D_TEXF_POINT
;
2639 tex_mip
= WINED3D_TEXF_LINEAR
;
2641 case D3DFILTER_LINEARMIPLINEAR
:
2642 tex_min
= WINED3D_TEXF_LINEAR
;
2643 tex_mip
= WINED3D_TEXF_LINEAR
;
2647 FIXME("Unhandled texture min %#x.\n",value
);
2648 tex_min
= WINED3D_TEXF_POINT
;
2649 tex_mip
= WINED3D_TEXF_NONE
;
2653 wined3d_device_set_sampler_state(device
->wined3d_device
,
2654 0, WINED3D_SAMP_MIP_FILTER
, tex_mip
);
2655 wined3d_device_set_sampler_state(device
->wined3d_device
,
2656 0, WINED3D_SAMP_MIN_FILTER
, tex_min
);
2660 case D3DRENDERSTATE_TEXTUREADDRESS
:
2661 wined3d_device_set_sampler_state(device
->wined3d_device
,
2662 0, WINED3D_SAMP_ADDRESS_V
, value
);
2664 case D3DRENDERSTATE_TEXTUREADDRESSU
:
2665 wined3d_device_set_sampler_state(device
->wined3d_device
,
2666 0, WINED3D_SAMP_ADDRESS_U
, value
);
2668 case D3DRENDERSTATE_TEXTUREADDRESSV
:
2669 wined3d_device_set_sampler_state(device
->wined3d_device
,
2670 0, WINED3D_SAMP_ADDRESS_V
, value
);
2673 case D3DRENDERSTATE_BORDERCOLOR
:
2674 /* This should probably just forward to the corresponding sampler
2675 * state. Needs tests. */
2676 FIXME("Unhandled render state D3DRENDERSTATE_BORDERCOLOR.\n");
2680 case D3DRENDERSTATE_TEXTUREHANDLE
:
2681 case D3DRENDERSTATE_TEXTUREMAPBLEND
:
2682 WARN("Render state %#x is invalid in d3d7.\n", state
);
2683 hr
= DDERR_INVALIDPARAMS
;
2686 case D3DRENDERSTATE_ZBIAS
:
2687 wined3d_device_set_render_state(device
->wined3d_device
, WINED3D_RS_DEPTHBIAS
, value
);
2691 if (state
>= D3DRENDERSTATE_STIPPLEPATTERN00
2692 && state
<= D3DRENDERSTATE_STIPPLEPATTERN31
)
2694 FIXME("Unhandled stipple pattern render state (%#x).\n", state
);
2699 wined3d_device_set_render_state(device
->wined3d_device
, state
, value
);
2702 wined3d_mutex_unlock();
2707 static HRESULT WINAPI
d3d_device7_SetRenderState_FPUSetup(IDirect3DDevice7
*iface
,
2708 D3DRENDERSTATETYPE state
, DWORD value
)
2710 return d3d_device7_SetRenderState(iface
, state
, value
);
2713 static HRESULT WINAPI
d3d_device7_SetRenderState_FPUPreserve(IDirect3DDevice7
*iface
,
2714 D3DRENDERSTATETYPE state
, DWORD value
)
2719 old_fpucw
= d3d_fpu_setup();
2720 hr
= d3d_device7_SetRenderState(iface
, state
, value
);
2721 set_fpu_control_word(old_fpucw
);
2726 static HRESULT WINAPI
d3d_device3_SetRenderState(IDirect3DDevice3
*iface
,
2727 D3DRENDERSTATETYPE state
, DWORD value
)
2729 /* Note about D3DRENDERSTATE_TEXTUREMAPBLEND implementation: most of values
2730 for this state can be directly mapped to texture stage colorop and alphaop, but
2731 D3DTBLEND_MODULATE is tricky: it uses alpha from texture when available and alpha
2732 from diffuse otherwise. So changing the texture must be monitored in SetTexture to modify
2733 alphaarg when needed.
2735 Aliens vs Predator 1 depends on accurate D3DTBLEND_MODULATE emulation
2737 Legacy texture blending (TEXTUREMAPBLEND) and texture stage states: directx6 docs state that
2738 TEXTUREMAPBLEND is deprecated, yet can still be used. Games must not use both or results
2739 are undefined. D3DTBLEND_MODULATE mode in particular is dependent on texture pixel format and
2740 requires fixup of stage 0 texture states when texture changes, but this fixup can interfere
2741 with games not using this deprecated state. So a flag 'legacyTextureBlending' has to be kept
2742 in device - TRUE if the app is using TEXTUREMAPBLEND.
2744 Tests show that setting TEXTUREMAPBLEND on native doesn't seem to change values returned by
2745 GetTextureStageState and vice versa. Not so on Wine, but it is 'undefined' anyway so, probably, ok,
2746 unless some broken game will be found that cares. */
2748 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
2751 TRACE("iface %p, state %#x, value %#x.\n", iface
, state
, value
);
2753 wined3d_mutex_lock();
2757 case D3DRENDERSTATE_TEXTUREHANDLE
:
2759 struct ddraw_surface
*surf
;
2763 hr
= wined3d_device_set_texture(device
->wined3d_device
, 0, NULL
);
2767 surf
= ddraw_get_object(&device
->handle_table
, value
- 1, DDRAW_HANDLE_SURFACE
);
2770 WARN("Invalid texture handle.\n");
2771 hr
= DDERR_INVALIDPARAMS
;
2775 hr
= IDirect3DDevice3_SetTexture(iface
, 0, &surf
->IDirect3DTexture2_iface
);
2779 case D3DRENDERSTATE_TEXTUREMAPBLEND
:
2781 device
->legacyTextureBlending
= TRUE
;
2785 case D3DTBLEND_MODULATE
:
2787 struct wined3d_texture
*tex
= NULL
;
2788 BOOL tex_alpha
= FALSE
;
2789 DDPIXELFORMAT ddfmt
;
2791 if ((tex
= wined3d_device_get_texture(device
->wined3d_device
, 0)))
2793 struct wined3d_resource
*sub_resource
;
2795 if ((sub_resource
= wined3d_texture_get_sub_resource(tex
, 0)))
2797 struct wined3d_resource_desc desc
;
2799 wined3d_resource_get_desc(sub_resource
, &desc
);
2800 ddfmt
.dwSize
= sizeof(ddfmt
);
2801 ddrawformat_from_wined3dformat(&ddfmt
, desc
.format
);
2802 if (ddfmt
.u5
.dwRGBAlphaBitMask
) tex_alpha
= TRUE
;
2807 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2808 0, WINED3D_TSS_ALPHA_OP
, WINED3D_TOP_SELECT_ARG1
);
2810 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2811 0, WINED3D_TSS_ALPHA_OP
, WINED3D_TOP_SELECT_ARG2
);
2812 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2813 0, WINED3D_TSS_ALPHA_ARG1
, WINED3DTA_TEXTURE
);
2814 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2815 0, WINED3D_TSS_ALPHA_ARG2
, WINED3DTA_CURRENT
);
2816 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2817 0, WINED3D_TSS_COLOR_ARG1
, WINED3DTA_TEXTURE
);
2818 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2819 0, WINED3D_TSS_COLOR_ARG2
, WINED3DTA_CURRENT
);
2820 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2821 0, WINED3D_TSS_COLOR_OP
, WINED3D_TOP_MODULATE
);
2826 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2827 0, WINED3D_TSS_COLOR_OP
, WINED3D_TOP_ADD
);
2828 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2829 0, WINED3D_TSS_COLOR_ARG1
, WINED3DTA_TEXTURE
);
2830 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2831 0, WINED3D_TSS_COLOR_ARG2
, WINED3DTA_CURRENT
);
2832 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2833 0, WINED3D_TSS_ALPHA_OP
, WINED3D_TOP_SELECT_ARG2
);
2834 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2835 0, WINED3D_TSS_ALPHA_ARG2
, WINED3DTA_CURRENT
);
2838 case D3DTBLEND_MODULATEALPHA
:
2839 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2840 0, WINED3D_TSS_COLOR_ARG1
, WINED3DTA_TEXTURE
);
2841 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2842 0, WINED3D_TSS_ALPHA_ARG1
, WINED3DTA_TEXTURE
);
2843 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2844 0, WINED3D_TSS_COLOR_ARG2
, WINED3DTA_CURRENT
);
2845 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2846 0, WINED3D_TSS_ALPHA_ARG2
, WINED3DTA_CURRENT
);
2847 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2848 0, WINED3D_TSS_COLOR_OP
, WINED3D_TOP_MODULATE
);
2849 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2850 0, WINED3D_TSS_ALPHA_OP
, WINED3D_TOP_MODULATE
);
2853 case D3DTBLEND_COPY
:
2854 case D3DTBLEND_DECAL
:
2855 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2856 0, WINED3D_TSS_COLOR_ARG1
, WINED3DTA_TEXTURE
);
2857 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2858 0, WINED3D_TSS_ALPHA_ARG1
, WINED3DTA_TEXTURE
);
2859 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2860 0, WINED3D_TSS_COLOR_OP
, WINED3D_TOP_SELECT_ARG1
);
2861 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2862 0, WINED3D_TSS_ALPHA_OP
, WINED3D_TOP_SELECT_ARG1
);
2865 case D3DTBLEND_DECALALPHA
:
2866 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2867 0, WINED3D_TSS_COLOR_OP
, WINED3D_TOP_BLEND_TEXTURE_ALPHA
);
2868 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2869 0, WINED3D_TSS_COLOR_ARG1
, WINED3DTA_TEXTURE
);
2870 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2871 0, WINED3D_TSS_COLOR_ARG2
, WINED3DTA_CURRENT
);
2872 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2873 0, WINED3D_TSS_ALPHA_OP
, WINED3D_TOP_SELECT_ARG2
);
2874 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2875 0, WINED3D_TSS_ALPHA_ARG2
, WINED3DTA_CURRENT
);
2879 FIXME("Unhandled texture environment %#x.\n", value
);
2886 case D3DRENDERSTATE_LIGHTING
:
2891 hr
= IDirect3DDevice7_SetRenderState(&device
->IDirect3DDevice7_iface
, state
, value
);
2894 wined3d_mutex_unlock();
2899 static HRESULT WINAPI
d3d_device2_SetRenderState(IDirect3DDevice2
*iface
,
2900 D3DRENDERSTATETYPE state
, DWORD value
)
2902 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
2904 TRACE("iface %p, state %#x, value %#x.\n", iface
, state
, value
);
2906 return IDirect3DDevice3_SetRenderState(&device
->IDirect3DDevice3_iface
, state
, value
);
2909 /*****************************************************************************
2910 * Direct3DDevice3::SetLightState
2912 * Sets a light state for Direct3DDevice3 and Direct3DDevice2. The
2913 * light states are forwarded to Direct3DDevice7 render states
2918 * LightStateType: The light state to change
2919 * Value: The value to assign to that light state
2923 * DDERR_INVALIDPARAMS if the parameters were incorrect
2924 * Also check IDirect3DDevice7::SetRenderState
2926 *****************************************************************************/
2927 static HRESULT WINAPI
d3d_device3_SetLightState(IDirect3DDevice3
*iface
,
2928 D3DLIGHTSTATETYPE state
, DWORD value
)
2930 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
2933 TRACE("iface %p, state %#x, value %#x.\n", iface
, state
, value
);
2935 if (!state
|| (state
> D3DLIGHTSTATE_COLORVERTEX
))
2937 TRACE("Unexpected Light State Type\n");
2938 return DDERR_INVALIDPARAMS
;
2941 wined3d_mutex_lock();
2942 if (state
== D3DLIGHTSTATE_MATERIAL
)
2946 struct d3d_material
*m
;
2948 if (!(m
= ddraw_get_object(&device
->handle_table
, value
- 1, DDRAW_HANDLE_MATERIAL
)))
2950 WARN("Invalid material handle.\n");
2951 wined3d_mutex_unlock();
2952 return DDERR_INVALIDPARAMS
;
2955 material_activate(m
);
2958 device
->material
= value
;
2960 else if (state
== D3DLIGHTSTATE_COLORMODEL
)
2965 ERR("DDCOLOR_MONO should not happen!\n");
2968 /* We are already in this mode */
2969 TRACE("Setting color model to RGB (no-op).\n");
2972 ERR("Unknown color model!\n");
2973 wined3d_mutex_unlock();
2974 return DDERR_INVALIDPARAMS
;
2979 D3DRENDERSTATETYPE rs
;
2982 case D3DLIGHTSTATE_AMBIENT
: /* 2 */
2983 rs
= D3DRENDERSTATE_AMBIENT
;
2985 case D3DLIGHTSTATE_FOGMODE
: /* 4 */
2986 rs
= D3DRENDERSTATE_FOGVERTEXMODE
;
2988 case D3DLIGHTSTATE_FOGSTART
: /* 5 */
2989 rs
= D3DRENDERSTATE_FOGSTART
;
2991 case D3DLIGHTSTATE_FOGEND
: /* 6 */
2992 rs
= D3DRENDERSTATE_FOGEND
;
2994 case D3DLIGHTSTATE_FOGDENSITY
: /* 7 */
2995 rs
= D3DRENDERSTATE_FOGDENSITY
;
2997 case D3DLIGHTSTATE_COLORVERTEX
: /* 8 */
2998 rs
= D3DRENDERSTATE_COLORVERTEX
;
3001 FIXME("Unhandled D3DLIGHTSTATETYPE %#x.\n", state
);
3002 wined3d_mutex_unlock();
3003 return DDERR_INVALIDPARAMS
;
3006 hr
= IDirect3DDevice7_SetRenderState(&device
->IDirect3DDevice7_iface
, rs
, value
);
3007 wined3d_mutex_unlock();
3010 wined3d_mutex_unlock();
3015 static HRESULT WINAPI
d3d_device2_SetLightState(IDirect3DDevice2
*iface
,
3016 D3DLIGHTSTATETYPE state
, DWORD value
)
3018 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
3020 TRACE("iface %p, state %#x, value %#x.\n", iface
, state
, value
);
3022 return d3d_device3_SetLightState(&device
->IDirect3DDevice3_iface
, state
, value
);
3025 /*****************************************************************************
3026 * IDirect3DDevice3::GetLightState
3028 * Returns the current setting of a light state. The state is read from
3029 * the Direct3DDevice7 render state.
3034 * LightStateType: The light state to return
3035 * Value: The address to store the light state setting at
3039 * DDDERR_INVALIDPARAMS if the parameters were incorrect
3040 * Also see IDirect3DDevice7::GetRenderState
3042 *****************************************************************************/
3043 static HRESULT WINAPI
d3d_device3_GetLightState(IDirect3DDevice3
*iface
,
3044 D3DLIGHTSTATETYPE state
, DWORD
*value
)
3046 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
3049 TRACE("iface %p, state %#x, value %p.\n", iface
, state
, value
);
3051 if (!state
|| (state
> D3DLIGHTSTATE_COLORVERTEX
))
3053 TRACE("Unexpected Light State Type\n");
3054 return DDERR_INVALIDPARAMS
;
3058 return DDERR_INVALIDPARAMS
;
3060 wined3d_mutex_lock();
3061 if (state
== D3DLIGHTSTATE_MATERIAL
)
3063 *value
= device
->material
;
3065 else if (state
== D3DLIGHTSTATE_COLORMODEL
)
3067 *value
= D3DCOLOR_RGB
;
3071 D3DRENDERSTATETYPE rs
;
3074 case D3DLIGHTSTATE_AMBIENT
: /* 2 */
3075 rs
= D3DRENDERSTATE_AMBIENT
;
3077 case D3DLIGHTSTATE_FOGMODE
: /* 4 */
3078 rs
= D3DRENDERSTATE_FOGVERTEXMODE
;
3080 case D3DLIGHTSTATE_FOGSTART
: /* 5 */
3081 rs
= D3DRENDERSTATE_FOGSTART
;
3083 case D3DLIGHTSTATE_FOGEND
: /* 6 */
3084 rs
= D3DRENDERSTATE_FOGEND
;
3086 case D3DLIGHTSTATE_FOGDENSITY
: /* 7 */
3087 rs
= D3DRENDERSTATE_FOGDENSITY
;
3089 case D3DLIGHTSTATE_COLORVERTEX
: /* 8 */
3090 rs
= D3DRENDERSTATE_COLORVERTEX
;
3093 FIXME("Unhandled D3DLIGHTSTATETYPE %#x.\n", state
);
3094 wined3d_mutex_unlock();
3095 return DDERR_INVALIDPARAMS
;
3098 hr
= IDirect3DDevice7_GetRenderState(&device
->IDirect3DDevice7_iface
, rs
, value
);
3099 wined3d_mutex_unlock();
3102 wined3d_mutex_unlock();
3107 static HRESULT WINAPI
d3d_device2_GetLightState(IDirect3DDevice2
*iface
,
3108 D3DLIGHTSTATETYPE state
, DWORD
*value
)
3110 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
3112 TRACE("iface %p, state %#x, value %p.\n", iface
, state
, value
);
3114 return d3d_device3_GetLightState(&device
->IDirect3DDevice3_iface
, state
, value
);
3117 /*****************************************************************************
3118 * IDirect3DDevice7::SetTransform
3120 * Assigns a D3DMATRIX to a transform type. The transform types are defined
3121 * in include/d3dtypes.h.
3122 * The D3DTRANSFORMSTATE_WORLD (=1) is translated to D3DTS_WORLDMATRIX(0)
3123 * (=255) for wined3d, because the 1 transform state was removed in d3d8
3124 * and WineD3D already understands the replacement D3DTS_WORLDMATRIX(0)
3126 * Version 2, 3 and 7
3129 * TransformStateType: transform state to set
3130 * Matrix: Matrix to assign to the state
3134 * DDERR_INVALIDPARAMS if Matrix == NULL
3135 * For details see IWineD3DDevice::SetTransform
3137 *****************************************************************************/
3138 static HRESULT
d3d_device7_SetTransform(IDirect3DDevice7
*iface
,
3139 D3DTRANSFORMSTATETYPE state
, D3DMATRIX
*matrix
)
3141 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
3142 enum wined3d_transform_state wined3d_state
;
3144 TRACE("iface %p, state %#x, matrix %p.\n", iface
, state
, matrix
);
3148 case D3DTRANSFORMSTATE_WORLD
:
3149 wined3d_state
= WINED3D_TS_WORLD_MATRIX(0);
3151 case D3DTRANSFORMSTATE_WORLD1
:
3152 wined3d_state
= WINED3D_TS_WORLD_MATRIX(1);
3154 case D3DTRANSFORMSTATE_WORLD2
:
3155 wined3d_state
= WINED3D_TS_WORLD_MATRIX(2);
3157 case D3DTRANSFORMSTATE_WORLD3
:
3158 wined3d_state
= WINED3D_TS_WORLD_MATRIX(3);
3161 wined3d_state
= state
;
3165 return DDERR_INVALIDPARAMS
;
3167 /* Note: D3DMATRIX is compatible with struct wined3d_matrix. */
3168 wined3d_mutex_lock();
3169 wined3d_device_set_transform(device
->wined3d_device
, wined3d_state
, (struct wined3d_matrix
*)matrix
);
3170 wined3d_mutex_unlock();
3175 static HRESULT WINAPI
d3d_device7_SetTransform_FPUSetup(IDirect3DDevice7
*iface
,
3176 D3DTRANSFORMSTATETYPE state
, D3DMATRIX
*matrix
)
3178 return d3d_device7_SetTransform(iface
, state
, matrix
);
3181 static HRESULT WINAPI
d3d_device7_SetTransform_FPUPreserve(IDirect3DDevice7
*iface
,
3182 D3DTRANSFORMSTATETYPE state
, D3DMATRIX
*matrix
)
3187 old_fpucw
= d3d_fpu_setup();
3188 hr
= d3d_device7_SetTransform(iface
, state
, matrix
);
3189 set_fpu_control_word(old_fpucw
);
3194 static HRESULT WINAPI
d3d_device3_SetTransform(IDirect3DDevice3
*iface
,
3195 D3DTRANSFORMSTATETYPE state
, D3DMATRIX
*matrix
)
3197 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
3199 TRACE("iface %p, state %#x, matrix %p.\n", iface
, state
, matrix
);
3202 return DDERR_INVALIDPARAMS
;
3204 if (state
== D3DTRANSFORMSTATE_PROJECTION
)
3206 D3DMATRIX projection
;
3208 wined3d_mutex_lock();
3209 multiply_matrix(&projection
, &device
->legacy_clipspace
, matrix
);
3210 wined3d_device_set_transform(device
->wined3d_device
,
3211 WINED3D_TS_PROJECTION
, (struct wined3d_matrix
*)&projection
);
3212 device
->legacy_projection
= *matrix
;
3213 wined3d_mutex_unlock();
3218 return IDirect3DDevice7_SetTransform(&device
->IDirect3DDevice7_iface
, state
, matrix
);
3221 static HRESULT WINAPI
d3d_device2_SetTransform(IDirect3DDevice2
*iface
,
3222 D3DTRANSFORMSTATETYPE state
, D3DMATRIX
*matrix
)
3224 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
3226 TRACE("iface %p, state %#x, matrix %p.\n", iface
, state
, matrix
);
3228 return IDirect3DDevice7_SetTransform(&device
->IDirect3DDevice7_iface
, state
, matrix
);
3231 /*****************************************************************************
3232 * IDirect3DDevice7::GetTransform
3234 * Returns the matrix assigned to a transform state
3235 * D3DTRANSFORMSTATE_WORLD is translated to D3DTS_WORLDMATRIX(0), see
3239 * TransformStateType: State to read the matrix from
3240 * Matrix: Address to store the matrix at
3244 * DDERR_INVALIDPARAMS if Matrix == NULL
3245 * For details, see IWineD3DDevice::GetTransform
3247 *****************************************************************************/
3248 static HRESULT
d3d_device7_GetTransform(IDirect3DDevice7
*iface
,
3249 D3DTRANSFORMSTATETYPE state
, D3DMATRIX
*matrix
)
3251 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
3252 enum wined3d_transform_state wined3d_state
;
3254 TRACE("iface %p, state %#x, matrix %p.\n", iface
, state
, matrix
);
3258 case D3DTRANSFORMSTATE_WORLD
:
3259 wined3d_state
= WINED3D_TS_WORLD_MATRIX(0);
3261 case D3DTRANSFORMSTATE_WORLD1
:
3262 wined3d_state
= WINED3D_TS_WORLD_MATRIX(1);
3264 case D3DTRANSFORMSTATE_WORLD2
:
3265 wined3d_state
= WINED3D_TS_WORLD_MATRIX(2);
3267 case D3DTRANSFORMSTATE_WORLD3
:
3268 wined3d_state
= WINED3D_TS_WORLD_MATRIX(3);
3271 wined3d_state
= state
;
3275 return DDERR_INVALIDPARAMS
;
3277 /* Note: D3DMATRIX is compatible with struct wined3d_matrix. */
3278 wined3d_mutex_lock();
3279 wined3d_device_get_transform(device
->wined3d_device
, wined3d_state
, (struct wined3d_matrix
*)matrix
);
3280 wined3d_mutex_unlock();
3285 static HRESULT WINAPI
d3d_device7_GetTransform_FPUSetup(IDirect3DDevice7
*iface
,
3286 D3DTRANSFORMSTATETYPE state
, D3DMATRIX
*matrix
)
3288 return d3d_device7_GetTransform(iface
, state
, matrix
);
3291 static HRESULT WINAPI
d3d_device7_GetTransform_FPUPreserve(IDirect3DDevice7
*iface
,
3292 D3DTRANSFORMSTATETYPE state
, D3DMATRIX
*matrix
)
3297 old_fpucw
= d3d_fpu_setup();
3298 hr
= d3d_device7_GetTransform(iface
, state
, matrix
);
3299 set_fpu_control_word(old_fpucw
);
3304 static HRESULT WINAPI
d3d_device3_GetTransform(IDirect3DDevice3
*iface
,
3305 D3DTRANSFORMSTATETYPE state
, D3DMATRIX
*matrix
)
3307 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
3309 TRACE("iface %p, state %#x, matrix %p.\n", iface
, state
, matrix
);
3312 return DDERR_INVALIDPARAMS
;
3314 if (state
== D3DTRANSFORMSTATE_PROJECTION
)
3316 wined3d_mutex_lock();
3317 *matrix
= device
->legacy_projection
;
3318 wined3d_mutex_unlock();
3322 return IDirect3DDevice7_GetTransform(&device
->IDirect3DDevice7_iface
, state
, matrix
);
3325 static HRESULT WINAPI
d3d_device2_GetTransform(IDirect3DDevice2
*iface
,
3326 D3DTRANSFORMSTATETYPE state
, D3DMATRIX
*matrix
)
3328 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
3330 TRACE("iface %p, state %#x, matrix %p.\n", iface
, state
, matrix
);
3332 return IDirect3DDevice7_GetTransform(&device
->IDirect3DDevice7_iface
, state
, matrix
);
3335 /*****************************************************************************
3336 * IDirect3DDevice7::MultiplyTransform
3338 * Multiplies the already-set transform matrix of a transform state
3339 * with another matrix. For the world matrix, see SetTransform
3341 * Version 2, 3 and 7
3344 * TransformStateType: Transform state to multiply
3345 * D3DMatrix Matrix to multiply with.
3349 * DDERR_INVALIDPARAMS if D3DMatrix is NULL
3350 * For details, see IWineD3DDevice::MultiplyTransform
3352 *****************************************************************************/
3353 static HRESULT
d3d_device7_MultiplyTransform(IDirect3DDevice7
*iface
,
3354 D3DTRANSFORMSTATETYPE state
, D3DMATRIX
*matrix
)
3356 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
3357 enum wined3d_transform_state wined3d_state
;
3359 TRACE("iface %p, state %#x, matrix %p.\n", iface
, state
, matrix
);
3363 case D3DTRANSFORMSTATE_WORLD
:
3364 wined3d_state
= WINED3D_TS_WORLD_MATRIX(0);
3366 case D3DTRANSFORMSTATE_WORLD1
:
3367 wined3d_state
= WINED3D_TS_WORLD_MATRIX(1);
3369 case D3DTRANSFORMSTATE_WORLD2
:
3370 wined3d_state
= WINED3D_TS_WORLD_MATRIX(2);
3372 case D3DTRANSFORMSTATE_WORLD3
:
3373 wined3d_state
= WINED3D_TS_WORLD_MATRIX(3);
3376 wined3d_state
= state
;
3379 /* Note: D3DMATRIX is compatible with struct wined3d_matrix. */
3380 wined3d_mutex_lock();
3381 wined3d_device_multiply_transform(device
->wined3d_device
,
3382 wined3d_state
, (struct wined3d_matrix
*)matrix
);
3383 wined3d_mutex_unlock();
3388 static HRESULT WINAPI
d3d_device7_MultiplyTransform_FPUSetup(IDirect3DDevice7
*iface
,
3389 D3DTRANSFORMSTATETYPE state
, D3DMATRIX
*matrix
)
3391 return d3d_device7_MultiplyTransform(iface
, state
, matrix
);
3394 static HRESULT WINAPI
d3d_device7_MultiplyTransform_FPUPreserve(IDirect3DDevice7
*iface
,
3395 D3DTRANSFORMSTATETYPE state
, D3DMATRIX
*matrix
)
3400 old_fpucw
= d3d_fpu_setup();
3401 hr
= d3d_device7_MultiplyTransform(iface
, state
, matrix
);
3402 set_fpu_control_word(old_fpucw
);
3407 static HRESULT WINAPI
d3d_device3_MultiplyTransform(IDirect3DDevice3
*iface
,
3408 D3DTRANSFORMSTATETYPE state
, D3DMATRIX
*matrix
)
3410 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
3412 TRACE("iface %p, state %#x, matrix %p.\n", iface
, state
, matrix
);
3414 if (state
== D3DTRANSFORMSTATE_PROJECTION
)
3416 D3DMATRIX projection
, tmp
;
3418 wined3d_mutex_lock();
3419 multiply_matrix(&tmp
, &device
->legacy_projection
, matrix
);
3420 multiply_matrix(&projection
, &device
->legacy_clipspace
, &tmp
);
3421 wined3d_device_set_transform(device
->wined3d_device
,
3422 WINED3D_TS_PROJECTION
, (struct wined3d_matrix
*)&projection
);
3423 device
->legacy_projection
= tmp
;
3424 wined3d_mutex_unlock();
3429 return IDirect3DDevice7_MultiplyTransform(&device
->IDirect3DDevice7_iface
, state
, matrix
);
3432 static HRESULT WINAPI
d3d_device2_MultiplyTransform(IDirect3DDevice2
*iface
,
3433 D3DTRANSFORMSTATETYPE state
, D3DMATRIX
*matrix
)
3435 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
3437 TRACE("iface %p, state %#x, matrix %p.\n", iface
, state
, matrix
);
3439 return IDirect3DDevice7_MultiplyTransform(&device
->IDirect3DDevice7_iface
, state
, matrix
);
3442 /*****************************************************************************
3443 * IDirect3DDevice7::DrawPrimitive
3445 * Draws primitives based on vertices in an application-provided pointer
3447 * Version 2, 3 and 7. The IDirect3DDevice2 thunk converts the fixed vertex type into
3448 * an FVF format for D3D7
3451 * PrimitiveType: The type of the primitives to draw
3452 * Vertex type: Flexible vertex format vertex description
3453 * Vertices: Pointer to the vertex array
3454 * VertexCount: The number of vertices to draw
3455 * Flags: As usual a few flags
3459 * DDERR_INVALIDPARAMS if Vertices is NULL
3460 * For details, see IWineD3DDevice::DrawPrimitiveUP
3462 *****************************************************************************/
3464 /* The caller is responsible for wined3d locking */
3465 static HRESULT
d3d_device_prepare_vertex_buffer(struct d3d_device
*device
, UINT min_size
)
3469 if (device
->vertex_buffer_size
< min_size
|| !device
->vertex_buffer
)
3471 UINT size
= max(device
->vertex_buffer_size
* 2, min_size
);
3472 struct wined3d_buffer
*buffer
;
3474 TRACE("Growing vertex buffer to %u bytes\n", size
);
3476 hr
= wined3d_buffer_create_vb(device
->wined3d_device
, size
, WINED3DUSAGE_DYNAMIC
| WINED3DUSAGE_WRITEONLY
,
3477 WINED3D_POOL_DEFAULT
, NULL
, &ddraw_null_wined3d_parent_ops
, &buffer
);
3480 ERR("(%p) wined3d_buffer_create_vb failed with hr = %08x\n", device
, hr
);
3484 if (device
->vertex_buffer
)
3485 wined3d_buffer_decref(device
->vertex_buffer
);
3487 device
->vertex_buffer
= buffer
;
3488 device
->vertex_buffer_size
= size
;
3489 device
->vertex_buffer_pos
= 0;
3494 static HRESULT
d3d_device7_DrawPrimitive(IDirect3DDevice7
*iface
,
3495 D3DPRIMITIVETYPE primitive_type
, DWORD fvf
, void *vertices
,
3496 DWORD vertex_count
, DWORD flags
)
3498 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
3499 UINT stride
, vb_pos
, size
, align
;
3503 TRACE("iface %p, primitive_type %#x, fvf %#x, vertices %p, vertex_count %u, flags %#x.\n",
3504 iface
, primitive_type
, fvf
, vertices
, vertex_count
, flags
);
3507 return DDERR_INVALIDPARAMS
;
3509 /* Get the stride */
3510 stride
= get_flexible_vertex_size(fvf
);
3511 size
= vertex_count
* stride
;
3513 wined3d_mutex_lock();
3514 hr
= d3d_device_prepare_vertex_buffer(device
, size
);
3518 vb_pos
= device
->vertex_buffer_pos
;
3519 align
= vb_pos
% stride
;
3520 if (align
) align
= stride
- align
;
3521 if (vb_pos
+ size
+ align
> device
->vertex_buffer_size
)
3526 hr
= wined3d_buffer_map(device
->vertex_buffer
, vb_pos
, size
, &data
,
3527 vb_pos
? WINED3D_MAP_NOOVERWRITE
: WINED3D_MAP_DISCARD
);
3530 memcpy(data
, vertices
, size
);
3531 wined3d_buffer_unmap(device
->vertex_buffer
);
3532 device
->vertex_buffer_pos
= vb_pos
+ size
;
3534 hr
= wined3d_device_set_stream_source(device
->wined3d_device
, 0, device
->vertex_buffer
, 0, stride
);
3538 wined3d_device_set_vertex_declaration(device
->wined3d_device
, ddraw_find_decl(device
->ddraw
, fvf
));
3539 wined3d_device_set_primitive_type(device
->wined3d_device
, primitive_type
);
3540 hr
= wined3d_device_draw_primitive(device
->wined3d_device
, vb_pos
/ stride
, vertex_count
);
3543 wined3d_mutex_unlock();
3547 static HRESULT WINAPI
d3d_device7_DrawPrimitive_FPUSetup(IDirect3DDevice7
*iface
,
3548 D3DPRIMITIVETYPE primitive_type
, DWORD fvf
, void *vertices
,
3549 DWORD vertex_count
, DWORD flags
)
3551 return d3d_device7_DrawPrimitive(iface
, primitive_type
, fvf
, vertices
, vertex_count
, flags
);
3554 static HRESULT WINAPI
d3d_device7_DrawPrimitive_FPUPreserve(IDirect3DDevice7
*iface
,
3555 D3DPRIMITIVETYPE primitive_type
, DWORD fvf
, void *vertices
,
3556 DWORD vertex_count
, DWORD flags
)
3561 old_fpucw
= d3d_fpu_setup();
3562 hr
= d3d_device7_DrawPrimitive(iface
, primitive_type
, fvf
, vertices
, vertex_count
, flags
);
3563 set_fpu_control_word(old_fpucw
);
3568 static void setup_lighting(const struct d3d_device
*device
, DWORD fvf
, DWORD flags
)
3572 /* Ignore the D3DFVF_XYZRHW case here, wined3d takes care of that */
3573 if (!device
->material
|| !(fvf
& D3DFVF_NORMAL
) || (flags
& D3DDP_DONOTLIGHT
))
3576 wined3d_device_set_render_state(device
->wined3d_device
, WINED3D_RS_LIGHTING
, enable
);
3580 static HRESULT WINAPI
d3d_device3_DrawPrimitive(IDirect3DDevice3
*iface
,
3581 D3DPRIMITIVETYPE primitive_type
, DWORD fvf
, void *vertices
, DWORD vertex_count
,
3584 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
3586 TRACE("iface %p, primitive_type %#x, fvf %#x, vertices %p, vertex_count %u, flags %#x.\n",
3587 iface
, primitive_type
, fvf
, vertices
, vertex_count
, flags
);
3589 setup_lighting(device
, fvf
, flags
);
3591 return IDirect3DDevice7_DrawPrimitive(&device
->IDirect3DDevice7_iface
,
3592 primitive_type
, fvf
, vertices
, vertex_count
, flags
);
3595 static HRESULT WINAPI
d3d_device2_DrawPrimitive(IDirect3DDevice2
*iface
,
3596 D3DPRIMITIVETYPE primitive_type
, D3DVERTEXTYPE vertex_type
, void *vertices
,
3597 DWORD vertex_count
, DWORD flags
)
3599 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
3602 TRACE("iface %p, primitive_type %#x, vertex_type %#x, vertices %p, vertex_count %u, flags %#x.\n",
3603 iface
, primitive_type
, vertex_type
, vertices
, vertex_count
, flags
);
3605 switch (vertex_type
)
3607 case D3DVT_VERTEX
: fvf
= D3DFVF_VERTEX
; break;
3608 case D3DVT_LVERTEX
: fvf
= D3DFVF_LVERTEX
; break;
3609 case D3DVT_TLVERTEX
: fvf
= D3DFVF_TLVERTEX
; break;
3611 FIXME("Unhandled vertex type %#x.\n", vertex_type
);
3612 return DDERR_INVALIDPARAMS
; /* Should never happen */
3615 return d3d_device3_DrawPrimitive(&device
->IDirect3DDevice3_iface
,
3616 primitive_type
, fvf
, vertices
, vertex_count
, flags
);
3619 /*****************************************************************************
3620 * IDirect3DDevice7::DrawIndexedPrimitive
3622 * Draws vertices from an application-provided pointer, based on the index
3623 * numbers in a WORD array.
3625 * Version 2, 3 and 7. The version 7 thunk translates the vertex type into
3626 * an FVF format for D3D7
3629 * PrimitiveType: The primitive type to draw
3630 * VertexType: The FVF vertex description
3631 * Vertices: Pointer to the vertex array
3633 * Indices: Pointer to the index array
3634 * IndexCount: Number of indices = Number of vertices to draw
3635 * Flags: As usual, some flags
3639 * DDERR_INVALIDPARAMS if Vertices or Indices is NULL
3640 * For details, see IWineD3DDevice::DrawIndexedPrimitiveUP
3642 *****************************************************************************/
3643 /* The caller is responsible for wined3d locking */
3644 static HRESULT
d3d_device_prepare_index_buffer(struct d3d_device
*device
, UINT min_size
)
3648 if (device
->index_buffer_size
< min_size
|| !device
->index_buffer
)
3650 UINT size
= max(device
->index_buffer_size
* 2, min_size
);
3651 struct wined3d_buffer
*buffer
;
3653 TRACE("Growing index buffer to %u bytes\n", size
);
3655 hr
= wined3d_buffer_create_ib(device
->wined3d_device
, size
, WINED3DUSAGE_DYNAMIC
| WINED3DUSAGE_WRITEONLY
,
3656 WINED3D_POOL_DEFAULT
, NULL
, &ddraw_null_wined3d_parent_ops
, &buffer
);
3659 ERR("(%p) wined3d_buffer_create_ib failed with hr = %08x\n", device
, hr
);
3663 if (device
->index_buffer
)
3664 wined3d_buffer_decref(device
->index_buffer
);
3665 device
->index_buffer
= buffer
;
3666 device
->index_buffer_size
= size
;
3667 device
->index_buffer_pos
= 0;
3672 static HRESULT
d3d_device7_DrawIndexedPrimitive(IDirect3DDevice7
*iface
,
3673 D3DPRIMITIVETYPE primitive_type
, DWORD fvf
, void *vertices
, DWORD vertex_count
,
3674 WORD
*indices
, DWORD index_count
, DWORD flags
)
3676 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
3678 UINT stride
= get_flexible_vertex_size(fvf
);
3679 UINT vtx_size
= stride
* vertex_count
, idx_size
= index_count
* sizeof(*indices
);
3680 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 /* Set the D3DDevice's FVF */
3688 wined3d_mutex_lock();
3690 hr
= d3d_device_prepare_vertex_buffer(device
, vtx_size
);
3694 vb_pos
= device
->vertex_buffer_pos
;
3695 align
= vb_pos
% stride
;
3696 if (align
) align
= stride
- align
;
3697 if (vb_pos
+ vtx_size
+ align
> device
->vertex_buffer_size
)
3702 hr
= wined3d_buffer_map(device
->vertex_buffer
, vb_pos
, vtx_size
, &data
,
3703 vb_pos
? WINED3D_MAP_NOOVERWRITE
: WINED3D_MAP_DISCARD
);
3706 memcpy(data
, vertices
, vtx_size
);
3707 wined3d_buffer_unmap(device
->vertex_buffer
);
3708 device
->vertex_buffer_pos
= vb_pos
+ vtx_size
;
3710 hr
= d3d_device_prepare_index_buffer(device
, idx_size
);
3713 ib_pos
= device
->index_buffer_pos
;
3714 if (device
->index_buffer_size
- idx_size
< ib_pos
)
3717 hr
= wined3d_buffer_map(device
->index_buffer
, ib_pos
, idx_size
, &data
,
3718 ib_pos
? WINED3D_MAP_NOOVERWRITE
: WINED3D_MAP_DISCARD
);
3721 memcpy(data
, indices
, idx_size
);
3722 wined3d_buffer_unmap(device
->index_buffer
);
3723 device
->index_buffer_pos
= ib_pos
+ idx_size
;
3725 hr
= wined3d_device_set_stream_source(device
->wined3d_device
, 0, device
->vertex_buffer
, 0, stride
);
3728 wined3d_device_set_index_buffer(device
->wined3d_device
, device
->index_buffer
, WINED3DFMT_R16_UINT
);
3730 wined3d_device_set_vertex_declaration(device
->wined3d_device
, ddraw_find_decl(device
->ddraw
, fvf
));
3731 wined3d_device_set_primitive_type(device
->wined3d_device
, primitive_type
);
3732 wined3d_device_set_base_vertex_index(device
->wined3d_device
, vb_pos
/ stride
);
3733 hr
= wined3d_device_draw_indexed_primitive(device
->wined3d_device
, ib_pos
/ sizeof(*indices
), index_count
);
3736 wined3d_mutex_unlock();
3740 static HRESULT WINAPI
d3d_device7_DrawIndexedPrimitive_FPUSetup(IDirect3DDevice7
*iface
,
3741 D3DPRIMITIVETYPE primitive_type
, DWORD fvf
, void *vertices
, DWORD vertex_count
,
3742 WORD
*indices
, DWORD index_count
, DWORD flags
)
3744 return d3d_device7_DrawIndexedPrimitive(iface
, primitive_type
, fvf
,
3745 vertices
, vertex_count
, indices
, index_count
, flags
);
3748 static HRESULT WINAPI
d3d_device7_DrawIndexedPrimitive_FPUPreserve(IDirect3DDevice7
*iface
,
3749 D3DPRIMITIVETYPE primitive_type
, DWORD fvf
, void *vertices
, DWORD vertex_count
,
3750 WORD
*indices
, DWORD index_count
, DWORD flags
)
3755 old_fpucw
= d3d_fpu_setup();
3756 hr
= d3d_device7_DrawIndexedPrimitive(iface
, primitive_type
, fvf
,
3757 vertices
, vertex_count
, indices
, index_count
, flags
);
3758 set_fpu_control_word(old_fpucw
);
3763 static HRESULT WINAPI
d3d_device3_DrawIndexedPrimitive(IDirect3DDevice3
*iface
,
3764 D3DPRIMITIVETYPE primitive_type
, DWORD fvf
, void *vertices
, DWORD vertex_count
,
3765 WORD
*indices
, DWORD index_count
, DWORD flags
)
3767 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
3769 TRACE("iface %p, primitive_type %#x, fvf %#x, vertices %p, vertex_count %u, "
3770 "indices %p, index_count %u, flags %#x.\n",
3771 iface
, primitive_type
, fvf
, vertices
, vertex_count
, indices
, index_count
, flags
);
3773 setup_lighting(device
, fvf
, flags
);
3775 return IDirect3DDevice7_DrawIndexedPrimitive(&device
->IDirect3DDevice7_iface
,
3776 primitive_type
, fvf
, vertices
, vertex_count
, indices
, index_count
, flags
);
3779 static HRESULT WINAPI
d3d_device2_DrawIndexedPrimitive(IDirect3DDevice2
*iface
,
3780 D3DPRIMITIVETYPE primitive_type
, D3DVERTEXTYPE vertex_type
, void *vertices
,
3781 DWORD vertex_count
, WORD
*indices
, DWORD index_count
, DWORD flags
)
3783 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
3786 TRACE("iface %p, primitive_type %#x, vertex_type %#x, vertices %p, vertex_count %u, "
3787 "indices %p, index_count %u, flags %#x.\n",
3788 iface
, primitive_type
, vertex_type
, vertices
, vertex_count
, indices
, index_count
, flags
);
3790 switch (vertex_type
)
3792 case D3DVT_VERTEX
: fvf
= D3DFVF_VERTEX
; break;
3793 case D3DVT_LVERTEX
: fvf
= D3DFVF_LVERTEX
; break;
3794 case D3DVT_TLVERTEX
: fvf
= D3DFVF_TLVERTEX
; break;
3796 ERR("Unhandled vertex type %#x.\n", vertex_type
);
3797 return DDERR_INVALIDPARAMS
; /* Should never happen */
3800 return d3d_device3_DrawIndexedPrimitive(&device
->IDirect3DDevice3_iface
,
3801 primitive_type
, fvf
, vertices
, vertex_count
, indices
, index_count
, flags
);
3804 /*****************************************************************************
3805 * IDirect3DDevice3::End
3807 * Ends a draw begun with IDirect3DDevice3::Begin or
3808 * IDirect3DDevice::BeginIndexed. The vertices specified with
3809 * IDirect3DDevice::Vertex or IDirect3DDevice::Index are drawn using
3810 * the IDirect3DDevice3::DrawPrimitive method. So far only
3811 * non-indexed mode is supported
3816 * Flags: Some flags, as usual. Don't know which are defined
3819 * The return value of IDirect3DDevice3::DrawPrimitive
3821 *****************************************************************************/
3822 static HRESULT WINAPI
d3d_device3_End(IDirect3DDevice3
*iface
, DWORD flags
)
3824 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
3826 TRACE("iface %p, flags %#x.\n", iface
, flags
);
3828 return d3d_device3_DrawPrimitive(&device
->IDirect3DDevice3_iface
, device
->primitive_type
,
3829 device
->vertex_type
, device
->sysmem_vertex_buffer
, device
->nb_vertices
, device
->render_flags
);
3832 static HRESULT WINAPI
d3d_device2_End(IDirect3DDevice2
*iface
, DWORD flags
)
3834 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
3836 TRACE("iface %p, flags %#x.\n", iface
, flags
);
3838 return d3d_device3_End(&device
->IDirect3DDevice3_iface
, flags
);
3841 /*****************************************************************************
3842 * IDirect3DDevice7::SetClipStatus
3844 * Sets the clip status. This defines things as clipping conditions and
3845 * the extents of the clipping region.
3847 * Version 2, 3 and 7
3853 * D3D_OK because it's a stub
3854 * (DDERR_INVALIDPARAMS if ClipStatus == NULL)
3856 *****************************************************************************/
3857 static HRESULT WINAPI
d3d_device7_SetClipStatus(IDirect3DDevice7
*iface
, D3DCLIPSTATUS
*clip_status
)
3859 FIXME("iface %p, clip_status %p stub!\n", iface
, clip_status
);
3861 /* D3DCLIPSTATUS and WINED3DCLIPSTATUS are different. I don't know how to convert them
3862 * Perhaps this needs a new data type and an additional IWineD3DDevice method
3864 /* return IWineD3DDevice_SetClipStatus(This->wineD3DDevice, ClipStatus);*/
3868 static HRESULT WINAPI
d3d_device3_SetClipStatus(IDirect3DDevice3
*iface
, D3DCLIPSTATUS
*clip_status
)
3870 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
3872 TRACE("iface %p, clip_status %p.\n", iface
, clip_status
);
3874 return IDirect3DDevice7_SetClipStatus(&device
->IDirect3DDevice7_iface
, clip_status
);
3877 static HRESULT WINAPI
d3d_device2_SetClipStatus(IDirect3DDevice2
*iface
, D3DCLIPSTATUS
*clip_status
)
3879 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
3881 TRACE("iface %p, clip_status %p.\n", iface
, clip_status
);
3883 return IDirect3DDevice7_SetClipStatus(&device
->IDirect3DDevice7_iface
, clip_status
);
3886 /*****************************************************************************
3887 * IDirect3DDevice7::GetClipStatus
3889 * Returns the clip status
3892 * ClipStatus: Address to write the clip status to
3895 * D3D_OK because it's a stub
3897 *****************************************************************************/
3898 static HRESULT WINAPI
d3d_device7_GetClipStatus(IDirect3DDevice7
*iface
, D3DCLIPSTATUS
*clip_status
)
3900 FIXME("iface %p, clip_status %p stub!\n", iface
, clip_status
);
3902 /* D3DCLIPSTATUS and WINED3DCLIPSTATUS are different. I don't know how to convert them */
3903 /* return IWineD3DDevice_GetClipStatus(This->wineD3DDevice, ClipStatus);*/
3907 static HRESULT WINAPI
d3d_device3_GetClipStatus(IDirect3DDevice3
*iface
, D3DCLIPSTATUS
*clip_status
)
3909 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
3911 TRACE("iface %p, clip_status %p.\n", iface
, clip_status
);
3913 return IDirect3DDevice7_GetClipStatus(&device
->IDirect3DDevice7_iface
, clip_status
);
3916 static HRESULT WINAPI
d3d_device2_GetClipStatus(IDirect3DDevice2
*iface
, D3DCLIPSTATUS
*clip_status
)
3918 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
3920 TRACE("iface %p, clip_status %p.\n", iface
, clip_status
);
3922 return IDirect3DDevice7_GetClipStatus(&device
->IDirect3DDevice7_iface
, clip_status
);
3925 /*****************************************************************************
3926 * IDirect3DDevice::DrawPrimitiveStrided
3928 * Draws vertices described by a D3DDRAWPRIMITIVESTRIDEDDATA structure.
3933 * PrimitiveType: The primitive type to draw
3934 * VertexType: The FVF description of the vertices to draw (for the stride??)
3935 * D3DDrawPrimStrideData: A D3DDRAWPRIMITIVESTRIDEDDATA structure describing
3936 * the vertex data locations
3937 * VertexCount: The number of vertices to draw
3941 * D3D_OK, because it's a stub
3942 * (DDERR_INVALIDPARAMS if D3DDrawPrimStrideData is NULL)
3943 * (For details, see IWineD3DDevice::DrawPrimitiveStrided)
3945 *****************************************************************************/
3946 static void pack_strided_data(BYTE
*dst
, DWORD count
, const D3DDRAWPRIMITIVESTRIDEDDATA
*src
, DWORD fvf
)
3948 DWORD i
, tex
, offset
;
3950 for (i
= 0; i
< count
; i
++)
3952 /* The contents of the strided data are determined by the fvf,
3953 * not by the members set in src. So it's valid
3954 * to have diffuse.lpvData set to 0xdeadbeef if the diffuse flag is
3955 * not set in the fvf. */
3956 if (fvf
& D3DFVF_POSITION_MASK
)
3958 offset
= i
* src
->position
.dwStride
;
3959 if (fvf
& D3DFVF_XYZRHW
)
3961 memcpy(dst
, ((BYTE
*)src
->position
.lpvData
) + offset
, 4 * sizeof(float));
3962 dst
+= 4 * sizeof(float);
3966 memcpy(dst
, ((BYTE
*)src
->position
.lpvData
) + offset
, 3 * sizeof(float));
3967 dst
+= 3 * sizeof(float);
3971 if (fvf
& D3DFVF_NORMAL
)
3973 offset
= i
* src
->normal
.dwStride
;
3974 memcpy(dst
, ((BYTE
*)src
->normal
.lpvData
) + offset
, 3 * sizeof(float));
3975 dst
+= 3 * sizeof(float);
3978 if (fvf
& D3DFVF_DIFFUSE
)
3980 offset
= i
* src
->diffuse
.dwStride
;
3981 memcpy(dst
, ((BYTE
*)src
->diffuse
.lpvData
) + offset
, sizeof(DWORD
));
3982 dst
+= sizeof(DWORD
);
3985 if (fvf
& D3DFVF_SPECULAR
)
3987 offset
= i
* src
->specular
.dwStride
;
3988 memcpy(dst
, ((BYTE
*)src
->specular
.lpvData
) + offset
, sizeof(DWORD
));
3989 dst
+= sizeof(DWORD
);
3992 for (tex
= 0; tex
< GET_TEXCOUNT_FROM_FVF(fvf
); ++tex
)
3994 DWORD attrib_count
= GET_TEXCOORD_SIZE_FROM_FVF(fvf
, tex
);
3995 offset
= i
* src
->textureCoords
[tex
].dwStride
;
3996 memcpy(dst
, ((BYTE
*)src
->textureCoords
[tex
].lpvData
) + offset
, attrib_count
* sizeof(float));
3997 dst
+= attrib_count
* sizeof(float);
4002 static HRESULT
d3d_device7_DrawPrimitiveStrided(IDirect3DDevice7
*iface
, D3DPRIMITIVETYPE PrimitiveType
,
4003 DWORD VertexType
, D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
, DWORD VertexCount
, DWORD Flags
)
4005 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
4007 UINT dst_stride
= get_flexible_vertex_size(VertexType
);
4008 UINT dst_size
= dst_stride
* VertexCount
;
4012 TRACE("iface %p, primitive_type %#x, FVF %#x, strided_data %p, vertex_count %u, flags %#x.\n",
4013 iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Flags
);
4015 wined3d_mutex_lock();
4016 hr
= d3d_device_prepare_vertex_buffer(device
, dst_size
);
4020 vb_pos
= device
->vertex_buffer_pos
;
4021 align
= vb_pos
% dst_stride
;
4022 if (align
) align
= dst_stride
- align
;
4023 if (vb_pos
+ dst_size
+ align
> device
->vertex_buffer_size
)
4028 hr
= wined3d_buffer_map(device
->vertex_buffer
, vb_pos
, dst_size
, &dst_data
,
4029 vb_pos
? WINED3D_MAP_NOOVERWRITE
: WINED3D_MAP_DISCARD
);
4032 pack_strided_data(dst_data
, VertexCount
, D3DDrawPrimStrideData
, VertexType
);
4033 wined3d_buffer_unmap(device
->vertex_buffer
);
4034 device
->vertex_buffer_pos
= vb_pos
+ dst_size
;
4036 hr
= wined3d_device_set_stream_source(device
->wined3d_device
, 0, device
->vertex_buffer
, 0, dst_stride
);
4039 wined3d_device_set_vertex_declaration(device
->wined3d_device
, ddraw_find_decl(device
->ddraw
, VertexType
));
4041 wined3d_device_set_primitive_type(device
->wined3d_device
, PrimitiveType
);
4042 hr
= wined3d_device_draw_primitive(device
->wined3d_device
, vb_pos
/ dst_stride
, VertexCount
);
4045 wined3d_mutex_unlock();
4049 static HRESULT WINAPI
d3d_device7_DrawPrimitiveStrided_FPUSetup(IDirect3DDevice7
*iface
,
4050 D3DPRIMITIVETYPE PrimitiveType
, DWORD VertexType
,
4051 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
, DWORD VertexCount
, DWORD Flags
)
4053 return d3d_device7_DrawPrimitiveStrided(iface
, PrimitiveType
,
4054 VertexType
, D3DDrawPrimStrideData
, VertexCount
, Flags
);
4057 static HRESULT WINAPI
d3d_device7_DrawPrimitiveStrided_FPUPreserve(IDirect3DDevice7
*iface
,
4058 D3DPRIMITIVETYPE PrimitiveType
, DWORD VertexType
,
4059 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
, DWORD VertexCount
, DWORD Flags
)
4064 old_fpucw
= d3d_fpu_setup();
4065 hr
= d3d_device7_DrawPrimitiveStrided(iface
, PrimitiveType
,
4066 VertexType
, D3DDrawPrimStrideData
, VertexCount
, Flags
);
4067 set_fpu_control_word(old_fpucw
);
4072 static HRESULT WINAPI
d3d_device3_DrawPrimitiveStrided(IDirect3DDevice3
*iface
,
4073 D3DPRIMITIVETYPE PrimitiveType
, DWORD VertexType
,
4074 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
, DWORD VertexCount
, DWORD Flags
)
4076 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
4078 TRACE("iface %p, primitive_type %#x, FVF %#x, strided_data %p, vertex_count %u, flags %#x.\n",
4079 iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Flags
);
4081 setup_lighting(device
, VertexType
, Flags
);
4083 return IDirect3DDevice7_DrawPrimitiveStrided(&device
->IDirect3DDevice7_iface
,
4084 PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Flags
);
4087 /*****************************************************************************
4088 * IDirect3DDevice7::DrawIndexedPrimitiveStrided
4090 * Draws primitives specified by strided data locations based on indices
4098 * D3D_OK, because it's a stub
4099 * (DDERR_INVALIDPARAMS if D3DDrawPrimStrideData is NULL)
4100 * (DDERR_INVALIDPARAMS if Indices is NULL)
4101 * (For more details, see IWineD3DDevice::DrawIndexedPrimitiveStrided)
4103 *****************************************************************************/
4104 static HRESULT
d3d_device7_DrawIndexedPrimitiveStrided(IDirect3DDevice7
*iface
,
4105 D3DPRIMITIVETYPE PrimitiveType
, DWORD VertexType
,
4106 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
, DWORD VertexCount
,
4107 WORD
*Indices
, DWORD IndexCount
, DWORD Flags
)
4109 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
4111 UINT vtx_dst_stride
= get_flexible_vertex_size(VertexType
);
4112 UINT vtx_dst_size
= VertexCount
* vtx_dst_stride
;
4114 UINT idx_size
= IndexCount
* sizeof(WORD
);
4118 TRACE("iface %p, primitive_type %#x, FVF %#x, strided_data %p, vertex_count %u, indices %p, index_count %u, flags %#x.\n",
4119 iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Indices
, IndexCount
, Flags
);
4121 wined3d_mutex_lock();
4123 hr
= d3d_device_prepare_vertex_buffer(device
, vtx_dst_size
);
4127 vb_pos
= device
->vertex_buffer_pos
;
4128 align
= vb_pos
% vtx_dst_stride
;
4129 if (align
) align
= vtx_dst_stride
- align
;
4130 if (vb_pos
+ vtx_dst_size
+ align
> device
->vertex_buffer_size
)
4135 hr
= wined3d_buffer_map(device
->vertex_buffer
, vb_pos
, vtx_dst_size
, &dst_data
,
4136 vb_pos
? WINED3D_MAP_NOOVERWRITE
: WINED3D_MAP_DISCARD
);
4139 pack_strided_data(dst_data
, VertexCount
, D3DDrawPrimStrideData
, VertexType
);
4140 wined3d_buffer_unmap(device
->vertex_buffer
);
4141 device
->vertex_buffer_pos
= vb_pos
+ vtx_dst_size
;
4143 hr
= d3d_device_prepare_index_buffer(device
, idx_size
);
4146 ib_pos
= device
->index_buffer_pos
;
4147 if (device
->index_buffer_size
- idx_size
< ib_pos
)
4150 hr
= wined3d_buffer_map(device
->index_buffer
, ib_pos
, idx_size
, &dst_data
,
4151 ib_pos
? WINED3D_MAP_NOOVERWRITE
: WINED3D_MAP_DISCARD
);
4154 memcpy(dst_data
, Indices
, idx_size
);
4155 wined3d_buffer_unmap(device
->index_buffer
);
4156 device
->index_buffer_pos
= ib_pos
+ idx_size
;
4158 hr
= wined3d_device_set_stream_source(device
->wined3d_device
, 0, device
->vertex_buffer
, 0, vtx_dst_stride
);
4161 wined3d_device_set_index_buffer(device
->wined3d_device
, device
->index_buffer
, WINED3DFMT_R16_UINT
);
4162 wined3d_device_set_base_vertex_index(device
->wined3d_device
, vb_pos
/ vtx_dst_stride
);
4164 wined3d_device_set_vertex_declaration(device
->wined3d_device
, ddraw_find_decl(device
->ddraw
, VertexType
));
4165 wined3d_device_set_primitive_type(device
->wined3d_device
, PrimitiveType
);
4166 hr
= wined3d_device_draw_indexed_primitive(device
->wined3d_device
, ib_pos
/ sizeof(WORD
), IndexCount
);
4169 wined3d_mutex_unlock();
4173 static HRESULT WINAPI
d3d_device7_DrawIndexedPrimitiveStrided_FPUSetup(IDirect3DDevice7
*iface
,
4174 D3DPRIMITIVETYPE PrimitiveType
, DWORD VertexType
,
4175 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
, DWORD VertexCount
,
4176 WORD
*Indices
, DWORD IndexCount
, DWORD Flags
)
4178 return d3d_device7_DrawIndexedPrimitiveStrided(iface
, PrimitiveType
, VertexType
,
4179 D3DDrawPrimStrideData
, VertexCount
, Indices
, IndexCount
, Flags
);
4182 static HRESULT WINAPI
d3d_device7_DrawIndexedPrimitiveStrided_FPUPreserve(IDirect3DDevice7
*iface
,
4183 D3DPRIMITIVETYPE PrimitiveType
, DWORD VertexType
,
4184 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
, DWORD VertexCount
,
4185 WORD
*Indices
, DWORD IndexCount
, DWORD Flags
)
4190 old_fpucw
= d3d_fpu_setup();
4191 hr
= d3d_device7_DrawIndexedPrimitiveStrided(iface
, PrimitiveType
, VertexType
,
4192 D3DDrawPrimStrideData
, VertexCount
, Indices
, IndexCount
, Flags
);
4193 set_fpu_control_word(old_fpucw
);
4198 static HRESULT WINAPI
d3d_device3_DrawIndexedPrimitiveStrided(IDirect3DDevice3
*iface
,
4199 D3DPRIMITIVETYPE PrimitiveType
, DWORD VertexType
,
4200 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
, DWORD VertexCount
, WORD
*Indices
,
4201 DWORD IndexCount
, DWORD Flags
)
4203 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
4205 TRACE("iface %p, primitive_type %#x, FVF %#x, strided_data %p, vertex_count %u, indices %p, index_count %u, flags %#x.\n",
4206 iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Indices
, IndexCount
, Flags
);
4208 setup_lighting(device
, VertexType
, Flags
);
4210 return IDirect3DDevice7_DrawIndexedPrimitiveStrided(&device
->IDirect3DDevice7_iface
,
4211 PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Indices
, IndexCount
, Flags
);
4214 /*****************************************************************************
4215 * IDirect3DDevice7::DrawPrimitiveVB
4217 * Draws primitives from a vertex buffer to the screen.
4222 * PrimitiveType: Type of primitive to be rendered.
4223 * D3DVertexBuf: Source Vertex Buffer
4224 * StartVertex: Index of the first vertex from the buffer to be rendered
4225 * NumVertices: Number of vertices to be rendered
4226 * Flags: Can be D3DDP_WAIT to wait until rendering has finished
4230 * DDERR_INVALIDPARAMS if D3DVertexBuf is NULL
4232 *****************************************************************************/
4233 static HRESULT
d3d_device7_DrawPrimitiveVB(IDirect3DDevice7
*iface
, D3DPRIMITIVETYPE PrimitiveType
,
4234 IDirect3DVertexBuffer7
*D3DVertexBuf
, DWORD StartVertex
, DWORD NumVertices
, DWORD Flags
)
4236 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
4237 struct d3d_vertex_buffer
*vb
= unsafe_impl_from_IDirect3DVertexBuffer7(D3DVertexBuf
);
4241 TRACE("iface %p, primitive_type %#x, vb %p, start_vertex %u, vertex_count %u, flags %#x.\n",
4242 iface
, PrimitiveType
, D3DVertexBuf
, StartVertex
, NumVertices
, Flags
);
4247 WARN("No Vertex buffer specified.\n");
4248 return DDERR_INVALIDPARAMS
;
4250 stride
= get_flexible_vertex_size(vb
->fvf
);
4252 wined3d_mutex_lock();
4253 wined3d_device_set_vertex_declaration(device
->wined3d_device
, vb
->wineD3DVertexDeclaration
);
4254 hr
= wined3d_device_set_stream_source(device
->wined3d_device
, 0, vb
->wineD3DVertexBuffer
, 0, stride
);
4257 WARN("Failed to set stream source, hr %#x.\n", hr
);
4258 wined3d_mutex_unlock();
4262 /* Now draw the primitives */
4263 wined3d_device_set_primitive_type(device
->wined3d_device
, PrimitiveType
);
4264 hr
= wined3d_device_draw_primitive(device
->wined3d_device
, StartVertex
, NumVertices
);
4266 wined3d_mutex_unlock();
4271 static HRESULT WINAPI
d3d_device7_DrawPrimitiveVB_FPUSetup(IDirect3DDevice7
*iface
, D3DPRIMITIVETYPE PrimitiveType
,
4272 IDirect3DVertexBuffer7
*D3DVertexBuf
, DWORD StartVertex
, DWORD NumVertices
, DWORD Flags
)
4274 return d3d_device7_DrawPrimitiveVB(iface
, PrimitiveType
, D3DVertexBuf
, StartVertex
, NumVertices
, Flags
);
4277 static HRESULT WINAPI
d3d_device7_DrawPrimitiveVB_FPUPreserve(IDirect3DDevice7
*iface
, D3DPRIMITIVETYPE PrimitiveType
,
4278 IDirect3DVertexBuffer7
*D3DVertexBuf
, DWORD StartVertex
, DWORD NumVertices
, DWORD Flags
)
4283 old_fpucw
= d3d_fpu_setup();
4284 hr
= d3d_device7_DrawPrimitiveVB(iface
, PrimitiveType
, D3DVertexBuf
, StartVertex
, NumVertices
, Flags
);
4285 set_fpu_control_word(old_fpucw
);
4290 static HRESULT WINAPI
d3d_device3_DrawPrimitiveVB(IDirect3DDevice3
*iface
, D3DPRIMITIVETYPE PrimitiveType
,
4291 IDirect3DVertexBuffer
*D3DVertexBuf
, DWORD StartVertex
, DWORD NumVertices
, DWORD Flags
)
4293 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
4294 struct d3d_vertex_buffer
*vb
= unsafe_impl_from_IDirect3DVertexBuffer(D3DVertexBuf
);
4296 TRACE("iface %p, primitive_type %#x, vb %p, start_vertex %u, vertex_count %u, flags %#x.\n",
4297 iface
, PrimitiveType
, D3DVertexBuf
, StartVertex
, NumVertices
, Flags
);
4299 setup_lighting(device
, vb
->fvf
, Flags
);
4301 return IDirect3DDevice7_DrawPrimitiveVB(&device
->IDirect3DDevice7_iface
,
4302 PrimitiveType
, &vb
->IDirect3DVertexBuffer7_iface
, StartVertex
, NumVertices
, Flags
);
4305 /*****************************************************************************
4306 * IDirect3DDevice7::DrawIndexedPrimitiveVB
4308 * Draws primitives from a vertex buffer to the screen
4311 * PrimitiveType: Type of primitive to be rendered.
4312 * D3DVertexBuf: Source Vertex Buffer
4313 * StartVertex: Index of the first vertex from the buffer to be rendered
4314 * NumVertices: Number of vertices to be rendered
4315 * Indices: Array of DWORDs used to index into the Vertices
4316 * IndexCount: Number of indices in Indices
4317 * Flags: Can be D3DDP_WAIT to wait until rendering has finished
4321 *****************************************************************************/
4322 static HRESULT
d3d_device7_DrawIndexedPrimitiveVB(IDirect3DDevice7
*iface
,
4323 D3DPRIMITIVETYPE PrimitiveType
, IDirect3DVertexBuffer7
*D3DVertexBuf
,
4324 DWORD StartVertex
, DWORD NumVertices
, WORD
*Indices
, DWORD IndexCount
, DWORD Flags
)
4326 struct d3d_device
*This
= impl_from_IDirect3DDevice7(iface
);
4327 struct d3d_vertex_buffer
*vb
= unsafe_impl_from_IDirect3DVertexBuffer7(D3DVertexBuf
);
4328 DWORD stride
= get_flexible_vertex_size(vb
->fvf
);
4329 WORD
*LockedIndices
;
4333 TRACE("iface %p, primitive_type %#x, vb %p, start_vertex %u, vertex_count %u, indices %p, index_count %u, flags %#x.\n",
4334 iface
, PrimitiveType
, D3DVertexBuf
, StartVertex
, NumVertices
, Indices
, IndexCount
, Flags
);
4337 * 1) Upload the Indices to the index buffer
4338 * 2) Set the index source
4339 * 3) Set the Vertex Buffer as the Stream source
4340 * 4) Call IWineD3DDevice::DrawIndexedPrimitive
4343 wined3d_mutex_lock();
4345 wined3d_device_set_vertex_declaration(This
->wined3d_device
, vb
->wineD3DVertexDeclaration
);
4347 hr
= d3d_device_prepare_index_buffer(This
, IndexCount
* sizeof(WORD
));
4350 wined3d_mutex_unlock();
4353 ib_pos
= This
->index_buffer_pos
;
4355 if (This
->index_buffer_size
- IndexCount
* sizeof(WORD
) < ib_pos
)
4358 /* Copy the index stream into the index buffer. A new IWineD3DDevice
4359 * method could be created which takes an user pointer containing the
4360 * indices or a SetData-Method for the index buffer, which overrides the
4361 * index buffer data with our pointer. */
4362 hr
= wined3d_buffer_map(This
->index_buffer
, ib_pos
, IndexCount
* sizeof(WORD
),
4363 (BYTE
**)&LockedIndices
, ib_pos
? WINED3D_MAP_NOOVERWRITE
: WINED3D_MAP_DISCARD
);
4366 ERR("Failed to map buffer, hr %#x.\n", hr
);
4367 wined3d_mutex_unlock();
4370 memcpy(LockedIndices
, Indices
, IndexCount
* sizeof(WORD
));
4371 wined3d_buffer_unmap(This
->index_buffer
);
4372 This
->index_buffer_pos
= ib_pos
+ IndexCount
* sizeof(WORD
);
4374 /* Set the index stream */
4375 wined3d_device_set_base_vertex_index(This
->wined3d_device
, StartVertex
);
4376 wined3d_device_set_index_buffer(This
->wined3d_device
, This
->index_buffer
, WINED3DFMT_R16_UINT
);
4378 /* Set the vertex stream source */
4379 hr
= wined3d_device_set_stream_source(This
->wined3d_device
, 0, vb
->wineD3DVertexBuffer
, 0, stride
);
4382 ERR("(%p) IDirect3DDevice::SetStreamSource failed with hr = %08x\n", This
, hr
);
4383 wined3d_mutex_unlock();
4388 wined3d_device_set_primitive_type(This
->wined3d_device
, PrimitiveType
);
4389 hr
= wined3d_device_draw_indexed_primitive(This
->wined3d_device
, ib_pos
/ sizeof(WORD
), IndexCount
);
4391 wined3d_mutex_unlock();
4396 static HRESULT WINAPI
d3d_device7_DrawIndexedPrimitiveVB_FPUSetup(IDirect3DDevice7
*iface
,
4397 D3DPRIMITIVETYPE PrimitiveType
, IDirect3DVertexBuffer7
*D3DVertexBuf
,
4398 DWORD StartVertex
, DWORD NumVertices
, WORD
*Indices
, DWORD IndexCount
, DWORD Flags
)
4400 return d3d_device7_DrawIndexedPrimitiveVB(iface
, PrimitiveType
,
4401 D3DVertexBuf
, StartVertex
, NumVertices
, Indices
, IndexCount
, Flags
);
4404 static HRESULT WINAPI
d3d_device7_DrawIndexedPrimitiveVB_FPUPreserve(IDirect3DDevice7
*iface
,
4405 D3DPRIMITIVETYPE PrimitiveType
, IDirect3DVertexBuffer7
*D3DVertexBuf
,
4406 DWORD StartVertex
, DWORD NumVertices
, WORD
*Indices
, DWORD IndexCount
, DWORD Flags
)
4411 old_fpucw
= d3d_fpu_setup();
4412 hr
= d3d_device7_DrawIndexedPrimitiveVB(iface
, PrimitiveType
,
4413 D3DVertexBuf
, StartVertex
, NumVertices
, Indices
, IndexCount
, Flags
);
4414 set_fpu_control_word(old_fpucw
);
4419 static HRESULT WINAPI
d3d_device3_DrawIndexedPrimitiveVB(IDirect3DDevice3
*iface
,
4420 D3DPRIMITIVETYPE PrimitiveType
, IDirect3DVertexBuffer
*D3DVertexBuf
, WORD
*Indices
,
4421 DWORD IndexCount
, DWORD Flags
)
4423 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
4424 struct d3d_vertex_buffer
*vb
= unsafe_impl_from_IDirect3DVertexBuffer(D3DVertexBuf
);
4426 TRACE("iface %p, primitive_type %#x, vb %p, indices %p, index_count %u, flags %#x.\n",
4427 iface
, PrimitiveType
, D3DVertexBuf
, Indices
, IndexCount
, Flags
);
4429 setup_lighting(device
, vb
->fvf
, Flags
);
4431 return IDirect3DDevice7_DrawIndexedPrimitiveVB(&device
->IDirect3DDevice7_iface
, PrimitiveType
,
4432 &vb
->IDirect3DVertexBuffer7_iface
, 0, IndexCount
, Indices
, IndexCount
, Flags
);
4435 /*****************************************************************************
4436 * IDirect3DDevice7::ComputeSphereVisibility
4438 * Calculates the visibility of spheres in the current viewport. The spheres
4439 * are passed in the Centers and Radii arrays, the results are passed back
4440 * in the ReturnValues array. Return values are either completely visible,
4441 * partially visible or completely invisible.
4442 * The return value consists of a combination of D3DCLIP_* flags, or is
4443 * 0 if the sphere is completely visible (according to the SDK, not checked)
4448 * Centers: Array containing the sphere centers
4449 * Radii: Array containing the sphere radii
4450 * NumSpheres: The number of centers and radii in the arrays
4452 * ReturnValues: Array to write the results to
4456 * (DDERR_INVALIDPARAMS if Centers, Radii or ReturnValues are NULL)
4457 * (D3DERR_INVALIDMATRIX if the combined world, view and proj matrix
4460 *****************************************************************************/
4462 static DWORD
in_plane(UINT plane
, D3DVECTOR normal
, D3DVALUE origin_plane
, D3DVECTOR center
, D3DVALUE radius
)
4464 float distance
, norm
;
4466 norm
= sqrtf(normal
.u1
.x
* normal
.u1
.x
+ normal
.u2
.y
* normal
.u2
.y
+ normal
.u3
.z
* normal
.u3
.z
);
4467 distance
= ( origin_plane
+ normal
.u1
.x
* center
.u1
.x
+ normal
.u2
.y
* center
.u2
.y
+ normal
.u3
.z
* center
.u3
.z
) / norm
;
4469 if ( fabs( distance
) < radius
) return D3DSTATUS_CLIPUNIONLEFT
<< plane
;
4470 if ( distance
< -radius
) return (D3DSTATUS_CLIPUNIONLEFT
| D3DSTATUS_CLIPINTERSECTIONLEFT
) << plane
;
4474 static HRESULT WINAPI
d3d_device7_ComputeSphereVisibility(IDirect3DDevice7
*iface
,
4475 D3DVECTOR
*centers
, D3DVALUE
*radii
, DWORD sphere_count
, DWORD flags
, DWORD
*return_values
)
4478 D3DVALUE origin_plane
[6];
4483 TRACE("iface %p, centers %p, radii %p, sphere_count %u, flags %#x, return_values %p.\n",
4484 iface
, centers
, radii
, sphere_count
, flags
, return_values
);
4486 hr
= d3d_device7_GetTransform(iface
, D3DTRANSFORMSTATE_WORLD
, &m
);
4487 if ( hr
!= DD_OK
) return DDERR_INVALIDPARAMS
;
4488 hr
= d3d_device7_GetTransform(iface
, D3DTRANSFORMSTATE_VIEW
, &temp
);
4489 if ( hr
!= DD_OK
) return DDERR_INVALIDPARAMS
;
4490 multiply_matrix(&m
, &temp
, &m
);
4492 hr
= d3d_device7_GetTransform(iface
, D3DTRANSFORMSTATE_PROJECTION
, &temp
);
4493 if ( hr
!= DD_OK
) return DDERR_INVALIDPARAMS
;
4494 multiply_matrix(&m
, &temp
, &m
);
4497 vec
[0].u1
.x
= m
._14
+ m
._11
;
4498 vec
[0].u2
.y
= m
._24
+ m
._21
;
4499 vec
[0].u3
.z
= m
._34
+ m
._31
;
4500 origin_plane
[0] = m
._44
+ m
._41
;
4503 vec
[1].u1
.x
= m
._14
- m
._11
;
4504 vec
[1].u2
.y
= m
._24
- m
._21
;
4505 vec
[1].u3
.z
= m
._34
- m
._31
;
4506 origin_plane
[1] = m
._44
- m
._41
;
4509 vec
[2].u1
.x
= m
._14
- m
._12
;
4510 vec
[2].u2
.y
= m
._24
- m
._22
;
4511 vec
[2].u3
.z
= m
._34
- m
._32
;
4512 origin_plane
[2] = m
._44
- m
._42
;
4515 vec
[3].u1
.x
= m
._14
+ m
._12
;
4516 vec
[3].u2
.y
= m
._24
+ m
._22
;
4517 vec
[3].u3
.z
= m
._34
+ m
._32
;
4518 origin_plane
[3] = m
._44
+ m
._42
;
4521 vec
[4].u1
.x
= m
._13
;
4522 vec
[4].u2
.y
= m
._23
;
4523 vec
[4].u3
.z
= m
._33
;
4524 origin_plane
[4] = m
._43
;
4527 vec
[5].u1
.x
= m
._14
- m
._13
;
4528 vec
[5].u2
.y
= m
._24
- m
._23
;
4529 vec
[5].u3
.z
= m
._34
- m
._33
;
4530 origin_plane
[5] = m
._44
- m
._43
;
4532 for (i
= 0; i
< sphere_count
; ++i
)
4534 return_values
[i
] = 0;
4535 for (j
= 0; j
< 6; ++j
)
4536 return_values
[i
] |= in_plane(j
, vec
[j
], origin_plane
[j
], centers
[i
], radii
[i
]);
4542 static HRESULT WINAPI
d3d_device3_ComputeSphereVisibility(IDirect3DDevice3
*iface
,
4543 D3DVECTOR
*centers
, D3DVALUE
*radii
, DWORD sphere_count
, DWORD flags
, DWORD
*return_values
)
4545 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
4547 TRACE("iface %p, centers %p, radii %p, sphere_count %u, flags %#x, return_values %p.\n",
4548 iface
, centers
, radii
, sphere_count
, flags
, return_values
);
4550 return IDirect3DDevice7_ComputeSphereVisibility(&device
->IDirect3DDevice7_iface
,
4551 centers
, radii
, sphere_count
, flags
, return_values
);
4554 /*****************************************************************************
4555 * IDirect3DDevice7::GetTexture
4557 * Returns the texture interface handle assigned to a texture stage.
4558 * The returned texture is AddRefed. This is taken from old ddraw,
4559 * not checked in Windows.
4564 * Stage: Texture stage to read the texture from
4565 * Texture: Address to store the interface pointer at
4569 * DDERR_INVALIDPARAMS if Texture is NULL
4570 * For details, see IWineD3DDevice::GetTexture
4572 *****************************************************************************/
4573 static HRESULT
d3d_device7_GetTexture(IDirect3DDevice7
*iface
,
4574 DWORD stage
, IDirectDrawSurface7
**texture
)
4576 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
4577 struct wined3d_texture
*wined3d_texture
;
4578 struct ddraw_texture
*ddraw_texture
;
4580 TRACE("iface %p, stage %u, texture %p.\n", iface
, stage
, texture
);
4583 return DDERR_INVALIDPARAMS
;
4585 wined3d_mutex_lock();
4586 if (!(wined3d_texture
= wined3d_device_get_texture(device
->wined3d_device
, stage
)))
4589 wined3d_mutex_unlock();
4593 ddraw_texture
= wined3d_texture_get_parent(wined3d_texture
);
4594 *texture
= &ddraw_texture
->root
->IDirectDrawSurface7_iface
;
4595 IDirectDrawSurface7_AddRef(*texture
);
4596 wined3d_mutex_unlock();
4601 static HRESULT WINAPI
d3d_device7_GetTexture_FPUSetup(IDirect3DDevice7
*iface
,
4602 DWORD stage
, IDirectDrawSurface7
**Texture
)
4604 return d3d_device7_GetTexture(iface
, stage
, Texture
);
4607 static HRESULT WINAPI
d3d_device7_GetTexture_FPUPreserve(IDirect3DDevice7
*iface
,
4608 DWORD stage
, IDirectDrawSurface7
**Texture
)
4613 old_fpucw
= d3d_fpu_setup();
4614 hr
= d3d_device7_GetTexture(iface
, stage
, Texture
);
4615 set_fpu_control_word(old_fpucw
);
4620 static HRESULT WINAPI
d3d_device3_GetTexture(IDirect3DDevice3
*iface
, DWORD stage
, IDirect3DTexture2
**Texture2
)
4622 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
4623 struct ddraw_surface
*ret_val_impl
;
4625 IDirectDrawSurface7
*ret_val
;
4627 TRACE("iface %p, stage %u, texture %p.\n", iface
, stage
, Texture2
);
4629 ret
= IDirect3DDevice7_GetTexture(&device
->IDirect3DDevice7_iface
, stage
, &ret_val
);
4631 ret_val_impl
= unsafe_impl_from_IDirectDrawSurface7(ret_val
);
4632 *Texture2
= ret_val_impl
? &ret_val_impl
->IDirect3DTexture2_iface
: NULL
;
4634 TRACE("Returning texture %p.\n", *Texture2
);
4639 /*****************************************************************************
4640 * IDirect3DDevice7::SetTexture
4642 * Assigns a texture to a texture stage. Is the texture AddRef-ed?
4647 * Stage: The stage to assign the texture to
4648 * Texture: Interface pointer to the texture surface
4652 * For details, see IWineD3DDevice::SetTexture
4654 *****************************************************************************/
4655 static HRESULT
d3d_device7_SetTexture(IDirect3DDevice7
*iface
,
4656 DWORD stage
, IDirectDrawSurface7
*texture
)
4658 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
4659 struct ddraw_surface
*surf
= unsafe_impl_from_IDirectDrawSurface7(texture
);
4660 struct wined3d_texture
*wined3d_texture
= NULL
;
4663 TRACE("iface %p, stage %u, texture %p.\n", iface
, stage
, texture
);
4665 if (surf
&& (surf
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_TEXTURE
))
4666 wined3d_texture
= surf
->wined3d_texture
;
4668 wined3d_mutex_lock();
4669 hr
= wined3d_device_set_texture(device
->wined3d_device
, stage
, wined3d_texture
);
4670 wined3d_mutex_unlock();
4675 static HRESULT WINAPI
d3d_device7_SetTexture_FPUSetup(IDirect3DDevice7
*iface
,
4676 DWORD stage
, IDirectDrawSurface7
*texture
)
4678 return d3d_device7_SetTexture(iface
, stage
, texture
);
4681 static HRESULT WINAPI
d3d_device7_SetTexture_FPUPreserve(IDirect3DDevice7
*iface
,
4682 DWORD stage
, IDirectDrawSurface7
*texture
)
4687 old_fpucw
= d3d_fpu_setup();
4688 hr
= d3d_device7_SetTexture(iface
, stage
, texture
);
4689 set_fpu_control_word(old_fpucw
);
4694 static HRESULT WINAPI
d3d_device3_SetTexture(IDirect3DDevice3
*iface
,
4695 DWORD stage
, IDirect3DTexture2
*texture
)
4697 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
4698 struct ddraw_surface
*tex
= unsafe_impl_from_IDirect3DTexture2(texture
);
4702 TRACE("iface %p, stage %u, texture %p.\n", iface
, stage
, texture
);
4704 wined3d_mutex_lock();
4706 if (device
->legacyTextureBlending
)
4707 IDirect3DDevice3_GetRenderState(iface
, D3DRENDERSTATE_TEXTUREMAPBLEND
, &texmapblend
);
4709 hr
= IDirect3DDevice7_SetTexture(&device
->IDirect3DDevice7_iface
, stage
, &tex
->IDirectDrawSurface7_iface
);
4711 if (device
->legacyTextureBlending
&& texmapblend
== D3DTBLEND_MODULATE
)
4713 /* This fixup is required by the way D3DTBLEND_MODULATE maps to texture stage states.
4714 See d3d_device3_SetRenderState() for details. */
4715 struct wined3d_texture
*tex
= NULL
;
4716 BOOL tex_alpha
= FALSE
;
4717 DDPIXELFORMAT ddfmt
;
4719 if ((tex
= wined3d_device_get_texture(device
->wined3d_device
, 0)))
4721 struct wined3d_resource
*sub_resource
;
4723 if ((sub_resource
= wined3d_texture_get_sub_resource(tex
, 0)))
4725 struct wined3d_resource_desc desc
;
4727 wined3d_resource_get_desc(sub_resource
, &desc
);
4728 ddfmt
.dwSize
= sizeof(ddfmt
);
4729 ddrawformat_from_wined3dformat(&ddfmt
, desc
.format
);
4730 if (ddfmt
.u5
.dwRGBAlphaBitMask
) tex_alpha
= TRUE
;
4734 /* Args 1 and 2 are already set to WINED3DTA_TEXTURE/WINED3DTA_CURRENT in case of D3DTBLEND_MODULATE */
4736 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
4737 0, WINED3D_TSS_ALPHA_OP
, WINED3D_TOP_SELECT_ARG1
);
4739 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
4740 0, WINED3D_TSS_ALPHA_OP
, WINED3D_TOP_SELECT_ARG2
);
4743 wined3d_mutex_unlock();
4748 static const struct tss_lookup
4751 enum wined3d_texture_stage_state state
;
4755 {FALSE
, WINED3D_TSS_INVALID
}, /* 0, unused */
4756 {FALSE
, WINED3D_TSS_COLOR_OP
}, /* 1, D3DTSS_COLOROP */
4757 {FALSE
, WINED3D_TSS_COLOR_ARG1
}, /* 2, D3DTSS_COLORARG1 */
4758 {FALSE
, WINED3D_TSS_COLOR_ARG2
}, /* 3, D3DTSS_COLORARG2 */
4759 {FALSE
, WINED3D_TSS_ALPHA_OP
}, /* 4, D3DTSS_ALPHAOP */
4760 {FALSE
, WINED3D_TSS_ALPHA_ARG1
}, /* 5, D3DTSS_ALPHAARG1 */
4761 {FALSE
, WINED3D_TSS_ALPHA_ARG2
}, /* 6, D3DTSS_ALPHAARG2 */
4762 {FALSE
, WINED3D_TSS_BUMPENV_MAT00
}, /* 7, D3DTSS_BUMPENVMAT00 */
4763 {FALSE
, WINED3D_TSS_BUMPENV_MAT01
}, /* 8, D3DTSS_BUMPENVMAT01 */
4764 {FALSE
, WINED3D_TSS_BUMPENV_MAT10
}, /* 9, D3DTSS_BUMPENVMAT10 */
4765 {FALSE
, WINED3D_TSS_BUMPENV_MAT11
}, /* 10, D3DTSS_BUMPENVMAT11 */
4766 {FALSE
, WINED3D_TSS_TEXCOORD_INDEX
}, /* 11, D3DTSS_TEXCOORDINDEX */
4767 {TRUE
, WINED3D_SAMP_ADDRESS_U
}, /* 12, D3DTSS_ADDRESS */
4768 {TRUE
, WINED3D_SAMP_ADDRESS_U
}, /* 13, D3DTSS_ADDRESSU */
4769 {TRUE
, WINED3D_SAMP_ADDRESS_V
}, /* 14, D3DTSS_ADDRESSV */
4770 {TRUE
, WINED3D_SAMP_BORDER_COLOR
}, /* 15, D3DTSS_BORDERCOLOR */
4771 {TRUE
, WINED3D_SAMP_MAG_FILTER
}, /* 16, D3DTSS_MAGFILTER */
4772 {TRUE
, WINED3D_SAMP_MIN_FILTER
}, /* 17, D3DTSS_MINFILTER */
4773 {TRUE
, WINED3D_SAMP_MIP_FILTER
}, /* 18, D3DTSS_MIPFILTER */
4774 {TRUE
, WINED3D_SAMP_MIPMAP_LOD_BIAS
}, /* 19, D3DTSS_MIPMAPLODBIAS */
4775 {TRUE
, WINED3D_SAMP_MAX_MIP_LEVEL
}, /* 20, D3DTSS_MAXMIPLEVEL */
4776 {TRUE
, WINED3D_SAMP_MAX_ANISOTROPY
}, /* 21, D3DTSS_MAXANISOTROPY */
4777 {FALSE
, WINED3D_TSS_BUMPENV_LSCALE
}, /* 22, D3DTSS_BUMPENVLSCALE */
4778 {FALSE
, WINED3D_TSS_BUMPENV_LOFFSET
}, /* 23, D3DTSS_BUMPENVLOFFSET */
4779 {FALSE
, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS
}, /* 24, D3DTSS_TEXTURETRANSFORMFLAGS */
4782 /*****************************************************************************
4783 * IDirect3DDevice7::GetTextureStageState
4785 * Retrieves a state from a texture stage.
4790 * Stage: The stage to retrieve the state from
4791 * TexStageStateType: The state type to retrieve
4792 * State: Address to store the state's value at
4796 * DDERR_INVALIDPARAMS if State is NULL
4797 * For details, see IWineD3DDevice::GetTextureStageState
4799 *****************************************************************************/
4800 static HRESULT
d3d_device7_GetTextureStageState(IDirect3DDevice7
*iface
,
4801 DWORD stage
, D3DTEXTURESTAGESTATETYPE state
, DWORD
*value
)
4803 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
4804 const struct tss_lookup
*l
;
4806 TRACE("iface %p, stage %u, state %#x, value %p.\n",
4807 iface
, stage
, state
, value
);
4810 return DDERR_INVALIDPARAMS
;
4812 if (state
> D3DTSS_TEXTURETRANSFORMFLAGS
)
4814 WARN("Invalid state %#x passed.\n", state
);
4818 l
= &tss_lookup
[state
];
4820 wined3d_mutex_lock();
4822 if (l
->sampler_state
)
4824 *value
= wined3d_device_get_sampler_state(device
->wined3d_device
, stage
, l
->state
);
4828 /* Mipfilter is a sampler state with different values */
4829 case D3DTSS_MIPFILTER
:
4833 case WINED3D_TEXF_NONE
:
4834 *value
= D3DTFP_NONE
;
4836 case WINED3D_TEXF_POINT
:
4837 *value
= D3DTFP_POINT
;
4839 case WINED3D_TEXF_LINEAR
:
4840 *value
= D3DTFP_LINEAR
;
4843 ERR("Unexpected mipfilter value %#x.\n", *value
);
4844 *value
= D3DTFP_NONE
;
4850 /* Magfilter has slightly different values */
4851 case D3DTSS_MAGFILTER
:
4855 case WINED3D_TEXF_POINT
:
4856 *value
= D3DTFG_POINT
;
4858 case WINED3D_TEXF_LINEAR
:
4859 *value
= D3DTFG_LINEAR
;
4861 case WINED3D_TEXF_ANISOTROPIC
:
4862 *value
= D3DTFG_ANISOTROPIC
;
4864 case WINED3D_TEXF_FLAT_CUBIC
:
4865 *value
= D3DTFG_FLATCUBIC
;
4867 case WINED3D_TEXF_GAUSSIAN_CUBIC
:
4868 *value
= D3DTFG_GAUSSIANCUBIC
;
4871 ERR("Unexpected wined3d mag filter value %#x.\n", *value
);
4872 *value
= D3DTFG_POINT
;
4884 *value
= wined3d_device_get_texture_stage_state(device
->wined3d_device
, stage
, l
->state
);
4887 wined3d_mutex_unlock();
4892 static HRESULT WINAPI
d3d_device7_GetTextureStageState_FPUSetup(IDirect3DDevice7
*iface
,
4893 DWORD stage
, D3DTEXTURESTAGESTATETYPE state
, DWORD
*value
)
4895 return d3d_device7_GetTextureStageState(iface
, stage
, state
, value
);
4898 static HRESULT WINAPI
d3d_device7_GetTextureStageState_FPUPreserve(IDirect3DDevice7
*iface
,
4899 DWORD stage
, D3DTEXTURESTAGESTATETYPE state
, DWORD
*value
)
4904 old_fpucw
= d3d_fpu_setup();
4905 hr
= d3d_device7_GetTextureStageState(iface
, stage
, state
, value
);
4906 set_fpu_control_word(old_fpucw
);
4911 static HRESULT WINAPI
d3d_device3_GetTextureStageState(IDirect3DDevice3
*iface
,
4912 DWORD stage
, D3DTEXTURESTAGESTATETYPE state
, DWORD
*value
)
4914 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
4916 TRACE("iface %p, stage %u, state %#x, value %p.\n",
4917 iface
, stage
, state
, value
);
4919 return IDirect3DDevice7_GetTextureStageState(&device
->IDirect3DDevice7_iface
, stage
, state
, value
);
4922 /*****************************************************************************
4923 * IDirect3DDevice7::SetTextureStageState
4925 * Sets a texture stage state. Some stage types need to be handled specially,
4926 * because they do not exist in WineD3D and were moved to another place
4931 * Stage: The stage to modify
4932 * TexStageStateType: The state to change
4933 * State: The new value for the state
4937 * For details, see IWineD3DDevice::SetTextureStageState
4939 *****************************************************************************/
4940 static HRESULT
d3d_device7_SetTextureStageState(IDirect3DDevice7
*iface
,
4941 DWORD stage
, D3DTEXTURESTAGESTATETYPE state
, DWORD value
)
4943 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
4944 const struct tss_lookup
*l
;
4946 TRACE("iface %p, stage %u, state %#x, value %#x.\n",
4947 iface
, stage
, state
, value
);
4949 if (state
> D3DTSS_TEXTURETRANSFORMFLAGS
)
4951 WARN("Invalid state %#x passed.\n", state
);
4955 l
= &tss_lookup
[state
];
4957 wined3d_mutex_lock();
4959 if (l
->sampler_state
)
4963 /* Mipfilter is a sampler state with different values */
4964 case D3DTSS_MIPFILTER
:
4969 value
= WINED3D_TEXF_NONE
;
4972 value
= WINED3D_TEXF_POINT
;
4974 case 0: /* Unchecked */
4976 value
= WINED3D_TEXF_LINEAR
;
4979 ERR("Unexpected mipfilter value %#x.\n", value
);
4980 value
= WINED3D_TEXF_NONE
;
4986 /* Magfilter has slightly different values */
4987 case D3DTSS_MAGFILTER
:
4992 value
= WINED3D_TEXF_POINT
;
4995 value
= WINED3D_TEXF_LINEAR
;
4997 case D3DTFG_FLATCUBIC
:
4998 value
= WINED3D_TEXF_FLAT_CUBIC
;
5000 case D3DTFG_GAUSSIANCUBIC
:
5001 value
= WINED3D_TEXF_GAUSSIAN_CUBIC
;
5003 case D3DTFG_ANISOTROPIC
:
5004 value
= WINED3D_TEXF_ANISOTROPIC
;
5007 ERR("Unexpected d3d7 mag filter value %#x.\n", value
);
5008 value
= WINED3D_TEXF_POINT
;
5014 case D3DTSS_ADDRESS
:
5015 wined3d_device_set_sampler_state(device
->wined3d_device
, stage
, WINED3D_SAMP_ADDRESS_V
, value
);
5022 wined3d_device_set_sampler_state(device
->wined3d_device
, stage
, l
->state
, value
);
5026 wined3d_device_set_texture_stage_state(device
->wined3d_device
, stage
, l
->state
, value
);
5029 wined3d_mutex_unlock();
5034 static HRESULT WINAPI
d3d_device7_SetTextureStageState_FPUSetup(IDirect3DDevice7
*iface
,
5035 DWORD stage
, D3DTEXTURESTAGESTATETYPE state
, DWORD value
)
5037 return d3d_device7_SetTextureStageState(iface
, stage
, state
, value
);
5040 static HRESULT WINAPI
d3d_device7_SetTextureStageState_FPUPreserve(IDirect3DDevice7
*iface
,
5041 DWORD stage
, D3DTEXTURESTAGESTATETYPE state
, DWORD value
)
5046 old_fpucw
= d3d_fpu_setup();
5047 hr
= d3d_device7_SetTextureStageState(iface
, stage
, state
, value
);
5048 set_fpu_control_word(old_fpucw
);
5053 static HRESULT WINAPI
d3d_device3_SetTextureStageState(IDirect3DDevice3
*iface
,
5054 DWORD stage
, D3DTEXTURESTAGESTATETYPE state
, DWORD value
)
5056 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
5058 TRACE("iface %p, stage %u, state %#x, value %#x.\n",
5059 iface
, stage
, state
, value
);
5061 return IDirect3DDevice7_SetTextureStageState(&device
->IDirect3DDevice7_iface
, stage
, state
, value
);
5064 /*****************************************************************************
5065 * IDirect3DDevice7::ValidateDevice
5067 * SDK: "Reports the device's ability to render the currently set
5068 * texture-blending operations in a single pass". Whatever that means
5074 * NumPasses: Address to write the number of necessary passes for the
5075 * desired effect to.
5079 * See IWineD3DDevice::ValidateDevice for more details
5081 *****************************************************************************/
5082 static HRESULT
d3d_device7_ValidateDevice(IDirect3DDevice7
*iface
, DWORD
*pass_count
)
5084 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
5087 TRACE("iface %p, pass_count %p.\n", iface
, pass_count
);
5089 wined3d_mutex_lock();
5090 hr
= wined3d_device_validate_device(device
->wined3d_device
, pass_count
);
5091 wined3d_mutex_unlock();
5096 static HRESULT WINAPI
d3d_device7_ValidateDevice_FPUSetup(IDirect3DDevice7
*iface
, DWORD
*pass_count
)
5098 return d3d_device7_ValidateDevice(iface
, pass_count
);
5101 static HRESULT WINAPI
d3d_device7_ValidateDevice_FPUPreserve(IDirect3DDevice7
*iface
, DWORD
*pass_count
)
5106 old_fpucw
= d3d_fpu_setup();
5107 hr
= d3d_device7_ValidateDevice(iface
, pass_count
);
5108 set_fpu_control_word(old_fpucw
);
5113 static HRESULT WINAPI
d3d_device3_ValidateDevice(IDirect3DDevice3
*iface
, DWORD
*pass_count
)
5115 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
5117 TRACE("iface %p, pass_count %p.\n", iface
, pass_count
);
5119 return IDirect3DDevice7_ValidateDevice(&device
->IDirect3DDevice7_iface
, pass_count
);
5122 /*****************************************************************************
5123 * IDirect3DDevice7::Clear
5125 * Fills the render target, the z buffer and the stencil buffer with a
5126 * clear color / value
5131 * Count: Number of rectangles in Rects must be 0 if Rects is NULL
5132 * Rects: Rectangles to clear. If NULL, the whole surface is cleared
5133 * Flags: Some flags, as usual
5134 * Color: Clear color for the render target
5135 * Z: Clear value for the Z buffer
5136 * Stencil: Clear value to store in each stencil buffer entry
5140 * For details, see IWineD3DDevice::Clear
5142 *****************************************************************************/
5143 static HRESULT
d3d_device7_Clear(IDirect3DDevice7
*iface
, DWORD count
,
5144 D3DRECT
*rects
, DWORD flags
, D3DCOLOR color
, D3DVALUE z
, DWORD stencil
)
5146 const struct wined3d_color c
=
5148 ((color
>> 16) & 0xff) / 255.0f
,
5149 ((color
>> 8) & 0xff) / 255.0f
,
5150 (color
& 0xff) / 255.0f
,
5151 ((color
>> 24) & 0xff) / 255.0f
,
5153 struct d3d_device
*This
= impl_from_IDirect3DDevice7(iface
);
5156 TRACE("iface %p, count %u, rects %p, flags %#x, color 0x%08x, z %.8e, stencil %#x.\n",
5157 iface
, count
, rects
, flags
, color
, z
, stencil
);
5159 wined3d_mutex_lock();
5160 hr
= wined3d_device_clear(This
->wined3d_device
, count
, (RECT
*)rects
, flags
, &c
, z
, stencil
);
5161 wined3d_mutex_unlock();
5166 static HRESULT WINAPI
d3d_device7_Clear_FPUSetup(IDirect3DDevice7
*iface
, DWORD count
,
5167 D3DRECT
*rects
, DWORD flags
, D3DCOLOR color
, D3DVALUE z
, DWORD stencil
)
5169 return d3d_device7_Clear(iface
, count
, rects
, flags
, color
, z
, stencil
);
5172 static HRESULT WINAPI
d3d_device7_Clear_FPUPreserve(IDirect3DDevice7
*iface
, DWORD count
,
5173 D3DRECT
*rects
, DWORD flags
, D3DCOLOR color
, D3DVALUE z
, DWORD stencil
)
5178 old_fpucw
= d3d_fpu_setup();
5179 hr
= d3d_device7_Clear(iface
, count
, rects
, flags
, color
, z
, stencil
);
5180 set_fpu_control_word(old_fpucw
);
5185 /*****************************************************************************
5186 * IDirect3DDevice7::SetViewport
5188 * Sets the current viewport.
5190 * Version 7 only, but IDirect3DViewport uses this call for older
5194 * Data: The new viewport to set
5198 * DDERR_INVALIDPARAMS if Data is NULL
5199 * For more details, see IWineDDDevice::SetViewport
5201 *****************************************************************************/
5202 static HRESULT
d3d_device7_SetViewport(IDirect3DDevice7
*iface
, D3DVIEWPORT7
*viewport
)
5204 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
5206 TRACE("iface %p, viewport %p.\n", iface
, viewport
);
5209 return DDERR_INVALIDPARAMS
;
5211 /* Note: D3DVIEWPORT7 is compatible with struct wined3d_viewport. */
5212 wined3d_mutex_lock();
5213 wined3d_device_set_viewport(device
->wined3d_device
, (struct wined3d_viewport
*)viewport
);
5214 wined3d_mutex_unlock();
5219 static HRESULT WINAPI
d3d_device7_SetViewport_FPUSetup(IDirect3DDevice7
*iface
, D3DVIEWPORT7
*viewport
)
5221 return d3d_device7_SetViewport(iface
, viewport
);
5224 static HRESULT WINAPI
d3d_device7_SetViewport_FPUPreserve(IDirect3DDevice7
*iface
, D3DVIEWPORT7
*viewport
)
5229 old_fpucw
= d3d_fpu_setup();
5230 hr
= d3d_device7_SetViewport(iface
, viewport
);
5231 set_fpu_control_word(old_fpucw
);
5236 /*****************************************************************************
5237 * IDirect3DDevice::GetViewport
5239 * Returns the current viewport
5244 * Data: D3D7Viewport structure to write the viewport information to
5248 * DDERR_INVALIDPARAMS if Data is NULL
5249 * For more details, see IWineD3DDevice::GetViewport
5251 *****************************************************************************/
5252 static HRESULT
d3d_device7_GetViewport(IDirect3DDevice7
*iface
, D3DVIEWPORT7
*viewport
)
5254 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
5256 TRACE("iface %p, viewport %p.\n", iface
, viewport
);
5259 return DDERR_INVALIDPARAMS
;
5261 /* Note: D3DVIEWPORT7 is compatible with struct wined3d_viewport. */
5262 wined3d_mutex_lock();
5263 wined3d_device_get_viewport(device
->wined3d_device
, (struct wined3d_viewport
*)viewport
);
5264 wined3d_mutex_unlock();
5269 static HRESULT WINAPI
d3d_device7_GetViewport_FPUSetup(IDirect3DDevice7
*iface
, D3DVIEWPORT7
*viewport
)
5271 return d3d_device7_GetViewport(iface
, viewport
);
5274 static HRESULT WINAPI
d3d_device7_GetViewport_FPUPreserve(IDirect3DDevice7
*iface
, D3DVIEWPORT7
*viewport
)
5279 old_fpucw
= d3d_fpu_setup();
5280 hr
= d3d_device7_GetViewport(iface
, viewport
);
5281 set_fpu_control_word(old_fpucw
);
5286 /*****************************************************************************
5287 * IDirect3DDevice7::SetMaterial
5294 * Mat: The material to set
5298 * DDERR_INVALIDPARAMS if Mat is NULL.
5299 * For more details, see IWineD3DDevice::SetMaterial
5301 *****************************************************************************/
5302 static HRESULT
d3d_device7_SetMaterial(IDirect3DDevice7
*iface
, D3DMATERIAL7
*material
)
5304 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
5306 TRACE("iface %p, material %p.\n", iface
, material
);
5309 return DDERR_INVALIDPARAMS
;
5311 wined3d_mutex_lock();
5312 /* Note: D3DMATERIAL7 is compatible with struct wined3d_material. */
5313 wined3d_device_set_material(device
->wined3d_device
, (struct wined3d_material
*)material
);
5314 wined3d_mutex_unlock();
5319 static HRESULT WINAPI
d3d_device7_SetMaterial_FPUSetup(IDirect3DDevice7
*iface
, D3DMATERIAL7
*material
)
5321 return d3d_device7_SetMaterial(iface
, material
);
5324 static HRESULT WINAPI
d3d_device7_SetMaterial_FPUPreserve(IDirect3DDevice7
*iface
, D3DMATERIAL7
*material
)
5329 old_fpucw
= d3d_fpu_setup();
5330 hr
= d3d_device7_SetMaterial(iface
, material
);
5331 set_fpu_control_word(old_fpucw
);
5336 /*****************************************************************************
5337 * IDirect3DDevice7::GetMaterial
5339 * Returns the current material
5344 * Mat: D3DMATERIAL7 structure to write the material parameters to
5348 * DDERR_INVALIDPARAMS if Mat is NULL
5349 * For more details, see IWineD3DDevice::GetMaterial
5351 *****************************************************************************/
5352 static HRESULT
d3d_device7_GetMaterial(IDirect3DDevice7
*iface
, D3DMATERIAL7
*material
)
5354 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
5356 TRACE("iface %p, material %p.\n", iface
, material
);
5358 wined3d_mutex_lock();
5359 /* Note: D3DMATERIAL7 is compatible with struct wined3d_material. */
5360 wined3d_device_get_material(device
->wined3d_device
, (struct wined3d_material
*)material
);
5361 wined3d_mutex_unlock();
5366 static HRESULT WINAPI
d3d_device7_GetMaterial_FPUSetup(IDirect3DDevice7
*iface
, D3DMATERIAL7
*material
)
5368 return d3d_device7_GetMaterial(iface
, material
);
5371 static HRESULT WINAPI
d3d_device7_GetMaterial_FPUPreserve(IDirect3DDevice7
*iface
, D3DMATERIAL7
*material
)
5376 old_fpucw
= d3d_fpu_setup();
5377 hr
= d3d_device7_GetMaterial(iface
, material
);
5378 set_fpu_control_word(old_fpucw
);
5383 /*****************************************************************************
5384 * IDirect3DDevice7::SetLight
5386 * Assigns a light to a light index, but doesn't activate it yet.
5388 * Version 7, IDirect3DLight uses this method for older versions
5391 * LightIndex: The index of the new light
5392 * Light: A D3DLIGHT7 structure describing the light
5396 * For more details, see IWineD3DDevice::SetLight
5398 *****************************************************************************/
5399 static HRESULT
d3d_device7_SetLight(IDirect3DDevice7
*iface
, DWORD light_idx
, D3DLIGHT7
*light
)
5401 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
5404 TRACE("iface %p, light_idx %u, light %p.\n", iface
, light_idx
, light
);
5406 wined3d_mutex_lock();
5407 /* Note: D3DLIGHT7 is compatible with struct wined3d_light. */
5408 hr
= wined3d_device_set_light(device
->wined3d_device
, light_idx
, (struct wined3d_light
*)light
);
5409 wined3d_mutex_unlock();
5411 return hr_ddraw_from_wined3d(hr
);
5414 static HRESULT WINAPI
d3d_device7_SetLight_FPUSetup(IDirect3DDevice7
*iface
, DWORD light_idx
, D3DLIGHT7
*light
)
5416 return d3d_device7_SetLight(iface
, light_idx
, light
);
5419 static HRESULT WINAPI
d3d_device7_SetLight_FPUPreserve(IDirect3DDevice7
*iface
, DWORD light_idx
, D3DLIGHT7
*light
)
5424 old_fpucw
= d3d_fpu_setup();
5425 hr
= d3d_device7_SetLight(iface
, light_idx
, light
);
5426 set_fpu_control_word(old_fpucw
);
5431 /*****************************************************************************
5432 * IDirect3DDevice7::GetLight
5434 * Returns the light assigned to a light index
5437 * Light: Structure to write the light information to
5441 * DDERR_INVALIDPARAMS if Light is NULL
5442 * For details, see IWineD3DDevice::GetLight
5444 *****************************************************************************/
5445 static HRESULT
d3d_device7_GetLight(IDirect3DDevice7
*iface
, DWORD light_idx
, D3DLIGHT7
*light
)
5447 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
5450 TRACE("iface %p, light_idx %u, light %p.\n", iface
, light_idx
, light
);
5452 wined3d_mutex_lock();
5453 /* Note: D3DLIGHT7 is compatible with struct wined3d_light. */
5454 rc
= wined3d_device_get_light(device
->wined3d_device
, light_idx
, (struct wined3d_light
*)light
);
5455 wined3d_mutex_unlock();
5457 /* Translate the result. WineD3D returns other values than D3D7 */
5458 return hr_ddraw_from_wined3d(rc
);
5461 static HRESULT WINAPI
d3d_device7_GetLight_FPUSetup(IDirect3DDevice7
*iface
, DWORD light_idx
, D3DLIGHT7
*light
)
5463 return d3d_device7_GetLight(iface
, light_idx
, light
);
5466 static HRESULT WINAPI
d3d_device7_GetLight_FPUPreserve(IDirect3DDevice7
*iface
, DWORD light_idx
, D3DLIGHT7
*light
)
5471 old_fpucw
= d3d_fpu_setup();
5472 hr
= d3d_device7_GetLight(iface
, light_idx
, light
);
5473 set_fpu_control_word(old_fpucw
);
5478 /*****************************************************************************
5479 * IDirect3DDevice7::BeginStateBlock
5481 * Begins recording to a stateblock
5487 * For details see IWineD3DDevice::BeginStateBlock
5489 *****************************************************************************/
5490 static HRESULT
d3d_device7_BeginStateBlock(IDirect3DDevice7
*iface
)
5492 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
5495 TRACE("iface %p.\n", iface
);
5497 wined3d_mutex_lock();
5498 hr
= wined3d_device_begin_stateblock(device
->wined3d_device
);
5499 wined3d_mutex_unlock();
5501 return hr_ddraw_from_wined3d(hr
);
5504 static HRESULT WINAPI
d3d_device7_BeginStateBlock_FPUSetup(IDirect3DDevice7
*iface
)
5506 return d3d_device7_BeginStateBlock(iface
);
5509 static HRESULT WINAPI
d3d_device7_BeginStateBlock_FPUPreserve(IDirect3DDevice7
*iface
)
5514 old_fpucw
= d3d_fpu_setup();
5515 hr
= d3d_device7_BeginStateBlock(iface
);
5516 set_fpu_control_word(old_fpucw
);
5521 /*****************************************************************************
5522 * IDirect3DDevice7::EndStateBlock
5524 * Stops recording to a state block and returns the created stateblock
5530 * BlockHandle: Address to store the stateblock's handle to
5534 * DDERR_INVALIDPARAMS if BlockHandle is NULL
5535 * See IWineD3DDevice::EndStateBlock for more details
5537 *****************************************************************************/
5538 static HRESULT
d3d_device7_EndStateBlock(IDirect3DDevice7
*iface
, DWORD
*stateblock
)
5540 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
5541 struct wined3d_stateblock
*wined3d_sb
;
5545 TRACE("iface %p, stateblock %p.\n", iface
, stateblock
);
5548 return DDERR_INVALIDPARAMS
;
5550 wined3d_mutex_lock();
5552 hr
= wined3d_device_end_stateblock(device
->wined3d_device
, &wined3d_sb
);
5555 WARN("Failed to end stateblock, hr %#x.\n", hr
);
5556 wined3d_mutex_unlock();
5558 return hr_ddraw_from_wined3d(hr
);
5561 h
= ddraw_allocate_handle(&device
->handle_table
, wined3d_sb
, DDRAW_HANDLE_STATEBLOCK
);
5562 if (h
== DDRAW_INVALID_HANDLE
)
5564 ERR("Failed to allocate a stateblock handle.\n");
5565 wined3d_stateblock_decref(wined3d_sb
);
5566 wined3d_mutex_unlock();
5568 return DDERR_OUTOFMEMORY
;
5571 wined3d_mutex_unlock();
5572 *stateblock
= h
+ 1;
5574 return hr_ddraw_from_wined3d(hr
);
5577 static HRESULT WINAPI
d3d_device7_EndStateBlock_FPUSetup(IDirect3DDevice7
*iface
, DWORD
*stateblock
)
5579 return d3d_device7_EndStateBlock(iface
, stateblock
);
5582 static HRESULT WINAPI
d3d_device7_EndStateBlock_FPUPreserve(IDirect3DDevice7
*iface
, DWORD
*stateblock
)
5587 old_fpucw
= d3d_fpu_setup();
5588 hr
= d3d_device7_EndStateBlock(iface
, stateblock
);
5589 set_fpu_control_word(old_fpucw
);
5594 /*****************************************************************************
5595 * IDirect3DDevice7::PreLoad
5597 * Allows the app to signal that a texture will be used soon, to allow
5598 * the Direct3DDevice to load it to the video card in the meantime.
5603 * Texture: The texture to preload
5607 * DDERR_INVALIDPARAMS if Texture is NULL
5608 * See IWineD3DSurface::PreLoad for details
5610 *****************************************************************************/
5611 static HRESULT
d3d_device7_PreLoad(IDirect3DDevice7
*iface
, IDirectDrawSurface7
*texture
)
5613 struct ddraw_surface
*surface
= unsafe_impl_from_IDirectDrawSurface7(texture
);
5615 TRACE("iface %p, texture %p.\n", iface
, texture
);
5618 return DDERR_INVALIDPARAMS
;
5620 wined3d_mutex_lock();
5621 wined3d_surface_preload(surface
->wined3d_surface
);
5622 wined3d_mutex_unlock();
5627 static HRESULT WINAPI
d3d_device7_PreLoad_FPUSetup(IDirect3DDevice7
*iface
, IDirectDrawSurface7
*texture
)
5629 return d3d_device7_PreLoad(iface
, texture
);
5632 static HRESULT WINAPI
d3d_device7_PreLoad_FPUPreserve(IDirect3DDevice7
*iface
, IDirectDrawSurface7
*texture
)
5637 old_fpucw
= d3d_fpu_setup();
5638 hr
= d3d_device7_PreLoad(iface
, texture
);
5639 set_fpu_control_word(old_fpucw
);
5644 /*****************************************************************************
5645 * IDirect3DDevice7::ApplyStateBlock
5647 * Activates the state stored in a state block handle.
5650 * BlockHandle: The stateblock handle to activate
5654 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is NULL
5656 *****************************************************************************/
5657 static HRESULT
d3d_device7_ApplyStateBlock(IDirect3DDevice7
*iface
, DWORD stateblock
)
5659 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
5660 struct wined3d_stateblock
*wined3d_sb
;
5662 TRACE("iface %p, stateblock %#x.\n", iface
, stateblock
);
5664 wined3d_mutex_lock();
5665 wined3d_sb
= ddraw_get_object(&device
->handle_table
, stateblock
- 1, DDRAW_HANDLE_STATEBLOCK
);
5668 WARN("Invalid stateblock handle.\n");
5669 wined3d_mutex_unlock();
5670 return D3DERR_INVALIDSTATEBLOCK
;
5673 wined3d_stateblock_apply(wined3d_sb
);
5674 wined3d_mutex_unlock();
5679 static HRESULT WINAPI
d3d_device7_ApplyStateBlock_FPUSetup(IDirect3DDevice7
*iface
, DWORD stateblock
)
5681 return d3d_device7_ApplyStateBlock(iface
, stateblock
);
5684 static HRESULT WINAPI
d3d_device7_ApplyStateBlock_FPUPreserve(IDirect3DDevice7
*iface
, DWORD stateblock
)
5689 old_fpucw
= d3d_fpu_setup();
5690 hr
= d3d_device7_ApplyStateBlock(iface
, stateblock
);
5691 set_fpu_control_word(old_fpucw
);
5696 /*****************************************************************************
5697 * IDirect3DDevice7::CaptureStateBlock
5699 * Updates a stateblock's values to the values currently set for the device
5704 * BlockHandle: Stateblock to update
5708 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is NULL
5709 * See IWineD3DDevice::CaptureStateBlock for more details
5711 *****************************************************************************/
5712 static HRESULT
d3d_device7_CaptureStateBlock(IDirect3DDevice7
*iface
, DWORD stateblock
)
5714 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
5715 struct wined3d_stateblock
*wined3d_sb
;
5717 TRACE("iface %p, stateblock %#x.\n", iface
, stateblock
);
5719 wined3d_mutex_lock();
5720 wined3d_sb
= ddraw_get_object(&device
->handle_table
, stateblock
- 1, DDRAW_HANDLE_STATEBLOCK
);
5723 WARN("Invalid stateblock handle.\n");
5724 wined3d_mutex_unlock();
5725 return D3DERR_INVALIDSTATEBLOCK
;
5728 wined3d_stateblock_capture(wined3d_sb
);
5729 wined3d_mutex_unlock();
5734 static HRESULT WINAPI
d3d_device7_CaptureStateBlock_FPUSetup(IDirect3DDevice7
*iface
, DWORD stateblock
)
5736 return d3d_device7_CaptureStateBlock(iface
, stateblock
);
5739 static HRESULT WINAPI
d3d_device7_CaptureStateBlock_FPUPreserve(IDirect3DDevice7
*iface
, DWORD stateblock
)
5744 old_fpucw
= d3d_fpu_setup();
5745 hr
= d3d_device7_CaptureStateBlock(iface
, stateblock
);
5746 set_fpu_control_word(old_fpucw
);
5751 /*****************************************************************************
5752 * IDirect3DDevice7::DeleteStateBlock
5754 * Deletes a stateblock handle. This means releasing the WineD3DStateBlock
5759 * BlockHandle: Stateblock handle to delete
5763 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is 0
5765 *****************************************************************************/
5766 static HRESULT
d3d_device7_DeleteStateBlock(IDirect3DDevice7
*iface
, DWORD stateblock
)
5768 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
5769 struct wined3d_stateblock
*wined3d_sb
;
5772 TRACE("iface %p, stateblock %#x.\n", iface
, stateblock
);
5774 wined3d_mutex_lock();
5776 wined3d_sb
= ddraw_free_handle(&device
->handle_table
, stateblock
- 1, DDRAW_HANDLE_STATEBLOCK
);
5779 WARN("Invalid stateblock handle.\n");
5780 wined3d_mutex_unlock();
5781 return D3DERR_INVALIDSTATEBLOCK
;
5784 if ((ref
= wined3d_stateblock_decref(wined3d_sb
)))
5786 ERR("Something is still holding stateblock %p (refcount %u).\n", wined3d_sb
, ref
);
5789 wined3d_mutex_unlock();
5794 static HRESULT WINAPI
d3d_device7_DeleteStateBlock_FPUSetup(IDirect3DDevice7
*iface
, DWORD stateblock
)
5796 return d3d_device7_DeleteStateBlock(iface
, stateblock
);
5799 static HRESULT WINAPI
d3d_device7_DeleteStateBlock_FPUPreserve(IDirect3DDevice7
*iface
, DWORD stateblock
)
5804 old_fpucw
= d3d_fpu_setup();
5805 hr
= d3d_device7_DeleteStateBlock(iface
, stateblock
);
5806 set_fpu_control_word(old_fpucw
);
5811 /*****************************************************************************
5812 * IDirect3DDevice7::CreateStateBlock
5814 * Creates a new state block handle.
5819 * Type: The state block type
5820 * BlockHandle: Address to write the created handle to
5824 * DDERR_INVALIDPARAMS if BlockHandle is NULL
5826 *****************************************************************************/
5827 static HRESULT
d3d_device7_CreateStateBlock(IDirect3DDevice7
*iface
,
5828 D3DSTATEBLOCKTYPE type
, DWORD
*stateblock
)
5830 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
5831 struct wined3d_stateblock
*wined3d_sb
;
5835 TRACE("iface %p, type %#x, stateblock %p.\n", iface
, type
, stateblock
);
5838 return DDERR_INVALIDPARAMS
;
5840 if (type
!= D3DSBT_ALL
5841 && type
!= D3DSBT_PIXELSTATE
5842 && type
!= D3DSBT_VERTEXSTATE
)
5844 WARN("Unexpected stateblock type, returning DDERR_INVALIDPARAMS\n");
5845 return DDERR_INVALIDPARAMS
;
5848 wined3d_mutex_lock();
5850 /* The D3DSTATEBLOCKTYPE enum is fine here. */
5851 hr
= wined3d_stateblock_create(device
->wined3d_device
, type
, &wined3d_sb
);
5854 WARN("Failed to create stateblock, hr %#x.\n", hr
);
5855 wined3d_mutex_unlock();
5856 return hr_ddraw_from_wined3d(hr
);
5859 h
= ddraw_allocate_handle(&device
->handle_table
, wined3d_sb
, DDRAW_HANDLE_STATEBLOCK
);
5860 if (h
== DDRAW_INVALID_HANDLE
)
5862 ERR("Failed to allocate stateblock handle.\n");
5863 wined3d_stateblock_decref(wined3d_sb
);
5864 wined3d_mutex_unlock();
5865 return DDERR_OUTOFMEMORY
;
5868 *stateblock
= h
+ 1;
5869 wined3d_mutex_unlock();
5871 return hr_ddraw_from_wined3d(hr
);
5874 static HRESULT WINAPI
d3d_device7_CreateStateBlock_FPUSetup(IDirect3DDevice7
*iface
,
5875 D3DSTATEBLOCKTYPE type
, DWORD
*stateblock
)
5877 return d3d_device7_CreateStateBlock(iface
, type
, stateblock
);
5880 static HRESULT WINAPI
d3d_device7_CreateStateBlock_FPUPreserve(IDirect3DDevice7
*iface
,
5881 D3DSTATEBLOCKTYPE type
, DWORD
*stateblock
)
5886 old_fpucw
= d3d_fpu_setup();
5887 hr
= d3d_device7_CreateStateBlock(iface
, type
, stateblock
);
5888 set_fpu_control_word(old_fpucw
);
5893 static BOOL
is_mip_level_subset(struct ddraw_surface
*dest
, struct ddraw_surface
*src
)
5895 struct ddraw_surface
*src_level
, *dest_level
;
5896 IDirectDrawSurface7
*temp
;
5897 DDSURFACEDESC2 ddsd
;
5898 BOOL levelFound
; /* at least one suitable sublevel in dest found */
5900 /* To satisfy "destination is mip level subset of source" criteria (regular texture counts as 1 level),
5901 * 1) there must be at least one mip level in destination that matched dimensions of some mip level in source and
5902 * 2) there must be no destination levels that don't match any levels in source. Otherwise it's INVALIDPARAMS.
5909 for (;src_level
&& dest_level
;)
5911 if (src_level
->surface_desc
.dwWidth
== dest_level
->surface_desc
.dwWidth
&&
5912 src_level
->surface_desc
.dwHeight
== dest_level
->surface_desc
.dwHeight
)
5916 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
5917 ddsd
.ddsCaps
.dwCaps2
= DDSCAPS2_MIPMAPSUBLEVEL
;
5918 IDirectDrawSurface7_GetAttachedSurface(&dest_level
->IDirectDrawSurface7_iface
, &ddsd
.ddsCaps
, &temp
);
5920 if (dest_level
!= dest
) IDirectDrawSurface7_Release(&dest_level
->IDirectDrawSurface7_iface
);
5922 dest_level
= unsafe_impl_from_IDirectDrawSurface7(temp
);
5925 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
5926 ddsd
.ddsCaps
.dwCaps2
= DDSCAPS2_MIPMAPSUBLEVEL
;
5927 IDirectDrawSurface7_GetAttachedSurface(&src_level
->IDirectDrawSurface7_iface
, &ddsd
.ddsCaps
, &temp
);
5929 if (src_level
!= src
) IDirectDrawSurface7_Release(&src_level
->IDirectDrawSurface7_iface
);
5931 src_level
= unsafe_impl_from_IDirectDrawSurface7(temp
);
5934 if (src_level
&& src_level
!= src
) IDirectDrawSurface7_Release(&src_level
->IDirectDrawSurface7_iface
);
5935 if (dest_level
&& dest_level
!= dest
) IDirectDrawSurface7_Release(&dest_level
->IDirectDrawSurface7_iface
);
5937 return !dest_level
&& levelFound
;
5940 static void copy_mipmap_chain(struct d3d_device
*device
, struct ddraw_surface
*dest
,
5941 struct ddraw_surface
*src
, const POINT
*DestPoint
, const RECT
*SrcRect
)
5943 struct ddraw_surface
*src_level
, *dest_level
;
5944 IDirectDrawSurface7
*temp
;
5945 DDSURFACEDESC2 ddsd
;
5949 IDirectDrawPalette
*pal
= NULL
, *pal_src
= NULL
;
5953 /* Copy palette, if possible. */
5954 IDirectDrawSurface7_GetPalette(&src
->IDirectDrawSurface7_iface
, &pal_src
);
5955 IDirectDrawSurface7_GetPalette(&dest
->IDirectDrawSurface7_iface
, &pal
);
5957 if (pal_src
!= NULL
&& pal
!= NULL
)
5959 PALETTEENTRY palent
[256];
5961 IDirectDrawPalette_GetEntries(pal_src
, 0, 0, 256, palent
);
5962 IDirectDrawPalette_SetEntries(pal
, 0, 0, 256, palent
);
5965 if (pal
) IDirectDrawPalette_Release(pal
);
5966 if (pal_src
) IDirectDrawPalette_Release(pal_src
);
5968 /* Copy colorkeys, if present. */
5969 for (ckeyflag
= DDCKEY_DESTBLT
; ckeyflag
<= DDCKEY_SRCOVERLAY
; ckeyflag
<<= 1)
5971 hr
= IDirectDrawSurface7_GetColorKey(&src
->IDirectDrawSurface7_iface
, ckeyflag
, &ddckey
);
5975 IDirectDrawSurface7_SetColorKey(&dest
->IDirectDrawSurface7_iface
, ckeyflag
, &ddckey
);
5983 src_rect
= *SrcRect
;
5985 for (;src_level
&& dest_level
;)
5987 if (src_level
->surface_desc
.dwWidth
== dest_level
->surface_desc
.dwWidth
&&
5988 src_level
->surface_desc
.dwHeight
== dest_level
->surface_desc
.dwHeight
)
5990 UINT src_w
= src_rect
.right
- src_rect
.left
;
5991 UINT src_h
= src_rect
.bottom
- src_rect
.top
;
5992 RECT dst_rect
= {point
.x
, point
.y
, point
.x
+ src_w
, point
.y
+ src_h
};
5994 if (FAILED(hr
= wined3d_surface_blt(dest_level
->wined3d_surface
, &dst_rect
,
5995 src_level
->wined3d_surface
, &src_rect
, 0, NULL
, WINED3D_TEXF_POINT
)))
5996 ERR("Blit failed, hr %#x.\n", hr
);
5998 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
5999 ddsd
.ddsCaps
.dwCaps2
= DDSCAPS2_MIPMAPSUBLEVEL
;
6000 IDirectDrawSurface7_GetAttachedSurface(&dest_level
->IDirectDrawSurface7_iface
, &ddsd
.ddsCaps
, &temp
);
6002 if (dest_level
!= dest
) IDirectDrawSurface7_Release(&dest_level
->IDirectDrawSurface7_iface
);
6004 dest_level
= unsafe_impl_from_IDirectDrawSurface7(temp
);
6007 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
6008 ddsd
.ddsCaps
.dwCaps2
= DDSCAPS2_MIPMAPSUBLEVEL
;
6009 IDirectDrawSurface7_GetAttachedSurface(&src_level
->IDirectDrawSurface7_iface
, &ddsd
.ddsCaps
, &temp
);
6011 if (src_level
!= src
) IDirectDrawSurface7_Release(&src_level
->IDirectDrawSurface7_iface
);
6013 src_level
= unsafe_impl_from_IDirectDrawSurface7(temp
);
6020 src_rect
.right
= (src_rect
.right
+ 1) / 2;
6021 src_rect
.bottom
= (src_rect
.bottom
+ 1) / 2;
6024 if (src_level
&& src_level
!= src
) IDirectDrawSurface7_Release(&src_level
->IDirectDrawSurface7_iface
);
6025 if (dest_level
&& dest_level
!= dest
) IDirectDrawSurface7_Release(&dest_level
->IDirectDrawSurface7_iface
);
6028 /*****************************************************************************
6029 * IDirect3DDevice7::Load
6031 * Loads a rectangular area from the source into the destination texture.
6032 * It can also copy the source to the faces of a cubic environment map
6037 * DestTex: Destination texture
6038 * DestPoint: Point in the destination where the source image should be
6040 * SrcTex: Source texture
6041 * SrcRect: Source rectangle
6042 * Flags: Cubemap faces to load (DDSCAPS2_CUBEMAP_ALLFACES, DDSCAPS2_CUBEMAP_POSITIVEX,
6043 * DDSCAPS2_CUBEMAP_NEGATIVEX, DDSCAPS2_CUBEMAP_POSITIVEY, DDSCAPS2_CUBEMAP_NEGATIVEY,
6044 * DDSCAPS2_CUBEMAP_POSITIVEZ, DDSCAPS2_CUBEMAP_NEGATIVEZ)
6048 * DDERR_INVALIDPARAMS if dst_texture or src_texture is NULL, broken coordinates or anything unexpected.
6051 *****************************************************************************/
6052 static HRESULT
d3d_device7_Load(IDirect3DDevice7
*iface
, IDirectDrawSurface7
*dst_texture
, POINT
*dst_pos
,
6053 IDirectDrawSurface7
*src_texture
, RECT
*src_rect
, DWORD flags
)
6055 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
6056 struct ddraw_surface
*dest
= unsafe_impl_from_IDirectDrawSurface7(dst_texture
);
6057 struct ddraw_surface
*src
= unsafe_impl_from_IDirectDrawSurface7(src_texture
);
6061 TRACE("iface %p, dst_texture %p, dst_pos %s, src_texture %p, src_rect %s, flags %#x.\n",
6062 iface
, dst_texture
, wine_dbgstr_point(dst_pos
), src_texture
, wine_dbgstr_rect(src_rect
), flags
);
6064 if( (!src
) || (!dest
) )
6065 return DDERR_INVALIDPARAMS
;
6067 wined3d_mutex_lock();
6071 srcrect
.left
= srcrect
.top
= 0;
6072 srcrect
.right
= src
->surface_desc
.dwWidth
;
6073 srcrect
.bottom
= src
->surface_desc
.dwHeight
;
6076 srcrect
= *src_rect
;
6079 destpoint
.x
= destpoint
.y
= 0;
6081 destpoint
= *dst_pos
;
6083 /* Check bad dimensions. dst_pos is validated against src, not dest, because
6084 * destination can be a subset of mip levels, in which case actual coordinates used
6085 * for it may be divided. If any dimension of dest is larger than source, it can't be
6086 * mip level subset, so an error can be returned early.
6088 if (srcrect
.left
>= srcrect
.right
|| srcrect
.top
>= srcrect
.bottom
||
6089 srcrect
.right
> src
->surface_desc
.dwWidth
||
6090 srcrect
.bottom
> src
->surface_desc
.dwHeight
||
6091 destpoint
.x
+ srcrect
.right
- srcrect
.left
> src
->surface_desc
.dwWidth
||
6092 destpoint
.y
+ srcrect
.bottom
- srcrect
.top
> src
->surface_desc
.dwHeight
||
6093 dest
->surface_desc
.dwWidth
> src
->surface_desc
.dwWidth
||
6094 dest
->surface_desc
.dwHeight
> src
->surface_desc
.dwHeight
)
6096 wined3d_mutex_unlock();
6097 return DDERR_INVALIDPARAMS
;
6100 /* Must be top level surfaces. */
6101 if (src
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_MIPMAPSUBLEVEL
||
6102 dest
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_MIPMAPSUBLEVEL
)
6104 wined3d_mutex_unlock();
6105 return DDERR_INVALIDPARAMS
;
6108 if (src
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_CUBEMAP
)
6110 struct ddraw_surface
*src_face
, *dest_face
;
6111 DWORD src_face_flag
, dest_face_flag
;
6112 IDirectDrawSurface7
*temp
;
6113 DDSURFACEDESC2 ddsd
;
6116 if (!(dest
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_CUBEMAP
))
6118 wined3d_mutex_unlock();
6119 return DDERR_INVALIDPARAMS
;
6122 /* Iterate through cube faces 2 times. First time is just to check INVALIDPARAMS conditions, second
6123 * time it's actual surface loading. */
6124 for (i
= 0; i
< 2; i
++)
6129 for (;dest_face
&& src_face
;)
6131 src_face_flag
= src_face
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_CUBEMAP_ALLFACES
;
6132 dest_face_flag
= dest_face
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_CUBEMAP_ALLFACES
;
6134 if (src_face_flag
== dest_face_flag
)
6138 /* Destination mip levels must be subset of source mip levels. */
6139 if (!is_mip_level_subset(dest_face
, src_face
))
6141 wined3d_mutex_unlock();
6142 return DDERR_INVALIDPARAMS
;
6145 else if (flags
& dest_face_flag
)
6147 copy_mipmap_chain(device
, dest_face
, src_face
, &destpoint
, &srcrect
);
6150 if (src_face_flag
< DDSCAPS2_CUBEMAP_NEGATIVEZ
)
6152 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
6153 ddsd
.ddsCaps
.dwCaps2
= DDSCAPS2_CUBEMAP
| (src_face_flag
<< 1);
6154 IDirectDrawSurface7_GetAttachedSurface(&src
->IDirectDrawSurface7_iface
, &ddsd
.ddsCaps
, &temp
);
6156 if (src_face
!= src
) IDirectDrawSurface7_Release(&src_face
->IDirectDrawSurface7_iface
);
6158 src_face
= unsafe_impl_from_IDirectDrawSurface7(temp
);
6162 if (src_face
!= src
) IDirectDrawSurface7_Release(&src_face
->IDirectDrawSurface7_iface
);
6168 if (dest_face_flag
< DDSCAPS2_CUBEMAP_NEGATIVEZ
)
6170 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
6171 ddsd
.ddsCaps
.dwCaps2
= DDSCAPS2_CUBEMAP
| (dest_face_flag
<< 1);
6172 IDirectDrawSurface7_GetAttachedSurface(&dest
->IDirectDrawSurface7_iface
, &ddsd
.ddsCaps
, &temp
);
6174 if (dest_face
!= dest
) IDirectDrawSurface7_Release(&dest_face
->IDirectDrawSurface7_iface
);
6176 dest_face
= unsafe_impl_from_IDirectDrawSurface7(temp
);
6180 if (dest_face
!= dest
) IDirectDrawSurface7_Release(&dest_face
->IDirectDrawSurface7_iface
);
6188 /* Native returns error if src faces are not subset of dest faces. */
6191 wined3d_mutex_unlock();
6192 return DDERR_INVALIDPARAMS
;
6197 wined3d_mutex_unlock();
6200 else if (dest
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_CUBEMAP
)
6202 wined3d_mutex_unlock();
6203 return DDERR_INVALIDPARAMS
;
6206 /* Handle non cube map textures. */
6208 /* Destination mip levels must be subset of source mip levels. */
6209 if (!is_mip_level_subset(dest
, src
))
6211 wined3d_mutex_unlock();
6212 return DDERR_INVALIDPARAMS
;
6215 copy_mipmap_chain(device
, dest
, src
, &destpoint
, &srcrect
);
6217 wined3d_mutex_unlock();
6222 static HRESULT WINAPI
d3d_device7_Load_FPUSetup(IDirect3DDevice7
*iface
, IDirectDrawSurface7
*dst_texture
,
6223 POINT
*dst_pos
, IDirectDrawSurface7
*src_texture
, RECT
*src_rect
, DWORD flags
)
6225 return d3d_device7_Load(iface
, dst_texture
, dst_pos
, src_texture
, src_rect
, flags
);
6228 static HRESULT WINAPI
d3d_device7_Load_FPUPreserve(IDirect3DDevice7
*iface
, IDirectDrawSurface7
*dst_texture
,
6229 POINT
*dst_pos
, IDirectDrawSurface7
*src_texture
, RECT
*src_rect
, DWORD flags
)
6234 old_fpucw
= d3d_fpu_setup();
6235 hr
= d3d_device7_Load(iface
, dst_texture
, dst_pos
, src_texture
, src_rect
, flags
);
6236 set_fpu_control_word(old_fpucw
);
6241 /*****************************************************************************
6242 * IDirect3DDevice7::LightEnable
6244 * Enables or disables a light
6246 * Version 7, IDirect3DLight uses this method too.
6249 * LightIndex: The index of the light to enable / disable
6250 * Enable: Enable or disable the light
6254 * For more details, see IWineD3DDevice::SetLightEnable
6256 *****************************************************************************/
6257 static HRESULT
d3d_device7_LightEnable(IDirect3DDevice7
*iface
, DWORD light_idx
, BOOL enabled
)
6259 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
6262 TRACE("iface %p, light_idx %u, enabled %#x.\n", iface
, light_idx
, enabled
);
6264 wined3d_mutex_lock();
6265 hr
= wined3d_device_set_light_enable(device
->wined3d_device
, light_idx
, enabled
);
6266 wined3d_mutex_unlock();
6268 return hr_ddraw_from_wined3d(hr
);
6271 static HRESULT WINAPI
d3d_device7_LightEnable_FPUSetup(IDirect3DDevice7
*iface
, DWORD light_idx
, BOOL enabled
)
6273 return d3d_device7_LightEnable(iface
, light_idx
, enabled
);
6276 static HRESULT WINAPI
d3d_device7_LightEnable_FPUPreserve(IDirect3DDevice7
*iface
, DWORD light_idx
, BOOL enabled
)
6281 old_fpucw
= d3d_fpu_setup();
6282 hr
= d3d_device7_LightEnable(iface
, light_idx
, enabled
);
6283 set_fpu_control_word(old_fpucw
);
6288 /*****************************************************************************
6289 * IDirect3DDevice7::GetLightEnable
6291 * Retrieves if the light with the given index is enabled or not
6296 * LightIndex: Index of desired light
6297 * Enable: Pointer to a BOOL which contains the result
6301 * DDERR_INVALIDPARAMS if Enable is NULL
6302 * See IWineD3DDevice::GetLightEnable for more details
6304 *****************************************************************************/
6305 static HRESULT
d3d_device7_GetLightEnable(IDirect3DDevice7
*iface
, DWORD light_idx
, BOOL
*enabled
)
6307 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
6310 TRACE("iface %p, light_idx %u, enabled %p.\n", iface
, light_idx
, enabled
);
6313 return DDERR_INVALIDPARAMS
;
6315 wined3d_mutex_lock();
6316 hr
= wined3d_device_get_light_enable(device
->wined3d_device
, light_idx
, enabled
);
6317 wined3d_mutex_unlock();
6319 return hr_ddraw_from_wined3d(hr
);
6322 static HRESULT WINAPI
d3d_device7_GetLightEnable_FPUSetup(IDirect3DDevice7
*iface
, DWORD light_idx
, BOOL
*enabled
)
6324 return d3d_device7_GetLightEnable(iface
, light_idx
, enabled
);
6327 static HRESULT WINAPI
d3d_device7_GetLightEnable_FPUPreserve(IDirect3DDevice7
*iface
, DWORD light_idx
, BOOL
*enabled
)
6332 old_fpucw
= d3d_fpu_setup();
6333 hr
= d3d_device7_GetLightEnable(iface
, light_idx
, enabled
);
6334 set_fpu_control_word(old_fpucw
);
6339 /*****************************************************************************
6340 * IDirect3DDevice7::SetClipPlane
6342 * Sets custom clipping plane
6347 * Index: The index of the clipping plane
6348 * PlaneEquation: An equation defining the clipping plane
6352 * DDERR_INVALIDPARAMS if PlaneEquation is NULL
6353 * See IWineD3DDevice::SetClipPlane for more details
6355 *****************************************************************************/
6356 static HRESULT
d3d_device7_SetClipPlane(IDirect3DDevice7
*iface
, DWORD idx
, D3DVALUE
*plane
)
6358 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
6361 TRACE("iface %p, idx %u, plane %p.\n", iface
, idx
, plane
);
6364 return DDERR_INVALIDPARAMS
;
6366 wined3d_mutex_lock();
6367 hr
= wined3d_device_set_clip_plane(device
->wined3d_device
, idx
, (struct wined3d_vec4
*)plane
);
6368 wined3d_mutex_unlock();
6373 static HRESULT WINAPI
d3d_device7_SetClipPlane_FPUSetup(IDirect3DDevice7
*iface
, DWORD idx
, D3DVALUE
*plane
)
6375 return d3d_device7_SetClipPlane(iface
, idx
, plane
);
6378 static HRESULT WINAPI
d3d_device7_SetClipPlane_FPUPreserve(IDirect3DDevice7
*iface
, DWORD idx
, D3DVALUE
*plane
)
6383 old_fpucw
= d3d_fpu_setup();
6384 hr
= d3d_device7_SetClipPlane(iface
, idx
, plane
);
6385 set_fpu_control_word(old_fpucw
);
6390 /*****************************************************************************
6391 * IDirect3DDevice7::GetClipPlane
6393 * Returns the clipping plane with a specific index
6396 * Index: The index of the desired plane
6397 * PlaneEquation: Address to store the plane equation to
6401 * DDERR_INVALIDPARAMS if PlaneEquation is NULL
6402 * See IWineD3DDevice::GetClipPlane for more details
6404 *****************************************************************************/
6405 static HRESULT
d3d_device7_GetClipPlane(IDirect3DDevice7
*iface
, DWORD idx
, D3DVALUE
*plane
)
6407 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
6410 TRACE("iface %p, idx %u, plane %p.\n", iface
, idx
, plane
);
6413 return DDERR_INVALIDPARAMS
;
6415 wined3d_mutex_lock();
6416 hr
= wined3d_device_get_clip_plane(device
->wined3d_device
, idx
, (struct wined3d_vec4
*)plane
);
6417 wined3d_mutex_unlock();
6422 static HRESULT WINAPI
d3d_device7_GetClipPlane_FPUSetup(IDirect3DDevice7
*iface
, DWORD idx
, D3DVALUE
*plane
)
6424 return d3d_device7_GetClipPlane(iface
, idx
, plane
);
6427 static HRESULT WINAPI
d3d_device7_GetClipPlane_FPUPreserve(IDirect3DDevice7
*iface
, DWORD idx
, D3DVALUE
*plane
)
6432 old_fpucw
= d3d_fpu_setup();
6433 hr
= d3d_device7_GetClipPlane(iface
, idx
, plane
);
6434 set_fpu_control_word(old_fpucw
);
6439 /*****************************************************************************
6440 * IDirect3DDevice7::GetInfo
6442 * Retrieves some information about the device. The DirectX sdk says that
6443 * this version returns S_FALSE for all retail builds of DirectX, that's what
6444 * this implementation does.
6447 * DevInfoID: Information type requested
6448 * DevInfoStruct: Pointer to a structure to store the info to
6449 * Size: Size of the structure
6452 * S_FALSE, because it's a non-debug driver
6454 *****************************************************************************/
6455 static HRESULT WINAPI
d3d_device7_GetInfo(IDirect3DDevice7
*iface
, DWORD info_id
, void *info
, DWORD info_size
)
6457 TRACE("iface %p, info_id %#x, info %p, info_size %u.\n",
6458 iface
, info_id
, info
, info_size
);
6460 if (TRACE_ON(ddraw
))
6462 TRACE(" info requested : ");
6465 case D3DDEVINFOID_TEXTUREMANAGER
: TRACE("D3DDEVINFOID_TEXTUREMANAGER\n"); break;
6466 case D3DDEVINFOID_D3DTEXTUREMANAGER
: TRACE("D3DDEVINFOID_D3DTEXTUREMANAGER\n"); break;
6467 case D3DDEVINFOID_TEXTURING
: TRACE("D3DDEVINFOID_TEXTURING\n"); break;
6468 default: ERR(" invalid flag !!!\n"); return DDERR_INVALIDPARAMS
;
6472 return S_FALSE
; /* According to MSDN, this is valid for a non-debug driver */
6475 /* For performance optimization, devices created in FPUSETUP and FPUPRESERVE modes
6476 * have separate vtables. Simple functions where this doesn't matter like GetDirect3D
6477 * are not duplicated.
6479 * Device created with DDSCL_FPUSETUP (d3d7 default) - device methods assume that FPU
6480 * has already been setup for optimal d3d operation.
6482 * Device created with DDSCL_FPUPRESERVE - resets and restores FPU mode when necessary in
6483 * d3d calls (FPU may be in a mode non-suitable for d3d when the app calls d3d). Required
6484 * by Sacrifice (game). */
6485 static const struct IDirect3DDevice7Vtbl d3d_device7_fpu_setup_vtbl
=
6487 /*** IUnknown Methods ***/
6488 d3d_device7_QueryInterface
,
6490 d3d_device7_Release
,
6491 /*** IDirect3DDevice7 ***/
6492 d3d_device7_GetCaps_FPUSetup
,
6493 d3d_device7_EnumTextureFormats_FPUSetup
,
6494 d3d_device7_BeginScene_FPUSetup
,
6495 d3d_device7_EndScene_FPUSetup
,
6496 d3d_device7_GetDirect3D
,
6497 d3d_device7_SetRenderTarget_FPUSetup
,
6498 d3d_device7_GetRenderTarget
,
6499 d3d_device7_Clear_FPUSetup
,
6500 d3d_device7_SetTransform_FPUSetup
,
6501 d3d_device7_GetTransform_FPUSetup
,
6502 d3d_device7_SetViewport_FPUSetup
,
6503 d3d_device7_MultiplyTransform_FPUSetup
,
6504 d3d_device7_GetViewport_FPUSetup
,
6505 d3d_device7_SetMaterial_FPUSetup
,
6506 d3d_device7_GetMaterial_FPUSetup
,
6507 d3d_device7_SetLight_FPUSetup
,
6508 d3d_device7_GetLight_FPUSetup
,
6509 d3d_device7_SetRenderState_FPUSetup
,
6510 d3d_device7_GetRenderState_FPUSetup
,
6511 d3d_device7_BeginStateBlock_FPUSetup
,
6512 d3d_device7_EndStateBlock_FPUSetup
,
6513 d3d_device7_PreLoad_FPUSetup
,
6514 d3d_device7_DrawPrimitive_FPUSetup
,
6515 d3d_device7_DrawIndexedPrimitive_FPUSetup
,
6516 d3d_device7_SetClipStatus
,
6517 d3d_device7_GetClipStatus
,
6518 d3d_device7_DrawPrimitiveStrided_FPUSetup
,
6519 d3d_device7_DrawIndexedPrimitiveStrided_FPUSetup
,
6520 d3d_device7_DrawPrimitiveVB_FPUSetup
,
6521 d3d_device7_DrawIndexedPrimitiveVB_FPUSetup
,
6522 d3d_device7_ComputeSphereVisibility
,
6523 d3d_device7_GetTexture_FPUSetup
,
6524 d3d_device7_SetTexture_FPUSetup
,
6525 d3d_device7_GetTextureStageState_FPUSetup
,
6526 d3d_device7_SetTextureStageState_FPUSetup
,
6527 d3d_device7_ValidateDevice_FPUSetup
,
6528 d3d_device7_ApplyStateBlock_FPUSetup
,
6529 d3d_device7_CaptureStateBlock_FPUSetup
,
6530 d3d_device7_DeleteStateBlock_FPUSetup
,
6531 d3d_device7_CreateStateBlock_FPUSetup
,
6532 d3d_device7_Load_FPUSetup
,
6533 d3d_device7_LightEnable_FPUSetup
,
6534 d3d_device7_GetLightEnable_FPUSetup
,
6535 d3d_device7_SetClipPlane_FPUSetup
,
6536 d3d_device7_GetClipPlane_FPUSetup
,
6540 static const struct IDirect3DDevice7Vtbl d3d_device7_fpu_preserve_vtbl
=
6542 /*** IUnknown Methods ***/
6543 d3d_device7_QueryInterface
,
6545 d3d_device7_Release
,
6546 /*** IDirect3DDevice7 ***/
6547 d3d_device7_GetCaps_FPUPreserve
,
6548 d3d_device7_EnumTextureFormats_FPUPreserve
,
6549 d3d_device7_BeginScene_FPUPreserve
,
6550 d3d_device7_EndScene_FPUPreserve
,
6551 d3d_device7_GetDirect3D
,
6552 d3d_device7_SetRenderTarget_FPUPreserve
,
6553 d3d_device7_GetRenderTarget
,
6554 d3d_device7_Clear_FPUPreserve
,
6555 d3d_device7_SetTransform_FPUPreserve
,
6556 d3d_device7_GetTransform_FPUPreserve
,
6557 d3d_device7_SetViewport_FPUPreserve
,
6558 d3d_device7_MultiplyTransform_FPUPreserve
,
6559 d3d_device7_GetViewport_FPUPreserve
,
6560 d3d_device7_SetMaterial_FPUPreserve
,
6561 d3d_device7_GetMaterial_FPUPreserve
,
6562 d3d_device7_SetLight_FPUPreserve
,
6563 d3d_device7_GetLight_FPUPreserve
,
6564 d3d_device7_SetRenderState_FPUPreserve
,
6565 d3d_device7_GetRenderState_FPUPreserve
,
6566 d3d_device7_BeginStateBlock_FPUPreserve
,
6567 d3d_device7_EndStateBlock_FPUPreserve
,
6568 d3d_device7_PreLoad_FPUPreserve
,
6569 d3d_device7_DrawPrimitive_FPUPreserve
,
6570 d3d_device7_DrawIndexedPrimitive_FPUPreserve
,
6571 d3d_device7_SetClipStatus
,
6572 d3d_device7_GetClipStatus
,
6573 d3d_device7_DrawPrimitiveStrided_FPUPreserve
,
6574 d3d_device7_DrawIndexedPrimitiveStrided_FPUPreserve
,
6575 d3d_device7_DrawPrimitiveVB_FPUPreserve
,
6576 d3d_device7_DrawIndexedPrimitiveVB_FPUPreserve
,
6577 d3d_device7_ComputeSphereVisibility
,
6578 d3d_device7_GetTexture_FPUPreserve
,
6579 d3d_device7_SetTexture_FPUPreserve
,
6580 d3d_device7_GetTextureStageState_FPUPreserve
,
6581 d3d_device7_SetTextureStageState_FPUPreserve
,
6582 d3d_device7_ValidateDevice_FPUPreserve
,
6583 d3d_device7_ApplyStateBlock_FPUPreserve
,
6584 d3d_device7_CaptureStateBlock_FPUPreserve
,
6585 d3d_device7_DeleteStateBlock_FPUPreserve
,
6586 d3d_device7_CreateStateBlock_FPUPreserve
,
6587 d3d_device7_Load_FPUPreserve
,
6588 d3d_device7_LightEnable_FPUPreserve
,
6589 d3d_device7_GetLightEnable_FPUPreserve
,
6590 d3d_device7_SetClipPlane_FPUPreserve
,
6591 d3d_device7_GetClipPlane_FPUPreserve
,
6595 static const struct IDirect3DDevice3Vtbl d3d_device3_vtbl
=
6597 /*** IUnknown Methods ***/
6598 d3d_device3_QueryInterface
,
6600 d3d_device3_Release
,
6601 /*** IDirect3DDevice3 ***/
6602 d3d_device3_GetCaps
,
6603 d3d_device3_GetStats
,
6604 d3d_device3_AddViewport
,
6605 d3d_device3_DeleteViewport
,
6606 d3d_device3_NextViewport
,
6607 d3d_device3_EnumTextureFormats
,
6608 d3d_device3_BeginScene
,
6609 d3d_device3_EndScene
,
6610 d3d_device3_GetDirect3D
,
6611 d3d_device3_SetCurrentViewport
,
6612 d3d_device3_GetCurrentViewport
,
6613 d3d_device3_SetRenderTarget
,
6614 d3d_device3_GetRenderTarget
,
6616 d3d_device3_BeginIndexed
,
6620 d3d_device3_GetRenderState
,
6621 d3d_device3_SetRenderState
,
6622 d3d_device3_GetLightState
,
6623 d3d_device3_SetLightState
,
6624 d3d_device3_SetTransform
,
6625 d3d_device3_GetTransform
,
6626 d3d_device3_MultiplyTransform
,
6627 d3d_device3_DrawPrimitive
,
6628 d3d_device3_DrawIndexedPrimitive
,
6629 d3d_device3_SetClipStatus
,
6630 d3d_device3_GetClipStatus
,
6631 d3d_device3_DrawPrimitiveStrided
,
6632 d3d_device3_DrawIndexedPrimitiveStrided
,
6633 d3d_device3_DrawPrimitiveVB
,
6634 d3d_device3_DrawIndexedPrimitiveVB
,
6635 d3d_device3_ComputeSphereVisibility
,
6636 d3d_device3_GetTexture
,
6637 d3d_device3_SetTexture
,
6638 d3d_device3_GetTextureStageState
,
6639 d3d_device3_SetTextureStageState
,
6640 d3d_device3_ValidateDevice
6643 static const struct IDirect3DDevice2Vtbl d3d_device2_vtbl
=
6645 /*** IUnknown Methods ***/
6646 d3d_device2_QueryInterface
,
6648 d3d_device2_Release
,
6649 /*** IDirect3DDevice2 ***/
6650 d3d_device2_GetCaps
,
6651 d3d_device2_SwapTextureHandles
,
6652 d3d_device2_GetStats
,
6653 d3d_device2_AddViewport
,
6654 d3d_device2_DeleteViewport
,
6655 d3d_device2_NextViewport
,
6656 d3d_device2_EnumTextureFormats
,
6657 d3d_device2_BeginScene
,
6658 d3d_device2_EndScene
,
6659 d3d_device2_GetDirect3D
,
6660 d3d_device2_SetCurrentViewport
,
6661 d3d_device2_GetCurrentViewport
,
6662 d3d_device2_SetRenderTarget
,
6663 d3d_device2_GetRenderTarget
,
6665 d3d_device2_BeginIndexed
,
6669 d3d_device2_GetRenderState
,
6670 d3d_device2_SetRenderState
,
6671 d3d_device2_GetLightState
,
6672 d3d_device2_SetLightState
,
6673 d3d_device2_SetTransform
,
6674 d3d_device2_GetTransform
,
6675 d3d_device2_MultiplyTransform
,
6676 d3d_device2_DrawPrimitive
,
6677 d3d_device2_DrawIndexedPrimitive
,
6678 d3d_device2_SetClipStatus
,
6679 d3d_device2_GetClipStatus
6682 static const struct IDirect3DDeviceVtbl d3d_device1_vtbl
=
6684 /*** IUnknown Methods ***/
6685 d3d_device1_QueryInterface
,
6687 d3d_device1_Release
,
6688 /*** IDirect3DDevice1 ***/
6689 d3d_device1_Initialize
,
6690 d3d_device1_GetCaps
,
6691 d3d_device1_SwapTextureHandles
,
6692 d3d_device1_CreateExecuteBuffer
,
6693 d3d_device1_GetStats
,
6694 d3d_device1_Execute
,
6695 d3d_device1_AddViewport
,
6696 d3d_device1_DeleteViewport
,
6697 d3d_device1_NextViewport
,
6699 d3d_device1_GetPickRecords
,
6700 d3d_device1_EnumTextureFormats
,
6701 d3d_device1_CreateMatrix
,
6702 d3d_device1_SetMatrix
,
6703 d3d_device1_GetMatrix
,
6704 d3d_device1_DeleteMatrix
,
6705 d3d_device1_BeginScene
,
6706 d3d_device1_EndScene
,
6707 d3d_device1_GetDirect3D
6710 static const struct IUnknownVtbl d3d_device_inner_vtbl
=
6712 d3d_device_inner_QueryInterface
,
6713 d3d_device_inner_AddRef
,
6714 d3d_device_inner_Release
,
6717 struct d3d_device
*unsafe_impl_from_IDirect3DDevice7(IDirect3DDevice7
*iface
)
6719 if (!iface
) return NULL
;
6720 assert((iface
->lpVtbl
== &d3d_device7_fpu_preserve_vtbl
) || (iface
->lpVtbl
== &d3d_device7_fpu_setup_vtbl
));
6721 return CONTAINING_RECORD(iface
, struct d3d_device
, IDirect3DDevice7_iface
);
6724 struct d3d_device
*unsafe_impl_from_IDirect3DDevice3(IDirect3DDevice3
*iface
)
6726 if (!iface
) return NULL
;
6727 assert(iface
->lpVtbl
== &d3d_device3_vtbl
);
6728 return CONTAINING_RECORD(iface
, struct d3d_device
, IDirect3DDevice3_iface
);
6731 struct d3d_device
*unsafe_impl_from_IDirect3DDevice2(IDirect3DDevice2
*iface
)
6733 if (!iface
) return NULL
;
6734 assert(iface
->lpVtbl
== &d3d_device2_vtbl
);
6735 return CONTAINING_RECORD(iface
, struct d3d_device
, IDirect3DDevice2_iface
);
6738 struct d3d_device
*unsafe_impl_from_IDirect3DDevice(IDirect3DDevice
*iface
)
6740 if (!iface
) return NULL
;
6741 assert(iface
->lpVtbl
== &d3d_device1_vtbl
);
6742 return CONTAINING_RECORD(iface
, struct d3d_device
, IDirect3DDevice_iface
);
6745 enum wined3d_depth_buffer_type
d3d_device_update_depth_stencil(struct d3d_device
*device
)
6747 IDirectDrawSurface7
*depthStencil
= NULL
;
6748 IDirectDrawSurface7
*render_target
;
6749 static DDSCAPS2 depthcaps
= { DDSCAPS_ZBUFFER
, 0, 0, {0} };
6750 struct ddraw_surface
*dsi
;
6752 if (device
->rt_iface
&& SUCCEEDED(IUnknown_QueryInterface(device
->rt_iface
,
6753 &IID_IDirectDrawSurface7
, (void **)&render_target
)))
6755 IDirectDrawSurface7_GetAttachedSurface(render_target
, &depthcaps
, &depthStencil
);
6756 IDirectDrawSurface7_Release(render_target
);
6760 TRACE("Setting wined3d depth stencil to NULL\n");
6761 wined3d_device_set_depth_stencil_view(device
->wined3d_device
, NULL
);
6762 return WINED3D_ZB_FALSE
;
6765 dsi
= impl_from_IDirectDrawSurface7(depthStencil
);
6766 wined3d_device_set_depth_stencil_view(device
->wined3d_device
,
6767 ddraw_surface_get_rendertarget_view(dsi
));
6769 IDirectDrawSurface7_Release(depthStencil
);
6770 return WINED3D_ZB_TRUE
;
6773 static HRESULT
d3d_device_init(struct d3d_device
*device
, struct ddraw
*ddraw
,
6774 struct ddraw_surface
*target
, IUnknown
*rt_iface
, UINT version
, IUnknown
*outer_unknown
)
6776 static const D3DMATRIX ident
=
6778 1.0f
, 0.0f
, 0.0f
, 0.0f
,
6779 0.0f
, 1.0f
, 0.0f
, 0.0f
,
6780 0.0f
, 0.0f
, 1.0f
, 0.0f
,
6781 0.0f
, 0.0f
, 0.0f
, 1.0f
,
6785 if (ddraw
->cooperative_level
& DDSCL_FPUPRESERVE
)
6786 device
->IDirect3DDevice7_iface
.lpVtbl
= &d3d_device7_fpu_preserve_vtbl
;
6788 device
->IDirect3DDevice7_iface
.lpVtbl
= &d3d_device7_fpu_setup_vtbl
;
6790 device
->IDirect3DDevice3_iface
.lpVtbl
= &d3d_device3_vtbl
;
6791 device
->IDirect3DDevice2_iface
.lpVtbl
= &d3d_device2_vtbl
;
6792 device
->IDirect3DDevice_iface
.lpVtbl
= &d3d_device1_vtbl
;
6793 device
->IUnknown_inner
.lpVtbl
= &d3d_device_inner_vtbl
;
6795 device
->version
= version
;
6798 device
->outer_unknown
= outer_unknown
;
6800 device
->outer_unknown
= &device
->IUnknown_inner
;
6802 device
->ddraw
= ddraw
;
6803 list_init(&device
->viewport_list
);
6805 if (!ddraw_handle_table_init(&device
->handle_table
, 64))
6807 ERR("Failed to initialize handle table.\n");
6808 return DDERR_OUTOFMEMORY
;
6811 device
->legacyTextureBlending
= FALSE
;
6812 device
->legacy_projection
= ident
;
6813 device
->legacy_clipspace
= ident
;
6815 /* This is for convenience. */
6816 device
->wined3d_device
= ddraw
->wined3d_device
;
6817 wined3d_device_incref(ddraw
->wined3d_device
);
6819 /* Render to the back buffer */
6820 if (FAILED(hr
= wined3d_device_set_rendertarget_view(ddraw
->wined3d_device
,
6821 0, ddraw_surface_get_rendertarget_view(target
), TRUE
)))
6823 ERR("Failed to set render target, hr %#x.\n", hr
);
6824 ddraw_handle_table_destroy(&device
->handle_table
);
6828 device
->rt_iface
= rt_iface
;
6830 IUnknown_AddRef(device
->rt_iface
);
6832 ddraw
->d3ddevice
= device
;
6834 wined3d_device_set_render_state(ddraw
->wined3d_device
, WINED3D_RS_ZENABLE
,
6835 d3d_device_update_depth_stencil(device
));
6836 if (version
== 1) /* Color keying is initially enabled for version 1 devices. */
6837 wined3d_device_set_render_state(ddraw
->wined3d_device
, WINED3D_RS_COLORKEYENABLE
, TRUE
);
6838 else if (version
== 2)
6839 wined3d_device_set_render_state(ddraw
->wined3d_device
, WINED3D_RS_SPECULARENABLE
, TRUE
);
6844 HRESULT
d3d_device_create(struct ddraw
*ddraw
, struct ddraw_surface
*target
, IUnknown
*rt_iface
,
6845 UINT version
, struct d3d_device
**device
, IUnknown
*outer_unknown
)
6847 struct d3d_device
*object
;
6850 TRACE("ddraw %p, target %p, version %u, device %p, outer_unknown %p.\n",
6851 ddraw
, target
, version
, device
, outer_unknown
);
6853 if (!(target
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_3DDEVICE
)
6854 || (target
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_ZBUFFER
))
6856 WARN("Surface %p is not a render target.\n", target
);
6857 return DDERR_INVALIDCAPS
;
6860 if (!validate_surface_palette(target
))
6862 WARN("Surface %p has an indexed pixel format, but no palette.\n", target
);
6863 return DDERR_NOPALETTEATTACHED
;
6866 if (!(target
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_VIDEOMEMORY
))
6868 WARN("Surface %p is not in video memory.\n", target
);
6869 return D3DERR_SURFACENOTINVIDMEM
;
6872 if (ddraw
->flags
& DDRAW_NO3D
)
6874 ERR_(winediag
)("The application wants to create a Direct3D device, "
6875 "but the current DirectDrawRenderer does not support this.\n");
6880 if (ddraw
->d3ddevice
)
6882 FIXME("Only one Direct3D device per DirectDraw object supported.\n");
6883 return DDERR_INVALIDPARAMS
;
6886 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*object
));
6889 ERR("Failed to allocate device memory.\n");
6890 return DDERR_OUTOFMEMORY
;
6893 if (FAILED(hr
= d3d_device_init(object
, ddraw
, target
, rt_iface
, version
, outer_unknown
)))
6895 WARN("Failed to initialize device, hr %#x.\n", hr
);
6896 HeapFree(GetProcessHeap(), 0, object
);
6900 TRACE("Created device %p.\n", object
);