2 * Copyright (c) 1998-2004 Lionel Ulmer
3 * Copyright (c) 2002-2005 Christian Costa
4 * Copyright (c) 2006-2009, 2011-2013 Stefan Dösinger
5 * Copyright (c) 2008 Alexander Dorofeyev
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 * IDirect3DDevice implementation, version 1, 2, 3 and 7. Rendering is relayed
22 * to WineD3D, some minimal DirectDraw specific management is handled here.
23 * The Direct3DDevice is NOT the parent of the WineD3DDevice, because d3d
24 * is initialized when DirectDraw creates the primary surface.
25 * Some type management is necessary, because some D3D types changed between
31 #include "wine/port.h"
33 #include "ddraw_private.h"
35 WINE_DEFAULT_DEBUG_CHANNEL(ddraw
);
36 WINE_DECLARE_DEBUG_CHANNEL(winediag
);
39 const GUID IID_D3DDEVICE_WineD3D
= {
43 { 0xb7,0x98,0xc6,0x8a,0x77,0x2d,0x72,0x2a }
46 static inline void set_fpu_control_word(WORD fpucw
)
48 #if defined(__i386__) && defined(__GNUC__)
49 __asm__
volatile ("fldcw %0" : : "m" (fpucw
));
50 #elif defined(__i386__) && defined(_MSC_VER)
55 static inline WORD
d3d_fpu_setup(void)
59 #if defined(__i386__) && defined(__GNUC__)
60 __asm__
volatile ("fnstcw %0" : "=m" (oldcw
));
61 #elif defined(__i386__) && defined(_MSC_VER)
64 static BOOL warned
= FALSE
;
67 FIXME("FPUPRESERVE not implemented for this platform / compiler\n");
73 set_fpu_control_word(0x37f);
78 static inline struct d3d_device
*impl_from_IUnknown(IUnknown
*iface
)
80 return CONTAINING_RECORD(iface
, struct d3d_device
, IUnknown_inner
);
83 static HRESULT WINAPI
d3d_device_inner_QueryInterface(IUnknown
*iface
, REFIID riid
, void **out
)
85 struct d3d_device
*device
= impl_from_IUnknown(iface
);
87 TRACE("iface %p, riid %s, out %p.\n", iface
, debugstr_guid(riid
), out
);
92 return DDERR_INVALIDPARAMS
;
95 if (IsEqualGUID(&IID_IUnknown
, riid
))
97 IDirect3DDevice7_AddRef(&device
->IDirect3DDevice7_iface
);
98 *out
= &device
->IDirect3DDevice7_iface
;
102 if (device
->version
== 7)
104 if (IsEqualGUID(&IID_IDirect3DDevice7
, riid
))
106 IDirect3DDevice7_AddRef(&device
->IDirect3DDevice7_iface
);
107 *out
= &device
->IDirect3DDevice7_iface
;
113 if (IsEqualGUID(&IID_IDirect3DDevice3
, riid
) && device
->version
== 3)
115 IDirect3DDevice3_AddRef(&device
->IDirect3DDevice3_iface
);
116 *out
= &device
->IDirect3DDevice3_iface
;
120 if (IsEqualGUID(&IID_IDirect3DDevice2
, riid
) && device
->version
>= 2)
122 IDirect3DDevice2_AddRef(&device
->IDirect3DDevice2_iface
);
123 *out
= &device
->IDirect3DDevice2_iface
;
127 if (IsEqualGUID(&IID_IDirect3DDevice
, riid
))
129 IDirect3DDevice_AddRef(&device
->IDirect3DDevice_iface
);
130 *out
= &device
->IDirect3DDevice_iface
;
135 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid
));
138 return E_NOINTERFACE
;
141 static HRESULT WINAPI
d3d_device7_QueryInterface(IDirect3DDevice7
*iface
, REFIID riid
, void **out
)
143 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
145 TRACE("iface %p, riid %s, out %p.\n", iface
, debugstr_guid(riid
), out
);
147 return IUnknown_QueryInterface(device
->outer_unknown
, riid
, out
);
150 static HRESULT WINAPI
d3d_device3_QueryInterface(IDirect3DDevice3
*iface
, REFIID riid
, void **out
)
152 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
154 TRACE("iface %p, riid %s, out %p.\n", iface
, debugstr_guid(riid
), out
);
156 return IUnknown_QueryInterface(device
->outer_unknown
, riid
, out
);
159 static HRESULT WINAPI
d3d_device2_QueryInterface(IDirect3DDevice2
*iface
, REFIID riid
, void **out
)
161 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
163 TRACE("iface %p, riid %s, out %p.\n", iface
, debugstr_guid(riid
), out
);
165 return IUnknown_QueryInterface(device
->outer_unknown
, riid
, out
);
168 static HRESULT WINAPI
d3d_device1_QueryInterface(IDirect3DDevice
*iface
, REFIID riid
, void **out
)
170 struct d3d_device
*device
= impl_from_IDirect3DDevice(iface
);
172 TRACE("iface %p, riid %s, out %p.\n", iface
, debugstr_guid(riid
), out
);
174 return IUnknown_QueryInterface(device
->outer_unknown
, riid
, out
);
177 static ULONG WINAPI
d3d_device_inner_AddRef(IUnknown
*iface
)
179 struct d3d_device
*device
= impl_from_IUnknown(iface
);
180 ULONG ref
= InterlockedIncrement(&device
->ref
);
182 TRACE("%p increasing refcount to %u.\n", device
, ref
);
187 static ULONG WINAPI
d3d_device7_AddRef(IDirect3DDevice7
*iface
)
189 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
191 TRACE("iface %p.\n", iface
);
193 return IUnknown_AddRef(device
->outer_unknown
);
196 static ULONG WINAPI
d3d_device3_AddRef(IDirect3DDevice3
*iface
)
198 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
200 TRACE("iface %p.\n", iface
);
202 return IUnknown_AddRef(device
->outer_unknown
);
205 static ULONG WINAPI
d3d_device2_AddRef(IDirect3DDevice2
*iface
)
207 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
209 TRACE("iface %p.\n", iface
);
211 return IUnknown_AddRef(device
->outer_unknown
);
214 static ULONG WINAPI
d3d_device1_AddRef(IDirect3DDevice
*iface
)
216 struct d3d_device
*device
= impl_from_IDirect3DDevice(iface
);
218 TRACE("iface %p.\n", iface
);
220 return IUnknown_AddRef(device
->outer_unknown
);
223 static ULONG WINAPI
d3d_device_inner_Release(IUnknown
*iface
)
225 struct d3d_device
*This
= impl_from_IUnknown(iface
);
226 ULONG ref
= InterlockedDecrement(&This
->ref
);
229 TRACE("%p decreasing refcount to %u.\n", This
, ref
);
231 /* This method doesn't destroy the wined3d device, because it's still in
232 * use for 2D rendering. IDirectDrawSurface7::Release will destroy the
233 * wined3d device when the render target is released. */
237 struct list
*vp_entry
, *vp_entry2
;
239 wined3d_mutex_lock();
241 /* There is no need to unset any resources here, wined3d will take
242 * care of that on uninit_3d(). */
244 if (This
->index_buffer
)
245 wined3d_buffer_decref(This
->index_buffer
);
246 if (This
->vertex_buffer
)
247 wined3d_buffer_decref(This
->vertex_buffer
);
249 wined3d_device_set_rendertarget_view(This
->wined3d_device
, 0, NULL
, FALSE
);
251 /* Release the wined3d device. This won't destroy it. */
252 if (!wined3d_device_decref(This
->wined3d_device
))
253 ERR("The wined3d device (%p) was destroyed unexpectedly.\n", This
->wined3d_device
);
255 /* The texture handles should be unset by now, but there might be some bits
256 * missing in our reference counting(needs test). Do a sanity check. */
257 for (i
= 0; i
< This
->handle_table
.entry_count
; ++i
)
259 struct ddraw_handle_entry
*entry
= &This
->handle_table
.entries
[i
];
263 case DDRAW_HANDLE_FREE
:
266 case DDRAW_HANDLE_MATERIAL
:
268 struct d3d_material
*m
= entry
->object
;
269 FIXME("Material handle %#x (%p) not unset properly.\n", i
+ 1, m
);
274 case DDRAW_HANDLE_MATRIX
:
276 /* No FIXME here because this might happen because of sloppy applications. */
277 WARN("Leftover matrix handle %#x (%p), deleting.\n", i
+ 1, entry
->object
);
278 IDirect3DDevice_DeleteMatrix(&This
->IDirect3DDevice_iface
, i
+ 1);
282 case DDRAW_HANDLE_STATEBLOCK
:
284 /* No FIXME here because this might happen because of sloppy applications. */
285 WARN("Leftover stateblock handle %#x (%p), deleting.\n", i
+ 1, entry
->object
);
286 IDirect3DDevice7_DeleteStateBlock(&This
->IDirect3DDevice7_iface
, i
+ 1);
290 case DDRAW_HANDLE_SURFACE
:
292 struct ddraw_surface
*surf
= entry
->object
;
293 FIXME("Texture handle %#x (%p) not unset properly.\n", i
+ 1, surf
);
299 FIXME("Handle %#x (%p) has unknown type %#x.\n", i
+ 1, entry
->object
, entry
->type
);
304 ddraw_handle_table_destroy(&This
->handle_table
);
306 LIST_FOR_EACH_SAFE(vp_entry
, vp_entry2
, &This
->viewport_list
)
308 struct d3d_viewport
*vp
= LIST_ENTRY(vp_entry
, struct d3d_viewport
, entry
);
309 IDirect3DDevice3_DeleteViewport(&This
->IDirect3DDevice3_iface
, &vp
->IDirect3DViewport3_iface
);
312 TRACE("Releasing render target %p.\n", This
->rt_iface
);
313 rt_iface
= This
->rt_iface
;
314 This
->rt_iface
= NULL
;
315 if (This
->version
!= 1)
316 IUnknown_Release(rt_iface
);
317 TRACE("Render target release done.\n");
319 /* Releasing the render target above may have released the last
320 * reference to the ddraw object. */
322 This
->ddraw
->d3ddevice
= NULL
;
324 /* Now free the structure */
325 HeapFree(GetProcessHeap(), 0, This
);
326 wined3d_mutex_unlock();
333 static ULONG WINAPI
d3d_device7_Release(IDirect3DDevice7
*iface
)
335 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
337 TRACE("iface %p.\n", iface
);
339 return IUnknown_Release(device
->outer_unknown
);
342 static ULONG WINAPI
d3d_device3_Release(IDirect3DDevice3
*iface
)
344 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
346 TRACE("iface %p.\n", iface
);
348 return IUnknown_Release(device
->outer_unknown
);
351 static ULONG WINAPI
d3d_device2_Release(IDirect3DDevice2
*iface
)
353 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
355 TRACE("iface %p.\n", iface
);
357 return IUnknown_Release(device
->outer_unknown
);
360 static ULONG WINAPI
d3d_device1_Release(IDirect3DDevice
*iface
)
362 struct d3d_device
*device
= impl_from_IDirect3DDevice(iface
);
364 TRACE("iface %p.\n", iface
);
366 return IUnknown_Release(device
->outer_unknown
);
369 /*****************************************************************************
370 * IDirect3DDevice Methods
371 *****************************************************************************/
373 /*****************************************************************************
374 * IDirect3DDevice::Initialize
376 * Initializes a Direct3DDevice. This implementation is a no-op, as all
377 * initialization is done at create time.
379 * Exists in Version 1
382 * No idea what they mean, as the MSDN page is gone
386 *****************************************************************************/
387 static HRESULT WINAPI
d3d_device1_Initialize(IDirect3DDevice
*iface
,
388 IDirect3D
*d3d
, GUID
*guid
, D3DDEVICEDESC
*device_desc
)
390 /* It shouldn't be crucial, but print a FIXME, I'm interested if
391 * any game calls it and when. */
392 FIXME("iface %p, d3d %p, guid %s, device_desc %p nop!\n",
393 iface
, d3d
, debugstr_guid(guid
), device_desc
);
398 static HRESULT
d3d_device7_GetCaps(IDirect3DDevice7
*iface
, D3DDEVICEDESC7
*device_desc
)
400 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
402 TRACE("iface %p, device_desc %p.\n", iface
, device_desc
);
406 WARN("device_desc is NULL, returning DDERR_INVALIDPARAMS.\n");
407 return DDERR_INVALIDPARAMS
;
410 /* Call the same function used by IDirect3D, this saves code */
411 return ddraw_get_d3dcaps(device
->ddraw
, device_desc
);
414 static HRESULT WINAPI
d3d_device7_GetCaps_FPUSetup(IDirect3DDevice7
*iface
, D3DDEVICEDESC7
*desc
)
416 return d3d_device7_GetCaps(iface
, desc
);
419 static HRESULT WINAPI
d3d_device7_GetCaps_FPUPreserve(IDirect3DDevice7
*iface
, D3DDEVICEDESC7
*desc
)
424 old_fpucw
= d3d_fpu_setup();
425 hr
= d3d_device7_GetCaps(iface
, desc
);
426 set_fpu_control_word(old_fpucw
);
430 /*****************************************************************************
431 * IDirect3DDevice3::GetCaps
433 * Retrieves the capabilities of the hardware device and the emulation
434 * device. For Wine, hardware and emulation are the same (it's all HW).
436 * This implementation is used for Version 1, 2, and 3. Version 7 has its own
439 * HWDesc: Structure to fill with the HW caps
440 * HelDesc: Structure to fill with the hardware emulation caps
444 * D3DERR_* if a problem occurs. See WineD3D
446 *****************************************************************************/
448 /* There are 3 versions of D3DDEVICEDESC. All 3 share the same name because
449 * Microsoft just expanded the existing structure without naming them
450 * D3DDEVICEDESC2 and D3DDEVICEDESC3. Which version is used have depends
451 * on the version of the DirectX SDK. DirectX 6+ and Wine use the latest
452 * one with 252 bytes.
454 * All 3 versions are allowed as parameters and only the specified amount of
457 * Note that Direct3D7 and earlier are not available in native Win64
458 * ddraw.dll builds, so possible size differences between 32 bit and
459 * 64 bit are a non-issue.
461 static inline BOOL
check_d3ddevicedesc_size(DWORD size
)
463 if (size
== FIELD_OFFSET(D3DDEVICEDESC
, dwMinTextureWidth
) /* 172 */
464 || size
== FIELD_OFFSET(D3DDEVICEDESC
, dwMaxTextureRepeat
) /* 204 */
465 || size
== sizeof(D3DDEVICEDESC
) /* 252 */) return TRUE
;
469 static HRESULT WINAPI
d3d_device3_GetCaps(IDirect3DDevice3
*iface
,
470 D3DDEVICEDESC
*HWDesc
, D3DDEVICEDESC
*HelDesc
)
472 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
473 D3DDEVICEDESC7 desc7
;
477 TRACE("iface %p, hw_desc %p, hel_desc %p.\n", iface
, HWDesc
, HelDesc
);
481 WARN("HWDesc is NULL, returning DDERR_INVALIDPARAMS.\n");
482 return DDERR_INVALIDPARAMS
;
484 if (!check_d3ddevicedesc_size(HWDesc
->dwSize
))
486 WARN("HWDesc->dwSize is %u, returning DDERR_INVALIDPARAMS.\n", HWDesc
->dwSize
);
487 return DDERR_INVALIDPARAMS
;
491 WARN("HelDesc is NULL, returning DDERR_INVALIDPARAMS.\n");
492 return DDERR_INVALIDPARAMS
;
494 if (!check_d3ddevicedesc_size(HelDesc
->dwSize
))
496 WARN("HelDesc->dwSize is %u, returning DDERR_INVALIDPARAMS.\n", HelDesc
->dwSize
);
497 return DDERR_INVALIDPARAMS
;
500 if (FAILED(hr
= ddraw_get_d3dcaps(device
->ddraw
, &desc7
)))
503 ddraw_d3dcaps1_from_7(&desc1
, &desc7
);
504 DD_STRUCT_COPY_BYSIZE(HWDesc
, &desc1
);
505 DD_STRUCT_COPY_BYSIZE(HelDesc
, &desc1
);
509 static HRESULT WINAPI
d3d_device2_GetCaps(IDirect3DDevice2
*iface
,
510 D3DDEVICEDESC
*hw_desc
, D3DDEVICEDESC
*hel_desc
)
512 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
514 TRACE("iface %p, hw_desc %p, hel_desc %p.\n", iface
, hw_desc
, hel_desc
);
516 return d3d_device3_GetCaps(&device
->IDirect3DDevice3_iface
, hw_desc
, hel_desc
);
519 static HRESULT WINAPI
d3d_device1_GetCaps(IDirect3DDevice
*iface
,
520 D3DDEVICEDESC
*hw_desc
, D3DDEVICEDESC
*hel_desc
)
522 struct d3d_device
*device
= impl_from_IDirect3DDevice(iface
);
524 TRACE("iface %p, hw_desc %p, hel_desc %p.\n", iface
, hw_desc
, hel_desc
);
526 return d3d_device3_GetCaps(&device
->IDirect3DDevice3_iface
, hw_desc
, hel_desc
);
529 /*****************************************************************************
530 * IDirect3DDevice2::SwapTextureHandles
532 * Swaps the texture handles of 2 Texture interfaces. Version 1 and 2
535 * Tex1, Tex2: The 2 Textures to swap
540 *****************************************************************************/
541 static HRESULT WINAPI
d3d_device2_SwapTextureHandles(IDirect3DDevice2
*iface
,
542 IDirect3DTexture2
*tex1
, IDirect3DTexture2
*tex2
)
544 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
545 struct ddraw_surface
*surf1
= unsafe_impl_from_IDirect3DTexture2(tex1
);
546 struct ddraw_surface
*surf2
= unsafe_impl_from_IDirect3DTexture2(tex2
);
549 TRACE("iface %p, tex1 %p, tex2 %p.\n", iface
, tex1
, tex2
);
551 wined3d_mutex_lock();
553 h1
= surf1
->Handle
- 1;
554 h2
= surf2
->Handle
- 1;
555 device
->handle_table
.entries
[h1
].object
= surf2
;
556 device
->handle_table
.entries
[h2
].object
= surf1
;
557 surf2
->Handle
= h1
+ 1;
558 surf1
->Handle
= h2
+ 1;
560 wined3d_mutex_unlock();
565 static HRESULT WINAPI
d3d_device1_SwapTextureHandles(IDirect3DDevice
*iface
,
566 IDirect3DTexture
*tex1
, IDirect3DTexture
*tex2
)
568 struct d3d_device
*device
= impl_from_IDirect3DDevice(iface
);
569 struct ddraw_surface
*surf1
= unsafe_impl_from_IDirect3DTexture(tex1
);
570 struct ddraw_surface
*surf2
= unsafe_impl_from_IDirect3DTexture(tex2
);
571 IDirect3DTexture2
*t1
= surf1
? &surf1
->IDirect3DTexture2_iface
: NULL
;
572 IDirect3DTexture2
*t2
= surf2
? &surf2
->IDirect3DTexture2_iface
: NULL
;
574 TRACE("iface %p, tex1 %p, tex2 %p.\n", iface
, tex1
, tex2
);
576 return d3d_device2_SwapTextureHandles(&device
->IDirect3DDevice2_iface
, t1
, t2
);
579 /*****************************************************************************
580 * IDirect3DDevice3::GetStats
582 * This method seems to retrieve some stats from the device.
583 * The MSDN documentation doesn't exist any more, but the D3DSTATS
584 * structure suggests that the amount of drawn primitives and processed
585 * vertices is returned.
587 * Exists in Version 1, 2 and 3
590 * Stats: Pointer to a D3DSTATS structure to be filled
594 * DDERR_INVALIDPARAMS if Stats == NULL
596 *****************************************************************************/
597 static HRESULT WINAPI
d3d_device3_GetStats(IDirect3DDevice3
*iface
, D3DSTATS
*Stats
)
599 FIXME("iface %p, stats %p stub!\n", iface
, Stats
);
602 return DDERR_INVALIDPARAMS
;
604 /* Fill the Stats with 0 */
605 Stats
->dwTrianglesDrawn
= 0;
606 Stats
->dwLinesDrawn
= 0;
607 Stats
->dwPointsDrawn
= 0;
608 Stats
->dwSpansDrawn
= 0;
609 Stats
->dwVerticesProcessed
= 0;
614 static HRESULT WINAPI
d3d_device2_GetStats(IDirect3DDevice2
*iface
, D3DSTATS
*stats
)
616 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
618 TRACE("iface %p, stats %p.\n", iface
, stats
);
620 return d3d_device3_GetStats(&device
->IDirect3DDevice3_iface
, stats
);
623 static HRESULT WINAPI
d3d_device1_GetStats(IDirect3DDevice
*iface
, D3DSTATS
*stats
)
625 struct d3d_device
*device
= impl_from_IDirect3DDevice(iface
);
627 TRACE("iface %p, stats %p.\n", iface
, stats
);
629 return d3d_device3_GetStats(&device
->IDirect3DDevice3_iface
, stats
);
632 /*****************************************************************************
633 * IDirect3DDevice::CreateExecuteBuffer
635 * Creates an IDirect3DExecuteBuffer, used for rendering with a
641 * Desc: Buffer description
642 * ExecuteBuffer: Address to return the Interface pointer at
643 * UnkOuter: Must be NULL. Basically for aggregation, which ddraw doesn't
647 * CLASS_E_NOAGGREGATION if UnkOuter != NULL
648 * DDERR_OUTOFMEMORY if we ran out of memory
651 *****************************************************************************/
652 static HRESULT WINAPI
d3d_device1_CreateExecuteBuffer(IDirect3DDevice
*iface
,
653 D3DEXECUTEBUFFERDESC
*buffer_desc
, IDirect3DExecuteBuffer
**ExecuteBuffer
, IUnknown
*outer_unknown
)
655 struct d3d_device
*device
= impl_from_IDirect3DDevice(iface
);
656 struct d3d_execute_buffer
*object
;
659 TRACE("iface %p, buffer_desc %p, buffer %p, outer_unknown %p.\n",
660 iface
, buffer_desc
, ExecuteBuffer
, outer_unknown
);
663 return CLASS_E_NOAGGREGATION
;
665 /* Allocate the new Execute Buffer */
666 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*object
));
669 ERR("Failed to allocate execute buffer memory.\n");
670 return DDERR_OUTOFMEMORY
;
673 hr
= d3d_execute_buffer_init(object
, device
, buffer_desc
);
676 WARN("Failed to initialize execute buffer, hr %#x.\n", hr
);
677 HeapFree(GetProcessHeap(), 0, object
);
681 *ExecuteBuffer
= &object
->IDirect3DExecuteBuffer_iface
;
683 TRACE(" Returning IDirect3DExecuteBuffer at %p, implementation is at %p\n", *ExecuteBuffer
, object
);
688 /*****************************************************************************
689 * IDirect3DDevice::Execute
691 * Executes all the stuff in an execute buffer.
694 * ExecuteBuffer: The buffer to execute
695 * Viewport: The viewport used for rendering
699 * DDERR_INVALIDPARAMS if ExecuteBuffer == NULL
702 *****************************************************************************/
703 static HRESULT WINAPI
d3d_device1_Execute(IDirect3DDevice
*iface
,
704 IDirect3DExecuteBuffer
*ExecuteBuffer
, IDirect3DViewport
*viewport
, DWORD flags
)
706 struct d3d_device
*device
= impl_from_IDirect3DDevice(iface
);
707 struct d3d_execute_buffer
*buffer
= unsafe_impl_from_IDirect3DExecuteBuffer(ExecuteBuffer
);
708 struct d3d_viewport
*viewport_impl
= unsafe_impl_from_IDirect3DViewport(viewport
);
711 TRACE("iface %p, buffer %p, viewport %p, flags %#x.\n", iface
, ExecuteBuffer
, viewport
, flags
);
714 return DDERR_INVALIDPARAMS
;
717 wined3d_mutex_lock();
718 hr
= d3d_execute_buffer_execute(buffer
, device
, viewport_impl
);
719 wined3d_mutex_unlock();
724 /*****************************************************************************
725 * IDirect3DDevice3::AddViewport
727 * Add a Direct3DViewport to the device's viewport list. These viewports
728 * are wrapped to IDirect3DDevice7 viewports in viewport.c
730 * Exists in Version 1, 2 and 3. Note that IDirect3DViewport 1, 2 and 3
731 * are the same interfaces.
734 * Viewport: The viewport to add
737 * DDERR_INVALIDPARAMS if Viewport == NULL
740 *****************************************************************************/
741 static HRESULT WINAPI
d3d_device3_AddViewport(IDirect3DDevice3
*iface
, IDirect3DViewport3
*viewport
)
743 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
744 struct d3d_viewport
*vp
= unsafe_impl_from_IDirect3DViewport3(viewport
);
746 TRACE("iface %p, viewport %p.\n", iface
, viewport
);
750 return DDERR_INVALIDPARAMS
;
752 wined3d_mutex_lock();
753 IDirect3DViewport3_AddRef(viewport
);
754 list_add_head(&device
->viewport_list
, &vp
->entry
);
755 /* Viewport must be usable for Clear() after AddViewport, so set active_device here. */
756 vp
->active_device
= device
;
757 wined3d_mutex_unlock();
762 static HRESULT WINAPI
d3d_device2_AddViewport(IDirect3DDevice2
*iface
,
763 IDirect3DViewport2
*viewport
)
765 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
766 struct d3d_viewport
*vp
= unsafe_impl_from_IDirect3DViewport2(viewport
);
768 TRACE("iface %p, viewport %p.\n", iface
, viewport
);
770 return d3d_device3_AddViewport(&device
->IDirect3DDevice3_iface
, &vp
->IDirect3DViewport3_iface
);
773 static HRESULT WINAPI
d3d_device1_AddViewport(IDirect3DDevice
*iface
, IDirect3DViewport
*viewport
)
775 struct d3d_device
*device
= impl_from_IDirect3DDevice(iface
);
776 struct d3d_viewport
*vp
= unsafe_impl_from_IDirect3DViewport(viewport
);
778 TRACE("iface %p, viewport %p.\n", iface
, viewport
);
780 return d3d_device3_AddViewport(&device
->IDirect3DDevice3_iface
, &vp
->IDirect3DViewport3_iface
);
783 /*****************************************************************************
784 * IDirect3DDevice3::DeleteViewport
786 * Deletes a Direct3DViewport from the device's viewport list.
788 * Exists in Version 1, 2 and 3. Note that all Viewport interface versions
792 * Viewport: The viewport to delete
796 * DDERR_INVALIDPARAMS if the viewport wasn't found in the list
798 *****************************************************************************/
799 static HRESULT WINAPI
d3d_device3_DeleteViewport(IDirect3DDevice3
*iface
, IDirect3DViewport3
*viewport
)
801 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
802 struct d3d_viewport
*vp
= unsafe_impl_from_IDirect3DViewport3(viewport
);
804 TRACE("iface %p, viewport %p.\n", iface
, viewport
);
808 WARN("NULL viewport, returning DDERR_INVALIDPARAMS\n");
809 return DDERR_INVALIDPARAMS
;
812 wined3d_mutex_lock();
814 if (vp
->active_device
!= device
)
816 WARN("Viewport %p active device is %p.\n", vp
, vp
->active_device
);
817 wined3d_mutex_unlock();
818 return DDERR_INVALIDPARAMS
;
821 if (device
->current_viewport
== vp
)
823 TRACE("Deleting current viewport, unsetting and releasing\n");
824 IDirect3DViewport3_Release(viewport
);
825 device
->current_viewport
= NULL
;
828 vp
->active_device
= NULL
;
829 list_remove(&vp
->entry
);
831 IDirect3DViewport3_Release(viewport
);
833 wined3d_mutex_unlock();
838 static HRESULT WINAPI
d3d_device2_DeleteViewport(IDirect3DDevice2
*iface
, IDirect3DViewport2
*viewport
)
840 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
841 struct d3d_viewport
*vp
= unsafe_impl_from_IDirect3DViewport2(viewport
);
843 TRACE("iface %p, viewport %p.\n", iface
, viewport
);
845 return d3d_device3_DeleteViewport(&device
->IDirect3DDevice3_iface
,
846 vp
? &vp
->IDirect3DViewport3_iface
: NULL
);
849 static HRESULT WINAPI
d3d_device1_DeleteViewport(IDirect3DDevice
*iface
, IDirect3DViewport
*viewport
)
851 struct d3d_device
*device
= impl_from_IDirect3DDevice(iface
);
852 struct d3d_viewport
*vp
= unsafe_impl_from_IDirect3DViewport(viewport
);
854 TRACE("iface %p, viewport %p.\n", iface
, viewport
);
856 return d3d_device3_DeleteViewport(&device
->IDirect3DDevice3_iface
,
857 vp
? &vp
->IDirect3DViewport3_iface
: NULL
);
860 /*****************************************************************************
861 * IDirect3DDevice3::NextViewport
863 * Returns a viewport from the viewport list, depending on the
864 * passed viewport and the flags.
866 * Exists in Version 1, 2 and 3. Note that all Viewport interface versions
870 * Viewport: Viewport to use for beginning the search
871 * Flags: D3DNEXT_NEXT, D3DNEXT_HEAD or D3DNEXT_TAIL
875 * DDERR_INVALIDPARAMS if the flags were wrong, or Viewport was NULL
877 *****************************************************************************/
878 static HRESULT WINAPI
d3d_device3_NextViewport(IDirect3DDevice3
*iface
,
879 IDirect3DViewport3
*Viewport3
, IDirect3DViewport3
**lplpDirect3DViewport3
, DWORD flags
)
881 struct d3d_device
*This
= impl_from_IDirect3DDevice3(iface
);
882 struct d3d_viewport
*vp
= unsafe_impl_from_IDirect3DViewport3(Viewport3
);
883 struct d3d_viewport
*next
;
886 TRACE("iface %p, viewport %p, next %p, flags %#x.\n",
887 iface
, Viewport3
, lplpDirect3DViewport3
, flags
);
891 *lplpDirect3DViewport3
= NULL
;
892 return DDERR_INVALIDPARAMS
;
896 wined3d_mutex_lock();
900 entry
= list_next(&This
->viewport_list
, &vp
->entry
);
904 entry
= list_head(&This
->viewport_list
);
908 entry
= list_tail(&This
->viewport_list
);
912 WARN("Invalid flags %#x.\n", flags
);
913 *lplpDirect3DViewport3
= NULL
;
914 wined3d_mutex_unlock();
915 return DDERR_INVALIDPARAMS
;
920 next
= LIST_ENTRY(entry
, struct d3d_viewport
, entry
);
921 *lplpDirect3DViewport3
= &next
->IDirect3DViewport3_iface
;
924 *lplpDirect3DViewport3
= NULL
;
926 wined3d_mutex_unlock();
931 static HRESULT WINAPI
d3d_device2_NextViewport(IDirect3DDevice2
*iface
,
932 IDirect3DViewport2
*viewport
, IDirect3DViewport2
**next
, DWORD flags
)
934 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
935 struct d3d_viewport
*vp
= unsafe_impl_from_IDirect3DViewport2(viewport
);
936 IDirect3DViewport3
*res
;
939 TRACE("iface %p, viewport %p, next %p, flags %#x.\n",
940 iface
, viewport
, next
, flags
);
942 hr
= d3d_device3_NextViewport(&device
->IDirect3DDevice3_iface
,
943 &vp
->IDirect3DViewport3_iface
, &res
, flags
);
944 *next
= (IDirect3DViewport2
*)res
;
948 static HRESULT WINAPI
d3d_device1_NextViewport(IDirect3DDevice
*iface
,
949 IDirect3DViewport
*viewport
, IDirect3DViewport
**next
, DWORD flags
)
951 struct d3d_device
*device
= impl_from_IDirect3DDevice(iface
);
952 struct d3d_viewport
*vp
= unsafe_impl_from_IDirect3DViewport(viewport
);
953 IDirect3DViewport3
*res
;
956 TRACE("iface %p, viewport %p, next %p, flags %#x.\n",
957 iface
, viewport
, next
, flags
);
959 hr
= d3d_device3_NextViewport(&device
->IDirect3DDevice3_iface
,
960 &vp
->IDirect3DViewport3_iface
, &res
, flags
);
961 *next
= (IDirect3DViewport
*)res
;
965 /*****************************************************************************
966 * IDirect3DDevice::Pick
968 * Executes an execute buffer without performing rendering. Instead, a
969 * list of primitives that intersect with (x1,y1) of the passed rectangle
970 * is created. IDirect3DDevice::GetPickRecords can be used to retrieve
976 * ExecuteBuffer: Buffer to execute
977 * Viewport: Viewport to use for execution
978 * Flags: None are defined, according to the SDK
979 * Rect: Specifies the coordinates to be picked. Only x1 and y2 are used,
980 * x2 and y2 are ignored.
983 * D3D_OK because it's a stub
985 *****************************************************************************/
986 static HRESULT WINAPI
d3d_device1_Pick(IDirect3DDevice
*iface
, IDirect3DExecuteBuffer
*buffer
,
987 IDirect3DViewport
*viewport
, DWORD flags
, D3DRECT
*rect
)
989 FIXME("iface %p, buffer %p, viewport %p, flags %#x, rect %s stub!\n",
990 iface
, buffer
, viewport
, flags
, wine_dbgstr_rect((RECT
*)rect
));
995 /*****************************************************************************
996 * IDirect3DDevice::GetPickRecords
998 * Retrieves the pick records generated by IDirect3DDevice::GetPickRecords
1003 * Count: Pointer to a DWORD containing the numbers of pick records to
1005 * D3DPickRec: Address to store the resulting D3DPICKRECORD array.
1008 * D3D_OK, because it's a stub
1010 *****************************************************************************/
1011 static HRESULT WINAPI
d3d_device1_GetPickRecords(IDirect3DDevice
*iface
,
1012 DWORD
*count
, D3DPICKRECORD
*records
)
1014 FIXME("iface %p, count %p, records %p stub!\n", iface
, count
, records
);
1019 /*****************************************************************************
1020 * IDirect3DDevice7::EnumTextureformats
1022 * Enumerates the supported texture formats. It has a list of all possible
1023 * formats and calls IWineD3D::CheckDeviceFormat for each format to see if
1024 * WineD3D supports it. If so, then it is passed to the app.
1026 * This is for Version 7 and 3, older versions have a different
1027 * callback function and their own implementation
1030 * Callback: Callback to call for each enumerated format
1031 * Arg: Argument to pass to the callback
1035 * DDERR_INVALIDPARAMS if Callback == NULL
1037 *****************************************************************************/
1038 static HRESULT
d3d_device7_EnumTextureFormats(IDirect3DDevice7
*iface
,
1039 LPD3DENUMPIXELFORMATSCALLBACK callback
, void *context
)
1041 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
1042 struct wined3d_display_mode mode
;
1046 static const enum wined3d_format_id FormatList
[] =
1049 WINED3DFMT_B5G5R5X1_UNORM
,
1050 WINED3DFMT_B5G5R5A1_UNORM
,
1051 WINED3DFMT_B4G4R4A4_UNORM
,
1052 WINED3DFMT_B5G6R5_UNORM
,
1054 WINED3DFMT_B8G8R8X8_UNORM
,
1055 WINED3DFMT_B8G8R8A8_UNORM
,
1057 WINED3DFMT_B2G3R3_UNORM
,
1067 static const enum wined3d_format_id BumpFormatList
[] =
1069 WINED3DFMT_R8G8_SNORM
,
1070 WINED3DFMT_R5G5_SNORM_L6_UNORM
,
1071 WINED3DFMT_R8G8_SNORM_L8X8_UNORM
,
1072 WINED3DFMT_R10G11B11_SNORM
,
1073 WINED3DFMT_R10G10B10_SNORM_A2_UNORM
1076 TRACE("iface %p, callback %p, context %p.\n", iface
, callback
, context
);
1079 return DDERR_INVALIDPARAMS
;
1081 wined3d_mutex_lock();
1083 memset(&mode
, 0, sizeof(mode
));
1084 if (FAILED(hr
= wined3d_get_adapter_display_mode(device
->ddraw
->wined3d
, WINED3DADAPTER_DEFAULT
, &mode
, NULL
)))
1086 wined3d_mutex_unlock();
1087 WARN("Cannot get the current adapter format\n");
1091 for (i
= 0; i
< sizeof(FormatList
) / sizeof(*FormatList
); ++i
)
1093 if (wined3d_check_device_format(device
->ddraw
->wined3d
, WINED3DADAPTER_DEFAULT
, WINED3D_DEVICE_TYPE_HAL
,
1094 mode
.format_id
, 0, WINED3D_RTYPE_TEXTURE
, FormatList
[i
]) == D3D_OK
)
1096 DDPIXELFORMAT pformat
;
1098 memset(&pformat
, 0, sizeof(pformat
));
1099 pformat
.dwSize
= sizeof(pformat
);
1100 ddrawformat_from_wined3dformat(&pformat
, FormatList
[i
]);
1102 TRACE("Enumerating WineD3DFormat %d\n", FormatList
[i
]);
1103 hr
= callback(&pformat
, context
);
1104 if(hr
!= DDENUMRET_OK
)
1106 TRACE("Format enumeration cancelled by application\n");
1107 wined3d_mutex_unlock();
1113 for (i
= 0; i
< sizeof(BumpFormatList
) / sizeof(*BumpFormatList
); ++i
)
1115 if (wined3d_check_device_format(device
->ddraw
->wined3d
, WINED3DADAPTER_DEFAULT
,
1116 WINED3D_DEVICE_TYPE_HAL
, mode
.format_id
, WINED3DUSAGE_QUERY_LEGACYBUMPMAP
,
1117 WINED3D_RTYPE_TEXTURE
, BumpFormatList
[i
]) == D3D_OK
)
1119 DDPIXELFORMAT pformat
;
1121 memset(&pformat
, 0, sizeof(pformat
));
1122 pformat
.dwSize
= sizeof(pformat
);
1123 ddrawformat_from_wined3dformat(&pformat
, BumpFormatList
[i
]);
1125 TRACE("Enumerating WineD3DFormat %d\n", BumpFormatList
[i
]);
1126 hr
= callback(&pformat
, context
);
1127 if(hr
!= DDENUMRET_OK
)
1129 TRACE("Format enumeration cancelled by application\n");
1130 wined3d_mutex_unlock();
1135 TRACE("End of enumeration\n");
1136 wined3d_mutex_unlock();
1141 static HRESULT WINAPI
d3d_device7_EnumTextureFormats_FPUSetup(IDirect3DDevice7
*iface
,
1142 LPD3DENUMPIXELFORMATSCALLBACK callback
, void *context
)
1144 return d3d_device7_EnumTextureFormats(iface
, callback
, context
);
1147 static HRESULT WINAPI
d3d_device7_EnumTextureFormats_FPUPreserve(IDirect3DDevice7
*iface
,
1148 LPD3DENUMPIXELFORMATSCALLBACK callback
, void *context
)
1153 old_fpucw
= d3d_fpu_setup();
1154 hr
= d3d_device7_EnumTextureFormats(iface
, callback
, context
);
1155 set_fpu_control_word(old_fpucw
);
1160 static HRESULT WINAPI
d3d_device3_EnumTextureFormats(IDirect3DDevice3
*iface
,
1161 LPD3DENUMPIXELFORMATSCALLBACK callback
, void *context
)
1163 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
1165 TRACE("iface %p, callback %p, context %p.\n", iface
, callback
, context
);
1167 return IDirect3DDevice7_EnumTextureFormats(&device
->IDirect3DDevice7_iface
, callback
, context
);
1170 /*****************************************************************************
1171 * IDirect3DDevice2::EnumTextureformats
1173 * EnumTextureFormats for Version 1 and 2, see
1174 * IDirect3DDevice7::EnumTexureFormats for a more detailed description.
1176 * This version has a different callback and does not enumerate FourCC
1179 *****************************************************************************/
1180 static HRESULT WINAPI
d3d_device2_EnumTextureFormats(IDirect3DDevice2
*iface
,
1181 LPD3DENUMTEXTUREFORMATSCALLBACK callback
, void *context
)
1183 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
1184 struct wined3d_display_mode mode
;
1188 static const enum wined3d_format_id FormatList
[] =
1191 WINED3DFMT_B5G5R5X1_UNORM
,
1192 WINED3DFMT_B5G5R5A1_UNORM
,
1193 WINED3DFMT_B4G4R4A4_UNORM
,
1194 WINED3DFMT_B5G6R5_UNORM
,
1196 WINED3DFMT_B8G8R8X8_UNORM
,
1197 WINED3DFMT_B8G8R8A8_UNORM
,
1199 WINED3DFMT_B2G3R3_UNORM
,
1201 /* FOURCC codes - Not in this version*/
1204 TRACE("iface %p, callback %p, context %p.\n", iface
, callback
, context
);
1207 return DDERR_INVALIDPARAMS
;
1209 wined3d_mutex_lock();
1211 memset(&mode
, 0, sizeof(mode
));
1212 if (FAILED(hr
= wined3d_get_adapter_display_mode(device
->ddraw
->wined3d
, WINED3DADAPTER_DEFAULT
, &mode
, NULL
)))
1214 wined3d_mutex_unlock();
1215 WARN("Cannot get the current adapter format\n");
1219 for (i
= 0; i
< sizeof(FormatList
) / sizeof(*FormatList
); ++i
)
1221 if (wined3d_check_device_format(device
->ddraw
->wined3d
, 0, WINED3D_DEVICE_TYPE_HAL
,
1222 mode
.format_id
, 0, WINED3D_RTYPE_TEXTURE
, FormatList
[i
]) == D3D_OK
)
1224 DDSURFACEDESC sdesc
;
1226 memset(&sdesc
, 0, sizeof(sdesc
));
1227 sdesc
.dwSize
= sizeof(sdesc
);
1228 sdesc
.dwFlags
= DDSD_PIXELFORMAT
| DDSD_CAPS
;
1229 sdesc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
1230 sdesc
.ddpfPixelFormat
.dwSize
= sizeof(sdesc
.ddpfPixelFormat
);
1231 ddrawformat_from_wined3dformat(&sdesc
.ddpfPixelFormat
, FormatList
[i
]);
1233 TRACE("Enumerating WineD3DFormat %d\n", FormatList
[i
]);
1234 hr
= callback(&sdesc
, context
);
1235 if(hr
!= DDENUMRET_OK
)
1237 TRACE("Format enumeration cancelled by application\n");
1238 wined3d_mutex_unlock();
1243 TRACE("End of enumeration\n");
1244 wined3d_mutex_unlock();
1249 static HRESULT WINAPI
d3d_device1_EnumTextureFormats(IDirect3DDevice
*iface
,
1250 LPD3DENUMTEXTUREFORMATSCALLBACK callback
, void *context
)
1252 struct d3d_device
*device
= impl_from_IDirect3DDevice(iface
);
1254 TRACE("iface %p, callback %p, context %p.\n", iface
, callback
, context
);
1256 return d3d_device2_EnumTextureFormats(&device
->IDirect3DDevice2_iface
, callback
, context
);
1259 /*****************************************************************************
1260 * IDirect3DDevice::CreateMatrix
1262 * Creates a matrix handle. A handle is created and memory for a D3DMATRIX is
1263 * allocated for the handle.
1268 * D3DMatHandle: Address to return the handle at
1272 * DDERR_INVALIDPARAMS if D3DMatHandle = NULL
1274 *****************************************************************************/
1275 static HRESULT WINAPI
d3d_device1_CreateMatrix(IDirect3DDevice
*iface
, D3DMATRIXHANDLE
*D3DMatHandle
)
1277 struct d3d_device
*device
= impl_from_IDirect3DDevice(iface
);
1281 TRACE("iface %p, matrix_handle %p.\n", iface
, D3DMatHandle
);
1284 return DDERR_INVALIDPARAMS
;
1286 Matrix
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(D3DMATRIX
));
1289 ERR("Out of memory when allocating a D3DMATRIX\n");
1290 return DDERR_OUTOFMEMORY
;
1293 wined3d_mutex_lock();
1295 h
= ddraw_allocate_handle(&device
->handle_table
, Matrix
, DDRAW_HANDLE_MATRIX
);
1296 if (h
== DDRAW_INVALID_HANDLE
)
1298 ERR("Failed to allocate a matrix handle.\n");
1299 HeapFree(GetProcessHeap(), 0, Matrix
);
1300 wined3d_mutex_unlock();
1301 return DDERR_OUTOFMEMORY
;
1304 *D3DMatHandle
= h
+ 1;
1306 TRACE(" returning matrix handle %d\n", *D3DMatHandle
);
1308 wined3d_mutex_unlock();
1313 /*****************************************************************************
1314 * IDirect3DDevice::SetMatrix
1316 * Sets a matrix for a matrix handle. The matrix is copied into the memory
1317 * allocated for the handle
1322 * D3DMatHandle: Handle to set the matrix to
1323 * D3DMatrix: Matrix to set
1327 * DDERR_INVALIDPARAMS if the handle of the matrix is invalid or the matrix
1330 *****************************************************************************/
1331 static HRESULT WINAPI
d3d_device1_SetMatrix(IDirect3DDevice
*iface
,
1332 D3DMATRIXHANDLE D3DMatHandle
, D3DMATRIX
*D3DMatrix
)
1334 struct d3d_device
*This
= impl_from_IDirect3DDevice(iface
);
1337 TRACE("iface %p, matrix_handle %#x, matrix %p.\n", iface
, D3DMatHandle
, D3DMatrix
);
1339 if (!D3DMatrix
) return DDERR_INVALIDPARAMS
;
1341 wined3d_mutex_lock();
1343 m
= ddraw_get_object(&This
->handle_table
, D3DMatHandle
- 1, DDRAW_HANDLE_MATRIX
);
1346 WARN("Invalid matrix handle.\n");
1347 wined3d_mutex_unlock();
1348 return DDERR_INVALIDPARAMS
;
1351 if (TRACE_ON(ddraw
))
1352 dump_D3DMATRIX(D3DMatrix
);
1356 if (D3DMatHandle
== This
->world
)
1357 wined3d_device_set_transform(This
->wined3d_device
,
1358 WINED3D_TS_WORLD_MATRIX(0), (struct wined3d_matrix
*)D3DMatrix
);
1360 if (D3DMatHandle
== This
->view
)
1361 wined3d_device_set_transform(This
->wined3d_device
,
1362 WINED3D_TS_VIEW
, (struct wined3d_matrix
*)D3DMatrix
);
1364 if (D3DMatHandle
== This
->proj
)
1365 wined3d_device_set_transform(This
->wined3d_device
,
1366 WINED3D_TS_PROJECTION
, (struct wined3d_matrix
*)D3DMatrix
);
1368 wined3d_mutex_unlock();
1373 /*****************************************************************************
1374 * IDirect3DDevice::GetMatrix
1376 * Returns the content of a D3DMATRIX handle
1381 * D3DMatHandle: Matrix handle to read the content from
1382 * D3DMatrix: Address to store the content at
1386 * DDERR_INVALIDPARAMS if D3DMatHandle is invalid or D3DMatrix is NULL
1388 *****************************************************************************/
1389 static HRESULT WINAPI
d3d_device1_GetMatrix(IDirect3DDevice
*iface
,
1390 D3DMATRIXHANDLE D3DMatHandle
, D3DMATRIX
*D3DMatrix
)
1392 struct d3d_device
*device
= impl_from_IDirect3DDevice(iface
);
1395 TRACE("iface %p, matrix_handle %#x, matrix %p.\n", iface
, D3DMatHandle
, D3DMatrix
);
1397 if (!D3DMatrix
) return DDERR_INVALIDPARAMS
;
1399 wined3d_mutex_lock();
1401 m
= ddraw_get_object(&device
->handle_table
, D3DMatHandle
- 1, DDRAW_HANDLE_MATRIX
);
1404 WARN("Invalid matrix handle.\n");
1405 wined3d_mutex_unlock();
1406 return DDERR_INVALIDPARAMS
;
1411 wined3d_mutex_unlock();
1416 /*****************************************************************************
1417 * IDirect3DDevice::DeleteMatrix
1419 * Destroys a Matrix handle. Frees the memory and unsets the handle data
1424 * D3DMatHandle: Handle to destroy
1428 * DDERR_INVALIDPARAMS if D3DMatHandle is invalid
1430 *****************************************************************************/
1431 static HRESULT WINAPI
d3d_device1_DeleteMatrix(IDirect3DDevice
*iface
, D3DMATRIXHANDLE D3DMatHandle
)
1433 struct d3d_device
*device
= impl_from_IDirect3DDevice(iface
);
1436 TRACE("iface %p, matrix_handle %#x.\n", iface
, D3DMatHandle
);
1438 wined3d_mutex_lock();
1440 m
= ddraw_free_handle(&device
->handle_table
, D3DMatHandle
- 1, DDRAW_HANDLE_MATRIX
);
1443 WARN("Invalid matrix handle.\n");
1444 wined3d_mutex_unlock();
1445 return DDERR_INVALIDPARAMS
;
1448 wined3d_mutex_unlock();
1450 HeapFree(GetProcessHeap(), 0, m
);
1455 /*****************************************************************************
1456 * IDirect3DDevice7::BeginScene
1458 * This method must be called before any rendering is performed.
1459 * IDirect3DDevice::EndScene has to be called after the scene is complete
1461 * Version 1, 2, 3 and 7
1464 * D3D_OK on success, for details see IWineD3DDevice::BeginScene
1465 * D3DERR_SCENE_IN_SCENE if WineD3D returns an error(Only in case of an already
1468 *****************************************************************************/
1469 static HRESULT
d3d_device7_BeginScene(IDirect3DDevice7
*iface
)
1471 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
1474 TRACE("iface %p.\n", iface
);
1476 wined3d_mutex_lock();
1477 hr
= wined3d_device_begin_scene(device
->wined3d_device
);
1478 wined3d_mutex_unlock();
1480 if(hr
== WINED3D_OK
) return D3D_OK
;
1481 else return D3DERR_SCENE_IN_SCENE
; /* TODO: Other possible causes of failure */
1484 static HRESULT WINAPI
d3d_device7_BeginScene_FPUSetup(IDirect3DDevice7
*iface
)
1486 return d3d_device7_BeginScene(iface
);
1489 static HRESULT WINAPI
d3d_device7_BeginScene_FPUPreserve(IDirect3DDevice7
*iface
)
1494 old_fpucw
= d3d_fpu_setup();
1495 hr
= d3d_device7_BeginScene(iface
);
1496 set_fpu_control_word(old_fpucw
);
1501 static HRESULT WINAPI
d3d_device3_BeginScene(IDirect3DDevice3
*iface
)
1503 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
1505 TRACE("iface %p.\n", iface
);
1507 return IDirect3DDevice7_BeginScene(&device
->IDirect3DDevice7_iface
);
1510 static HRESULT WINAPI
d3d_device2_BeginScene(IDirect3DDevice2
*iface
)
1512 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
1514 TRACE("iface %p.\n", iface
);
1516 return IDirect3DDevice7_BeginScene(&device
->IDirect3DDevice7_iface
);
1519 static HRESULT WINAPI
d3d_device1_BeginScene(IDirect3DDevice
*iface
)
1521 struct d3d_device
*device
= impl_from_IDirect3DDevice(iface
);
1523 TRACE("iface %p.\n", iface
);
1525 return IDirect3DDevice7_BeginScene(&device
->IDirect3DDevice7_iface
);
1528 /*****************************************************************************
1529 * IDirect3DDevice7::EndScene
1531 * Ends a scene that has been begun with IDirect3DDevice7::BeginScene.
1532 * This method must be called after rendering is finished.
1534 * Version 1, 2, 3 and 7
1537 * D3D_OK on success, for details see IWineD3DDevice::EndScene
1538 * D3DERR_SCENE_NOT_IN_SCENE is returned if WineD3D returns an error. It does
1539 * that only if the scene was already ended.
1541 *****************************************************************************/
1542 static HRESULT
d3d_device7_EndScene(IDirect3DDevice7
*iface
)
1544 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
1547 TRACE("iface %p.\n", iface
);
1549 wined3d_mutex_lock();
1550 hr
= wined3d_device_end_scene(device
->wined3d_device
);
1551 wined3d_mutex_unlock();
1553 if(hr
== WINED3D_OK
) return D3D_OK
;
1554 else return D3DERR_SCENE_NOT_IN_SCENE
;
1557 static HRESULT WINAPI DECLSPEC_HOTPATCH
d3d_device7_EndScene_FPUSetup(IDirect3DDevice7
*iface
)
1559 return d3d_device7_EndScene(iface
);
1562 static HRESULT WINAPI DECLSPEC_HOTPATCH
d3d_device7_EndScene_FPUPreserve(IDirect3DDevice7
*iface
)
1567 old_fpucw
= d3d_fpu_setup();
1568 hr
= d3d_device7_EndScene(iface
);
1569 set_fpu_control_word(old_fpucw
);
1574 static HRESULT WINAPI DECLSPEC_HOTPATCH
d3d_device3_EndScene(IDirect3DDevice3
*iface
)
1576 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
1578 TRACE("iface %p.\n", iface
);
1580 return IDirect3DDevice7_EndScene(&device
->IDirect3DDevice7_iface
);
1583 static HRESULT WINAPI DECLSPEC_HOTPATCH
d3d_device2_EndScene(IDirect3DDevice2
*iface
)
1585 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
1587 TRACE("iface %p.\n", iface
);
1589 return IDirect3DDevice7_EndScene(&device
->IDirect3DDevice7_iface
);
1592 static HRESULT WINAPI DECLSPEC_HOTPATCH
d3d_device1_EndScene(IDirect3DDevice
*iface
)
1594 struct d3d_device
*device
= impl_from_IDirect3DDevice(iface
);
1596 TRACE("iface %p.\n", iface
);
1598 return IDirect3DDevice7_EndScene(&device
->IDirect3DDevice7_iface
);
1601 /*****************************************************************************
1602 * IDirect3DDevice7::GetDirect3D
1604 * Returns the IDirect3D(= interface to the DirectDraw object) used to create
1608 * Direct3D7: Address to store the interface pointer at
1612 * DDERR_INVALIDPARAMS if Direct3D7 == NULL
1614 *****************************************************************************/
1615 static HRESULT WINAPI
d3d_device7_GetDirect3D(IDirect3DDevice7
*iface
, IDirect3D7
**d3d
)
1617 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
1619 TRACE("iface %p, d3d %p.\n", iface
, d3d
);
1622 return DDERR_INVALIDPARAMS
;
1624 *d3d
= &device
->ddraw
->IDirect3D7_iface
;
1625 IDirect3D7_AddRef(*d3d
);
1627 TRACE("Returning interface %p.\n", *d3d
);
1631 static HRESULT WINAPI
d3d_device3_GetDirect3D(IDirect3DDevice3
*iface
, IDirect3D3
**d3d
)
1633 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
1635 TRACE("iface %p, d3d %p.\n", iface
, d3d
);
1638 return DDERR_INVALIDPARAMS
;
1640 *d3d
= &device
->ddraw
->IDirect3D3_iface
;
1641 IDirect3D3_AddRef(*d3d
);
1643 TRACE("Returning interface %p.\n", *d3d
);
1647 static HRESULT WINAPI
d3d_device2_GetDirect3D(IDirect3DDevice2
*iface
, IDirect3D2
**d3d
)
1649 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
1651 TRACE("iface %p, d3d %p.\n", iface
, d3d
);
1654 return DDERR_INVALIDPARAMS
;
1656 *d3d
= &device
->ddraw
->IDirect3D2_iface
;
1657 IDirect3D2_AddRef(*d3d
);
1659 TRACE("Returning interface %p.\n", *d3d
);
1663 static HRESULT WINAPI
d3d_device1_GetDirect3D(IDirect3DDevice
*iface
, IDirect3D
**d3d
)
1665 struct d3d_device
*device
= impl_from_IDirect3DDevice(iface
);
1667 TRACE("iface %p, d3d %p.\n", iface
, d3d
);
1670 return DDERR_INVALIDPARAMS
;
1672 *d3d
= &device
->ddraw
->IDirect3D_iface
;
1673 IDirect3D_AddRef(*d3d
);
1675 TRACE("Returning interface %p.\n", *d3d
);
1679 /*****************************************************************************
1680 * IDirect3DDevice3::SetCurrentViewport
1682 * Sets a Direct3DViewport as the current viewport.
1683 * For the thunks note that all viewport interface versions are equal
1686 * Direct3DViewport3: The viewport to set
1692 * (Is a NULL viewport valid?)
1694 *****************************************************************************/
1695 static HRESULT WINAPI
d3d_device3_SetCurrentViewport(IDirect3DDevice3
*iface
, IDirect3DViewport3
*Direct3DViewport3
)
1697 struct d3d_device
*This
= impl_from_IDirect3DDevice3(iface
);
1698 struct d3d_viewport
*vp
= unsafe_impl_from_IDirect3DViewport3(Direct3DViewport3
);
1700 TRACE("iface %p, viewport %p.\n", iface
, Direct3DViewport3
);
1704 WARN("Direct3DViewport3 is NULL, returning DDERR_INVALIDPARAMS\n");
1705 return DDERR_INVALIDPARAMS
;
1708 wined3d_mutex_lock();
1709 /* Do nothing if the specified viewport is the same as the current one */
1710 if (This
->current_viewport
== vp
)
1712 wined3d_mutex_unlock();
1716 if (vp
->active_device
!= This
)
1718 WARN("Viewport %p active device is %p.\n", vp
, vp
->active_device
);
1719 wined3d_mutex_unlock();
1720 return DDERR_INVALIDPARAMS
;
1723 /* Release previous viewport and AddRef the new one */
1724 if (This
->current_viewport
)
1726 TRACE("ViewportImpl is at %p, interface is at %p\n", This
->current_viewport
,
1727 &This
->current_viewport
->IDirect3DViewport3_iface
);
1728 IDirect3DViewport3_Release(&This
->current_viewport
->IDirect3DViewport3_iface
);
1730 IDirect3DViewport3_AddRef(Direct3DViewport3
);
1732 /* Set this viewport as the current viewport */
1733 This
->current_viewport
= vp
;
1735 /* Activate this viewport */
1736 viewport_activate(This
->current_viewport
, FALSE
);
1738 wined3d_mutex_unlock();
1743 static HRESULT WINAPI
d3d_device2_SetCurrentViewport(IDirect3DDevice2
*iface
, IDirect3DViewport2
*viewport
)
1745 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
1746 struct d3d_viewport
*vp
= unsafe_impl_from_IDirect3DViewport2(viewport
);
1748 TRACE("iface %p, viewport %p.\n", iface
, viewport
);
1750 return d3d_device3_SetCurrentViewport(&device
->IDirect3DDevice3_iface
,
1751 vp
? &vp
->IDirect3DViewport3_iface
: NULL
);
1754 /*****************************************************************************
1755 * IDirect3DDevice3::GetCurrentViewport
1757 * Returns the currently active viewport.
1762 * Direct3DViewport3: Address to return the interface pointer at
1766 * DDERR_INVALIDPARAMS if Direct3DViewport == NULL
1768 *****************************************************************************/
1769 static HRESULT WINAPI
d3d_device3_GetCurrentViewport(IDirect3DDevice3
*iface
, IDirect3DViewport3
**viewport
)
1771 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
1773 TRACE("iface %p, viewport %p.\n", iface
, viewport
);
1775 wined3d_mutex_lock();
1776 if (!device
->current_viewport
)
1778 wined3d_mutex_unlock();
1779 WARN("No current viewport, returning D3DERR_NOCURRENTVIEWPORT\n");
1780 return D3DERR_NOCURRENTVIEWPORT
;
1783 *viewport
= &device
->current_viewport
->IDirect3DViewport3_iface
;
1784 IDirect3DViewport3_AddRef(*viewport
);
1786 TRACE("Returning interface %p.\n", *viewport
);
1787 wined3d_mutex_unlock();
1791 static HRESULT WINAPI
d3d_device2_GetCurrentViewport(IDirect3DDevice2
*iface
, IDirect3DViewport2
**viewport
)
1793 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
1795 TRACE("iface %p, viewport %p.\n", iface
, viewport
);
1797 return d3d_device3_GetCurrentViewport(&device
->IDirect3DDevice3_iface
,
1798 (IDirect3DViewport3
**)viewport
);
1801 static BOOL
validate_surface_palette(struct ddraw_surface
*surface
)
1803 return !format_is_paletteindexed(&surface
->surface_desc
.u4
.ddpfPixelFormat
)
1804 || surface
->palette
;
1807 static HRESULT
d3d_device_set_render_target(struct d3d_device
*device
,
1808 struct ddraw_surface
*target
, IUnknown
*rt_iface
)
1812 if (device
->rt_iface
== rt_iface
)
1814 TRACE("No-op SetRenderTarget operation, not doing anything\n");
1819 WARN("Trying to set render target to NULL.\n");
1820 return DDERR_INVALIDPARAMS
;
1823 if (FAILED(hr
= wined3d_device_set_rendertarget_view(device
->wined3d_device
,
1824 0, ddraw_surface_get_rendertarget_view(target
), FALSE
)))
1827 IUnknown_AddRef(rt_iface
);
1828 IUnknown_Release(device
->rt_iface
);
1829 device
->rt_iface
= rt_iface
;
1830 d3d_device_update_depth_stencil(device
);
1835 static HRESULT
d3d_device7_SetRenderTarget(IDirect3DDevice7
*iface
,
1836 IDirectDrawSurface7
*target
, DWORD flags
)
1838 struct ddraw_surface
*target_impl
= unsafe_impl_from_IDirectDrawSurface7(target
);
1839 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
1842 TRACE("iface %p, target %p, flags %#x.\n", iface
, target
, flags
);
1844 wined3d_mutex_lock();
1846 if (!validate_surface_palette(target_impl
))
1848 WARN("Surface %p has an indexed pixel format, but no palette.\n", target_impl
);
1849 wined3d_mutex_unlock();
1850 return DDERR_INVALIDCAPS
;
1853 if (!(target_impl
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_3DDEVICE
))
1855 WARN("Surface %p is not a render target.\n", target_impl
);
1856 wined3d_mutex_unlock();
1857 return DDERR_INVALIDCAPS
;
1860 if (!(target_impl
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_VIDEOMEMORY
))
1862 WARN("Surface %p is not in video memory.\n", target_impl
);
1863 wined3d_mutex_unlock();
1864 return DDERR_INVALIDPARAMS
;
1867 if (target_impl
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_ZBUFFER
)
1869 WARN("Surface %p is a depth buffer.\n", target_impl
);
1870 IDirectDrawSurface7_AddRef(target
);
1871 IUnknown_Release(device
->rt_iface
);
1872 device
->rt_iface
= (IUnknown
*)target
;
1873 wined3d_mutex_unlock();
1874 return DDERR_INVALIDPIXELFORMAT
;
1877 hr
= d3d_device_set_render_target(device
, target_impl
, (IUnknown
*)target
);
1878 wined3d_mutex_unlock();
1882 static HRESULT WINAPI
d3d_device7_SetRenderTarget_FPUSetup(IDirect3DDevice7
*iface
,
1883 IDirectDrawSurface7
*NewTarget
, DWORD flags
)
1885 return d3d_device7_SetRenderTarget(iface
, NewTarget
, flags
);
1888 static HRESULT WINAPI
d3d_device7_SetRenderTarget_FPUPreserve(IDirect3DDevice7
*iface
,
1889 IDirectDrawSurface7
*NewTarget
, DWORD flags
)
1894 old_fpucw
= d3d_fpu_setup();
1895 hr
= d3d_device7_SetRenderTarget(iface
, NewTarget
, flags
);
1896 set_fpu_control_word(old_fpucw
);
1901 static HRESULT WINAPI
d3d_device3_SetRenderTarget(IDirect3DDevice3
*iface
,
1902 IDirectDrawSurface4
*target
, DWORD flags
)
1904 struct ddraw_surface
*target_impl
= unsafe_impl_from_IDirectDrawSurface4(target
);
1905 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
1908 TRACE("iface %p, target %p, flags %#x.\n", iface
, target
, flags
);
1910 wined3d_mutex_lock();
1912 if (!validate_surface_palette(target_impl
))
1914 WARN("Surface %p has an indexed pixel format, but no palette.\n", target_impl
);
1915 wined3d_mutex_unlock();
1916 return DDERR_INVALIDCAPS
;
1919 if (!(target_impl
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_3DDEVICE
))
1921 WARN("Surface %p is not a render target.\n", target_impl
);
1922 wined3d_mutex_unlock();
1923 return DDERR_INVALIDCAPS
;
1926 if (target_impl
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_ZBUFFER
)
1928 WARN("Surface %p is a depth buffer.\n", target_impl
);
1929 IDirectDrawSurface4_AddRef(target
);
1930 IUnknown_Release(device
->rt_iface
);
1931 device
->rt_iface
= (IUnknown
*)target
;
1932 wined3d_mutex_unlock();
1933 return DDERR_INVALIDPIXELFORMAT
;
1936 if (!(target_impl
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_VIDEOMEMORY
))
1938 WARN("Surface %p is not in video memory.\n", target_impl
);
1939 IDirectDrawSurface4_AddRef(target
);
1940 IUnknown_Release(device
->rt_iface
);
1941 device
->rt_iface
= (IUnknown
*)target
;
1942 wined3d_mutex_unlock();
1946 hr
= d3d_device_set_render_target(device
, target_impl
, (IUnknown
*)target
);
1947 wined3d_mutex_unlock();
1951 static HRESULT WINAPI
d3d_device2_SetRenderTarget(IDirect3DDevice2
*iface
,
1952 IDirectDrawSurface
*target
, DWORD flags
)
1954 struct ddraw_surface
*target_impl
= unsafe_impl_from_IDirectDrawSurface(target
);
1955 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
1958 TRACE("iface %p, target %p, flags %#x.\n", iface
, target
, flags
);
1960 wined3d_mutex_lock();
1962 if (!validate_surface_palette(target_impl
))
1964 WARN("Surface %p has an indexed pixel format, but no palette.\n", target_impl
);
1965 wined3d_mutex_unlock();
1966 return DDERR_INVALIDCAPS
;
1969 if (!(target_impl
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_3DDEVICE
))
1971 WARN("Surface %p is not a render target.\n", target_impl
);
1972 wined3d_mutex_unlock();
1973 return DDERR_INVALIDCAPS
;
1976 if (target_impl
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_ZBUFFER
)
1978 WARN("Surface %p is a depth buffer.\n", target_impl
);
1979 IUnknown_Release(device
->rt_iface
);
1980 device
->rt_iface
= (IUnknown
*)target
;
1981 wined3d_mutex_unlock();
1982 return DDERR_INVALIDPIXELFORMAT
;
1985 if (!(target_impl
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_VIDEOMEMORY
))
1987 WARN("Surface %p is not in video memory.\n", target_impl
);
1988 IDirectDrawSurface_AddRef(target
);
1989 IUnknown_Release(device
->rt_iface
);
1990 device
->rt_iface
= (IUnknown
*)target
;
1991 wined3d_mutex_unlock();
1995 hr
= d3d_device_set_render_target(device
, target_impl
, (IUnknown
*)target
);
1996 wined3d_mutex_unlock();
2000 /*****************************************************************************
2001 * IDirect3DDevice7::GetRenderTarget
2003 * Returns the current render target.
2004 * This is handled locally, because the WineD3D render target's parent
2007 * Version 2, 3 and 7
2010 * RenderTarget: Address to store the surface interface pointer
2014 * DDERR_INVALIDPARAMS if RenderTarget == NULL
2016 *****************************************************************************/
2017 static HRESULT WINAPI
d3d_device7_GetRenderTarget(IDirect3DDevice7
*iface
, IDirectDrawSurface7
**RenderTarget
)
2019 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
2022 TRACE("iface %p, target %p.\n", iface
, RenderTarget
);
2025 return DDERR_INVALIDPARAMS
;
2027 wined3d_mutex_lock();
2028 hr
= IUnknown_QueryInterface(device
->rt_iface
, &IID_IDirectDrawSurface7
, (void **)RenderTarget
);
2029 wined3d_mutex_unlock();
2034 static HRESULT WINAPI
d3d_device3_GetRenderTarget(IDirect3DDevice3
*iface
, IDirectDrawSurface4
**RenderTarget
)
2036 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
2037 IDirectDrawSurface7
*RenderTarget7
;
2038 struct ddraw_surface
*RenderTargetImpl
;
2041 TRACE("iface %p, target %p.\n", iface
, RenderTarget
);
2044 return DDERR_INVALIDPARAMS
;
2046 hr
= d3d_device7_GetRenderTarget(&device
->IDirect3DDevice7_iface
, &RenderTarget7
);
2047 if(hr
!= D3D_OK
) return hr
;
2048 RenderTargetImpl
= impl_from_IDirectDrawSurface7(RenderTarget7
);
2049 *RenderTarget
= &RenderTargetImpl
->IDirectDrawSurface4_iface
;
2050 IDirectDrawSurface4_AddRef(*RenderTarget
);
2051 IDirectDrawSurface7_Release(RenderTarget7
);
2055 static HRESULT WINAPI
d3d_device2_GetRenderTarget(IDirect3DDevice2
*iface
, IDirectDrawSurface
**RenderTarget
)
2057 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
2058 IDirectDrawSurface7
*RenderTarget7
;
2059 struct ddraw_surface
*RenderTargetImpl
;
2062 TRACE("iface %p, target %p.\n", iface
, RenderTarget
);
2065 return DDERR_INVALIDPARAMS
;
2067 hr
= d3d_device7_GetRenderTarget(&device
->IDirect3DDevice7_iface
, &RenderTarget7
);
2068 if(hr
!= D3D_OK
) return hr
;
2069 RenderTargetImpl
= impl_from_IDirectDrawSurface7(RenderTarget7
);
2070 *RenderTarget
= &RenderTargetImpl
->IDirectDrawSurface_iface
;
2071 IDirectDrawSurface_AddRef(*RenderTarget
);
2072 IDirectDrawSurface7_Release(RenderTarget7
);
2076 /*****************************************************************************
2077 * IDirect3DDevice3::Begin
2079 * Begins a description block of vertices. This is similar to glBegin()
2080 * and glEnd(). After a call to IDirect3DDevice3::End, the vertices
2081 * described with IDirect3DDevice::Vertex are drawn.
2086 * PrimitiveType: The type of primitives to draw
2087 * VertexTypeDesc: A flexible vertex format description of the vertices
2088 * Flags: Some flags..
2093 *****************************************************************************/
2094 static HRESULT WINAPI
d3d_device3_Begin(IDirect3DDevice3
*iface
,
2095 D3DPRIMITIVETYPE primitive_type
, DWORD fvf
, DWORD flags
)
2097 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
2099 TRACE("iface %p, primitive_type %#x, fvf %#x, flags %#x.\n",
2100 iface
, primitive_type
, fvf
, flags
);
2102 wined3d_mutex_lock();
2103 device
->primitive_type
= primitive_type
;
2104 device
->vertex_type
= fvf
;
2105 device
->render_flags
= flags
;
2106 device
->vertex_size
= get_flexible_vertex_size(device
->vertex_type
);
2107 device
->nb_vertices
= 0;
2108 wined3d_mutex_unlock();
2113 static HRESULT WINAPI
d3d_device2_Begin(IDirect3DDevice2
*iface
,
2114 D3DPRIMITIVETYPE primitive_type
, D3DVERTEXTYPE vertex_type
, DWORD flags
)
2116 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
2119 TRACE("iface %p, primitive_type %#x, vertex_type %#x, flags %#x.\n",
2120 iface
, primitive_type
, vertex_type
, flags
);
2122 switch (vertex_type
)
2124 case D3DVT_VERTEX
: fvf
= D3DFVF_VERTEX
; break;
2125 case D3DVT_LVERTEX
: fvf
= D3DFVF_LVERTEX
; break;
2126 case D3DVT_TLVERTEX
: fvf
= D3DFVF_TLVERTEX
; break;
2128 ERR("Unexpected vertex type %#x.\n", vertex_type
);
2129 return DDERR_INVALIDPARAMS
; /* Should never happen */
2132 return d3d_device3_Begin(&device
->IDirect3DDevice3_iface
, primitive_type
, fvf
, flags
);
2135 /*****************************************************************************
2136 * IDirect3DDevice3::BeginIndexed
2138 * Draws primitives based on vertices in a vertex array which are specified
2144 * PrimitiveType: Primitive type to draw
2145 * VertexType: A FVF description of the vertex format
2146 * Vertices: pointer to an array containing the vertices
2147 * NumVertices: The number of vertices in the vertex array
2148 * Flags: Some flags ...
2151 * D3D_OK, because it's a stub
2153 *****************************************************************************/
2154 static HRESULT WINAPI
d3d_device3_BeginIndexed(IDirect3DDevice3
*iface
,
2155 D3DPRIMITIVETYPE primitive_type
, DWORD fvf
,
2156 void *vertices
, DWORD vertex_count
, DWORD flags
)
2158 FIXME("iface %p, primitive_type %#x, fvf %#x, vertices %p, vertex_count %u, flags %#x stub!\n",
2159 iface
, primitive_type
, fvf
, vertices
, vertex_count
, flags
);
2165 static HRESULT WINAPI
d3d_device2_BeginIndexed(IDirect3DDevice2
*iface
,
2166 D3DPRIMITIVETYPE primitive_type
, D3DVERTEXTYPE vertex_type
,
2167 void *vertices
, DWORD vertex_count
, DWORD flags
)
2169 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
2172 TRACE("iface %p, primitive_type %#x, vertex_type %#x, vertices %p, vertex_count %u, flags %#x stub!\n",
2173 iface
, primitive_type
, vertex_type
, vertices
, vertex_count
, flags
);
2175 switch (vertex_type
)
2177 case D3DVT_VERTEX
: fvf
= D3DFVF_VERTEX
; break;
2178 case D3DVT_LVERTEX
: fvf
= D3DFVF_LVERTEX
; break;
2179 case D3DVT_TLVERTEX
: fvf
= D3DFVF_TLVERTEX
; break;
2181 ERR("Unexpected vertex type %#x.\n", vertex_type
);
2182 return DDERR_INVALIDPARAMS
; /* Should never happen */
2185 return d3d_device3_BeginIndexed(&device
->IDirect3DDevice3_iface
,
2186 primitive_type
, fvf
, vertices
, vertex_count
, flags
);
2189 /*****************************************************************************
2190 * IDirect3DDevice3::Vertex
2192 * Draws a vertex as described by IDirect3DDevice3::Begin. It places all
2193 * drawn vertices in a vertex buffer. If the buffer is too small, its
2194 * size is increased.
2199 * Vertex: Pointer to the vertex
2202 * D3D_OK, on success
2203 * DDERR_INVALIDPARAMS if Vertex is NULL
2205 *****************************************************************************/
2206 static HRESULT WINAPI
d3d_device3_Vertex(IDirect3DDevice3
*iface
, void *vertex
)
2208 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
2210 TRACE("iface %p, vertex %p.\n", iface
, vertex
);
2213 return DDERR_INVALIDPARAMS
;
2215 wined3d_mutex_lock();
2216 if ((device
->nb_vertices
+ 1) * device
->vertex_size
> device
->buffer_size
)
2220 device
->buffer_size
= device
->buffer_size
? device
->buffer_size
* 2 : device
->vertex_size
* 3;
2221 old_buffer
= device
->sysmem_vertex_buffer
;
2222 device
->sysmem_vertex_buffer
= HeapAlloc(GetProcessHeap(), 0, device
->buffer_size
);
2225 memcpy(device
->sysmem_vertex_buffer
, old_buffer
, device
->nb_vertices
* device
->vertex_size
);
2226 HeapFree(GetProcessHeap(), 0, old_buffer
);
2230 memcpy(device
->sysmem_vertex_buffer
+ device
->nb_vertices
++ * device
->vertex_size
, vertex
, device
->vertex_size
);
2231 wined3d_mutex_unlock();
2236 static HRESULT WINAPI
d3d_device2_Vertex(IDirect3DDevice2
*iface
, void *vertex
)
2238 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
2240 TRACE("iface %p, vertex %p.\n", iface
, vertex
);
2242 return d3d_device3_Vertex(&device
->IDirect3DDevice3_iface
, vertex
);
2245 /*****************************************************************************
2246 * IDirect3DDevice3::Index
2248 * Specifies an index to a vertex to be drawn. The vertex array has to
2249 * be specified with BeginIndexed first.
2252 * VertexIndex: The index of the vertex to draw
2255 * D3D_OK because it's a stub
2257 *****************************************************************************/
2258 static HRESULT WINAPI
d3d_device3_Index(IDirect3DDevice3
*iface
, WORD index
)
2260 FIXME("iface %p, index %#x stub!\n", iface
, index
);
2265 static HRESULT WINAPI
d3d_device2_Index(IDirect3DDevice2
*iface
, WORD index
)
2267 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
2269 TRACE("iface %p, index %#x.\n", iface
, index
);
2271 return d3d_device3_Index(&device
->IDirect3DDevice3_iface
, index
);
2274 /*****************************************************************************
2275 * IDirect3DDevice7::GetRenderState
2277 * Returns the value of a render state. The possible render states are
2278 * defined in include/d3dtypes.h
2280 * Version 2, 3 and 7
2283 * RenderStateType: Render state to return the current setting of
2284 * Value: Address to store the value at
2287 * D3D_OK on success, for details see IWineD3DDevice::GetRenderState
2288 * DDERR_INVALIDPARAMS if Value == NULL
2290 *****************************************************************************/
2291 static HRESULT
d3d_device7_GetRenderState(IDirect3DDevice7
*iface
,
2292 D3DRENDERSTATETYPE state
, DWORD
*value
)
2294 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
2295 HRESULT hr
= D3D_OK
;
2297 TRACE("iface %p, state %#x, value %p.\n", iface
, state
, value
);
2300 return DDERR_INVALIDPARAMS
;
2302 wined3d_mutex_lock();
2305 case D3DRENDERSTATE_TEXTUREMAG
:
2307 enum wined3d_texture_filter_type tex_mag
;
2309 tex_mag
= wined3d_device_get_sampler_state(device
->wined3d_device
, 0, WINED3D_SAMP_MAG_FILTER
);
2312 case WINED3D_TEXF_POINT
:
2313 *value
= D3DFILTER_NEAREST
;
2315 case WINED3D_TEXF_LINEAR
:
2316 *value
= D3DFILTER_LINEAR
;
2319 ERR("Unhandled texture mag %d !\n",tex_mag
);
2325 case D3DRENDERSTATE_TEXTUREMIN
:
2327 enum wined3d_texture_filter_type tex_min
;
2328 enum wined3d_texture_filter_type tex_mip
;
2330 tex_min
= wined3d_device_get_sampler_state(device
->wined3d_device
, 0, WINED3D_SAMP_MIN_FILTER
);
2331 tex_mip
= wined3d_device_get_sampler_state(device
->wined3d_device
, 0, WINED3D_SAMP_MIP_FILTER
);
2334 case WINED3D_TEXF_POINT
:
2337 case WINED3D_TEXF_NONE
:
2338 *value
= D3DFILTER_NEAREST
;
2340 case WINED3D_TEXF_POINT
:
2341 *value
= D3DFILTER_MIPNEAREST
;
2343 case WINED3D_TEXF_LINEAR
:
2344 *value
= D3DFILTER_LINEARMIPNEAREST
;
2347 ERR("Unhandled mip filter %#x.\n", tex_mip
);
2348 *value
= D3DFILTER_NEAREST
;
2352 case WINED3D_TEXF_LINEAR
:
2355 case WINED3D_TEXF_NONE
:
2356 *value
= D3DFILTER_LINEAR
;
2358 case WINED3D_TEXF_POINT
:
2359 *value
= D3DFILTER_MIPLINEAR
;
2361 case WINED3D_TEXF_LINEAR
:
2362 *value
= D3DFILTER_LINEARMIPLINEAR
;
2365 ERR("Unhandled mip filter %#x.\n", tex_mip
);
2366 *value
= D3DFILTER_LINEAR
;
2371 ERR("Unhandled texture min filter %#x.\n",tex_min
);
2372 *value
= D3DFILTER_NEAREST
;
2378 case D3DRENDERSTATE_TEXTUREADDRESS
:
2379 case D3DRENDERSTATE_TEXTUREADDRESSU
:
2380 *value
= wined3d_device_get_sampler_state(device
->wined3d_device
, 0, WINED3D_SAMP_ADDRESS_U
);
2382 case D3DRENDERSTATE_TEXTUREADDRESSV
:
2383 *value
= wined3d_device_get_sampler_state(device
->wined3d_device
, 0, WINED3D_SAMP_ADDRESS_V
);
2386 case D3DRENDERSTATE_BORDERCOLOR
:
2387 FIXME("Unhandled render state D3DRENDERSTATE_BORDERCOLOR.\n");
2391 case D3DRENDERSTATE_TEXTUREHANDLE
:
2392 case D3DRENDERSTATE_TEXTUREMAPBLEND
:
2393 WARN("Render state %#x is invalid in d3d7.\n", state
);
2394 hr
= DDERR_INVALIDPARAMS
;
2397 case D3DRENDERSTATE_ZBIAS
:
2398 *value
= wined3d_device_get_render_state(device
->wined3d_device
, WINED3D_RS_DEPTHBIAS
);
2402 if (state
>= D3DRENDERSTATE_STIPPLEPATTERN00
2403 && state
<= D3DRENDERSTATE_STIPPLEPATTERN31
)
2405 FIXME("Unhandled stipple pattern render state (%#x).\n", state
);
2409 *value
= wined3d_device_get_render_state(device
->wined3d_device
, state
);
2411 wined3d_mutex_unlock();
2416 static HRESULT WINAPI
d3d_device7_GetRenderState_FPUSetup(IDirect3DDevice7
*iface
,
2417 D3DRENDERSTATETYPE state
, DWORD
*value
)
2419 return d3d_device7_GetRenderState(iface
, state
, value
);
2422 static HRESULT WINAPI
d3d_device7_GetRenderState_FPUPreserve(IDirect3DDevice7
*iface
,
2423 D3DRENDERSTATETYPE state
, DWORD
*value
)
2428 old_fpucw
= d3d_fpu_setup();
2429 hr
= d3d_device7_GetRenderState(iface
, state
, value
);
2430 set_fpu_control_word(old_fpucw
);
2435 static HRESULT WINAPI
d3d_device3_GetRenderState(IDirect3DDevice3
*iface
,
2436 D3DRENDERSTATETYPE state
, DWORD
*value
)
2438 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
2440 TRACE("iface %p, state %#x, value %p.\n", iface
, state
, value
);
2444 case D3DRENDERSTATE_TEXTUREHANDLE
:
2446 /* This state is wrapped to SetTexture in SetRenderState, so
2447 * it has to be wrapped to GetTexture here. */
2448 struct wined3d_texture
*tex
= NULL
;
2451 wined3d_mutex_lock();
2452 if ((tex
= wined3d_device_get_texture(device
->wined3d_device
, 0)))
2454 /* The parent of the texture is the IDirectDrawSurface7
2455 * interface of the ddraw surface. */
2456 struct ddraw_texture
*parent
= wined3d_texture_get_parent(tex
);
2458 *value
= parent
->root
->Handle
;
2460 wined3d_mutex_unlock();
2465 case D3DRENDERSTATE_TEXTUREMAPBLEND
:
2467 /* D3DRENDERSTATE_TEXTUREMAPBLEND is mapped to texture state stages in SetRenderState; reverse
2468 the mapping to get the value. */
2469 DWORD colorop
, colorarg1
, colorarg2
;
2470 DWORD alphaop
, alphaarg1
, alphaarg2
;
2472 wined3d_mutex_lock();
2474 device
->legacyTextureBlending
= TRUE
;
2476 colorop
= wined3d_device_get_texture_stage_state(device
->wined3d_device
, 0, WINED3D_TSS_COLOR_OP
);
2477 colorarg1
= wined3d_device_get_texture_stage_state(device
->wined3d_device
, 0, WINED3D_TSS_COLOR_ARG1
);
2478 colorarg2
= wined3d_device_get_texture_stage_state(device
->wined3d_device
, 0, WINED3D_TSS_COLOR_ARG2
);
2479 alphaop
= wined3d_device_get_texture_stage_state(device
->wined3d_device
, 0, WINED3D_TSS_ALPHA_OP
);
2480 alphaarg1
= wined3d_device_get_texture_stage_state(device
->wined3d_device
, 0, WINED3D_TSS_ALPHA_ARG1
);
2481 alphaarg2
= wined3d_device_get_texture_stage_state(device
->wined3d_device
, 0, WINED3D_TSS_ALPHA_ARG2
);
2483 if (colorop
== WINED3D_TOP_SELECT_ARG1
&& colorarg1
== WINED3DTA_TEXTURE
2484 && alphaop
== WINED3D_TOP_SELECT_ARG1
&& alphaarg1
== WINED3DTA_TEXTURE
)
2485 *value
= D3DTBLEND_DECAL
;
2486 else if (colorop
== WINED3D_TOP_SELECT_ARG1
&& colorarg1
== WINED3DTA_TEXTURE
2487 && alphaop
== WINED3D_TOP_MODULATE
2488 && alphaarg1
== WINED3DTA_TEXTURE
&& alphaarg2
== WINED3DTA_CURRENT
)
2489 *value
= D3DTBLEND_DECALALPHA
;
2490 else if (colorop
== WINED3D_TOP_MODULATE
2491 && colorarg1
== WINED3DTA_TEXTURE
&& colorarg2
== WINED3DTA_CURRENT
2492 && alphaop
== WINED3D_TOP_MODULATE
2493 && alphaarg1
== WINED3DTA_TEXTURE
&& alphaarg2
== WINED3DTA_CURRENT
)
2494 *value
= D3DTBLEND_MODULATEALPHA
;
2497 struct wined3d_texture
*tex
= NULL
;
2498 BOOL tex_alpha
= FALSE
;
2499 DDPIXELFORMAT ddfmt
;
2501 if ((tex
= wined3d_device_get_texture(device
->wined3d_device
, 0)))
2503 struct wined3d_resource
*sub_resource
;
2505 if ((sub_resource
= wined3d_texture_get_sub_resource(tex
, 0)))
2507 struct wined3d_resource_desc desc
;
2509 wined3d_resource_get_desc(sub_resource
, &desc
);
2510 ddfmt
.dwSize
= sizeof(ddfmt
);
2511 ddrawformat_from_wined3dformat(&ddfmt
, desc
.format
);
2512 if (ddfmt
.u5
.dwRGBAlphaBitMask
) tex_alpha
= TRUE
;
2516 if (!(colorop
== WINED3D_TOP_MODULATE
2517 && colorarg1
== WINED3DTA_TEXTURE
&& colorarg2
== WINED3DTA_CURRENT
2518 && alphaop
== (tex_alpha
? WINED3D_TOP_SELECT_ARG1
: WINED3D_TOP_SELECT_ARG2
)
2519 && alphaarg1
== WINED3DTA_TEXTURE
&& alphaarg2
== WINED3DTA_CURRENT
))
2520 ERR("Unexpected texture stage state setup, returning D3DTBLEND_MODULATE - likely erroneous.\n");
2522 *value
= D3DTBLEND_MODULATE
;
2525 wined3d_mutex_unlock();
2530 case D3DRENDERSTATE_LIGHTING
:
2531 case D3DRENDERSTATE_NORMALIZENORMALS
:
2532 case D3DRENDERSTATE_LOCALVIEWER
:
2533 *value
= 0xffffffff;
2537 return IDirect3DDevice7_GetRenderState(&device
->IDirect3DDevice7_iface
, state
, value
);
2541 static HRESULT WINAPI
d3d_device2_GetRenderState(IDirect3DDevice2
*iface
,
2542 D3DRENDERSTATETYPE state
, DWORD
*value
)
2544 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
2546 TRACE("iface %p, state %#x, value %p.\n", iface
, state
, value
);
2548 return IDirect3DDevice3_GetRenderState(&device
->IDirect3DDevice3_iface
, state
, value
);
2551 /*****************************************************************************
2552 * IDirect3DDevice7::SetRenderState
2554 * Sets a render state. The possible render states are defined in
2555 * include/d3dtypes.h
2557 * Version 2, 3 and 7
2560 * RenderStateType: State to set
2561 * Value: Value to assign to that state
2564 * D3D_OK on success,
2565 * for details see IWineD3DDevice::SetRenderState
2567 *****************************************************************************/
2568 static HRESULT
d3d_device7_SetRenderState(IDirect3DDevice7
*iface
,
2569 D3DRENDERSTATETYPE state
, DWORD value
)
2571 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
2572 HRESULT hr
= D3D_OK
;
2574 TRACE("iface %p, state %#x, value %#x.\n", iface
, state
, value
);
2576 wined3d_mutex_lock();
2577 /* Some render states need special care */
2581 * The ddraw texture filter mapping works like this:
2582 * D3DFILTER_NEAREST Point min/mag, no mip
2583 * D3DFILTER_MIPNEAREST Point min/mag, point mip
2584 * D3DFILTER_LINEARMIPNEAREST: Point min/mag, linear mip
2586 * D3DFILTER_LINEAR Linear min/mag, no mip
2587 * D3DFILTER_MIPLINEAR Linear min/mag, point mip
2588 * D3DFILTER_LINEARMIPLINEAR Linear min/mag, linear mip
2590 * This is the opposite of the GL naming convention,
2591 * D3DFILTER_LINEARMIPNEAREST corresponds to GL_NEAREST_MIPMAP_LINEAR.
2593 case D3DRENDERSTATE_TEXTUREMAG
:
2595 enum wined3d_texture_filter_type tex_mag
;
2599 case D3DFILTER_NEAREST
:
2600 case D3DFILTER_MIPNEAREST
:
2601 case D3DFILTER_LINEARMIPNEAREST
:
2602 tex_mag
= WINED3D_TEXF_POINT
;
2604 case D3DFILTER_LINEAR
:
2605 case D3DFILTER_MIPLINEAR
:
2606 case D3DFILTER_LINEARMIPLINEAR
:
2607 tex_mag
= WINED3D_TEXF_LINEAR
;
2610 tex_mag
= WINED3D_TEXF_POINT
;
2611 FIXME("Unhandled texture mag %#x.\n", value
);
2615 wined3d_device_set_sampler_state(device
->wined3d_device
, 0, WINED3D_SAMP_MAG_FILTER
, tex_mag
);
2619 case D3DRENDERSTATE_TEXTUREMIN
:
2621 enum wined3d_texture_filter_type tex_min
;
2622 enum wined3d_texture_filter_type tex_mip
;
2626 case D3DFILTER_NEAREST
:
2627 tex_min
= WINED3D_TEXF_POINT
;
2628 tex_mip
= WINED3D_TEXF_NONE
;
2630 case D3DFILTER_LINEAR
:
2631 tex_min
= WINED3D_TEXF_LINEAR
;
2632 tex_mip
= WINED3D_TEXF_NONE
;
2634 case D3DFILTER_MIPNEAREST
:
2635 tex_min
= WINED3D_TEXF_POINT
;
2636 tex_mip
= WINED3D_TEXF_POINT
;
2638 case D3DFILTER_MIPLINEAR
:
2639 tex_min
= WINED3D_TEXF_LINEAR
;
2640 tex_mip
= WINED3D_TEXF_POINT
;
2642 case D3DFILTER_LINEARMIPNEAREST
:
2643 tex_min
= WINED3D_TEXF_POINT
;
2644 tex_mip
= WINED3D_TEXF_LINEAR
;
2646 case D3DFILTER_LINEARMIPLINEAR
:
2647 tex_min
= WINED3D_TEXF_LINEAR
;
2648 tex_mip
= WINED3D_TEXF_LINEAR
;
2652 FIXME("Unhandled texture min %#x.\n",value
);
2653 tex_min
= WINED3D_TEXF_POINT
;
2654 tex_mip
= WINED3D_TEXF_NONE
;
2658 wined3d_device_set_sampler_state(device
->wined3d_device
,
2659 0, WINED3D_SAMP_MIP_FILTER
, tex_mip
);
2660 wined3d_device_set_sampler_state(device
->wined3d_device
,
2661 0, WINED3D_SAMP_MIN_FILTER
, tex_min
);
2665 case D3DRENDERSTATE_TEXTUREADDRESS
:
2666 wined3d_device_set_sampler_state(device
->wined3d_device
,
2667 0, WINED3D_SAMP_ADDRESS_V
, value
);
2669 case D3DRENDERSTATE_TEXTUREADDRESSU
:
2670 wined3d_device_set_sampler_state(device
->wined3d_device
,
2671 0, WINED3D_SAMP_ADDRESS_U
, value
);
2673 case D3DRENDERSTATE_TEXTUREADDRESSV
:
2674 wined3d_device_set_sampler_state(device
->wined3d_device
,
2675 0, WINED3D_SAMP_ADDRESS_V
, value
);
2678 case D3DRENDERSTATE_BORDERCOLOR
:
2679 /* This should probably just forward to the corresponding sampler
2680 * state. Needs tests. */
2681 FIXME("Unhandled render state D3DRENDERSTATE_BORDERCOLOR.\n");
2685 case D3DRENDERSTATE_TEXTUREHANDLE
:
2686 case D3DRENDERSTATE_TEXTUREMAPBLEND
:
2687 WARN("Render state %#x is invalid in d3d7.\n", state
);
2688 hr
= DDERR_INVALIDPARAMS
;
2691 case D3DRENDERSTATE_ZBIAS
:
2692 wined3d_device_set_render_state(device
->wined3d_device
, WINED3D_RS_DEPTHBIAS
, value
);
2696 if (state
>= D3DRENDERSTATE_STIPPLEPATTERN00
2697 && state
<= D3DRENDERSTATE_STIPPLEPATTERN31
)
2699 FIXME("Unhandled stipple pattern render state (%#x).\n", state
);
2704 wined3d_device_set_render_state(device
->wined3d_device
, state
, value
);
2707 wined3d_mutex_unlock();
2712 static HRESULT WINAPI
d3d_device7_SetRenderState_FPUSetup(IDirect3DDevice7
*iface
,
2713 D3DRENDERSTATETYPE state
, DWORD value
)
2715 return d3d_device7_SetRenderState(iface
, state
, value
);
2718 static HRESULT WINAPI
d3d_device7_SetRenderState_FPUPreserve(IDirect3DDevice7
*iface
,
2719 D3DRENDERSTATETYPE state
, DWORD value
)
2724 old_fpucw
= d3d_fpu_setup();
2725 hr
= d3d_device7_SetRenderState(iface
, state
, value
);
2726 set_fpu_control_word(old_fpucw
);
2731 static HRESULT WINAPI
d3d_device3_SetRenderState(IDirect3DDevice3
*iface
,
2732 D3DRENDERSTATETYPE state
, DWORD value
)
2734 /* Note about D3DRENDERSTATE_TEXTUREMAPBLEND implementation: most of values
2735 for this state can be directly mapped to texture stage colorop and alphaop, but
2736 D3DTBLEND_MODULATE is tricky: it uses alpha from texture when available and alpha
2737 from diffuse otherwise. So changing the texture must be monitored in SetTexture to modify
2738 alphaarg when needed.
2740 Aliens vs Predator 1 depends on accurate D3DTBLEND_MODULATE emulation
2742 Legacy texture blending (TEXTUREMAPBLEND) and texture stage states: directx6 docs state that
2743 TEXTUREMAPBLEND is deprecated, yet can still be used. Games must not use both or results
2744 are undefined. D3DTBLEND_MODULATE mode in particular is dependent on texture pixel format and
2745 requires fixup of stage 0 texture states when texture changes, but this fixup can interfere
2746 with games not using this deprecated state. So a flag 'legacyTextureBlending' has to be kept
2747 in device - TRUE if the app is using TEXTUREMAPBLEND.
2749 Tests show that setting TEXTUREMAPBLEND on native doesn't seem to change values returned by
2750 GetTextureStageState and vice versa. Not so on Wine, but it is 'undefined' anyway so, probably, ok,
2751 unless some broken game will be found that cares. */
2753 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
2756 TRACE("iface %p, state %#x, value %#x.\n", iface
, state
, value
);
2758 wined3d_mutex_lock();
2762 case D3DRENDERSTATE_TEXTUREHANDLE
:
2764 struct ddraw_surface
*surf
;
2768 hr
= wined3d_device_set_texture(device
->wined3d_device
, 0, NULL
);
2772 surf
= ddraw_get_object(&device
->handle_table
, value
- 1, DDRAW_HANDLE_SURFACE
);
2775 WARN("Invalid texture handle.\n");
2776 hr
= DDERR_INVALIDPARAMS
;
2780 hr
= IDirect3DDevice3_SetTexture(iface
, 0, &surf
->IDirect3DTexture2_iface
);
2784 case D3DRENDERSTATE_TEXTUREMAPBLEND
:
2786 device
->legacyTextureBlending
= TRUE
;
2790 case D3DTBLEND_MODULATE
:
2792 struct wined3d_texture
*tex
= NULL
;
2793 BOOL tex_alpha
= FALSE
;
2794 DDPIXELFORMAT ddfmt
;
2796 if ((tex
= wined3d_device_get_texture(device
->wined3d_device
, 0)))
2798 struct wined3d_resource
*sub_resource
;
2800 if ((sub_resource
= wined3d_texture_get_sub_resource(tex
, 0)))
2802 struct wined3d_resource_desc desc
;
2804 wined3d_resource_get_desc(sub_resource
, &desc
);
2805 ddfmt
.dwSize
= sizeof(ddfmt
);
2806 ddrawformat_from_wined3dformat(&ddfmt
, desc
.format
);
2807 if (ddfmt
.u5
.dwRGBAlphaBitMask
) tex_alpha
= TRUE
;
2812 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2813 0, WINED3D_TSS_ALPHA_OP
, WINED3D_TOP_SELECT_ARG1
);
2815 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2816 0, WINED3D_TSS_ALPHA_OP
, WINED3D_TOP_SELECT_ARG2
);
2817 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2818 0, WINED3D_TSS_ALPHA_ARG1
, WINED3DTA_TEXTURE
);
2819 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2820 0, WINED3D_TSS_ALPHA_ARG2
, WINED3DTA_CURRENT
);
2821 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2822 0, WINED3D_TSS_COLOR_ARG1
, WINED3DTA_TEXTURE
);
2823 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2824 0, WINED3D_TSS_COLOR_ARG2
, WINED3DTA_CURRENT
);
2825 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2826 0, WINED3D_TSS_COLOR_OP
, WINED3D_TOP_MODULATE
);
2831 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2832 0, WINED3D_TSS_COLOR_OP
, WINED3D_TOP_ADD
);
2833 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2834 0, WINED3D_TSS_COLOR_ARG1
, WINED3DTA_TEXTURE
);
2835 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2836 0, WINED3D_TSS_COLOR_ARG2
, WINED3DTA_CURRENT
);
2837 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2838 0, WINED3D_TSS_ALPHA_OP
, WINED3D_TOP_SELECT_ARG2
);
2839 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2840 0, WINED3D_TSS_ALPHA_ARG2
, WINED3DTA_CURRENT
);
2843 case D3DTBLEND_MODULATEALPHA
:
2844 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2845 0, WINED3D_TSS_COLOR_ARG1
, WINED3DTA_TEXTURE
);
2846 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2847 0, WINED3D_TSS_ALPHA_ARG1
, WINED3DTA_TEXTURE
);
2848 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2849 0, WINED3D_TSS_COLOR_ARG2
, WINED3DTA_CURRENT
);
2850 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2851 0, WINED3D_TSS_ALPHA_ARG2
, WINED3DTA_CURRENT
);
2852 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2853 0, WINED3D_TSS_COLOR_OP
, WINED3D_TOP_MODULATE
);
2854 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2855 0, WINED3D_TSS_ALPHA_OP
, WINED3D_TOP_MODULATE
);
2858 case D3DTBLEND_COPY
:
2859 case D3DTBLEND_DECAL
:
2860 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2861 0, WINED3D_TSS_COLOR_ARG1
, WINED3DTA_TEXTURE
);
2862 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2863 0, WINED3D_TSS_ALPHA_ARG1
, WINED3DTA_TEXTURE
);
2864 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2865 0, WINED3D_TSS_COLOR_OP
, WINED3D_TOP_SELECT_ARG1
);
2866 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2867 0, WINED3D_TSS_ALPHA_OP
, WINED3D_TOP_SELECT_ARG1
);
2870 case D3DTBLEND_DECALALPHA
:
2871 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2872 0, WINED3D_TSS_COLOR_OP
, WINED3D_TOP_BLEND_TEXTURE_ALPHA
);
2873 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2874 0, WINED3D_TSS_COLOR_ARG1
, WINED3DTA_TEXTURE
);
2875 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2876 0, WINED3D_TSS_COLOR_ARG2
, WINED3DTA_CURRENT
);
2877 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2878 0, WINED3D_TSS_ALPHA_OP
, WINED3D_TOP_SELECT_ARG2
);
2879 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
2880 0, WINED3D_TSS_ALPHA_ARG2
, WINED3DTA_CURRENT
);
2884 FIXME("Unhandled texture environment %#x.\n", value
);
2891 case D3DRENDERSTATE_LIGHTING
:
2892 case D3DRENDERSTATE_NORMALIZENORMALS
:
2893 case D3DRENDERSTATE_LOCALVIEWER
:
2898 hr
= IDirect3DDevice7_SetRenderState(&device
->IDirect3DDevice7_iface
, state
, value
);
2901 wined3d_mutex_unlock();
2906 static HRESULT WINAPI
d3d_device2_SetRenderState(IDirect3DDevice2
*iface
,
2907 D3DRENDERSTATETYPE state
, DWORD value
)
2909 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
2911 TRACE("iface %p, state %#x, value %#x.\n", iface
, state
, value
);
2913 return IDirect3DDevice3_SetRenderState(&device
->IDirect3DDevice3_iface
, state
, value
);
2916 /*****************************************************************************
2917 * Direct3DDevice3::SetLightState
2919 * Sets a light state for Direct3DDevice3 and Direct3DDevice2. The
2920 * light states are forwarded to Direct3DDevice7 render states
2925 * LightStateType: The light state to change
2926 * Value: The value to assign to that light state
2930 * DDERR_INVALIDPARAMS if the parameters were incorrect
2931 * Also check IDirect3DDevice7::SetRenderState
2933 *****************************************************************************/
2934 static HRESULT WINAPI
d3d_device3_SetLightState(IDirect3DDevice3
*iface
,
2935 D3DLIGHTSTATETYPE state
, DWORD value
)
2937 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
2940 TRACE("iface %p, state %#x, value %#x.\n", iface
, state
, value
);
2942 if (!state
|| (state
> D3DLIGHTSTATE_COLORVERTEX
))
2944 TRACE("Unexpected Light State Type\n");
2945 return DDERR_INVALIDPARAMS
;
2948 wined3d_mutex_lock();
2949 if (state
== D3DLIGHTSTATE_MATERIAL
)
2953 struct d3d_material
*m
;
2955 if (!(m
= ddraw_get_object(&device
->handle_table
, value
- 1, DDRAW_HANDLE_MATERIAL
)))
2957 WARN("Invalid material handle.\n");
2958 wined3d_mutex_unlock();
2959 return DDERR_INVALIDPARAMS
;
2962 material_activate(m
);
2965 device
->material
= value
;
2967 else if (state
== D3DLIGHTSTATE_COLORMODEL
)
2972 ERR("DDCOLOR_MONO should not happen!\n");
2975 /* We are already in this mode */
2976 TRACE("Setting color model to RGB (no-op).\n");
2979 ERR("Unknown color model!\n");
2980 wined3d_mutex_unlock();
2981 return DDERR_INVALIDPARAMS
;
2986 D3DRENDERSTATETYPE rs
;
2989 case D3DLIGHTSTATE_AMBIENT
: /* 2 */
2990 rs
= D3DRENDERSTATE_AMBIENT
;
2992 case D3DLIGHTSTATE_FOGMODE
: /* 4 */
2993 rs
= D3DRENDERSTATE_FOGVERTEXMODE
;
2995 case D3DLIGHTSTATE_FOGSTART
: /* 5 */
2996 rs
= D3DRENDERSTATE_FOGSTART
;
2998 case D3DLIGHTSTATE_FOGEND
: /* 6 */
2999 rs
= D3DRENDERSTATE_FOGEND
;
3001 case D3DLIGHTSTATE_FOGDENSITY
: /* 7 */
3002 rs
= D3DRENDERSTATE_FOGDENSITY
;
3004 case D3DLIGHTSTATE_COLORVERTEX
: /* 8 */
3005 rs
= D3DRENDERSTATE_COLORVERTEX
;
3008 FIXME("Unhandled D3DLIGHTSTATETYPE %#x.\n", state
);
3009 wined3d_mutex_unlock();
3010 return DDERR_INVALIDPARAMS
;
3013 hr
= IDirect3DDevice7_SetRenderState(&device
->IDirect3DDevice7_iface
, rs
, value
);
3014 wined3d_mutex_unlock();
3017 wined3d_mutex_unlock();
3022 static HRESULT WINAPI
d3d_device2_SetLightState(IDirect3DDevice2
*iface
,
3023 D3DLIGHTSTATETYPE state
, DWORD value
)
3025 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
3027 TRACE("iface %p, state %#x, value %#x.\n", iface
, state
, value
);
3029 return d3d_device3_SetLightState(&device
->IDirect3DDevice3_iface
, state
, value
);
3032 /*****************************************************************************
3033 * IDirect3DDevice3::GetLightState
3035 * Returns the current setting of a light state. The state is read from
3036 * the Direct3DDevice7 render state.
3041 * LightStateType: The light state to return
3042 * Value: The address to store the light state setting at
3046 * DDDERR_INVALIDPARAMS if the parameters were incorrect
3047 * Also see IDirect3DDevice7::GetRenderState
3049 *****************************************************************************/
3050 static HRESULT WINAPI
d3d_device3_GetLightState(IDirect3DDevice3
*iface
,
3051 D3DLIGHTSTATETYPE state
, DWORD
*value
)
3053 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
3056 TRACE("iface %p, state %#x, value %p.\n", iface
, state
, value
);
3058 if (!state
|| (state
> D3DLIGHTSTATE_COLORVERTEX
))
3060 TRACE("Unexpected Light State Type\n");
3061 return DDERR_INVALIDPARAMS
;
3065 return DDERR_INVALIDPARAMS
;
3067 wined3d_mutex_lock();
3068 if (state
== D3DLIGHTSTATE_MATERIAL
)
3070 *value
= device
->material
;
3072 else if (state
== D3DLIGHTSTATE_COLORMODEL
)
3074 *value
= D3DCOLOR_RGB
;
3078 D3DRENDERSTATETYPE rs
;
3081 case D3DLIGHTSTATE_AMBIENT
: /* 2 */
3082 rs
= D3DRENDERSTATE_AMBIENT
;
3084 case D3DLIGHTSTATE_FOGMODE
: /* 4 */
3085 rs
= D3DRENDERSTATE_FOGVERTEXMODE
;
3087 case D3DLIGHTSTATE_FOGSTART
: /* 5 */
3088 rs
= D3DRENDERSTATE_FOGSTART
;
3090 case D3DLIGHTSTATE_FOGEND
: /* 6 */
3091 rs
= D3DRENDERSTATE_FOGEND
;
3093 case D3DLIGHTSTATE_FOGDENSITY
: /* 7 */
3094 rs
= D3DRENDERSTATE_FOGDENSITY
;
3096 case D3DLIGHTSTATE_COLORVERTEX
: /* 8 */
3097 rs
= D3DRENDERSTATE_COLORVERTEX
;
3100 FIXME("Unhandled D3DLIGHTSTATETYPE %#x.\n", state
);
3101 wined3d_mutex_unlock();
3102 return DDERR_INVALIDPARAMS
;
3105 hr
= IDirect3DDevice7_GetRenderState(&device
->IDirect3DDevice7_iface
, rs
, value
);
3106 wined3d_mutex_unlock();
3109 wined3d_mutex_unlock();
3114 static HRESULT WINAPI
d3d_device2_GetLightState(IDirect3DDevice2
*iface
,
3115 D3DLIGHTSTATETYPE state
, DWORD
*value
)
3117 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
3119 TRACE("iface %p, state %#x, value %p.\n", iface
, state
, value
);
3121 return d3d_device3_GetLightState(&device
->IDirect3DDevice3_iface
, state
, value
);
3124 /*****************************************************************************
3125 * IDirect3DDevice7::SetTransform
3127 * Assigns a D3DMATRIX to a transform type. The transform types are defined
3128 * in include/d3dtypes.h.
3129 * The D3DTRANSFORMSTATE_WORLD (=1) is translated to D3DTS_WORLDMATRIX(0)
3130 * (=255) for wined3d, because the 1 transform state was removed in d3d8
3131 * and WineD3D already understands the replacement D3DTS_WORLDMATRIX(0)
3133 * Version 2, 3 and 7
3136 * TransformStateType: transform state to set
3137 * Matrix: Matrix to assign to the state
3141 * DDERR_INVALIDPARAMS if Matrix == NULL
3142 * For details see IWineD3DDevice::SetTransform
3144 *****************************************************************************/
3145 static HRESULT
d3d_device7_SetTransform(IDirect3DDevice7
*iface
,
3146 D3DTRANSFORMSTATETYPE state
, D3DMATRIX
*matrix
)
3148 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
3149 enum wined3d_transform_state wined3d_state
;
3151 TRACE("iface %p, state %#x, matrix %p.\n", iface
, state
, matrix
);
3155 case D3DTRANSFORMSTATE_WORLD
:
3156 wined3d_state
= WINED3D_TS_WORLD_MATRIX(0);
3158 case D3DTRANSFORMSTATE_WORLD1
:
3159 wined3d_state
= WINED3D_TS_WORLD_MATRIX(1);
3161 case D3DTRANSFORMSTATE_WORLD2
:
3162 wined3d_state
= WINED3D_TS_WORLD_MATRIX(2);
3164 case D3DTRANSFORMSTATE_WORLD3
:
3165 wined3d_state
= WINED3D_TS_WORLD_MATRIX(3);
3168 wined3d_state
= state
;
3172 return DDERR_INVALIDPARAMS
;
3174 /* Note: D3DMATRIX is compatible with struct wined3d_matrix. */
3175 wined3d_mutex_lock();
3176 wined3d_device_set_transform(device
->wined3d_device
, wined3d_state
, (struct wined3d_matrix
*)matrix
);
3177 wined3d_mutex_unlock();
3182 static HRESULT WINAPI
d3d_device7_SetTransform_FPUSetup(IDirect3DDevice7
*iface
,
3183 D3DTRANSFORMSTATETYPE state
, D3DMATRIX
*matrix
)
3185 return d3d_device7_SetTransform(iface
, state
, matrix
);
3188 static HRESULT WINAPI
d3d_device7_SetTransform_FPUPreserve(IDirect3DDevice7
*iface
,
3189 D3DTRANSFORMSTATETYPE state
, D3DMATRIX
*matrix
)
3194 old_fpucw
= d3d_fpu_setup();
3195 hr
= d3d_device7_SetTransform(iface
, state
, matrix
);
3196 set_fpu_control_word(old_fpucw
);
3201 static HRESULT WINAPI
d3d_device3_SetTransform(IDirect3DDevice3
*iface
,
3202 D3DTRANSFORMSTATETYPE state
, D3DMATRIX
*matrix
)
3204 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
3206 TRACE("iface %p, state %#x, matrix %p.\n", iface
, state
, matrix
);
3209 return DDERR_INVALIDPARAMS
;
3211 if (state
== D3DTRANSFORMSTATE_PROJECTION
)
3213 D3DMATRIX projection
;
3215 wined3d_mutex_lock();
3216 multiply_matrix(&projection
, &device
->legacy_clipspace
, matrix
);
3217 wined3d_device_set_transform(device
->wined3d_device
,
3218 WINED3D_TS_PROJECTION
, (struct wined3d_matrix
*)&projection
);
3219 device
->legacy_projection
= *matrix
;
3220 wined3d_mutex_unlock();
3225 return IDirect3DDevice7_SetTransform(&device
->IDirect3DDevice7_iface
, state
, matrix
);
3228 static HRESULT WINAPI
d3d_device2_SetTransform(IDirect3DDevice2
*iface
,
3229 D3DTRANSFORMSTATETYPE state
, D3DMATRIX
*matrix
)
3231 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
3233 TRACE("iface %p, state %#x, matrix %p.\n", iface
, state
, matrix
);
3235 return IDirect3DDevice7_SetTransform(&device
->IDirect3DDevice7_iface
, state
, matrix
);
3238 /*****************************************************************************
3239 * IDirect3DDevice7::GetTransform
3241 * Returns the matrix assigned to a transform state
3242 * D3DTRANSFORMSTATE_WORLD is translated to D3DTS_WORLDMATRIX(0), see
3246 * TransformStateType: State to read the matrix from
3247 * Matrix: Address to store the matrix at
3251 * DDERR_INVALIDPARAMS if Matrix == NULL
3252 * For details, see IWineD3DDevice::GetTransform
3254 *****************************************************************************/
3255 static HRESULT
d3d_device7_GetTransform(IDirect3DDevice7
*iface
,
3256 D3DTRANSFORMSTATETYPE state
, D3DMATRIX
*matrix
)
3258 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
3259 enum wined3d_transform_state wined3d_state
;
3261 TRACE("iface %p, state %#x, matrix %p.\n", iface
, state
, matrix
);
3265 case D3DTRANSFORMSTATE_WORLD
:
3266 wined3d_state
= WINED3D_TS_WORLD_MATRIX(0);
3268 case D3DTRANSFORMSTATE_WORLD1
:
3269 wined3d_state
= WINED3D_TS_WORLD_MATRIX(1);
3271 case D3DTRANSFORMSTATE_WORLD2
:
3272 wined3d_state
= WINED3D_TS_WORLD_MATRIX(2);
3274 case D3DTRANSFORMSTATE_WORLD3
:
3275 wined3d_state
= WINED3D_TS_WORLD_MATRIX(3);
3278 wined3d_state
= state
;
3282 return DDERR_INVALIDPARAMS
;
3284 /* Note: D3DMATRIX is compatible with struct wined3d_matrix. */
3285 wined3d_mutex_lock();
3286 wined3d_device_get_transform(device
->wined3d_device
, wined3d_state
, (struct wined3d_matrix
*)matrix
);
3287 wined3d_mutex_unlock();
3292 static HRESULT WINAPI
d3d_device7_GetTransform_FPUSetup(IDirect3DDevice7
*iface
,
3293 D3DTRANSFORMSTATETYPE state
, D3DMATRIX
*matrix
)
3295 return d3d_device7_GetTransform(iface
, state
, matrix
);
3298 static HRESULT WINAPI
d3d_device7_GetTransform_FPUPreserve(IDirect3DDevice7
*iface
,
3299 D3DTRANSFORMSTATETYPE state
, D3DMATRIX
*matrix
)
3304 old_fpucw
= d3d_fpu_setup();
3305 hr
= d3d_device7_GetTransform(iface
, state
, matrix
);
3306 set_fpu_control_word(old_fpucw
);
3311 static HRESULT WINAPI
d3d_device3_GetTransform(IDirect3DDevice3
*iface
,
3312 D3DTRANSFORMSTATETYPE state
, D3DMATRIX
*matrix
)
3314 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
3316 TRACE("iface %p, state %#x, matrix %p.\n", iface
, state
, matrix
);
3319 return DDERR_INVALIDPARAMS
;
3321 if (state
== D3DTRANSFORMSTATE_PROJECTION
)
3323 wined3d_mutex_lock();
3324 *matrix
= device
->legacy_projection
;
3325 wined3d_mutex_unlock();
3329 return IDirect3DDevice7_GetTransform(&device
->IDirect3DDevice7_iface
, state
, matrix
);
3332 static HRESULT WINAPI
d3d_device2_GetTransform(IDirect3DDevice2
*iface
,
3333 D3DTRANSFORMSTATETYPE state
, D3DMATRIX
*matrix
)
3335 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
3337 TRACE("iface %p, state %#x, matrix %p.\n", iface
, state
, matrix
);
3339 return IDirect3DDevice7_GetTransform(&device
->IDirect3DDevice7_iface
, state
, matrix
);
3342 /*****************************************************************************
3343 * IDirect3DDevice7::MultiplyTransform
3345 * Multiplies the already-set transform matrix of a transform state
3346 * with another matrix. For the world matrix, see SetTransform
3348 * Version 2, 3 and 7
3351 * TransformStateType: Transform state to multiply
3352 * D3DMatrix Matrix to multiply with.
3356 * DDERR_INVALIDPARAMS if D3DMatrix is NULL
3357 * For details, see IWineD3DDevice::MultiplyTransform
3359 *****************************************************************************/
3360 static HRESULT
d3d_device7_MultiplyTransform(IDirect3DDevice7
*iface
,
3361 D3DTRANSFORMSTATETYPE state
, D3DMATRIX
*matrix
)
3363 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
3364 enum wined3d_transform_state wined3d_state
;
3366 TRACE("iface %p, state %#x, matrix %p.\n", iface
, state
, matrix
);
3370 case D3DTRANSFORMSTATE_WORLD
:
3371 wined3d_state
= WINED3D_TS_WORLD_MATRIX(0);
3373 case D3DTRANSFORMSTATE_WORLD1
:
3374 wined3d_state
= WINED3D_TS_WORLD_MATRIX(1);
3376 case D3DTRANSFORMSTATE_WORLD2
:
3377 wined3d_state
= WINED3D_TS_WORLD_MATRIX(2);
3379 case D3DTRANSFORMSTATE_WORLD3
:
3380 wined3d_state
= WINED3D_TS_WORLD_MATRIX(3);
3383 wined3d_state
= state
;
3386 /* Note: D3DMATRIX is compatible with struct wined3d_matrix. */
3387 wined3d_mutex_lock();
3388 wined3d_device_multiply_transform(device
->wined3d_device
,
3389 wined3d_state
, (struct wined3d_matrix
*)matrix
);
3390 wined3d_mutex_unlock();
3395 static HRESULT WINAPI
d3d_device7_MultiplyTransform_FPUSetup(IDirect3DDevice7
*iface
,
3396 D3DTRANSFORMSTATETYPE state
, D3DMATRIX
*matrix
)
3398 return d3d_device7_MultiplyTransform(iface
, state
, matrix
);
3401 static HRESULT WINAPI
d3d_device7_MultiplyTransform_FPUPreserve(IDirect3DDevice7
*iface
,
3402 D3DTRANSFORMSTATETYPE state
, D3DMATRIX
*matrix
)
3407 old_fpucw
= d3d_fpu_setup();
3408 hr
= d3d_device7_MultiplyTransform(iface
, state
, matrix
);
3409 set_fpu_control_word(old_fpucw
);
3414 static HRESULT WINAPI
d3d_device3_MultiplyTransform(IDirect3DDevice3
*iface
,
3415 D3DTRANSFORMSTATETYPE state
, D3DMATRIX
*matrix
)
3417 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
3419 TRACE("iface %p, state %#x, matrix %p.\n", iface
, state
, matrix
);
3421 if (state
== D3DTRANSFORMSTATE_PROJECTION
)
3423 D3DMATRIX projection
, tmp
;
3425 wined3d_mutex_lock();
3426 multiply_matrix(&tmp
, &device
->legacy_projection
, matrix
);
3427 multiply_matrix(&projection
, &device
->legacy_clipspace
, &tmp
);
3428 wined3d_device_set_transform(device
->wined3d_device
,
3429 WINED3D_TS_PROJECTION
, (struct wined3d_matrix
*)&projection
);
3430 device
->legacy_projection
= tmp
;
3431 wined3d_mutex_unlock();
3436 return IDirect3DDevice7_MultiplyTransform(&device
->IDirect3DDevice7_iface
, state
, matrix
);
3439 static HRESULT WINAPI
d3d_device2_MultiplyTransform(IDirect3DDevice2
*iface
,
3440 D3DTRANSFORMSTATETYPE state
, D3DMATRIX
*matrix
)
3442 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
3444 TRACE("iface %p, state %#x, matrix %p.\n", iface
, state
, matrix
);
3446 return IDirect3DDevice7_MultiplyTransform(&device
->IDirect3DDevice7_iface
, state
, matrix
);
3449 /*****************************************************************************
3450 * IDirect3DDevice7::DrawPrimitive
3452 * Draws primitives based on vertices in an application-provided pointer
3454 * Version 2, 3 and 7. The IDirect3DDevice2 thunk converts the fixed vertex type into
3455 * an FVF format for D3D7
3458 * PrimitiveType: The type of the primitives to draw
3459 * Vertex type: Flexible vertex format vertex description
3460 * Vertices: Pointer to the vertex array
3461 * VertexCount: The number of vertices to draw
3462 * Flags: As usual a few flags
3466 * DDERR_INVALIDPARAMS if Vertices is NULL
3467 * For details, see IWineD3DDevice::DrawPrimitiveUP
3469 *****************************************************************************/
3471 /* The caller is responsible for wined3d locking */
3472 static HRESULT
d3d_device_prepare_vertex_buffer(struct d3d_device
*device
, UINT min_size
)
3476 if (device
->vertex_buffer_size
< min_size
|| !device
->vertex_buffer
)
3478 UINT size
= max(device
->vertex_buffer_size
* 2, min_size
);
3479 struct wined3d_buffer
*buffer
;
3481 TRACE("Growing vertex buffer to %u bytes\n", size
);
3483 hr
= wined3d_buffer_create_vb(device
->wined3d_device
, size
, WINED3DUSAGE_DYNAMIC
| WINED3DUSAGE_WRITEONLY
,
3484 WINED3D_POOL_DEFAULT
, NULL
, &ddraw_null_wined3d_parent_ops
, &buffer
);
3487 ERR("(%p) wined3d_buffer_create_vb failed with hr = %08x\n", device
, hr
);
3491 if (device
->vertex_buffer
)
3492 wined3d_buffer_decref(device
->vertex_buffer
);
3494 device
->vertex_buffer
= buffer
;
3495 device
->vertex_buffer_size
= size
;
3496 device
->vertex_buffer_pos
= 0;
3501 static HRESULT
d3d_device7_DrawPrimitive(IDirect3DDevice7
*iface
,
3502 D3DPRIMITIVETYPE primitive_type
, DWORD fvf
, void *vertices
,
3503 DWORD vertex_count
, DWORD flags
)
3505 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
3506 UINT stride
, vb_pos
, size
, align
;
3510 TRACE("iface %p, primitive_type %#x, fvf %#x, vertices %p, vertex_count %u, flags %#x.\n",
3511 iface
, primitive_type
, fvf
, vertices
, vertex_count
, flags
);
3514 return DDERR_INVALIDPARAMS
;
3516 /* Get the stride */
3517 stride
= get_flexible_vertex_size(fvf
);
3518 size
= vertex_count
* stride
;
3520 wined3d_mutex_lock();
3521 hr
= d3d_device_prepare_vertex_buffer(device
, size
);
3525 vb_pos
= device
->vertex_buffer_pos
;
3526 align
= vb_pos
% stride
;
3527 if (align
) align
= stride
- align
;
3528 if (vb_pos
+ size
+ align
> device
->vertex_buffer_size
)
3533 hr
= wined3d_buffer_map(device
->vertex_buffer
, vb_pos
, size
, &data
,
3534 vb_pos
? WINED3D_MAP_NOOVERWRITE
: WINED3D_MAP_DISCARD
);
3537 memcpy(data
, vertices
, size
);
3538 wined3d_buffer_unmap(device
->vertex_buffer
);
3539 device
->vertex_buffer_pos
= vb_pos
+ size
;
3541 hr
= wined3d_device_set_stream_source(device
->wined3d_device
, 0, device
->vertex_buffer
, 0, stride
);
3545 wined3d_device_set_vertex_declaration(device
->wined3d_device
, ddraw_find_decl(device
->ddraw
, fvf
));
3546 wined3d_device_set_primitive_type(device
->wined3d_device
, primitive_type
);
3547 hr
= wined3d_device_draw_primitive(device
->wined3d_device
, vb_pos
/ stride
, vertex_count
);
3550 wined3d_mutex_unlock();
3554 static HRESULT WINAPI
d3d_device7_DrawPrimitive_FPUSetup(IDirect3DDevice7
*iface
,
3555 D3DPRIMITIVETYPE primitive_type
, DWORD fvf
, void *vertices
,
3556 DWORD vertex_count
, DWORD flags
)
3558 return d3d_device7_DrawPrimitive(iface
, primitive_type
, fvf
, vertices
, vertex_count
, flags
);
3561 static HRESULT WINAPI
d3d_device7_DrawPrimitive_FPUPreserve(IDirect3DDevice7
*iface
,
3562 D3DPRIMITIVETYPE primitive_type
, DWORD fvf
, void *vertices
,
3563 DWORD vertex_count
, DWORD flags
)
3568 old_fpucw
= d3d_fpu_setup();
3569 hr
= d3d_device7_DrawPrimitive(iface
, primitive_type
, fvf
, vertices
, vertex_count
, flags
);
3570 set_fpu_control_word(old_fpucw
);
3575 static void setup_lighting(const struct d3d_device
*device
, DWORD fvf
, DWORD flags
)
3579 /* Ignore the D3DFVF_XYZRHW case here, wined3d takes care of that */
3580 if (!device
->material
|| !(fvf
& D3DFVF_NORMAL
) || (flags
& D3DDP_DONOTLIGHT
))
3583 wined3d_device_set_render_state(device
->wined3d_device
, WINED3D_RS_LIGHTING
, enable
);
3587 static HRESULT WINAPI
d3d_device3_DrawPrimitive(IDirect3DDevice3
*iface
,
3588 D3DPRIMITIVETYPE primitive_type
, DWORD fvf
, void *vertices
, DWORD vertex_count
,
3591 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
3593 TRACE("iface %p, primitive_type %#x, fvf %#x, vertices %p, vertex_count %u, flags %#x.\n",
3594 iface
, primitive_type
, fvf
, vertices
, vertex_count
, flags
);
3596 setup_lighting(device
, fvf
, flags
);
3598 return IDirect3DDevice7_DrawPrimitive(&device
->IDirect3DDevice7_iface
,
3599 primitive_type
, fvf
, vertices
, vertex_count
, flags
);
3602 static HRESULT WINAPI
d3d_device2_DrawPrimitive(IDirect3DDevice2
*iface
,
3603 D3DPRIMITIVETYPE primitive_type
, D3DVERTEXTYPE vertex_type
, void *vertices
,
3604 DWORD vertex_count
, DWORD flags
)
3606 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
3609 TRACE("iface %p, primitive_type %#x, vertex_type %#x, vertices %p, vertex_count %u, flags %#x.\n",
3610 iface
, primitive_type
, vertex_type
, vertices
, vertex_count
, flags
);
3612 switch (vertex_type
)
3614 case D3DVT_VERTEX
: fvf
= D3DFVF_VERTEX
; break;
3615 case D3DVT_LVERTEX
: fvf
= D3DFVF_LVERTEX
; break;
3616 case D3DVT_TLVERTEX
: fvf
= D3DFVF_TLVERTEX
; break;
3618 FIXME("Unhandled vertex type %#x.\n", vertex_type
);
3619 return DDERR_INVALIDPARAMS
; /* Should never happen */
3622 return d3d_device3_DrawPrimitive(&device
->IDirect3DDevice3_iface
,
3623 primitive_type
, fvf
, vertices
, vertex_count
, flags
);
3626 /*****************************************************************************
3627 * IDirect3DDevice7::DrawIndexedPrimitive
3629 * Draws vertices from an application-provided pointer, based on the index
3630 * numbers in a WORD array.
3632 * Version 2, 3 and 7. The version 7 thunk translates the vertex type into
3633 * an FVF format for D3D7
3636 * PrimitiveType: The primitive type to draw
3637 * VertexType: The FVF vertex description
3638 * Vertices: Pointer to the vertex array
3640 * Indices: Pointer to the index array
3641 * IndexCount: Number of indices = Number of vertices to draw
3642 * Flags: As usual, some flags
3646 * DDERR_INVALIDPARAMS if Vertices or Indices is NULL
3647 * For details, see IWineD3DDevice::DrawIndexedPrimitiveUP
3649 *****************************************************************************/
3650 /* The caller is responsible for wined3d locking */
3651 static HRESULT
d3d_device_prepare_index_buffer(struct d3d_device
*device
, UINT min_size
)
3655 if (device
->index_buffer_size
< min_size
|| !device
->index_buffer
)
3657 UINT size
= max(device
->index_buffer_size
* 2, min_size
);
3658 struct wined3d_buffer
*buffer
;
3660 TRACE("Growing index buffer to %u bytes\n", size
);
3662 hr
= wined3d_buffer_create_ib(device
->wined3d_device
, size
, WINED3DUSAGE_DYNAMIC
| WINED3DUSAGE_WRITEONLY
,
3663 WINED3D_POOL_DEFAULT
, NULL
, &ddraw_null_wined3d_parent_ops
, &buffer
);
3666 ERR("(%p) wined3d_buffer_create_ib failed with hr = %08x\n", device
, hr
);
3670 if (device
->index_buffer
)
3671 wined3d_buffer_decref(device
->index_buffer
);
3672 device
->index_buffer
= buffer
;
3673 device
->index_buffer_size
= size
;
3674 device
->index_buffer_pos
= 0;
3679 static HRESULT
d3d_device7_DrawIndexedPrimitive(IDirect3DDevice7
*iface
,
3680 D3DPRIMITIVETYPE primitive_type
, DWORD fvf
, void *vertices
, DWORD vertex_count
,
3681 WORD
*indices
, DWORD index_count
, DWORD flags
)
3683 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
3685 UINT stride
= get_flexible_vertex_size(fvf
);
3686 UINT vtx_size
= stride
* vertex_count
, idx_size
= index_count
* sizeof(*indices
);
3687 UINT vb_pos
, ib_pos
, align
;
3690 TRACE("iface %p, primitive_type %#x, fvf %#x, vertices %p, vertex_count %u, "
3691 "indices %p, index_count %u, flags %#x.\n",
3692 iface
, primitive_type
, fvf
, vertices
, vertex_count
, indices
, index_count
, flags
);
3694 /* Set the D3DDevice's FVF */
3695 wined3d_mutex_lock();
3697 hr
= d3d_device_prepare_vertex_buffer(device
, vtx_size
);
3701 vb_pos
= device
->vertex_buffer_pos
;
3702 align
= vb_pos
% stride
;
3703 if (align
) align
= stride
- align
;
3704 if (vb_pos
+ vtx_size
+ align
> device
->vertex_buffer_size
)
3709 hr
= wined3d_buffer_map(device
->vertex_buffer
, vb_pos
, vtx_size
, &data
,
3710 vb_pos
? WINED3D_MAP_NOOVERWRITE
: WINED3D_MAP_DISCARD
);
3713 memcpy(data
, vertices
, vtx_size
);
3714 wined3d_buffer_unmap(device
->vertex_buffer
);
3715 device
->vertex_buffer_pos
= vb_pos
+ vtx_size
;
3717 hr
= d3d_device_prepare_index_buffer(device
, idx_size
);
3720 ib_pos
= device
->index_buffer_pos
;
3721 if (device
->index_buffer_size
- idx_size
< ib_pos
)
3724 hr
= wined3d_buffer_map(device
->index_buffer
, ib_pos
, idx_size
, &data
,
3725 ib_pos
? WINED3D_MAP_NOOVERWRITE
: WINED3D_MAP_DISCARD
);
3728 memcpy(data
, indices
, idx_size
);
3729 wined3d_buffer_unmap(device
->index_buffer
);
3730 device
->index_buffer_pos
= ib_pos
+ idx_size
;
3732 hr
= wined3d_device_set_stream_source(device
->wined3d_device
, 0, device
->vertex_buffer
, 0, stride
);
3735 wined3d_device_set_index_buffer(device
->wined3d_device
, device
->index_buffer
, WINED3DFMT_R16_UINT
);
3737 wined3d_device_set_vertex_declaration(device
->wined3d_device
, ddraw_find_decl(device
->ddraw
, fvf
));
3738 wined3d_device_set_primitive_type(device
->wined3d_device
, primitive_type
);
3739 wined3d_device_set_base_vertex_index(device
->wined3d_device
, vb_pos
/ stride
);
3740 hr
= wined3d_device_draw_indexed_primitive(device
->wined3d_device
, ib_pos
/ sizeof(*indices
), index_count
);
3743 wined3d_mutex_unlock();
3747 static HRESULT WINAPI
d3d_device7_DrawIndexedPrimitive_FPUSetup(IDirect3DDevice7
*iface
,
3748 D3DPRIMITIVETYPE primitive_type
, DWORD fvf
, void *vertices
, DWORD vertex_count
,
3749 WORD
*indices
, DWORD index_count
, DWORD flags
)
3751 return d3d_device7_DrawIndexedPrimitive(iface
, primitive_type
, fvf
,
3752 vertices
, vertex_count
, indices
, index_count
, flags
);
3755 static HRESULT WINAPI
d3d_device7_DrawIndexedPrimitive_FPUPreserve(IDirect3DDevice7
*iface
,
3756 D3DPRIMITIVETYPE primitive_type
, DWORD fvf
, void *vertices
, DWORD vertex_count
,
3757 WORD
*indices
, DWORD index_count
, DWORD flags
)
3762 old_fpucw
= d3d_fpu_setup();
3763 hr
= d3d_device7_DrawIndexedPrimitive(iface
, primitive_type
, fvf
,
3764 vertices
, vertex_count
, indices
, index_count
, flags
);
3765 set_fpu_control_word(old_fpucw
);
3770 static HRESULT WINAPI
d3d_device3_DrawIndexedPrimitive(IDirect3DDevice3
*iface
,
3771 D3DPRIMITIVETYPE primitive_type
, DWORD fvf
, void *vertices
, DWORD vertex_count
,
3772 WORD
*indices
, DWORD index_count
, DWORD flags
)
3774 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
3776 TRACE("iface %p, primitive_type %#x, fvf %#x, vertices %p, vertex_count %u, "
3777 "indices %p, index_count %u, flags %#x.\n",
3778 iface
, primitive_type
, fvf
, vertices
, vertex_count
, indices
, index_count
, flags
);
3780 setup_lighting(device
, fvf
, flags
);
3782 return IDirect3DDevice7_DrawIndexedPrimitive(&device
->IDirect3DDevice7_iface
,
3783 primitive_type
, fvf
, vertices
, vertex_count
, indices
, index_count
, flags
);
3786 static HRESULT WINAPI
d3d_device2_DrawIndexedPrimitive(IDirect3DDevice2
*iface
,
3787 D3DPRIMITIVETYPE primitive_type
, D3DVERTEXTYPE vertex_type
, void *vertices
,
3788 DWORD vertex_count
, WORD
*indices
, DWORD index_count
, DWORD flags
)
3790 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
3793 TRACE("iface %p, primitive_type %#x, vertex_type %#x, vertices %p, vertex_count %u, "
3794 "indices %p, index_count %u, flags %#x.\n",
3795 iface
, primitive_type
, vertex_type
, vertices
, vertex_count
, indices
, index_count
, flags
);
3797 switch (vertex_type
)
3799 case D3DVT_VERTEX
: fvf
= D3DFVF_VERTEX
; break;
3800 case D3DVT_LVERTEX
: fvf
= D3DFVF_LVERTEX
; break;
3801 case D3DVT_TLVERTEX
: fvf
= D3DFVF_TLVERTEX
; break;
3803 ERR("Unhandled vertex type %#x.\n", vertex_type
);
3804 return DDERR_INVALIDPARAMS
; /* Should never happen */
3807 return d3d_device3_DrawIndexedPrimitive(&device
->IDirect3DDevice3_iface
,
3808 primitive_type
, fvf
, vertices
, vertex_count
, indices
, index_count
, flags
);
3811 /*****************************************************************************
3812 * IDirect3DDevice3::End
3814 * Ends a draw begun with IDirect3DDevice3::Begin or
3815 * IDirect3DDevice::BeginIndexed. The vertices specified with
3816 * IDirect3DDevice::Vertex or IDirect3DDevice::Index are drawn using
3817 * the IDirect3DDevice3::DrawPrimitive method. So far only
3818 * non-indexed mode is supported
3823 * Flags: Some flags, as usual. Don't know which are defined
3826 * The return value of IDirect3DDevice3::DrawPrimitive
3828 *****************************************************************************/
3829 static HRESULT WINAPI
d3d_device3_End(IDirect3DDevice3
*iface
, DWORD flags
)
3831 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
3833 TRACE("iface %p, flags %#x.\n", iface
, flags
);
3835 return d3d_device3_DrawPrimitive(&device
->IDirect3DDevice3_iface
, device
->primitive_type
,
3836 device
->vertex_type
, device
->sysmem_vertex_buffer
, device
->nb_vertices
, device
->render_flags
);
3839 static HRESULT WINAPI
d3d_device2_End(IDirect3DDevice2
*iface
, DWORD flags
)
3841 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
3843 TRACE("iface %p, flags %#x.\n", iface
, flags
);
3845 return d3d_device3_End(&device
->IDirect3DDevice3_iface
, flags
);
3848 /*****************************************************************************
3849 * IDirect3DDevice7::SetClipStatus
3851 * Sets the clip status. This defines things as clipping conditions and
3852 * the extents of the clipping region.
3854 * Version 2, 3 and 7
3860 * D3D_OK because it's a stub
3861 * (DDERR_INVALIDPARAMS if ClipStatus == NULL)
3863 *****************************************************************************/
3864 static HRESULT WINAPI
d3d_device7_SetClipStatus(IDirect3DDevice7
*iface
, D3DCLIPSTATUS
*clip_status
)
3866 FIXME("iface %p, clip_status %p stub!\n", iface
, clip_status
);
3868 /* D3DCLIPSTATUS and WINED3DCLIPSTATUS are different. I don't know how to convert them
3869 * Perhaps this needs a new data type and an additional IWineD3DDevice method
3871 /* return IWineD3DDevice_SetClipStatus(This->wineD3DDevice, ClipStatus);*/
3875 static HRESULT WINAPI
d3d_device3_SetClipStatus(IDirect3DDevice3
*iface
, D3DCLIPSTATUS
*clip_status
)
3877 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
3879 TRACE("iface %p, clip_status %p.\n", iface
, clip_status
);
3881 return IDirect3DDevice7_SetClipStatus(&device
->IDirect3DDevice7_iface
, clip_status
);
3884 static HRESULT WINAPI
d3d_device2_SetClipStatus(IDirect3DDevice2
*iface
, D3DCLIPSTATUS
*clip_status
)
3886 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
3888 TRACE("iface %p, clip_status %p.\n", iface
, clip_status
);
3890 return IDirect3DDevice7_SetClipStatus(&device
->IDirect3DDevice7_iface
, clip_status
);
3893 /*****************************************************************************
3894 * IDirect3DDevice7::GetClipStatus
3896 * Returns the clip status
3899 * ClipStatus: Address to write the clip status to
3902 * D3D_OK because it's a stub
3904 *****************************************************************************/
3905 static HRESULT WINAPI
d3d_device7_GetClipStatus(IDirect3DDevice7
*iface
, D3DCLIPSTATUS
*clip_status
)
3907 FIXME("iface %p, clip_status %p stub!\n", iface
, clip_status
);
3909 /* D3DCLIPSTATUS and WINED3DCLIPSTATUS are different. I don't know how to convert them */
3910 /* return IWineD3DDevice_GetClipStatus(This->wineD3DDevice, ClipStatus);*/
3914 static HRESULT WINAPI
d3d_device3_GetClipStatus(IDirect3DDevice3
*iface
, D3DCLIPSTATUS
*clip_status
)
3916 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
3918 TRACE("iface %p, clip_status %p.\n", iface
, clip_status
);
3920 return IDirect3DDevice7_GetClipStatus(&device
->IDirect3DDevice7_iface
, clip_status
);
3923 static HRESULT WINAPI
d3d_device2_GetClipStatus(IDirect3DDevice2
*iface
, D3DCLIPSTATUS
*clip_status
)
3925 struct d3d_device
*device
= impl_from_IDirect3DDevice2(iface
);
3927 TRACE("iface %p, clip_status %p.\n", iface
, clip_status
);
3929 return IDirect3DDevice7_GetClipStatus(&device
->IDirect3DDevice7_iface
, clip_status
);
3932 /*****************************************************************************
3933 * IDirect3DDevice::DrawPrimitiveStrided
3935 * Draws vertices described by a D3DDRAWPRIMITIVESTRIDEDDATA structure.
3940 * PrimitiveType: The primitive type to draw
3941 * VertexType: The FVF description of the vertices to draw (for the stride??)
3942 * D3DDrawPrimStrideData: A D3DDRAWPRIMITIVESTRIDEDDATA structure describing
3943 * the vertex data locations
3944 * VertexCount: The number of vertices to draw
3948 * D3D_OK, because it's a stub
3949 * (DDERR_INVALIDPARAMS if D3DDrawPrimStrideData is NULL)
3950 * (For details, see IWineD3DDevice::DrawPrimitiveStrided)
3952 *****************************************************************************/
3953 static void pack_strided_data(BYTE
*dst
, DWORD count
, const D3DDRAWPRIMITIVESTRIDEDDATA
*src
, DWORD fvf
)
3955 DWORD i
, tex
, offset
;
3957 for (i
= 0; i
< count
; i
++)
3959 /* The contents of the strided data are determined by the fvf,
3960 * not by the members set in src. So it's valid
3961 * to have diffuse.lpvData set to 0xdeadbeef if the diffuse flag is
3962 * not set in the fvf. */
3963 if (fvf
& D3DFVF_POSITION_MASK
)
3965 offset
= i
* src
->position
.dwStride
;
3966 if (fvf
& D3DFVF_XYZRHW
)
3968 memcpy(dst
, ((BYTE
*)src
->position
.lpvData
) + offset
, 4 * sizeof(float));
3969 dst
+= 4 * sizeof(float);
3973 memcpy(dst
, ((BYTE
*)src
->position
.lpvData
) + offset
, 3 * sizeof(float));
3974 dst
+= 3 * sizeof(float);
3978 if (fvf
& D3DFVF_NORMAL
)
3980 offset
= i
* src
->normal
.dwStride
;
3981 memcpy(dst
, ((BYTE
*)src
->normal
.lpvData
) + offset
, 3 * sizeof(float));
3982 dst
+= 3 * sizeof(float);
3985 if (fvf
& D3DFVF_DIFFUSE
)
3987 offset
= i
* src
->diffuse
.dwStride
;
3988 memcpy(dst
, ((BYTE
*)src
->diffuse
.lpvData
) + offset
, sizeof(DWORD
));
3989 dst
+= sizeof(DWORD
);
3992 if (fvf
& D3DFVF_SPECULAR
)
3994 offset
= i
* src
->specular
.dwStride
;
3995 memcpy(dst
, ((BYTE
*)src
->specular
.lpvData
) + offset
, sizeof(DWORD
));
3996 dst
+= sizeof(DWORD
);
3999 for (tex
= 0; tex
< GET_TEXCOUNT_FROM_FVF(fvf
); ++tex
)
4001 DWORD attrib_count
= GET_TEXCOORD_SIZE_FROM_FVF(fvf
, tex
);
4002 offset
= i
* src
->textureCoords
[tex
].dwStride
;
4003 memcpy(dst
, ((BYTE
*)src
->textureCoords
[tex
].lpvData
) + offset
, attrib_count
* sizeof(float));
4004 dst
+= attrib_count
* sizeof(float);
4009 static HRESULT
d3d_device7_DrawPrimitiveStrided(IDirect3DDevice7
*iface
, D3DPRIMITIVETYPE PrimitiveType
,
4010 DWORD VertexType
, D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
, DWORD VertexCount
, DWORD Flags
)
4012 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
4014 UINT dst_stride
= get_flexible_vertex_size(VertexType
);
4015 UINT dst_size
= dst_stride
* VertexCount
;
4019 TRACE("iface %p, primitive_type %#x, FVF %#x, strided_data %p, vertex_count %u, flags %#x.\n",
4020 iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Flags
);
4022 wined3d_mutex_lock();
4023 hr
= d3d_device_prepare_vertex_buffer(device
, dst_size
);
4027 vb_pos
= device
->vertex_buffer_pos
;
4028 align
= vb_pos
% dst_stride
;
4029 if (align
) align
= dst_stride
- align
;
4030 if (vb_pos
+ dst_size
+ align
> device
->vertex_buffer_size
)
4035 hr
= wined3d_buffer_map(device
->vertex_buffer
, vb_pos
, dst_size
, &dst_data
,
4036 vb_pos
? WINED3D_MAP_NOOVERWRITE
: WINED3D_MAP_DISCARD
);
4039 pack_strided_data(dst_data
, VertexCount
, D3DDrawPrimStrideData
, VertexType
);
4040 wined3d_buffer_unmap(device
->vertex_buffer
);
4041 device
->vertex_buffer_pos
= vb_pos
+ dst_size
;
4043 hr
= wined3d_device_set_stream_source(device
->wined3d_device
, 0, device
->vertex_buffer
, 0, dst_stride
);
4046 wined3d_device_set_vertex_declaration(device
->wined3d_device
, ddraw_find_decl(device
->ddraw
, VertexType
));
4048 wined3d_device_set_primitive_type(device
->wined3d_device
, PrimitiveType
);
4049 hr
= wined3d_device_draw_primitive(device
->wined3d_device
, vb_pos
/ dst_stride
, VertexCount
);
4052 wined3d_mutex_unlock();
4056 static HRESULT WINAPI
d3d_device7_DrawPrimitiveStrided_FPUSetup(IDirect3DDevice7
*iface
,
4057 D3DPRIMITIVETYPE PrimitiveType
, DWORD VertexType
,
4058 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
, DWORD VertexCount
, DWORD Flags
)
4060 return d3d_device7_DrawPrimitiveStrided(iface
, PrimitiveType
,
4061 VertexType
, D3DDrawPrimStrideData
, VertexCount
, Flags
);
4064 static HRESULT WINAPI
d3d_device7_DrawPrimitiveStrided_FPUPreserve(IDirect3DDevice7
*iface
,
4065 D3DPRIMITIVETYPE PrimitiveType
, DWORD VertexType
,
4066 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
, DWORD VertexCount
, DWORD Flags
)
4071 old_fpucw
= d3d_fpu_setup();
4072 hr
= d3d_device7_DrawPrimitiveStrided(iface
, PrimitiveType
,
4073 VertexType
, D3DDrawPrimStrideData
, VertexCount
, Flags
);
4074 set_fpu_control_word(old_fpucw
);
4079 static HRESULT WINAPI
d3d_device3_DrawPrimitiveStrided(IDirect3DDevice3
*iface
,
4080 D3DPRIMITIVETYPE PrimitiveType
, DWORD VertexType
,
4081 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
, DWORD VertexCount
, DWORD Flags
)
4083 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
4085 TRACE("iface %p, primitive_type %#x, FVF %#x, strided_data %p, vertex_count %u, flags %#x.\n",
4086 iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Flags
);
4088 setup_lighting(device
, VertexType
, Flags
);
4090 return IDirect3DDevice7_DrawPrimitiveStrided(&device
->IDirect3DDevice7_iface
,
4091 PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Flags
);
4094 /*****************************************************************************
4095 * IDirect3DDevice7::DrawIndexedPrimitiveStrided
4097 * Draws primitives specified by strided data locations based on indices
4105 * D3D_OK, because it's a stub
4106 * (DDERR_INVALIDPARAMS if D3DDrawPrimStrideData is NULL)
4107 * (DDERR_INVALIDPARAMS if Indices is NULL)
4108 * (For more details, see IWineD3DDevice::DrawIndexedPrimitiveStrided)
4110 *****************************************************************************/
4111 static HRESULT
d3d_device7_DrawIndexedPrimitiveStrided(IDirect3DDevice7
*iface
,
4112 D3DPRIMITIVETYPE PrimitiveType
, DWORD VertexType
,
4113 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
, DWORD VertexCount
,
4114 WORD
*Indices
, DWORD IndexCount
, DWORD Flags
)
4116 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
4118 UINT vtx_dst_stride
= get_flexible_vertex_size(VertexType
);
4119 UINT vtx_dst_size
= VertexCount
* vtx_dst_stride
;
4121 UINT idx_size
= IndexCount
* sizeof(WORD
);
4125 TRACE("iface %p, primitive_type %#x, FVF %#x, strided_data %p, vertex_count %u, indices %p, index_count %u, flags %#x.\n",
4126 iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Indices
, IndexCount
, Flags
);
4128 wined3d_mutex_lock();
4130 hr
= d3d_device_prepare_vertex_buffer(device
, vtx_dst_size
);
4134 vb_pos
= device
->vertex_buffer_pos
;
4135 align
= vb_pos
% vtx_dst_stride
;
4136 if (align
) align
= vtx_dst_stride
- align
;
4137 if (vb_pos
+ vtx_dst_size
+ align
> device
->vertex_buffer_size
)
4142 hr
= wined3d_buffer_map(device
->vertex_buffer
, vb_pos
, vtx_dst_size
, &dst_data
,
4143 vb_pos
? WINED3D_MAP_NOOVERWRITE
: WINED3D_MAP_DISCARD
);
4146 pack_strided_data(dst_data
, VertexCount
, D3DDrawPrimStrideData
, VertexType
);
4147 wined3d_buffer_unmap(device
->vertex_buffer
);
4148 device
->vertex_buffer_pos
= vb_pos
+ vtx_dst_size
;
4150 hr
= d3d_device_prepare_index_buffer(device
, idx_size
);
4153 ib_pos
= device
->index_buffer_pos
;
4154 if (device
->index_buffer_size
- idx_size
< ib_pos
)
4157 hr
= wined3d_buffer_map(device
->index_buffer
, ib_pos
, idx_size
, &dst_data
,
4158 ib_pos
? WINED3D_MAP_NOOVERWRITE
: WINED3D_MAP_DISCARD
);
4161 memcpy(dst_data
, Indices
, idx_size
);
4162 wined3d_buffer_unmap(device
->index_buffer
);
4163 device
->index_buffer_pos
= ib_pos
+ idx_size
;
4165 hr
= wined3d_device_set_stream_source(device
->wined3d_device
, 0, device
->vertex_buffer
, 0, vtx_dst_stride
);
4168 wined3d_device_set_index_buffer(device
->wined3d_device
, device
->index_buffer
, WINED3DFMT_R16_UINT
);
4169 wined3d_device_set_base_vertex_index(device
->wined3d_device
, vb_pos
/ vtx_dst_stride
);
4171 wined3d_device_set_vertex_declaration(device
->wined3d_device
, ddraw_find_decl(device
->ddraw
, VertexType
));
4172 wined3d_device_set_primitive_type(device
->wined3d_device
, PrimitiveType
);
4173 hr
= wined3d_device_draw_indexed_primitive(device
->wined3d_device
, ib_pos
/ sizeof(WORD
), IndexCount
);
4176 wined3d_mutex_unlock();
4180 static HRESULT WINAPI
d3d_device7_DrawIndexedPrimitiveStrided_FPUSetup(IDirect3DDevice7
*iface
,
4181 D3DPRIMITIVETYPE PrimitiveType
, DWORD VertexType
,
4182 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
, DWORD VertexCount
,
4183 WORD
*Indices
, DWORD IndexCount
, DWORD Flags
)
4185 return d3d_device7_DrawIndexedPrimitiveStrided(iface
, PrimitiveType
, VertexType
,
4186 D3DDrawPrimStrideData
, VertexCount
, Indices
, IndexCount
, Flags
);
4189 static HRESULT WINAPI
d3d_device7_DrawIndexedPrimitiveStrided_FPUPreserve(IDirect3DDevice7
*iface
,
4190 D3DPRIMITIVETYPE PrimitiveType
, DWORD VertexType
,
4191 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
, DWORD VertexCount
,
4192 WORD
*Indices
, DWORD IndexCount
, DWORD Flags
)
4197 old_fpucw
= d3d_fpu_setup();
4198 hr
= d3d_device7_DrawIndexedPrimitiveStrided(iface
, PrimitiveType
, VertexType
,
4199 D3DDrawPrimStrideData
, VertexCount
, Indices
, IndexCount
, Flags
);
4200 set_fpu_control_word(old_fpucw
);
4205 static HRESULT WINAPI
d3d_device3_DrawIndexedPrimitiveStrided(IDirect3DDevice3
*iface
,
4206 D3DPRIMITIVETYPE PrimitiveType
, DWORD VertexType
,
4207 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
, DWORD VertexCount
, WORD
*Indices
,
4208 DWORD IndexCount
, DWORD Flags
)
4210 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
4212 TRACE("iface %p, primitive_type %#x, FVF %#x, strided_data %p, vertex_count %u, indices %p, index_count %u, flags %#x.\n",
4213 iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Indices
, IndexCount
, Flags
);
4215 setup_lighting(device
, VertexType
, Flags
);
4217 return IDirect3DDevice7_DrawIndexedPrimitiveStrided(&device
->IDirect3DDevice7_iface
,
4218 PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Indices
, IndexCount
, Flags
);
4221 /*****************************************************************************
4222 * IDirect3DDevice7::DrawPrimitiveVB
4224 * Draws primitives from a vertex buffer to the screen.
4229 * PrimitiveType: Type of primitive to be rendered.
4230 * D3DVertexBuf: Source Vertex Buffer
4231 * StartVertex: Index of the first vertex from the buffer to be rendered
4232 * NumVertices: Number of vertices to be rendered
4233 * Flags: Can be D3DDP_WAIT to wait until rendering has finished
4237 * DDERR_INVALIDPARAMS if D3DVertexBuf is NULL
4239 *****************************************************************************/
4240 static HRESULT
d3d_device7_DrawPrimitiveVB(IDirect3DDevice7
*iface
, D3DPRIMITIVETYPE PrimitiveType
,
4241 IDirect3DVertexBuffer7
*D3DVertexBuf
, DWORD StartVertex
, DWORD NumVertices
, DWORD Flags
)
4243 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
4244 struct d3d_vertex_buffer
*vb
= unsafe_impl_from_IDirect3DVertexBuffer7(D3DVertexBuf
);
4248 TRACE("iface %p, primitive_type %#x, vb %p, start_vertex %u, vertex_count %u, flags %#x.\n",
4249 iface
, PrimitiveType
, D3DVertexBuf
, StartVertex
, NumVertices
, Flags
);
4254 WARN("No Vertex buffer specified.\n");
4255 return DDERR_INVALIDPARAMS
;
4257 stride
= get_flexible_vertex_size(vb
->fvf
);
4259 wined3d_mutex_lock();
4260 wined3d_device_set_vertex_declaration(device
->wined3d_device
, vb
->wineD3DVertexDeclaration
);
4261 hr
= wined3d_device_set_stream_source(device
->wined3d_device
, 0, vb
->wineD3DVertexBuffer
, 0, stride
);
4264 WARN("Failed to set stream source, hr %#x.\n", hr
);
4265 wined3d_mutex_unlock();
4269 /* Now draw the primitives */
4270 wined3d_device_set_primitive_type(device
->wined3d_device
, PrimitiveType
);
4271 hr
= wined3d_device_draw_primitive(device
->wined3d_device
, StartVertex
, NumVertices
);
4273 wined3d_mutex_unlock();
4278 static HRESULT WINAPI
d3d_device7_DrawPrimitiveVB_FPUSetup(IDirect3DDevice7
*iface
, D3DPRIMITIVETYPE PrimitiveType
,
4279 IDirect3DVertexBuffer7
*D3DVertexBuf
, DWORD StartVertex
, DWORD NumVertices
, DWORD Flags
)
4281 return d3d_device7_DrawPrimitiveVB(iface
, PrimitiveType
, D3DVertexBuf
, StartVertex
, NumVertices
, Flags
);
4284 static HRESULT WINAPI
d3d_device7_DrawPrimitiveVB_FPUPreserve(IDirect3DDevice7
*iface
, D3DPRIMITIVETYPE PrimitiveType
,
4285 IDirect3DVertexBuffer7
*D3DVertexBuf
, DWORD StartVertex
, DWORD NumVertices
, DWORD Flags
)
4290 old_fpucw
= d3d_fpu_setup();
4291 hr
= d3d_device7_DrawPrimitiveVB(iface
, PrimitiveType
, D3DVertexBuf
, StartVertex
, NumVertices
, Flags
);
4292 set_fpu_control_word(old_fpucw
);
4297 static HRESULT WINAPI
d3d_device3_DrawPrimitiveVB(IDirect3DDevice3
*iface
, D3DPRIMITIVETYPE PrimitiveType
,
4298 IDirect3DVertexBuffer
*D3DVertexBuf
, DWORD StartVertex
, DWORD NumVertices
, DWORD Flags
)
4300 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
4301 struct d3d_vertex_buffer
*vb
= unsafe_impl_from_IDirect3DVertexBuffer(D3DVertexBuf
);
4303 TRACE("iface %p, primitive_type %#x, vb %p, start_vertex %u, vertex_count %u, flags %#x.\n",
4304 iface
, PrimitiveType
, D3DVertexBuf
, StartVertex
, NumVertices
, Flags
);
4306 setup_lighting(device
, vb
->fvf
, Flags
);
4308 return IDirect3DDevice7_DrawPrimitiveVB(&device
->IDirect3DDevice7_iface
,
4309 PrimitiveType
, &vb
->IDirect3DVertexBuffer7_iface
, StartVertex
, NumVertices
, Flags
);
4312 /*****************************************************************************
4313 * IDirect3DDevice7::DrawIndexedPrimitiveVB
4315 * Draws primitives from a vertex buffer to the screen
4318 * PrimitiveType: Type of primitive to be rendered.
4319 * D3DVertexBuf: Source Vertex Buffer
4320 * StartVertex: Index of the first vertex from the buffer to be rendered
4321 * NumVertices: Number of vertices to be rendered
4322 * Indices: Array of DWORDs used to index into the Vertices
4323 * IndexCount: Number of indices in Indices
4324 * Flags: Can be D3DDP_WAIT to wait until rendering has finished
4328 *****************************************************************************/
4329 static HRESULT
d3d_device7_DrawIndexedPrimitiveVB(IDirect3DDevice7
*iface
,
4330 D3DPRIMITIVETYPE PrimitiveType
, IDirect3DVertexBuffer7
*D3DVertexBuf
,
4331 DWORD StartVertex
, DWORD NumVertices
, WORD
*Indices
, DWORD IndexCount
, DWORD Flags
)
4333 struct d3d_device
*This
= impl_from_IDirect3DDevice7(iface
);
4334 struct d3d_vertex_buffer
*vb
= unsafe_impl_from_IDirect3DVertexBuffer7(D3DVertexBuf
);
4335 DWORD stride
= get_flexible_vertex_size(vb
->fvf
);
4336 WORD
*LockedIndices
;
4340 TRACE("iface %p, primitive_type %#x, vb %p, start_vertex %u, vertex_count %u, indices %p, index_count %u, flags %#x.\n",
4341 iface
, PrimitiveType
, D3DVertexBuf
, StartVertex
, NumVertices
, Indices
, IndexCount
, Flags
);
4344 * 1) Upload the Indices to the index buffer
4345 * 2) Set the index source
4346 * 3) Set the Vertex Buffer as the Stream source
4347 * 4) Call IWineD3DDevice::DrawIndexedPrimitive
4350 wined3d_mutex_lock();
4352 wined3d_device_set_vertex_declaration(This
->wined3d_device
, vb
->wineD3DVertexDeclaration
);
4354 hr
= d3d_device_prepare_index_buffer(This
, IndexCount
* sizeof(WORD
));
4357 wined3d_mutex_unlock();
4360 ib_pos
= This
->index_buffer_pos
;
4362 if (This
->index_buffer_size
- IndexCount
* sizeof(WORD
) < ib_pos
)
4365 /* Copy the index stream into the index buffer. A new IWineD3DDevice
4366 * method could be created which takes an user pointer containing the
4367 * indices or a SetData-Method for the index buffer, which overrides the
4368 * index buffer data with our pointer. */
4369 hr
= wined3d_buffer_map(This
->index_buffer
, ib_pos
, IndexCount
* sizeof(WORD
),
4370 (BYTE
**)&LockedIndices
, ib_pos
? WINED3D_MAP_NOOVERWRITE
: WINED3D_MAP_DISCARD
);
4373 ERR("Failed to map buffer, hr %#x.\n", hr
);
4374 wined3d_mutex_unlock();
4377 memcpy(LockedIndices
, Indices
, IndexCount
* sizeof(WORD
));
4378 wined3d_buffer_unmap(This
->index_buffer
);
4379 This
->index_buffer_pos
= ib_pos
+ IndexCount
* sizeof(WORD
);
4381 /* Set the index stream */
4382 wined3d_device_set_base_vertex_index(This
->wined3d_device
, StartVertex
);
4383 wined3d_device_set_index_buffer(This
->wined3d_device
, This
->index_buffer
, WINED3DFMT_R16_UINT
);
4385 /* Set the vertex stream source */
4386 hr
= wined3d_device_set_stream_source(This
->wined3d_device
, 0, vb
->wineD3DVertexBuffer
, 0, stride
);
4389 ERR("(%p) IDirect3DDevice::SetStreamSource failed with hr = %08x\n", This
, hr
);
4390 wined3d_mutex_unlock();
4395 wined3d_device_set_primitive_type(This
->wined3d_device
, PrimitiveType
);
4396 hr
= wined3d_device_draw_indexed_primitive(This
->wined3d_device
, ib_pos
/ sizeof(WORD
), IndexCount
);
4398 wined3d_mutex_unlock();
4403 static HRESULT WINAPI
d3d_device7_DrawIndexedPrimitiveVB_FPUSetup(IDirect3DDevice7
*iface
,
4404 D3DPRIMITIVETYPE PrimitiveType
, IDirect3DVertexBuffer7
*D3DVertexBuf
,
4405 DWORD StartVertex
, DWORD NumVertices
, WORD
*Indices
, DWORD IndexCount
, DWORD Flags
)
4407 return d3d_device7_DrawIndexedPrimitiveVB(iface
, PrimitiveType
,
4408 D3DVertexBuf
, StartVertex
, NumVertices
, Indices
, IndexCount
, Flags
);
4411 static HRESULT WINAPI
d3d_device7_DrawIndexedPrimitiveVB_FPUPreserve(IDirect3DDevice7
*iface
,
4412 D3DPRIMITIVETYPE PrimitiveType
, IDirect3DVertexBuffer7
*D3DVertexBuf
,
4413 DWORD StartVertex
, DWORD NumVertices
, WORD
*Indices
, DWORD IndexCount
, DWORD Flags
)
4418 old_fpucw
= d3d_fpu_setup();
4419 hr
= d3d_device7_DrawIndexedPrimitiveVB(iface
, PrimitiveType
,
4420 D3DVertexBuf
, StartVertex
, NumVertices
, Indices
, IndexCount
, Flags
);
4421 set_fpu_control_word(old_fpucw
);
4426 static HRESULT WINAPI
d3d_device3_DrawIndexedPrimitiveVB(IDirect3DDevice3
*iface
,
4427 D3DPRIMITIVETYPE PrimitiveType
, IDirect3DVertexBuffer
*D3DVertexBuf
, WORD
*Indices
,
4428 DWORD IndexCount
, DWORD Flags
)
4430 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
4431 struct d3d_vertex_buffer
*vb
= unsafe_impl_from_IDirect3DVertexBuffer(D3DVertexBuf
);
4433 TRACE("iface %p, primitive_type %#x, vb %p, indices %p, index_count %u, flags %#x.\n",
4434 iface
, PrimitiveType
, D3DVertexBuf
, Indices
, IndexCount
, Flags
);
4436 setup_lighting(device
, vb
->fvf
, Flags
);
4438 return IDirect3DDevice7_DrawIndexedPrimitiveVB(&device
->IDirect3DDevice7_iface
, PrimitiveType
,
4439 &vb
->IDirect3DVertexBuffer7_iface
, 0, IndexCount
, Indices
, IndexCount
, Flags
);
4442 /*****************************************************************************
4443 * IDirect3DDevice7::ComputeSphereVisibility
4445 * Calculates the visibility of spheres in the current viewport. The spheres
4446 * are passed in the Centers and Radii arrays, the results are passed back
4447 * in the ReturnValues array. Return values are either completely visible,
4448 * partially visible or completely invisible.
4449 * The return value consists of a combination of D3DCLIP_* flags, or is
4450 * 0 if the sphere is completely visible (according to the SDK, not checked)
4455 * Centers: Array containing the sphere centers
4456 * Radii: Array containing the sphere radii
4457 * NumSpheres: The number of centers and radii in the arrays
4459 * ReturnValues: Array to write the results to
4463 * (DDERR_INVALIDPARAMS if Centers, Radii or ReturnValues are NULL)
4464 * (D3DERR_INVALIDMATRIX if the combined world, view and proj matrix
4467 *****************************************************************************/
4469 static DWORD
in_plane(UINT plane
, D3DVECTOR normal
, D3DVALUE origin_plane
, D3DVECTOR center
, D3DVALUE radius
)
4471 float distance
, norm
;
4473 norm
= sqrtf(normal
.u1
.x
* normal
.u1
.x
+ normal
.u2
.y
* normal
.u2
.y
+ normal
.u3
.z
* normal
.u3
.z
);
4474 distance
= ( origin_plane
+ normal
.u1
.x
* center
.u1
.x
+ normal
.u2
.y
* center
.u2
.y
+ normal
.u3
.z
* center
.u3
.z
) / norm
;
4476 if ( fabs( distance
) < radius
) return D3DSTATUS_CLIPUNIONLEFT
<< plane
;
4477 if ( distance
< -radius
) return (D3DSTATUS_CLIPUNIONLEFT
| D3DSTATUS_CLIPINTERSECTIONLEFT
) << plane
;
4481 static HRESULT WINAPI
d3d_device7_ComputeSphereVisibility(IDirect3DDevice7
*iface
,
4482 D3DVECTOR
*centers
, D3DVALUE
*radii
, DWORD sphere_count
, DWORD flags
, DWORD
*return_values
)
4485 D3DVALUE origin_plane
[6];
4490 TRACE("iface %p, centers %p, radii %p, sphere_count %u, flags %#x, return_values %p.\n",
4491 iface
, centers
, radii
, sphere_count
, flags
, return_values
);
4493 hr
= d3d_device7_GetTransform(iface
, D3DTRANSFORMSTATE_WORLD
, &m
);
4494 if ( hr
!= DD_OK
) return DDERR_INVALIDPARAMS
;
4495 hr
= d3d_device7_GetTransform(iface
, D3DTRANSFORMSTATE_VIEW
, &temp
);
4496 if ( hr
!= DD_OK
) return DDERR_INVALIDPARAMS
;
4497 multiply_matrix(&m
, &temp
, &m
);
4499 hr
= d3d_device7_GetTransform(iface
, D3DTRANSFORMSTATE_PROJECTION
, &temp
);
4500 if ( hr
!= DD_OK
) return DDERR_INVALIDPARAMS
;
4501 multiply_matrix(&m
, &temp
, &m
);
4504 vec
[0].u1
.x
= m
._14
+ m
._11
;
4505 vec
[0].u2
.y
= m
._24
+ m
._21
;
4506 vec
[0].u3
.z
= m
._34
+ m
._31
;
4507 origin_plane
[0] = m
._44
+ m
._41
;
4510 vec
[1].u1
.x
= m
._14
- m
._11
;
4511 vec
[1].u2
.y
= m
._24
- m
._21
;
4512 vec
[1].u3
.z
= m
._34
- m
._31
;
4513 origin_plane
[1] = m
._44
- m
._41
;
4516 vec
[2].u1
.x
= m
._14
- m
._12
;
4517 vec
[2].u2
.y
= m
._24
- m
._22
;
4518 vec
[2].u3
.z
= m
._34
- m
._32
;
4519 origin_plane
[2] = m
._44
- m
._42
;
4522 vec
[3].u1
.x
= m
._14
+ m
._12
;
4523 vec
[3].u2
.y
= m
._24
+ m
._22
;
4524 vec
[3].u3
.z
= m
._34
+ m
._32
;
4525 origin_plane
[3] = m
._44
+ m
._42
;
4528 vec
[4].u1
.x
= m
._13
;
4529 vec
[4].u2
.y
= m
._23
;
4530 vec
[4].u3
.z
= m
._33
;
4531 origin_plane
[4] = m
._43
;
4534 vec
[5].u1
.x
= m
._14
- m
._13
;
4535 vec
[5].u2
.y
= m
._24
- m
._23
;
4536 vec
[5].u3
.z
= m
._34
- m
._33
;
4537 origin_plane
[5] = m
._44
- m
._43
;
4539 for (i
= 0; i
< sphere_count
; ++i
)
4541 return_values
[i
] = 0;
4542 for (j
= 0; j
< 6; ++j
)
4543 return_values
[i
] |= in_plane(j
, vec
[j
], origin_plane
[j
], centers
[i
], radii
[i
]);
4549 static HRESULT WINAPI
d3d_device3_ComputeSphereVisibility(IDirect3DDevice3
*iface
,
4550 D3DVECTOR
*centers
, D3DVALUE
*radii
, DWORD sphere_count
, DWORD flags
, DWORD
*return_values
)
4552 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
4554 TRACE("iface %p, centers %p, radii %p, sphere_count %u, flags %#x, return_values %p.\n",
4555 iface
, centers
, radii
, sphere_count
, flags
, return_values
);
4557 return IDirect3DDevice7_ComputeSphereVisibility(&device
->IDirect3DDevice7_iface
,
4558 centers
, radii
, sphere_count
, flags
, return_values
);
4561 /*****************************************************************************
4562 * IDirect3DDevice7::GetTexture
4564 * Returns the texture interface handle assigned to a texture stage.
4565 * The returned texture is AddRefed. This is taken from old ddraw,
4566 * not checked in Windows.
4571 * Stage: Texture stage to read the texture from
4572 * Texture: Address to store the interface pointer at
4576 * DDERR_INVALIDPARAMS if Texture is NULL
4577 * For details, see IWineD3DDevice::GetTexture
4579 *****************************************************************************/
4580 static HRESULT
d3d_device7_GetTexture(IDirect3DDevice7
*iface
,
4581 DWORD stage
, IDirectDrawSurface7
**texture
)
4583 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
4584 struct wined3d_texture
*wined3d_texture
;
4585 struct ddraw_texture
*ddraw_texture
;
4587 TRACE("iface %p, stage %u, texture %p.\n", iface
, stage
, texture
);
4590 return DDERR_INVALIDPARAMS
;
4592 wined3d_mutex_lock();
4593 if (!(wined3d_texture
= wined3d_device_get_texture(device
->wined3d_device
, stage
)))
4596 wined3d_mutex_unlock();
4600 ddraw_texture
= wined3d_texture_get_parent(wined3d_texture
);
4601 *texture
= &ddraw_texture
->root
->IDirectDrawSurface7_iface
;
4602 IDirectDrawSurface7_AddRef(*texture
);
4603 wined3d_mutex_unlock();
4608 static HRESULT WINAPI
d3d_device7_GetTexture_FPUSetup(IDirect3DDevice7
*iface
,
4609 DWORD stage
, IDirectDrawSurface7
**Texture
)
4611 return d3d_device7_GetTexture(iface
, stage
, Texture
);
4614 static HRESULT WINAPI
d3d_device7_GetTexture_FPUPreserve(IDirect3DDevice7
*iface
,
4615 DWORD stage
, IDirectDrawSurface7
**Texture
)
4620 old_fpucw
= d3d_fpu_setup();
4621 hr
= d3d_device7_GetTexture(iface
, stage
, Texture
);
4622 set_fpu_control_word(old_fpucw
);
4627 static HRESULT WINAPI
d3d_device3_GetTexture(IDirect3DDevice3
*iface
, DWORD stage
, IDirect3DTexture2
**Texture2
)
4629 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
4630 struct ddraw_surface
*ret_val_impl
;
4632 IDirectDrawSurface7
*ret_val
;
4634 TRACE("iface %p, stage %u, texture %p.\n", iface
, stage
, Texture2
);
4636 ret
= IDirect3DDevice7_GetTexture(&device
->IDirect3DDevice7_iface
, stage
, &ret_val
);
4638 ret_val_impl
= unsafe_impl_from_IDirectDrawSurface7(ret_val
);
4639 *Texture2
= ret_val_impl
? &ret_val_impl
->IDirect3DTexture2_iface
: NULL
;
4641 TRACE("Returning texture %p.\n", *Texture2
);
4646 /*****************************************************************************
4647 * IDirect3DDevice7::SetTexture
4649 * Assigns a texture to a texture stage. Is the texture AddRef-ed?
4654 * Stage: The stage to assign the texture to
4655 * Texture: Interface pointer to the texture surface
4659 * For details, see IWineD3DDevice::SetTexture
4661 *****************************************************************************/
4662 static HRESULT
d3d_device7_SetTexture(IDirect3DDevice7
*iface
,
4663 DWORD stage
, IDirectDrawSurface7
*texture
)
4665 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
4666 struct ddraw_surface
*surf
= unsafe_impl_from_IDirectDrawSurface7(texture
);
4667 struct wined3d_texture
*wined3d_texture
= NULL
;
4670 TRACE("iface %p, stage %u, texture %p.\n", iface
, stage
, texture
);
4672 if (surf
&& (surf
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_TEXTURE
))
4673 wined3d_texture
= surf
->wined3d_texture
;
4675 wined3d_mutex_lock();
4676 hr
= wined3d_device_set_texture(device
->wined3d_device
, stage
, wined3d_texture
);
4677 wined3d_mutex_unlock();
4682 static HRESULT WINAPI
d3d_device7_SetTexture_FPUSetup(IDirect3DDevice7
*iface
,
4683 DWORD stage
, IDirectDrawSurface7
*texture
)
4685 return d3d_device7_SetTexture(iface
, stage
, texture
);
4688 static HRESULT WINAPI
d3d_device7_SetTexture_FPUPreserve(IDirect3DDevice7
*iface
,
4689 DWORD stage
, IDirectDrawSurface7
*texture
)
4694 old_fpucw
= d3d_fpu_setup();
4695 hr
= d3d_device7_SetTexture(iface
, stage
, texture
);
4696 set_fpu_control_word(old_fpucw
);
4701 static HRESULT WINAPI
d3d_device3_SetTexture(IDirect3DDevice3
*iface
,
4702 DWORD stage
, IDirect3DTexture2
*texture
)
4704 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
4705 struct ddraw_surface
*tex
= unsafe_impl_from_IDirect3DTexture2(texture
);
4709 TRACE("iface %p, stage %u, texture %p.\n", iface
, stage
, texture
);
4711 wined3d_mutex_lock();
4713 if (device
->legacyTextureBlending
)
4714 IDirect3DDevice3_GetRenderState(iface
, D3DRENDERSTATE_TEXTUREMAPBLEND
, &texmapblend
);
4716 hr
= IDirect3DDevice7_SetTexture(&device
->IDirect3DDevice7_iface
, stage
, &tex
->IDirectDrawSurface7_iface
);
4718 if (device
->legacyTextureBlending
&& texmapblend
== D3DTBLEND_MODULATE
)
4720 /* This fixup is required by the way D3DTBLEND_MODULATE maps to texture stage states.
4721 See d3d_device3_SetRenderState() for details. */
4722 struct wined3d_texture
*tex
= NULL
;
4723 BOOL tex_alpha
= FALSE
;
4724 DDPIXELFORMAT ddfmt
;
4726 if ((tex
= wined3d_device_get_texture(device
->wined3d_device
, 0)))
4728 struct wined3d_resource
*sub_resource
;
4730 if ((sub_resource
= wined3d_texture_get_sub_resource(tex
, 0)))
4732 struct wined3d_resource_desc desc
;
4734 wined3d_resource_get_desc(sub_resource
, &desc
);
4735 ddfmt
.dwSize
= sizeof(ddfmt
);
4736 ddrawformat_from_wined3dformat(&ddfmt
, desc
.format
);
4737 if (ddfmt
.u5
.dwRGBAlphaBitMask
) tex_alpha
= TRUE
;
4741 /* Args 1 and 2 are already set to WINED3DTA_TEXTURE/WINED3DTA_CURRENT in case of D3DTBLEND_MODULATE */
4743 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
4744 0, WINED3D_TSS_ALPHA_OP
, WINED3D_TOP_SELECT_ARG1
);
4746 wined3d_device_set_texture_stage_state(device
->wined3d_device
,
4747 0, WINED3D_TSS_ALPHA_OP
, WINED3D_TOP_SELECT_ARG2
);
4750 wined3d_mutex_unlock();
4755 static const struct tss_lookup
4758 enum wined3d_texture_stage_state state
;
4762 {FALSE
, WINED3D_TSS_INVALID
}, /* 0, unused */
4763 {FALSE
, WINED3D_TSS_COLOR_OP
}, /* 1, D3DTSS_COLOROP */
4764 {FALSE
, WINED3D_TSS_COLOR_ARG1
}, /* 2, D3DTSS_COLORARG1 */
4765 {FALSE
, WINED3D_TSS_COLOR_ARG2
}, /* 3, D3DTSS_COLORARG2 */
4766 {FALSE
, WINED3D_TSS_ALPHA_OP
}, /* 4, D3DTSS_ALPHAOP */
4767 {FALSE
, WINED3D_TSS_ALPHA_ARG1
}, /* 5, D3DTSS_ALPHAARG1 */
4768 {FALSE
, WINED3D_TSS_ALPHA_ARG2
}, /* 6, D3DTSS_ALPHAARG2 */
4769 {FALSE
, WINED3D_TSS_BUMPENV_MAT00
}, /* 7, D3DTSS_BUMPENVMAT00 */
4770 {FALSE
, WINED3D_TSS_BUMPENV_MAT01
}, /* 8, D3DTSS_BUMPENVMAT01 */
4771 {FALSE
, WINED3D_TSS_BUMPENV_MAT10
}, /* 9, D3DTSS_BUMPENVMAT10 */
4772 {FALSE
, WINED3D_TSS_BUMPENV_MAT11
}, /* 10, D3DTSS_BUMPENVMAT11 */
4773 {FALSE
, WINED3D_TSS_TEXCOORD_INDEX
}, /* 11, D3DTSS_TEXCOORDINDEX */
4774 {TRUE
, WINED3D_SAMP_ADDRESS_U
}, /* 12, D3DTSS_ADDRESS */
4775 {TRUE
, WINED3D_SAMP_ADDRESS_U
}, /* 13, D3DTSS_ADDRESSU */
4776 {TRUE
, WINED3D_SAMP_ADDRESS_V
}, /* 14, D3DTSS_ADDRESSV */
4777 {TRUE
, WINED3D_SAMP_BORDER_COLOR
}, /* 15, D3DTSS_BORDERCOLOR */
4778 {TRUE
, WINED3D_SAMP_MAG_FILTER
}, /* 16, D3DTSS_MAGFILTER */
4779 {TRUE
, WINED3D_SAMP_MIN_FILTER
}, /* 17, D3DTSS_MINFILTER */
4780 {TRUE
, WINED3D_SAMP_MIP_FILTER
}, /* 18, D3DTSS_MIPFILTER */
4781 {TRUE
, WINED3D_SAMP_MIPMAP_LOD_BIAS
}, /* 19, D3DTSS_MIPMAPLODBIAS */
4782 {TRUE
, WINED3D_SAMP_MAX_MIP_LEVEL
}, /* 20, D3DTSS_MAXMIPLEVEL */
4783 {TRUE
, WINED3D_SAMP_MAX_ANISOTROPY
}, /* 21, D3DTSS_MAXANISOTROPY */
4784 {FALSE
, WINED3D_TSS_BUMPENV_LSCALE
}, /* 22, D3DTSS_BUMPENVLSCALE */
4785 {FALSE
, WINED3D_TSS_BUMPENV_LOFFSET
}, /* 23, D3DTSS_BUMPENVLOFFSET */
4786 {FALSE
, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS
}, /* 24, D3DTSS_TEXTURETRANSFORMFLAGS */
4789 /*****************************************************************************
4790 * IDirect3DDevice7::GetTextureStageState
4792 * Retrieves a state from a texture stage.
4797 * Stage: The stage to retrieve the state from
4798 * TexStageStateType: The state type to retrieve
4799 * State: Address to store the state's value at
4803 * DDERR_INVALIDPARAMS if State is NULL
4804 * For details, see IWineD3DDevice::GetTextureStageState
4806 *****************************************************************************/
4807 static HRESULT
d3d_device7_GetTextureStageState(IDirect3DDevice7
*iface
,
4808 DWORD stage
, D3DTEXTURESTAGESTATETYPE state
, DWORD
*value
)
4810 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
4811 const struct tss_lookup
*l
;
4813 TRACE("iface %p, stage %u, state %#x, value %p.\n",
4814 iface
, stage
, state
, value
);
4817 return DDERR_INVALIDPARAMS
;
4819 if (state
> D3DTSS_TEXTURETRANSFORMFLAGS
)
4821 WARN("Invalid state %#x passed.\n", state
);
4825 l
= &tss_lookup
[state
];
4827 wined3d_mutex_lock();
4829 if (l
->sampler_state
)
4831 *value
= wined3d_device_get_sampler_state(device
->wined3d_device
, stage
, l
->state
);
4835 /* Mipfilter is a sampler state with different values */
4836 case D3DTSS_MIPFILTER
:
4840 case WINED3D_TEXF_NONE
:
4841 *value
= D3DTFP_NONE
;
4843 case WINED3D_TEXF_POINT
:
4844 *value
= D3DTFP_POINT
;
4846 case WINED3D_TEXF_LINEAR
:
4847 *value
= D3DTFP_LINEAR
;
4850 ERR("Unexpected mipfilter value %#x.\n", *value
);
4851 *value
= D3DTFP_NONE
;
4857 /* Magfilter has slightly different values */
4858 case D3DTSS_MAGFILTER
:
4862 case WINED3D_TEXF_POINT
:
4863 *value
= D3DTFG_POINT
;
4865 case WINED3D_TEXF_LINEAR
:
4866 *value
= D3DTFG_LINEAR
;
4868 case WINED3D_TEXF_ANISOTROPIC
:
4869 *value
= D3DTFG_ANISOTROPIC
;
4871 case WINED3D_TEXF_FLAT_CUBIC
:
4872 *value
= D3DTFG_FLATCUBIC
;
4874 case WINED3D_TEXF_GAUSSIAN_CUBIC
:
4875 *value
= D3DTFG_GAUSSIANCUBIC
;
4878 ERR("Unexpected wined3d mag filter value %#x.\n", *value
);
4879 *value
= D3DTFG_POINT
;
4891 *value
= wined3d_device_get_texture_stage_state(device
->wined3d_device
, stage
, l
->state
);
4894 wined3d_mutex_unlock();
4899 static HRESULT WINAPI
d3d_device7_GetTextureStageState_FPUSetup(IDirect3DDevice7
*iface
,
4900 DWORD stage
, D3DTEXTURESTAGESTATETYPE state
, DWORD
*value
)
4902 return d3d_device7_GetTextureStageState(iface
, stage
, state
, value
);
4905 static HRESULT WINAPI
d3d_device7_GetTextureStageState_FPUPreserve(IDirect3DDevice7
*iface
,
4906 DWORD stage
, D3DTEXTURESTAGESTATETYPE state
, DWORD
*value
)
4911 old_fpucw
= d3d_fpu_setup();
4912 hr
= d3d_device7_GetTextureStageState(iface
, stage
, state
, value
);
4913 set_fpu_control_word(old_fpucw
);
4918 static HRESULT WINAPI
d3d_device3_GetTextureStageState(IDirect3DDevice3
*iface
,
4919 DWORD stage
, D3DTEXTURESTAGESTATETYPE state
, DWORD
*value
)
4921 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
4923 TRACE("iface %p, stage %u, state %#x, value %p.\n",
4924 iface
, stage
, state
, value
);
4926 return IDirect3DDevice7_GetTextureStageState(&device
->IDirect3DDevice7_iface
, stage
, state
, value
);
4929 /*****************************************************************************
4930 * IDirect3DDevice7::SetTextureStageState
4932 * Sets a texture stage state. Some stage types need to be handled specially,
4933 * because they do not exist in WineD3D and were moved to another place
4938 * Stage: The stage to modify
4939 * TexStageStateType: The state to change
4940 * State: The new value for the state
4944 * For details, see IWineD3DDevice::SetTextureStageState
4946 *****************************************************************************/
4947 static HRESULT
d3d_device7_SetTextureStageState(IDirect3DDevice7
*iface
,
4948 DWORD stage
, D3DTEXTURESTAGESTATETYPE state
, DWORD value
)
4950 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
4951 const struct tss_lookup
*l
;
4953 TRACE("iface %p, stage %u, state %#x, value %#x.\n",
4954 iface
, stage
, state
, value
);
4956 if (state
> D3DTSS_TEXTURETRANSFORMFLAGS
)
4958 WARN("Invalid state %#x passed.\n", state
);
4962 l
= &tss_lookup
[state
];
4964 wined3d_mutex_lock();
4966 if (l
->sampler_state
)
4970 /* Mipfilter is a sampler state with different values */
4971 case D3DTSS_MIPFILTER
:
4976 value
= WINED3D_TEXF_NONE
;
4979 value
= WINED3D_TEXF_POINT
;
4981 case 0: /* Unchecked */
4983 value
= WINED3D_TEXF_LINEAR
;
4986 ERR("Unexpected mipfilter value %#x.\n", value
);
4987 value
= WINED3D_TEXF_NONE
;
4993 /* Magfilter has slightly different values */
4994 case D3DTSS_MAGFILTER
:
4999 value
= WINED3D_TEXF_POINT
;
5002 value
= WINED3D_TEXF_LINEAR
;
5004 case D3DTFG_FLATCUBIC
:
5005 value
= WINED3D_TEXF_FLAT_CUBIC
;
5007 case D3DTFG_GAUSSIANCUBIC
:
5008 value
= WINED3D_TEXF_GAUSSIAN_CUBIC
;
5010 case D3DTFG_ANISOTROPIC
:
5011 value
= WINED3D_TEXF_ANISOTROPIC
;
5014 ERR("Unexpected d3d7 mag filter value %#x.\n", value
);
5015 value
= WINED3D_TEXF_POINT
;
5021 case D3DTSS_ADDRESS
:
5022 wined3d_device_set_sampler_state(device
->wined3d_device
, stage
, WINED3D_SAMP_ADDRESS_V
, value
);
5029 wined3d_device_set_sampler_state(device
->wined3d_device
, stage
, l
->state
, value
);
5033 wined3d_device_set_texture_stage_state(device
->wined3d_device
, stage
, l
->state
, value
);
5036 wined3d_mutex_unlock();
5041 static HRESULT WINAPI
d3d_device7_SetTextureStageState_FPUSetup(IDirect3DDevice7
*iface
,
5042 DWORD stage
, D3DTEXTURESTAGESTATETYPE state
, DWORD value
)
5044 return d3d_device7_SetTextureStageState(iface
, stage
, state
, value
);
5047 static HRESULT WINAPI
d3d_device7_SetTextureStageState_FPUPreserve(IDirect3DDevice7
*iface
,
5048 DWORD stage
, D3DTEXTURESTAGESTATETYPE state
, DWORD value
)
5053 old_fpucw
= d3d_fpu_setup();
5054 hr
= d3d_device7_SetTextureStageState(iface
, stage
, state
, value
);
5055 set_fpu_control_word(old_fpucw
);
5060 static HRESULT WINAPI
d3d_device3_SetTextureStageState(IDirect3DDevice3
*iface
,
5061 DWORD stage
, D3DTEXTURESTAGESTATETYPE state
, DWORD value
)
5063 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
5065 TRACE("iface %p, stage %u, state %#x, value %#x.\n",
5066 iface
, stage
, state
, value
);
5068 return IDirect3DDevice7_SetTextureStageState(&device
->IDirect3DDevice7_iface
, stage
, state
, value
);
5071 /*****************************************************************************
5072 * IDirect3DDevice7::ValidateDevice
5074 * SDK: "Reports the device's ability to render the currently set
5075 * texture-blending operations in a single pass". Whatever that means
5081 * NumPasses: Address to write the number of necessary passes for the
5082 * desired effect to.
5086 * See IWineD3DDevice::ValidateDevice for more details
5088 *****************************************************************************/
5089 static HRESULT
d3d_device7_ValidateDevice(IDirect3DDevice7
*iface
, DWORD
*pass_count
)
5091 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
5094 TRACE("iface %p, pass_count %p.\n", iface
, pass_count
);
5096 wined3d_mutex_lock();
5097 hr
= wined3d_device_validate_device(device
->wined3d_device
, pass_count
);
5098 wined3d_mutex_unlock();
5103 static HRESULT WINAPI
d3d_device7_ValidateDevice_FPUSetup(IDirect3DDevice7
*iface
, DWORD
*pass_count
)
5105 return d3d_device7_ValidateDevice(iface
, pass_count
);
5108 static HRESULT WINAPI
d3d_device7_ValidateDevice_FPUPreserve(IDirect3DDevice7
*iface
, DWORD
*pass_count
)
5113 old_fpucw
= d3d_fpu_setup();
5114 hr
= d3d_device7_ValidateDevice(iface
, pass_count
);
5115 set_fpu_control_word(old_fpucw
);
5120 static HRESULT WINAPI
d3d_device3_ValidateDevice(IDirect3DDevice3
*iface
, DWORD
*pass_count
)
5122 struct d3d_device
*device
= impl_from_IDirect3DDevice3(iface
);
5124 TRACE("iface %p, pass_count %p.\n", iface
, pass_count
);
5126 return IDirect3DDevice7_ValidateDevice(&device
->IDirect3DDevice7_iface
, pass_count
);
5129 /*****************************************************************************
5130 * IDirect3DDevice7::Clear
5132 * Fills the render target, the z buffer and the stencil buffer with a
5133 * clear color / value
5138 * Count: Number of rectangles in Rects must be 0 if Rects is NULL
5139 * Rects: Rectangles to clear. If NULL, the whole surface is cleared
5140 * Flags: Some flags, as usual
5141 * Color: Clear color for the render target
5142 * Z: Clear value for the Z buffer
5143 * Stencil: Clear value to store in each stencil buffer entry
5147 * For details, see IWineD3DDevice::Clear
5149 *****************************************************************************/
5150 static HRESULT
d3d_device7_Clear(IDirect3DDevice7
*iface
, DWORD count
,
5151 D3DRECT
*rects
, DWORD flags
, D3DCOLOR color
, D3DVALUE z
, DWORD stencil
)
5153 const struct wined3d_color c
=
5155 ((color
>> 16) & 0xff) / 255.0f
,
5156 ((color
>> 8) & 0xff) / 255.0f
,
5157 (color
& 0xff) / 255.0f
,
5158 ((color
>> 24) & 0xff) / 255.0f
,
5160 struct d3d_device
*This
= impl_from_IDirect3DDevice7(iface
);
5163 TRACE("iface %p, count %u, rects %p, flags %#x, color 0x%08x, z %.8e, stencil %#x.\n",
5164 iface
, count
, rects
, flags
, color
, z
, stencil
);
5166 wined3d_mutex_lock();
5167 hr
= wined3d_device_clear(This
->wined3d_device
, count
, (RECT
*)rects
, flags
, &c
, z
, stencil
);
5168 wined3d_mutex_unlock();
5173 static HRESULT WINAPI
d3d_device7_Clear_FPUSetup(IDirect3DDevice7
*iface
, DWORD count
,
5174 D3DRECT
*rects
, DWORD flags
, D3DCOLOR color
, D3DVALUE z
, DWORD stencil
)
5176 return d3d_device7_Clear(iface
, count
, rects
, flags
, color
, z
, stencil
);
5179 static HRESULT WINAPI
d3d_device7_Clear_FPUPreserve(IDirect3DDevice7
*iface
, DWORD count
,
5180 D3DRECT
*rects
, DWORD flags
, D3DCOLOR color
, D3DVALUE z
, DWORD stencil
)
5185 old_fpucw
= d3d_fpu_setup();
5186 hr
= d3d_device7_Clear(iface
, count
, rects
, flags
, color
, z
, stencil
);
5187 set_fpu_control_word(old_fpucw
);
5192 /*****************************************************************************
5193 * IDirect3DDevice7::SetViewport
5195 * Sets the current viewport.
5197 * Version 7 only, but IDirect3DViewport uses this call for older
5201 * Data: The new viewport to set
5205 * DDERR_INVALIDPARAMS if Data is NULL
5206 * For more details, see IWineDDDevice::SetViewport
5208 *****************************************************************************/
5209 static HRESULT
d3d_device7_SetViewport(IDirect3DDevice7
*iface
, D3DVIEWPORT7
*viewport
)
5211 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
5213 TRACE("iface %p, viewport %p.\n", iface
, viewport
);
5216 return DDERR_INVALIDPARAMS
;
5218 /* Note: D3DVIEWPORT7 is compatible with struct wined3d_viewport. */
5219 wined3d_mutex_lock();
5220 wined3d_device_set_viewport(device
->wined3d_device
, (struct wined3d_viewport
*)viewport
);
5221 wined3d_mutex_unlock();
5226 static HRESULT WINAPI
d3d_device7_SetViewport_FPUSetup(IDirect3DDevice7
*iface
, D3DVIEWPORT7
*viewport
)
5228 return d3d_device7_SetViewport(iface
, viewport
);
5231 static HRESULT WINAPI
d3d_device7_SetViewport_FPUPreserve(IDirect3DDevice7
*iface
, D3DVIEWPORT7
*viewport
)
5236 old_fpucw
= d3d_fpu_setup();
5237 hr
= d3d_device7_SetViewport(iface
, viewport
);
5238 set_fpu_control_word(old_fpucw
);
5243 /*****************************************************************************
5244 * IDirect3DDevice::GetViewport
5246 * Returns the current viewport
5251 * Data: D3D7Viewport structure to write the viewport information to
5255 * DDERR_INVALIDPARAMS if Data is NULL
5256 * For more details, see IWineD3DDevice::GetViewport
5258 *****************************************************************************/
5259 static HRESULT
d3d_device7_GetViewport(IDirect3DDevice7
*iface
, D3DVIEWPORT7
*viewport
)
5261 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
5263 TRACE("iface %p, viewport %p.\n", iface
, viewport
);
5266 return DDERR_INVALIDPARAMS
;
5268 /* Note: D3DVIEWPORT7 is compatible with struct wined3d_viewport. */
5269 wined3d_mutex_lock();
5270 wined3d_device_get_viewport(device
->wined3d_device
, (struct wined3d_viewport
*)viewport
);
5271 wined3d_mutex_unlock();
5276 static HRESULT WINAPI
d3d_device7_GetViewport_FPUSetup(IDirect3DDevice7
*iface
, D3DVIEWPORT7
*viewport
)
5278 return d3d_device7_GetViewport(iface
, viewport
);
5281 static HRESULT WINAPI
d3d_device7_GetViewport_FPUPreserve(IDirect3DDevice7
*iface
, D3DVIEWPORT7
*viewport
)
5286 old_fpucw
= d3d_fpu_setup();
5287 hr
= d3d_device7_GetViewport(iface
, viewport
);
5288 set_fpu_control_word(old_fpucw
);
5293 /*****************************************************************************
5294 * IDirect3DDevice7::SetMaterial
5301 * Mat: The material to set
5305 * DDERR_INVALIDPARAMS if Mat is NULL.
5306 * For more details, see IWineD3DDevice::SetMaterial
5308 *****************************************************************************/
5309 static HRESULT
d3d_device7_SetMaterial(IDirect3DDevice7
*iface
, D3DMATERIAL7
*material
)
5311 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
5313 TRACE("iface %p, material %p.\n", iface
, material
);
5316 return DDERR_INVALIDPARAMS
;
5318 wined3d_mutex_lock();
5319 /* Note: D3DMATERIAL7 is compatible with struct wined3d_material. */
5320 wined3d_device_set_material(device
->wined3d_device
, (struct wined3d_material
*)material
);
5321 wined3d_mutex_unlock();
5326 static HRESULT WINAPI
d3d_device7_SetMaterial_FPUSetup(IDirect3DDevice7
*iface
, D3DMATERIAL7
*material
)
5328 return d3d_device7_SetMaterial(iface
, material
);
5331 static HRESULT WINAPI
d3d_device7_SetMaterial_FPUPreserve(IDirect3DDevice7
*iface
, D3DMATERIAL7
*material
)
5336 old_fpucw
= d3d_fpu_setup();
5337 hr
= d3d_device7_SetMaterial(iface
, material
);
5338 set_fpu_control_word(old_fpucw
);
5343 /*****************************************************************************
5344 * IDirect3DDevice7::GetMaterial
5346 * Returns the current material
5351 * Mat: D3DMATERIAL7 structure to write the material parameters to
5355 * DDERR_INVALIDPARAMS if Mat is NULL
5356 * For more details, see IWineD3DDevice::GetMaterial
5358 *****************************************************************************/
5359 static HRESULT
d3d_device7_GetMaterial(IDirect3DDevice7
*iface
, D3DMATERIAL7
*material
)
5361 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
5363 TRACE("iface %p, material %p.\n", iface
, material
);
5365 wined3d_mutex_lock();
5366 /* Note: D3DMATERIAL7 is compatible with struct wined3d_material. */
5367 wined3d_device_get_material(device
->wined3d_device
, (struct wined3d_material
*)material
);
5368 wined3d_mutex_unlock();
5373 static HRESULT WINAPI
d3d_device7_GetMaterial_FPUSetup(IDirect3DDevice7
*iface
, D3DMATERIAL7
*material
)
5375 return d3d_device7_GetMaterial(iface
, material
);
5378 static HRESULT WINAPI
d3d_device7_GetMaterial_FPUPreserve(IDirect3DDevice7
*iface
, D3DMATERIAL7
*material
)
5383 old_fpucw
= d3d_fpu_setup();
5384 hr
= d3d_device7_GetMaterial(iface
, material
);
5385 set_fpu_control_word(old_fpucw
);
5390 /*****************************************************************************
5391 * IDirect3DDevice7::SetLight
5393 * Assigns a light to a light index, but doesn't activate it yet.
5395 * Version 7, IDirect3DLight uses this method for older versions
5398 * LightIndex: The index of the new light
5399 * Light: A D3DLIGHT7 structure describing the light
5403 * For more details, see IWineD3DDevice::SetLight
5405 *****************************************************************************/
5406 static HRESULT
d3d_device7_SetLight(IDirect3DDevice7
*iface
, DWORD light_idx
, D3DLIGHT7
*light
)
5408 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
5411 TRACE("iface %p, light_idx %u, light %p.\n", iface
, light_idx
, light
);
5413 wined3d_mutex_lock();
5414 /* Note: D3DLIGHT7 is compatible with struct wined3d_light. */
5415 hr
= wined3d_device_set_light(device
->wined3d_device
, light_idx
, (struct wined3d_light
*)light
);
5416 wined3d_mutex_unlock();
5418 return hr_ddraw_from_wined3d(hr
);
5421 static HRESULT WINAPI
d3d_device7_SetLight_FPUSetup(IDirect3DDevice7
*iface
, DWORD light_idx
, D3DLIGHT7
*light
)
5423 return d3d_device7_SetLight(iface
, light_idx
, light
);
5426 static HRESULT WINAPI
d3d_device7_SetLight_FPUPreserve(IDirect3DDevice7
*iface
, DWORD light_idx
, D3DLIGHT7
*light
)
5431 old_fpucw
= d3d_fpu_setup();
5432 hr
= d3d_device7_SetLight(iface
, light_idx
, light
);
5433 set_fpu_control_word(old_fpucw
);
5438 /*****************************************************************************
5439 * IDirect3DDevice7::GetLight
5441 * Returns the light assigned to a light index
5444 * Light: Structure to write the light information to
5448 * DDERR_INVALIDPARAMS if Light is NULL
5449 * For details, see IWineD3DDevice::GetLight
5451 *****************************************************************************/
5452 static HRESULT
d3d_device7_GetLight(IDirect3DDevice7
*iface
, DWORD light_idx
, D3DLIGHT7
*light
)
5454 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
5457 TRACE("iface %p, light_idx %u, light %p.\n", iface
, light_idx
, light
);
5459 wined3d_mutex_lock();
5460 /* Note: D3DLIGHT7 is compatible with struct wined3d_light. */
5461 rc
= wined3d_device_get_light(device
->wined3d_device
, light_idx
, (struct wined3d_light
*)light
);
5462 wined3d_mutex_unlock();
5464 /* Translate the result. WineD3D returns other values than D3D7 */
5465 return hr_ddraw_from_wined3d(rc
);
5468 static HRESULT WINAPI
d3d_device7_GetLight_FPUSetup(IDirect3DDevice7
*iface
, DWORD light_idx
, D3DLIGHT7
*light
)
5470 return d3d_device7_GetLight(iface
, light_idx
, light
);
5473 static HRESULT WINAPI
d3d_device7_GetLight_FPUPreserve(IDirect3DDevice7
*iface
, DWORD light_idx
, D3DLIGHT7
*light
)
5478 old_fpucw
= d3d_fpu_setup();
5479 hr
= d3d_device7_GetLight(iface
, light_idx
, light
);
5480 set_fpu_control_word(old_fpucw
);
5485 /*****************************************************************************
5486 * IDirect3DDevice7::BeginStateBlock
5488 * Begins recording to a stateblock
5494 * For details see IWineD3DDevice::BeginStateBlock
5496 *****************************************************************************/
5497 static HRESULT
d3d_device7_BeginStateBlock(IDirect3DDevice7
*iface
)
5499 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
5502 TRACE("iface %p.\n", iface
);
5504 wined3d_mutex_lock();
5505 hr
= wined3d_device_begin_stateblock(device
->wined3d_device
);
5506 wined3d_mutex_unlock();
5508 return hr_ddraw_from_wined3d(hr
);
5511 static HRESULT WINAPI
d3d_device7_BeginStateBlock_FPUSetup(IDirect3DDevice7
*iface
)
5513 return d3d_device7_BeginStateBlock(iface
);
5516 static HRESULT WINAPI
d3d_device7_BeginStateBlock_FPUPreserve(IDirect3DDevice7
*iface
)
5521 old_fpucw
= d3d_fpu_setup();
5522 hr
= d3d_device7_BeginStateBlock(iface
);
5523 set_fpu_control_word(old_fpucw
);
5528 /*****************************************************************************
5529 * IDirect3DDevice7::EndStateBlock
5531 * Stops recording to a state block and returns the created stateblock
5537 * BlockHandle: Address to store the stateblock's handle to
5541 * DDERR_INVALIDPARAMS if BlockHandle is NULL
5542 * See IWineD3DDevice::EndStateBlock for more details
5544 *****************************************************************************/
5545 static HRESULT
d3d_device7_EndStateBlock(IDirect3DDevice7
*iface
, DWORD
*stateblock
)
5547 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
5548 struct wined3d_stateblock
*wined3d_sb
;
5552 TRACE("iface %p, stateblock %p.\n", iface
, stateblock
);
5555 return DDERR_INVALIDPARAMS
;
5557 wined3d_mutex_lock();
5559 hr
= wined3d_device_end_stateblock(device
->wined3d_device
, &wined3d_sb
);
5562 WARN("Failed to end stateblock, hr %#x.\n", hr
);
5563 wined3d_mutex_unlock();
5565 return hr_ddraw_from_wined3d(hr
);
5568 h
= ddraw_allocate_handle(&device
->handle_table
, wined3d_sb
, DDRAW_HANDLE_STATEBLOCK
);
5569 if (h
== DDRAW_INVALID_HANDLE
)
5571 ERR("Failed to allocate a stateblock handle.\n");
5572 wined3d_stateblock_decref(wined3d_sb
);
5573 wined3d_mutex_unlock();
5575 return DDERR_OUTOFMEMORY
;
5578 wined3d_mutex_unlock();
5579 *stateblock
= h
+ 1;
5581 return hr_ddraw_from_wined3d(hr
);
5584 static HRESULT WINAPI
d3d_device7_EndStateBlock_FPUSetup(IDirect3DDevice7
*iface
, DWORD
*stateblock
)
5586 return d3d_device7_EndStateBlock(iface
, stateblock
);
5589 static HRESULT WINAPI
d3d_device7_EndStateBlock_FPUPreserve(IDirect3DDevice7
*iface
, DWORD
*stateblock
)
5594 old_fpucw
= d3d_fpu_setup();
5595 hr
= d3d_device7_EndStateBlock(iface
, stateblock
);
5596 set_fpu_control_word(old_fpucw
);
5601 /*****************************************************************************
5602 * IDirect3DDevice7::PreLoad
5604 * Allows the app to signal that a texture will be used soon, to allow
5605 * the Direct3DDevice to load it to the video card in the meantime.
5610 * Texture: The texture to preload
5614 * DDERR_INVALIDPARAMS if Texture is NULL
5615 * See IWineD3DSurface::PreLoad for details
5617 *****************************************************************************/
5618 static HRESULT
d3d_device7_PreLoad(IDirect3DDevice7
*iface
, IDirectDrawSurface7
*texture
)
5620 struct ddraw_surface
*surface
= unsafe_impl_from_IDirectDrawSurface7(texture
);
5622 TRACE("iface %p, texture %p.\n", iface
, texture
);
5625 return DDERR_INVALIDPARAMS
;
5627 wined3d_mutex_lock();
5628 wined3d_surface_preload(surface
->wined3d_surface
);
5629 wined3d_mutex_unlock();
5634 static HRESULT WINAPI
d3d_device7_PreLoad_FPUSetup(IDirect3DDevice7
*iface
, IDirectDrawSurface7
*texture
)
5636 return d3d_device7_PreLoad(iface
, texture
);
5639 static HRESULT WINAPI
d3d_device7_PreLoad_FPUPreserve(IDirect3DDevice7
*iface
, IDirectDrawSurface7
*texture
)
5644 old_fpucw
= d3d_fpu_setup();
5645 hr
= d3d_device7_PreLoad(iface
, texture
);
5646 set_fpu_control_word(old_fpucw
);
5651 /*****************************************************************************
5652 * IDirect3DDevice7::ApplyStateBlock
5654 * Activates the state stored in a state block handle.
5657 * BlockHandle: The stateblock handle to activate
5661 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is NULL
5663 *****************************************************************************/
5664 static HRESULT
d3d_device7_ApplyStateBlock(IDirect3DDevice7
*iface
, DWORD stateblock
)
5666 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
5667 struct wined3d_stateblock
*wined3d_sb
;
5669 TRACE("iface %p, stateblock %#x.\n", iface
, stateblock
);
5671 wined3d_mutex_lock();
5672 wined3d_sb
= ddraw_get_object(&device
->handle_table
, stateblock
- 1, DDRAW_HANDLE_STATEBLOCK
);
5675 WARN("Invalid stateblock handle.\n");
5676 wined3d_mutex_unlock();
5677 return D3DERR_INVALIDSTATEBLOCK
;
5680 wined3d_stateblock_apply(wined3d_sb
);
5681 wined3d_mutex_unlock();
5686 static HRESULT WINAPI
d3d_device7_ApplyStateBlock_FPUSetup(IDirect3DDevice7
*iface
, DWORD stateblock
)
5688 return d3d_device7_ApplyStateBlock(iface
, stateblock
);
5691 static HRESULT WINAPI
d3d_device7_ApplyStateBlock_FPUPreserve(IDirect3DDevice7
*iface
, DWORD stateblock
)
5696 old_fpucw
= d3d_fpu_setup();
5697 hr
= d3d_device7_ApplyStateBlock(iface
, stateblock
);
5698 set_fpu_control_word(old_fpucw
);
5703 /*****************************************************************************
5704 * IDirect3DDevice7::CaptureStateBlock
5706 * Updates a stateblock's values to the values currently set for the device
5711 * BlockHandle: Stateblock to update
5715 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is NULL
5716 * See IWineD3DDevice::CaptureStateBlock for more details
5718 *****************************************************************************/
5719 static HRESULT
d3d_device7_CaptureStateBlock(IDirect3DDevice7
*iface
, DWORD stateblock
)
5721 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
5722 struct wined3d_stateblock
*wined3d_sb
;
5724 TRACE("iface %p, stateblock %#x.\n", iface
, stateblock
);
5726 wined3d_mutex_lock();
5727 wined3d_sb
= ddraw_get_object(&device
->handle_table
, stateblock
- 1, DDRAW_HANDLE_STATEBLOCK
);
5730 WARN("Invalid stateblock handle.\n");
5731 wined3d_mutex_unlock();
5732 return D3DERR_INVALIDSTATEBLOCK
;
5735 wined3d_stateblock_capture(wined3d_sb
);
5736 wined3d_mutex_unlock();
5741 static HRESULT WINAPI
d3d_device7_CaptureStateBlock_FPUSetup(IDirect3DDevice7
*iface
, DWORD stateblock
)
5743 return d3d_device7_CaptureStateBlock(iface
, stateblock
);
5746 static HRESULT WINAPI
d3d_device7_CaptureStateBlock_FPUPreserve(IDirect3DDevice7
*iface
, DWORD stateblock
)
5751 old_fpucw
= d3d_fpu_setup();
5752 hr
= d3d_device7_CaptureStateBlock(iface
, stateblock
);
5753 set_fpu_control_word(old_fpucw
);
5758 /*****************************************************************************
5759 * IDirect3DDevice7::DeleteStateBlock
5761 * Deletes a stateblock handle. This means releasing the WineD3DStateBlock
5766 * BlockHandle: Stateblock handle to delete
5770 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is 0
5772 *****************************************************************************/
5773 static HRESULT
d3d_device7_DeleteStateBlock(IDirect3DDevice7
*iface
, DWORD stateblock
)
5775 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
5776 struct wined3d_stateblock
*wined3d_sb
;
5779 TRACE("iface %p, stateblock %#x.\n", iface
, stateblock
);
5781 wined3d_mutex_lock();
5783 wined3d_sb
= ddraw_free_handle(&device
->handle_table
, stateblock
- 1, DDRAW_HANDLE_STATEBLOCK
);
5786 WARN("Invalid stateblock handle.\n");
5787 wined3d_mutex_unlock();
5788 return D3DERR_INVALIDSTATEBLOCK
;
5791 if ((ref
= wined3d_stateblock_decref(wined3d_sb
)))
5793 ERR("Something is still holding stateblock %p (refcount %u).\n", wined3d_sb
, ref
);
5796 wined3d_mutex_unlock();
5801 static HRESULT WINAPI
d3d_device7_DeleteStateBlock_FPUSetup(IDirect3DDevice7
*iface
, DWORD stateblock
)
5803 return d3d_device7_DeleteStateBlock(iface
, stateblock
);
5806 static HRESULT WINAPI
d3d_device7_DeleteStateBlock_FPUPreserve(IDirect3DDevice7
*iface
, DWORD stateblock
)
5811 old_fpucw
= d3d_fpu_setup();
5812 hr
= d3d_device7_DeleteStateBlock(iface
, stateblock
);
5813 set_fpu_control_word(old_fpucw
);
5818 /*****************************************************************************
5819 * IDirect3DDevice7::CreateStateBlock
5821 * Creates a new state block handle.
5826 * Type: The state block type
5827 * BlockHandle: Address to write the created handle to
5831 * DDERR_INVALIDPARAMS if BlockHandle is NULL
5833 *****************************************************************************/
5834 static HRESULT
d3d_device7_CreateStateBlock(IDirect3DDevice7
*iface
,
5835 D3DSTATEBLOCKTYPE type
, DWORD
*stateblock
)
5837 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
5838 struct wined3d_stateblock
*wined3d_sb
;
5842 TRACE("iface %p, type %#x, stateblock %p.\n", iface
, type
, stateblock
);
5845 return DDERR_INVALIDPARAMS
;
5847 if (type
!= D3DSBT_ALL
5848 && type
!= D3DSBT_PIXELSTATE
5849 && type
!= D3DSBT_VERTEXSTATE
)
5851 WARN("Unexpected stateblock type, returning DDERR_INVALIDPARAMS\n");
5852 return DDERR_INVALIDPARAMS
;
5855 wined3d_mutex_lock();
5857 /* The D3DSTATEBLOCKTYPE enum is fine here. */
5858 hr
= wined3d_stateblock_create(device
->wined3d_device
, type
, &wined3d_sb
);
5861 WARN("Failed to create stateblock, hr %#x.\n", hr
);
5862 wined3d_mutex_unlock();
5863 return hr_ddraw_from_wined3d(hr
);
5866 h
= ddraw_allocate_handle(&device
->handle_table
, wined3d_sb
, DDRAW_HANDLE_STATEBLOCK
);
5867 if (h
== DDRAW_INVALID_HANDLE
)
5869 ERR("Failed to allocate stateblock handle.\n");
5870 wined3d_stateblock_decref(wined3d_sb
);
5871 wined3d_mutex_unlock();
5872 return DDERR_OUTOFMEMORY
;
5875 *stateblock
= h
+ 1;
5876 wined3d_mutex_unlock();
5878 return hr_ddraw_from_wined3d(hr
);
5881 static HRESULT WINAPI
d3d_device7_CreateStateBlock_FPUSetup(IDirect3DDevice7
*iface
,
5882 D3DSTATEBLOCKTYPE type
, DWORD
*stateblock
)
5884 return d3d_device7_CreateStateBlock(iface
, type
, stateblock
);
5887 static HRESULT WINAPI
d3d_device7_CreateStateBlock_FPUPreserve(IDirect3DDevice7
*iface
,
5888 D3DSTATEBLOCKTYPE type
, DWORD
*stateblock
)
5893 old_fpucw
= d3d_fpu_setup();
5894 hr
= d3d_device7_CreateStateBlock(iface
, type
, stateblock
);
5895 set_fpu_control_word(old_fpucw
);
5900 static BOOL
is_mip_level_subset(struct ddraw_surface
*dest
, struct ddraw_surface
*src
)
5902 struct ddraw_surface
*src_level
, *dest_level
;
5903 IDirectDrawSurface7
*temp
;
5904 DDSURFACEDESC2 ddsd
;
5905 BOOL levelFound
; /* at least one suitable sublevel in dest found */
5907 /* To satisfy "destination is mip level subset of source" criteria (regular texture counts as 1 level),
5908 * 1) there must be at least one mip level in destination that matched dimensions of some mip level in source and
5909 * 2) there must be no destination levels that don't match any levels in source. Otherwise it's INVALIDPARAMS.
5916 for (;src_level
&& dest_level
;)
5918 if (src_level
->surface_desc
.dwWidth
== dest_level
->surface_desc
.dwWidth
&&
5919 src_level
->surface_desc
.dwHeight
== dest_level
->surface_desc
.dwHeight
)
5923 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
5924 ddsd
.ddsCaps
.dwCaps2
= DDSCAPS2_MIPMAPSUBLEVEL
;
5925 IDirectDrawSurface7_GetAttachedSurface(&dest_level
->IDirectDrawSurface7_iface
, &ddsd
.ddsCaps
, &temp
);
5927 if (dest_level
!= dest
) IDirectDrawSurface7_Release(&dest_level
->IDirectDrawSurface7_iface
);
5929 dest_level
= unsafe_impl_from_IDirectDrawSurface7(temp
);
5932 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
5933 ddsd
.ddsCaps
.dwCaps2
= DDSCAPS2_MIPMAPSUBLEVEL
;
5934 IDirectDrawSurface7_GetAttachedSurface(&src_level
->IDirectDrawSurface7_iface
, &ddsd
.ddsCaps
, &temp
);
5936 if (src_level
!= src
) IDirectDrawSurface7_Release(&src_level
->IDirectDrawSurface7_iface
);
5938 src_level
= unsafe_impl_from_IDirectDrawSurface7(temp
);
5941 if (src_level
&& src_level
!= src
) IDirectDrawSurface7_Release(&src_level
->IDirectDrawSurface7_iface
);
5942 if (dest_level
&& dest_level
!= dest
) IDirectDrawSurface7_Release(&dest_level
->IDirectDrawSurface7_iface
);
5944 return !dest_level
&& levelFound
;
5947 static void copy_mipmap_chain(struct d3d_device
*device
, struct ddraw_surface
*dest
,
5948 struct ddraw_surface
*src
, const POINT
*DestPoint
, const RECT
*SrcRect
)
5950 struct ddraw_surface
*src_level
, *dest_level
;
5951 IDirectDrawSurface7
*temp
;
5952 DDSURFACEDESC2 ddsd
;
5956 IDirectDrawPalette
*pal
= NULL
, *pal_src
= NULL
;
5960 /* Copy palette, if possible. */
5961 IDirectDrawSurface7_GetPalette(&src
->IDirectDrawSurface7_iface
, &pal_src
);
5962 IDirectDrawSurface7_GetPalette(&dest
->IDirectDrawSurface7_iface
, &pal
);
5964 if (pal_src
!= NULL
&& pal
!= NULL
)
5966 PALETTEENTRY palent
[256];
5968 IDirectDrawPalette_GetEntries(pal_src
, 0, 0, 256, palent
);
5969 IDirectDrawPalette_SetEntries(pal
, 0, 0, 256, palent
);
5972 if (pal
) IDirectDrawPalette_Release(pal
);
5973 if (pal_src
) IDirectDrawPalette_Release(pal_src
);
5975 /* Copy colorkeys, if present. */
5976 for (ckeyflag
= DDCKEY_DESTBLT
; ckeyflag
<= DDCKEY_SRCOVERLAY
; ckeyflag
<<= 1)
5978 hr
= IDirectDrawSurface7_GetColorKey(&src
->IDirectDrawSurface7_iface
, ckeyflag
, &ddckey
);
5982 IDirectDrawSurface7_SetColorKey(&dest
->IDirectDrawSurface7_iface
, ckeyflag
, &ddckey
);
5990 src_rect
= *SrcRect
;
5992 for (;src_level
&& dest_level
;)
5994 if (src_level
->surface_desc
.dwWidth
== dest_level
->surface_desc
.dwWidth
&&
5995 src_level
->surface_desc
.dwHeight
== dest_level
->surface_desc
.dwHeight
)
5997 UINT src_w
= src_rect
.right
- src_rect
.left
;
5998 UINT src_h
= src_rect
.bottom
- src_rect
.top
;
5999 RECT dst_rect
= {point
.x
, point
.y
, point
.x
+ src_w
, point
.y
+ src_h
};
6001 if (FAILED(hr
= wined3d_surface_blt(dest_level
->wined3d_surface
, &dst_rect
,
6002 src_level
->wined3d_surface
, &src_rect
, 0, NULL
, WINED3D_TEXF_POINT
)))
6003 ERR("Blit failed, hr %#x.\n", hr
);
6005 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
6006 ddsd
.ddsCaps
.dwCaps2
= DDSCAPS2_MIPMAPSUBLEVEL
;
6007 IDirectDrawSurface7_GetAttachedSurface(&dest_level
->IDirectDrawSurface7_iface
, &ddsd
.ddsCaps
, &temp
);
6009 if (dest_level
!= dest
) IDirectDrawSurface7_Release(&dest_level
->IDirectDrawSurface7_iface
);
6011 dest_level
= unsafe_impl_from_IDirectDrawSurface7(temp
);
6014 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
6015 ddsd
.ddsCaps
.dwCaps2
= DDSCAPS2_MIPMAPSUBLEVEL
;
6016 IDirectDrawSurface7_GetAttachedSurface(&src_level
->IDirectDrawSurface7_iface
, &ddsd
.ddsCaps
, &temp
);
6018 if (src_level
!= src
) IDirectDrawSurface7_Release(&src_level
->IDirectDrawSurface7_iface
);
6020 src_level
= unsafe_impl_from_IDirectDrawSurface7(temp
);
6027 src_rect
.right
= (src_rect
.right
+ 1) / 2;
6028 src_rect
.bottom
= (src_rect
.bottom
+ 1) / 2;
6031 if (src_level
&& src_level
!= src
) IDirectDrawSurface7_Release(&src_level
->IDirectDrawSurface7_iface
);
6032 if (dest_level
&& dest_level
!= dest
) IDirectDrawSurface7_Release(&dest_level
->IDirectDrawSurface7_iface
);
6035 /*****************************************************************************
6036 * IDirect3DDevice7::Load
6038 * Loads a rectangular area from the source into the destination texture.
6039 * It can also copy the source to the faces of a cubic environment map
6044 * DestTex: Destination texture
6045 * DestPoint: Point in the destination where the source image should be
6047 * SrcTex: Source texture
6048 * SrcRect: Source rectangle
6049 * Flags: Cubemap faces to load (DDSCAPS2_CUBEMAP_ALLFACES, DDSCAPS2_CUBEMAP_POSITIVEX,
6050 * DDSCAPS2_CUBEMAP_NEGATIVEX, DDSCAPS2_CUBEMAP_POSITIVEY, DDSCAPS2_CUBEMAP_NEGATIVEY,
6051 * DDSCAPS2_CUBEMAP_POSITIVEZ, DDSCAPS2_CUBEMAP_NEGATIVEZ)
6055 * DDERR_INVALIDPARAMS if dst_texture or src_texture is NULL, broken coordinates or anything unexpected.
6058 *****************************************************************************/
6059 static HRESULT
d3d_device7_Load(IDirect3DDevice7
*iface
, IDirectDrawSurface7
*dst_texture
, POINT
*dst_pos
,
6060 IDirectDrawSurface7
*src_texture
, RECT
*src_rect
, DWORD flags
)
6062 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
6063 struct ddraw_surface
*dest
= unsafe_impl_from_IDirectDrawSurface7(dst_texture
);
6064 struct ddraw_surface
*src
= unsafe_impl_from_IDirectDrawSurface7(src_texture
);
6068 TRACE("iface %p, dst_texture %p, dst_pos %s, src_texture %p, src_rect %s, flags %#x.\n",
6069 iface
, dst_texture
, wine_dbgstr_point(dst_pos
), src_texture
, wine_dbgstr_rect(src_rect
), flags
);
6071 if( (!src
) || (!dest
) )
6072 return DDERR_INVALIDPARAMS
;
6074 wined3d_mutex_lock();
6078 srcrect
.left
= srcrect
.top
= 0;
6079 srcrect
.right
= src
->surface_desc
.dwWidth
;
6080 srcrect
.bottom
= src
->surface_desc
.dwHeight
;
6083 srcrect
= *src_rect
;
6086 destpoint
.x
= destpoint
.y
= 0;
6088 destpoint
= *dst_pos
;
6090 /* Check bad dimensions. dst_pos is validated against src, not dest, because
6091 * destination can be a subset of mip levels, in which case actual coordinates used
6092 * for it may be divided. If any dimension of dest is larger than source, it can't be
6093 * mip level subset, so an error can be returned early.
6095 if (srcrect
.left
>= srcrect
.right
|| srcrect
.top
>= srcrect
.bottom
||
6096 srcrect
.right
> src
->surface_desc
.dwWidth
||
6097 srcrect
.bottom
> src
->surface_desc
.dwHeight
||
6098 destpoint
.x
+ srcrect
.right
- srcrect
.left
> src
->surface_desc
.dwWidth
||
6099 destpoint
.y
+ srcrect
.bottom
- srcrect
.top
> src
->surface_desc
.dwHeight
||
6100 dest
->surface_desc
.dwWidth
> src
->surface_desc
.dwWidth
||
6101 dest
->surface_desc
.dwHeight
> src
->surface_desc
.dwHeight
)
6103 wined3d_mutex_unlock();
6104 return DDERR_INVALIDPARAMS
;
6107 /* Must be top level surfaces. */
6108 if (src
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_MIPMAPSUBLEVEL
||
6109 dest
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_MIPMAPSUBLEVEL
)
6111 wined3d_mutex_unlock();
6112 return DDERR_INVALIDPARAMS
;
6115 if (src
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_CUBEMAP
)
6117 struct ddraw_surface
*src_face
, *dest_face
;
6118 DWORD src_face_flag
, dest_face_flag
;
6119 IDirectDrawSurface7
*temp
;
6120 DDSURFACEDESC2 ddsd
;
6123 if (!(dest
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_CUBEMAP
))
6125 wined3d_mutex_unlock();
6126 return DDERR_INVALIDPARAMS
;
6129 /* Iterate through cube faces 2 times. First time is just to check INVALIDPARAMS conditions, second
6130 * time it's actual surface loading. */
6131 for (i
= 0; i
< 2; i
++)
6136 for (;dest_face
&& src_face
;)
6138 src_face_flag
= src_face
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_CUBEMAP_ALLFACES
;
6139 dest_face_flag
= dest_face
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_CUBEMAP_ALLFACES
;
6141 if (src_face_flag
== dest_face_flag
)
6145 /* Destination mip levels must be subset of source mip levels. */
6146 if (!is_mip_level_subset(dest_face
, src_face
))
6148 wined3d_mutex_unlock();
6149 return DDERR_INVALIDPARAMS
;
6152 else if (flags
& dest_face_flag
)
6154 copy_mipmap_chain(device
, dest_face
, src_face
, &destpoint
, &srcrect
);
6157 if (src_face_flag
< DDSCAPS2_CUBEMAP_NEGATIVEZ
)
6159 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
6160 ddsd
.ddsCaps
.dwCaps2
= DDSCAPS2_CUBEMAP
| (src_face_flag
<< 1);
6161 IDirectDrawSurface7_GetAttachedSurface(&src
->IDirectDrawSurface7_iface
, &ddsd
.ddsCaps
, &temp
);
6163 if (src_face
!= src
) IDirectDrawSurface7_Release(&src_face
->IDirectDrawSurface7_iface
);
6165 src_face
= unsafe_impl_from_IDirectDrawSurface7(temp
);
6169 if (src_face
!= src
) IDirectDrawSurface7_Release(&src_face
->IDirectDrawSurface7_iface
);
6175 if (dest_face_flag
< DDSCAPS2_CUBEMAP_NEGATIVEZ
)
6177 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
6178 ddsd
.ddsCaps
.dwCaps2
= DDSCAPS2_CUBEMAP
| (dest_face_flag
<< 1);
6179 IDirectDrawSurface7_GetAttachedSurface(&dest
->IDirectDrawSurface7_iface
, &ddsd
.ddsCaps
, &temp
);
6181 if (dest_face
!= dest
) IDirectDrawSurface7_Release(&dest_face
->IDirectDrawSurface7_iface
);
6183 dest_face
= unsafe_impl_from_IDirectDrawSurface7(temp
);
6187 if (dest_face
!= dest
) IDirectDrawSurface7_Release(&dest_face
->IDirectDrawSurface7_iface
);
6195 /* Native returns error if src faces are not subset of dest faces. */
6198 wined3d_mutex_unlock();
6199 return DDERR_INVALIDPARAMS
;
6204 wined3d_mutex_unlock();
6207 else if (dest
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_CUBEMAP
)
6209 wined3d_mutex_unlock();
6210 return DDERR_INVALIDPARAMS
;
6213 /* Handle non cube map textures. */
6215 /* Destination mip levels must be subset of source mip levels. */
6216 if (!is_mip_level_subset(dest
, src
))
6218 wined3d_mutex_unlock();
6219 return DDERR_INVALIDPARAMS
;
6222 copy_mipmap_chain(device
, dest
, src
, &destpoint
, &srcrect
);
6224 wined3d_mutex_unlock();
6229 static HRESULT WINAPI
d3d_device7_Load_FPUSetup(IDirect3DDevice7
*iface
, IDirectDrawSurface7
*dst_texture
,
6230 POINT
*dst_pos
, IDirectDrawSurface7
*src_texture
, RECT
*src_rect
, DWORD flags
)
6232 return d3d_device7_Load(iface
, dst_texture
, dst_pos
, src_texture
, src_rect
, flags
);
6235 static HRESULT WINAPI
d3d_device7_Load_FPUPreserve(IDirect3DDevice7
*iface
, IDirectDrawSurface7
*dst_texture
,
6236 POINT
*dst_pos
, IDirectDrawSurface7
*src_texture
, RECT
*src_rect
, DWORD flags
)
6241 old_fpucw
= d3d_fpu_setup();
6242 hr
= d3d_device7_Load(iface
, dst_texture
, dst_pos
, src_texture
, src_rect
, flags
);
6243 set_fpu_control_word(old_fpucw
);
6248 /*****************************************************************************
6249 * IDirect3DDevice7::LightEnable
6251 * Enables or disables a light
6253 * Version 7, IDirect3DLight uses this method too.
6256 * LightIndex: The index of the light to enable / disable
6257 * Enable: Enable or disable the light
6261 * For more details, see IWineD3DDevice::SetLightEnable
6263 *****************************************************************************/
6264 static HRESULT
d3d_device7_LightEnable(IDirect3DDevice7
*iface
, DWORD light_idx
, BOOL enabled
)
6266 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
6269 TRACE("iface %p, light_idx %u, enabled %#x.\n", iface
, light_idx
, enabled
);
6271 wined3d_mutex_lock();
6272 hr
= wined3d_device_set_light_enable(device
->wined3d_device
, light_idx
, enabled
);
6273 wined3d_mutex_unlock();
6275 return hr_ddraw_from_wined3d(hr
);
6278 static HRESULT WINAPI
d3d_device7_LightEnable_FPUSetup(IDirect3DDevice7
*iface
, DWORD light_idx
, BOOL enabled
)
6280 return d3d_device7_LightEnable(iface
, light_idx
, enabled
);
6283 static HRESULT WINAPI
d3d_device7_LightEnable_FPUPreserve(IDirect3DDevice7
*iface
, DWORD light_idx
, BOOL enabled
)
6288 old_fpucw
= d3d_fpu_setup();
6289 hr
= d3d_device7_LightEnable(iface
, light_idx
, enabled
);
6290 set_fpu_control_word(old_fpucw
);
6295 /*****************************************************************************
6296 * IDirect3DDevice7::GetLightEnable
6298 * Retrieves if the light with the given index is enabled or not
6303 * LightIndex: Index of desired light
6304 * Enable: Pointer to a BOOL which contains the result
6308 * DDERR_INVALIDPARAMS if Enable is NULL
6309 * See IWineD3DDevice::GetLightEnable for more details
6311 *****************************************************************************/
6312 static HRESULT
d3d_device7_GetLightEnable(IDirect3DDevice7
*iface
, DWORD light_idx
, BOOL
*enabled
)
6314 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
6317 TRACE("iface %p, light_idx %u, enabled %p.\n", iface
, light_idx
, enabled
);
6320 return DDERR_INVALIDPARAMS
;
6322 wined3d_mutex_lock();
6323 hr
= wined3d_device_get_light_enable(device
->wined3d_device
, light_idx
, enabled
);
6324 wined3d_mutex_unlock();
6326 return hr_ddraw_from_wined3d(hr
);
6329 static HRESULT WINAPI
d3d_device7_GetLightEnable_FPUSetup(IDirect3DDevice7
*iface
, DWORD light_idx
, BOOL
*enabled
)
6331 return d3d_device7_GetLightEnable(iface
, light_idx
, enabled
);
6334 static HRESULT WINAPI
d3d_device7_GetLightEnable_FPUPreserve(IDirect3DDevice7
*iface
, DWORD light_idx
, BOOL
*enabled
)
6339 old_fpucw
= d3d_fpu_setup();
6340 hr
= d3d_device7_GetLightEnable(iface
, light_idx
, enabled
);
6341 set_fpu_control_word(old_fpucw
);
6346 /*****************************************************************************
6347 * IDirect3DDevice7::SetClipPlane
6349 * Sets custom clipping plane
6354 * Index: The index of the clipping plane
6355 * PlaneEquation: An equation defining the clipping plane
6359 * DDERR_INVALIDPARAMS if PlaneEquation is NULL
6360 * See IWineD3DDevice::SetClipPlane for more details
6362 *****************************************************************************/
6363 static HRESULT
d3d_device7_SetClipPlane(IDirect3DDevice7
*iface
, DWORD idx
, D3DVALUE
*plane
)
6365 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
6368 TRACE("iface %p, idx %u, plane %p.\n", iface
, idx
, plane
);
6371 return DDERR_INVALIDPARAMS
;
6373 wined3d_mutex_lock();
6374 hr
= wined3d_device_set_clip_plane(device
->wined3d_device
, idx
, (struct wined3d_vec4
*)plane
);
6375 wined3d_mutex_unlock();
6380 static HRESULT WINAPI
d3d_device7_SetClipPlane_FPUSetup(IDirect3DDevice7
*iface
, DWORD idx
, D3DVALUE
*plane
)
6382 return d3d_device7_SetClipPlane(iface
, idx
, plane
);
6385 static HRESULT WINAPI
d3d_device7_SetClipPlane_FPUPreserve(IDirect3DDevice7
*iface
, DWORD idx
, D3DVALUE
*plane
)
6390 old_fpucw
= d3d_fpu_setup();
6391 hr
= d3d_device7_SetClipPlane(iface
, idx
, plane
);
6392 set_fpu_control_word(old_fpucw
);
6397 /*****************************************************************************
6398 * IDirect3DDevice7::GetClipPlane
6400 * Returns the clipping plane with a specific index
6403 * Index: The index of the desired plane
6404 * PlaneEquation: Address to store the plane equation to
6408 * DDERR_INVALIDPARAMS if PlaneEquation is NULL
6409 * See IWineD3DDevice::GetClipPlane for more details
6411 *****************************************************************************/
6412 static HRESULT
d3d_device7_GetClipPlane(IDirect3DDevice7
*iface
, DWORD idx
, D3DVALUE
*plane
)
6414 struct d3d_device
*device
= impl_from_IDirect3DDevice7(iface
);
6417 TRACE("iface %p, idx %u, plane %p.\n", iface
, idx
, plane
);
6420 return DDERR_INVALIDPARAMS
;
6422 wined3d_mutex_lock();
6423 hr
= wined3d_device_get_clip_plane(device
->wined3d_device
, idx
, (struct wined3d_vec4
*)plane
);
6424 wined3d_mutex_unlock();
6429 static HRESULT WINAPI
d3d_device7_GetClipPlane_FPUSetup(IDirect3DDevice7
*iface
, DWORD idx
, D3DVALUE
*plane
)
6431 return d3d_device7_GetClipPlane(iface
, idx
, plane
);
6434 static HRESULT WINAPI
d3d_device7_GetClipPlane_FPUPreserve(IDirect3DDevice7
*iface
, DWORD idx
, D3DVALUE
*plane
)
6439 old_fpucw
= d3d_fpu_setup();
6440 hr
= d3d_device7_GetClipPlane(iface
, idx
, plane
);
6441 set_fpu_control_word(old_fpucw
);
6446 /*****************************************************************************
6447 * IDirect3DDevice7::GetInfo
6449 * Retrieves some information about the device. The DirectX sdk says that
6450 * this version returns S_FALSE for all retail builds of DirectX, that's what
6451 * this implementation does.
6454 * DevInfoID: Information type requested
6455 * DevInfoStruct: Pointer to a structure to store the info to
6456 * Size: Size of the structure
6459 * S_FALSE, because it's a non-debug driver
6461 *****************************************************************************/
6462 static HRESULT WINAPI
d3d_device7_GetInfo(IDirect3DDevice7
*iface
, DWORD info_id
, void *info
, DWORD info_size
)
6464 TRACE("iface %p, info_id %#x, info %p, info_size %u.\n",
6465 iface
, info_id
, info
, info_size
);
6467 if (TRACE_ON(ddraw
))
6469 TRACE(" info requested : ");
6472 case D3DDEVINFOID_TEXTUREMANAGER
: TRACE("D3DDEVINFOID_TEXTUREMANAGER\n"); break;
6473 case D3DDEVINFOID_D3DTEXTUREMANAGER
: TRACE("D3DDEVINFOID_D3DTEXTUREMANAGER\n"); break;
6474 case D3DDEVINFOID_TEXTURING
: TRACE("D3DDEVINFOID_TEXTURING\n"); break;
6475 default: ERR(" invalid flag !!!\n"); return DDERR_INVALIDPARAMS
;
6479 return S_FALSE
; /* According to MSDN, this is valid for a non-debug driver */
6482 /* For performance optimization, devices created in FPUSETUP and FPUPRESERVE modes
6483 * have separate vtables. Simple functions where this doesn't matter like GetDirect3D
6484 * are not duplicated.
6486 * Device created with DDSCL_FPUSETUP (d3d7 default) - device methods assume that FPU
6487 * has already been setup for optimal d3d operation.
6489 * Device created with DDSCL_FPUPRESERVE - resets and restores FPU mode when necessary in
6490 * d3d calls (FPU may be in a mode non-suitable for d3d when the app calls d3d). Required
6491 * by Sacrifice (game). */
6492 static const struct IDirect3DDevice7Vtbl d3d_device7_fpu_setup_vtbl
=
6494 /*** IUnknown Methods ***/
6495 d3d_device7_QueryInterface
,
6497 d3d_device7_Release
,
6498 /*** IDirect3DDevice7 ***/
6499 d3d_device7_GetCaps_FPUSetup
,
6500 d3d_device7_EnumTextureFormats_FPUSetup
,
6501 d3d_device7_BeginScene_FPUSetup
,
6502 d3d_device7_EndScene_FPUSetup
,
6503 d3d_device7_GetDirect3D
,
6504 d3d_device7_SetRenderTarget_FPUSetup
,
6505 d3d_device7_GetRenderTarget
,
6506 d3d_device7_Clear_FPUSetup
,
6507 d3d_device7_SetTransform_FPUSetup
,
6508 d3d_device7_GetTransform_FPUSetup
,
6509 d3d_device7_SetViewport_FPUSetup
,
6510 d3d_device7_MultiplyTransform_FPUSetup
,
6511 d3d_device7_GetViewport_FPUSetup
,
6512 d3d_device7_SetMaterial_FPUSetup
,
6513 d3d_device7_GetMaterial_FPUSetup
,
6514 d3d_device7_SetLight_FPUSetup
,
6515 d3d_device7_GetLight_FPUSetup
,
6516 d3d_device7_SetRenderState_FPUSetup
,
6517 d3d_device7_GetRenderState_FPUSetup
,
6518 d3d_device7_BeginStateBlock_FPUSetup
,
6519 d3d_device7_EndStateBlock_FPUSetup
,
6520 d3d_device7_PreLoad_FPUSetup
,
6521 d3d_device7_DrawPrimitive_FPUSetup
,
6522 d3d_device7_DrawIndexedPrimitive_FPUSetup
,
6523 d3d_device7_SetClipStatus
,
6524 d3d_device7_GetClipStatus
,
6525 d3d_device7_DrawPrimitiveStrided_FPUSetup
,
6526 d3d_device7_DrawIndexedPrimitiveStrided_FPUSetup
,
6527 d3d_device7_DrawPrimitiveVB_FPUSetup
,
6528 d3d_device7_DrawIndexedPrimitiveVB_FPUSetup
,
6529 d3d_device7_ComputeSphereVisibility
,
6530 d3d_device7_GetTexture_FPUSetup
,
6531 d3d_device7_SetTexture_FPUSetup
,
6532 d3d_device7_GetTextureStageState_FPUSetup
,
6533 d3d_device7_SetTextureStageState_FPUSetup
,
6534 d3d_device7_ValidateDevice_FPUSetup
,
6535 d3d_device7_ApplyStateBlock_FPUSetup
,
6536 d3d_device7_CaptureStateBlock_FPUSetup
,
6537 d3d_device7_DeleteStateBlock_FPUSetup
,
6538 d3d_device7_CreateStateBlock_FPUSetup
,
6539 d3d_device7_Load_FPUSetup
,
6540 d3d_device7_LightEnable_FPUSetup
,
6541 d3d_device7_GetLightEnable_FPUSetup
,
6542 d3d_device7_SetClipPlane_FPUSetup
,
6543 d3d_device7_GetClipPlane_FPUSetup
,
6547 static const struct IDirect3DDevice7Vtbl d3d_device7_fpu_preserve_vtbl
=
6549 /*** IUnknown Methods ***/
6550 d3d_device7_QueryInterface
,
6552 d3d_device7_Release
,
6553 /*** IDirect3DDevice7 ***/
6554 d3d_device7_GetCaps_FPUPreserve
,
6555 d3d_device7_EnumTextureFormats_FPUPreserve
,
6556 d3d_device7_BeginScene_FPUPreserve
,
6557 d3d_device7_EndScene_FPUPreserve
,
6558 d3d_device7_GetDirect3D
,
6559 d3d_device7_SetRenderTarget_FPUPreserve
,
6560 d3d_device7_GetRenderTarget
,
6561 d3d_device7_Clear_FPUPreserve
,
6562 d3d_device7_SetTransform_FPUPreserve
,
6563 d3d_device7_GetTransform_FPUPreserve
,
6564 d3d_device7_SetViewport_FPUPreserve
,
6565 d3d_device7_MultiplyTransform_FPUPreserve
,
6566 d3d_device7_GetViewport_FPUPreserve
,
6567 d3d_device7_SetMaterial_FPUPreserve
,
6568 d3d_device7_GetMaterial_FPUPreserve
,
6569 d3d_device7_SetLight_FPUPreserve
,
6570 d3d_device7_GetLight_FPUPreserve
,
6571 d3d_device7_SetRenderState_FPUPreserve
,
6572 d3d_device7_GetRenderState_FPUPreserve
,
6573 d3d_device7_BeginStateBlock_FPUPreserve
,
6574 d3d_device7_EndStateBlock_FPUPreserve
,
6575 d3d_device7_PreLoad_FPUPreserve
,
6576 d3d_device7_DrawPrimitive_FPUPreserve
,
6577 d3d_device7_DrawIndexedPrimitive_FPUPreserve
,
6578 d3d_device7_SetClipStatus
,
6579 d3d_device7_GetClipStatus
,
6580 d3d_device7_DrawPrimitiveStrided_FPUPreserve
,
6581 d3d_device7_DrawIndexedPrimitiveStrided_FPUPreserve
,
6582 d3d_device7_DrawPrimitiveVB_FPUPreserve
,
6583 d3d_device7_DrawIndexedPrimitiveVB_FPUPreserve
,
6584 d3d_device7_ComputeSphereVisibility
,
6585 d3d_device7_GetTexture_FPUPreserve
,
6586 d3d_device7_SetTexture_FPUPreserve
,
6587 d3d_device7_GetTextureStageState_FPUPreserve
,
6588 d3d_device7_SetTextureStageState_FPUPreserve
,
6589 d3d_device7_ValidateDevice_FPUPreserve
,
6590 d3d_device7_ApplyStateBlock_FPUPreserve
,
6591 d3d_device7_CaptureStateBlock_FPUPreserve
,
6592 d3d_device7_DeleteStateBlock_FPUPreserve
,
6593 d3d_device7_CreateStateBlock_FPUPreserve
,
6594 d3d_device7_Load_FPUPreserve
,
6595 d3d_device7_LightEnable_FPUPreserve
,
6596 d3d_device7_GetLightEnable_FPUPreserve
,
6597 d3d_device7_SetClipPlane_FPUPreserve
,
6598 d3d_device7_GetClipPlane_FPUPreserve
,
6602 static const struct IDirect3DDevice3Vtbl d3d_device3_vtbl
=
6604 /*** IUnknown Methods ***/
6605 d3d_device3_QueryInterface
,
6607 d3d_device3_Release
,
6608 /*** IDirect3DDevice3 ***/
6609 d3d_device3_GetCaps
,
6610 d3d_device3_GetStats
,
6611 d3d_device3_AddViewport
,
6612 d3d_device3_DeleteViewport
,
6613 d3d_device3_NextViewport
,
6614 d3d_device3_EnumTextureFormats
,
6615 d3d_device3_BeginScene
,
6616 d3d_device3_EndScene
,
6617 d3d_device3_GetDirect3D
,
6618 d3d_device3_SetCurrentViewport
,
6619 d3d_device3_GetCurrentViewport
,
6620 d3d_device3_SetRenderTarget
,
6621 d3d_device3_GetRenderTarget
,
6623 d3d_device3_BeginIndexed
,
6627 d3d_device3_GetRenderState
,
6628 d3d_device3_SetRenderState
,
6629 d3d_device3_GetLightState
,
6630 d3d_device3_SetLightState
,
6631 d3d_device3_SetTransform
,
6632 d3d_device3_GetTransform
,
6633 d3d_device3_MultiplyTransform
,
6634 d3d_device3_DrawPrimitive
,
6635 d3d_device3_DrawIndexedPrimitive
,
6636 d3d_device3_SetClipStatus
,
6637 d3d_device3_GetClipStatus
,
6638 d3d_device3_DrawPrimitiveStrided
,
6639 d3d_device3_DrawIndexedPrimitiveStrided
,
6640 d3d_device3_DrawPrimitiveVB
,
6641 d3d_device3_DrawIndexedPrimitiveVB
,
6642 d3d_device3_ComputeSphereVisibility
,
6643 d3d_device3_GetTexture
,
6644 d3d_device3_SetTexture
,
6645 d3d_device3_GetTextureStageState
,
6646 d3d_device3_SetTextureStageState
,
6647 d3d_device3_ValidateDevice
6650 static const struct IDirect3DDevice2Vtbl d3d_device2_vtbl
=
6652 /*** IUnknown Methods ***/
6653 d3d_device2_QueryInterface
,
6655 d3d_device2_Release
,
6656 /*** IDirect3DDevice2 ***/
6657 d3d_device2_GetCaps
,
6658 d3d_device2_SwapTextureHandles
,
6659 d3d_device2_GetStats
,
6660 d3d_device2_AddViewport
,
6661 d3d_device2_DeleteViewport
,
6662 d3d_device2_NextViewport
,
6663 d3d_device2_EnumTextureFormats
,
6664 d3d_device2_BeginScene
,
6665 d3d_device2_EndScene
,
6666 d3d_device2_GetDirect3D
,
6667 d3d_device2_SetCurrentViewport
,
6668 d3d_device2_GetCurrentViewport
,
6669 d3d_device2_SetRenderTarget
,
6670 d3d_device2_GetRenderTarget
,
6672 d3d_device2_BeginIndexed
,
6676 d3d_device2_GetRenderState
,
6677 d3d_device2_SetRenderState
,
6678 d3d_device2_GetLightState
,
6679 d3d_device2_SetLightState
,
6680 d3d_device2_SetTransform
,
6681 d3d_device2_GetTransform
,
6682 d3d_device2_MultiplyTransform
,
6683 d3d_device2_DrawPrimitive
,
6684 d3d_device2_DrawIndexedPrimitive
,
6685 d3d_device2_SetClipStatus
,
6686 d3d_device2_GetClipStatus
6689 static const struct IDirect3DDeviceVtbl d3d_device1_vtbl
=
6691 /*** IUnknown Methods ***/
6692 d3d_device1_QueryInterface
,
6694 d3d_device1_Release
,
6695 /*** IDirect3DDevice1 ***/
6696 d3d_device1_Initialize
,
6697 d3d_device1_GetCaps
,
6698 d3d_device1_SwapTextureHandles
,
6699 d3d_device1_CreateExecuteBuffer
,
6700 d3d_device1_GetStats
,
6701 d3d_device1_Execute
,
6702 d3d_device1_AddViewport
,
6703 d3d_device1_DeleteViewport
,
6704 d3d_device1_NextViewport
,
6706 d3d_device1_GetPickRecords
,
6707 d3d_device1_EnumTextureFormats
,
6708 d3d_device1_CreateMatrix
,
6709 d3d_device1_SetMatrix
,
6710 d3d_device1_GetMatrix
,
6711 d3d_device1_DeleteMatrix
,
6712 d3d_device1_BeginScene
,
6713 d3d_device1_EndScene
,
6714 d3d_device1_GetDirect3D
6717 static const struct IUnknownVtbl d3d_device_inner_vtbl
=
6719 d3d_device_inner_QueryInterface
,
6720 d3d_device_inner_AddRef
,
6721 d3d_device_inner_Release
,
6724 struct d3d_device
*unsafe_impl_from_IDirect3DDevice7(IDirect3DDevice7
*iface
)
6726 if (!iface
) return NULL
;
6727 assert((iface
->lpVtbl
== &d3d_device7_fpu_preserve_vtbl
) || (iface
->lpVtbl
== &d3d_device7_fpu_setup_vtbl
));
6728 return CONTAINING_RECORD(iface
, struct d3d_device
, IDirect3DDevice7_iface
);
6731 struct d3d_device
*unsafe_impl_from_IDirect3DDevice3(IDirect3DDevice3
*iface
)
6733 if (!iface
) return NULL
;
6734 assert(iface
->lpVtbl
== &d3d_device3_vtbl
);
6735 return CONTAINING_RECORD(iface
, struct d3d_device
, IDirect3DDevice3_iface
);
6738 struct d3d_device
*unsafe_impl_from_IDirect3DDevice2(IDirect3DDevice2
*iface
)
6740 if (!iface
) return NULL
;
6741 assert(iface
->lpVtbl
== &d3d_device2_vtbl
);
6742 return CONTAINING_RECORD(iface
, struct d3d_device
, IDirect3DDevice2_iface
);
6745 struct d3d_device
*unsafe_impl_from_IDirect3DDevice(IDirect3DDevice
*iface
)
6747 if (!iface
) return NULL
;
6748 assert(iface
->lpVtbl
== &d3d_device1_vtbl
);
6749 return CONTAINING_RECORD(iface
, struct d3d_device
, IDirect3DDevice_iface
);
6752 enum wined3d_depth_buffer_type
d3d_device_update_depth_stencil(struct d3d_device
*device
)
6754 IDirectDrawSurface7
*depthStencil
= NULL
;
6755 IDirectDrawSurface7
*render_target
;
6756 static DDSCAPS2 depthcaps
= { DDSCAPS_ZBUFFER
, 0, 0, {0} };
6757 struct ddraw_surface
*dsi
;
6759 if (device
->rt_iface
&& SUCCEEDED(IUnknown_QueryInterface(device
->rt_iface
,
6760 &IID_IDirectDrawSurface7
, (void **)&render_target
)))
6762 IDirectDrawSurface7_GetAttachedSurface(render_target
, &depthcaps
, &depthStencil
);
6763 IDirectDrawSurface7_Release(render_target
);
6767 TRACE("Setting wined3d depth stencil to NULL\n");
6768 wined3d_device_set_depth_stencil_view(device
->wined3d_device
, NULL
);
6769 return WINED3D_ZB_FALSE
;
6772 dsi
= impl_from_IDirectDrawSurface7(depthStencil
);
6773 wined3d_device_set_depth_stencil_view(device
->wined3d_device
,
6774 ddraw_surface_get_rendertarget_view(dsi
));
6776 IDirectDrawSurface7_Release(depthStencil
);
6777 return WINED3D_ZB_TRUE
;
6780 static HRESULT
d3d_device_init(struct d3d_device
*device
, struct ddraw
*ddraw
,
6781 struct ddraw_surface
*target
, IUnknown
*rt_iface
, UINT version
, IUnknown
*outer_unknown
)
6783 static const D3DMATRIX ident
=
6785 1.0f
, 0.0f
, 0.0f
, 0.0f
,
6786 0.0f
, 1.0f
, 0.0f
, 0.0f
,
6787 0.0f
, 0.0f
, 1.0f
, 0.0f
,
6788 0.0f
, 0.0f
, 0.0f
, 1.0f
,
6792 if (ddraw
->cooperative_level
& DDSCL_FPUPRESERVE
)
6793 device
->IDirect3DDevice7_iface
.lpVtbl
= &d3d_device7_fpu_preserve_vtbl
;
6795 device
->IDirect3DDevice7_iface
.lpVtbl
= &d3d_device7_fpu_setup_vtbl
;
6797 device
->IDirect3DDevice3_iface
.lpVtbl
= &d3d_device3_vtbl
;
6798 device
->IDirect3DDevice2_iface
.lpVtbl
= &d3d_device2_vtbl
;
6799 device
->IDirect3DDevice_iface
.lpVtbl
= &d3d_device1_vtbl
;
6800 device
->IUnknown_inner
.lpVtbl
= &d3d_device_inner_vtbl
;
6802 device
->version
= version
;
6805 device
->outer_unknown
= outer_unknown
;
6807 device
->outer_unknown
= &device
->IUnknown_inner
;
6809 device
->ddraw
= ddraw
;
6810 list_init(&device
->viewport_list
);
6812 if (!ddraw_handle_table_init(&device
->handle_table
, 64))
6814 ERR("Failed to initialize handle table.\n");
6815 return DDERR_OUTOFMEMORY
;
6818 device
->legacyTextureBlending
= FALSE
;
6819 device
->legacy_projection
= ident
;
6820 device
->legacy_clipspace
= ident
;
6822 /* This is for convenience. */
6823 device
->wined3d_device
= ddraw
->wined3d_device
;
6824 wined3d_device_incref(ddraw
->wined3d_device
);
6826 /* Render to the back buffer */
6827 if (FAILED(hr
= wined3d_device_set_rendertarget_view(ddraw
->wined3d_device
,
6828 0, ddraw_surface_get_rendertarget_view(target
), TRUE
)))
6830 ERR("Failed to set render target, hr %#x.\n", hr
);
6831 ddraw_handle_table_destroy(&device
->handle_table
);
6835 device
->rt_iface
= rt_iface
;
6837 IUnknown_AddRef(device
->rt_iface
);
6839 ddraw
->d3ddevice
= device
;
6841 wined3d_device_set_render_state(ddraw
->wined3d_device
, WINED3D_RS_ZENABLE
,
6842 d3d_device_update_depth_stencil(device
));
6843 if (version
== 1) /* Color keying is initially enabled for version 1 devices. */
6844 wined3d_device_set_render_state(ddraw
->wined3d_device
, WINED3D_RS_COLORKEYENABLE
, TRUE
);
6845 else if (version
== 2)
6846 wined3d_device_set_render_state(ddraw
->wined3d_device
, WINED3D_RS_SPECULARENABLE
, TRUE
);
6848 wined3d_device_set_render_state(ddraw
->wined3d_device
, WINED3D_RS_NORMALIZENORMALS
, TRUE
);
6853 HRESULT
d3d_device_create(struct ddraw
*ddraw
, struct ddraw_surface
*target
, IUnknown
*rt_iface
,
6854 UINT version
, struct d3d_device
**device
, IUnknown
*outer_unknown
)
6856 struct d3d_device
*object
;
6859 TRACE("ddraw %p, target %p, version %u, device %p, outer_unknown %p.\n",
6860 ddraw
, target
, version
, device
, outer_unknown
);
6862 if (!(target
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_3DDEVICE
)
6863 || (target
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_ZBUFFER
))
6865 WARN("Surface %p is not a render target.\n", target
);
6866 return DDERR_INVALIDCAPS
;
6869 if (!validate_surface_palette(target
))
6871 WARN("Surface %p has an indexed pixel format, but no palette.\n", target
);
6872 return DDERR_NOPALETTEATTACHED
;
6875 if (!(target
->surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_VIDEOMEMORY
))
6877 WARN("Surface %p is not in video memory.\n", target
);
6878 return D3DERR_SURFACENOTINVIDMEM
;
6881 if (ddraw
->flags
& DDRAW_NO3D
)
6883 ERR_(winediag
)("The application wants to create a Direct3D device, "
6884 "but the current DirectDrawRenderer does not support this.\n");
6889 if (ddraw
->d3ddevice
)
6891 FIXME("Only one Direct3D device per DirectDraw object supported.\n");
6892 return DDERR_INVALIDPARAMS
;
6895 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*object
));
6898 ERR("Failed to allocate device memory.\n");
6899 return DDERR_OUTOFMEMORY
;
6902 if (FAILED(hr
= d3d_device_init(object
, ddraw
, target
, rt_iface
, version
, outer_unknown
)))
6904 WARN("Failed to initialize device, hr %#x.\n", hr
);
6905 HeapFree(GetProcessHeap(), 0, object
);
6909 TRACE("Created device %p.\n", object
);