2 * Copyright (c) 1998-2004 Lionel Ulmer
3 * Copyright (c) 2002-2005 Christian Costa
4 * Copyright (c) 2006 Stefan Dösinger
5 * Copyright (c) 2008 Alexander Dorofeyev
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 * IDirect3DDevice implementation, version 1, 2, 3 and 7. Rendering is relayed
22 * to WineD3D, some minimal DirectDraw specific management is handled here.
23 * The Direct3DDevice is NOT the parent of the WineD3DDevice, because d3d
24 * is initialized when DirectDraw creates the primary surface.
25 * Some type management is necessary, because some D3D types changed between
31 #include "wine/port.h"
33 #include "ddraw_private.h"
35 WINE_DEFAULT_DEBUG_CHANNEL(ddraw
);
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 /*****************************************************************************
79 * IUnknown Methods. Common for Version 1, 2, 3 and 7
80 *****************************************************************************/
82 /*****************************************************************************
83 * IDirect3DDevice7::QueryInterface
85 * Used to query other interfaces from a Direct3DDevice interface.
86 * It can return interface pointers to all Direct3DDevice versions as well
87 * as IDirectDraw and IDirect3D. For a link to QueryInterface
88 * rules see ddraw.c, IDirectDraw7::QueryInterface
90 * Exists in Version 1, 2, 3 and 7
93 * refiid: Interface ID queried for
94 * obj: Used to return the interface pointer
97 * D3D_OK or E_NOINTERFACE
99 *****************************************************************************/
100 static HRESULT WINAPI
101 IDirect3DDeviceImpl_7_QueryInterface(IDirect3DDevice7
*iface
,
105 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
107 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(refiid
), obj
);
109 /* According to COM docs, if the QueryInterface fails, obj should be set to NULL */
113 return DDERR_INVALIDPARAMS
;
115 if ( IsEqualGUID( &IID_IUnknown
, refiid
) )
121 else if ( IsEqualGUID( &IID_IDirect3DDevice
, refiid
) )
123 *obj
= &This
->IDirect3DDevice_iface
;
124 TRACE("(%p) Returning IDirect3DDevice interface at %p\n", This
, *obj
);
126 else if ( IsEqualGUID( &IID_IDirect3DDevice2
, refiid
) ) {
127 *obj
= &This
->IDirect3DDevice2_iface
;
128 TRACE("(%p) Returning IDirect3DDevice2 interface at %p\n", This
, *obj
);
130 else if ( IsEqualGUID( &IID_IDirect3DDevice3
, refiid
) ) {
131 *obj
= &This
->IDirect3DDevice3_iface
;
132 TRACE("(%p) Returning IDirect3DDevice3 interface at %p\n", This
, *obj
);
134 else if ( IsEqualGUID( &IID_IDirect3DDevice7
, refiid
) ) {
135 *obj
= &This
->IDirect3DDevice7_iface
;
136 TRACE("(%p) Returning IDirect3DDevice7 interface at %p\n", This
, *obj
);
139 /* DirectDrawSurface */
140 else if (IsEqualGUID(&IID_IDirectDrawSurface
, refiid
) && This
->version
== 1)
142 *obj
= &This
->target
->IDirectDrawSurface_iface
;
143 TRACE("Returning IDirectDrawSurface interface %p.\n", *obj
);
146 /* Unknown interface */
149 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(refiid
));
150 return E_NOINTERFACE
;
153 /* AddRef the returned interface */
154 IUnknown_AddRef( (IUnknown
*) *obj
);
158 static HRESULT WINAPI
IDirect3DDeviceImpl_3_QueryInterface(IDirect3DDevice3
*iface
, REFIID riid
,
161 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
162 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), obj
);
164 return IDirect3DDevice7_QueryInterface(&This
->IDirect3DDevice7_iface
, riid
, obj
);
167 static HRESULT WINAPI
IDirect3DDeviceImpl_2_QueryInterface(IDirect3DDevice2
*iface
, REFIID riid
,
170 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
171 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), obj
);
173 return IDirect3DDevice7_QueryInterface(&This
->IDirect3DDevice7_iface
, riid
, obj
);
176 static HRESULT WINAPI
IDirect3DDeviceImpl_1_QueryInterface(IDirect3DDevice
*iface
, REFIID riid
,
179 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
180 TRACE("iface %p, riid %s, object %p.\n", iface
, debugstr_guid(riid
), obp
);
182 return IDirect3DDevice7_QueryInterface(&This
->IDirect3DDevice7_iface
, riid
, obp
);
185 /*****************************************************************************
186 * IDirect3DDevice7::AddRef
188 * Increases the refcount....
189 * The most exciting Method, definitely
191 * Exists in Version 1, 2, 3 and 7
196 *****************************************************************************/
198 IDirect3DDeviceImpl_7_AddRef(IDirect3DDevice7
*iface
)
200 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
201 ULONG ref
= InterlockedIncrement(&This
->ref
);
203 TRACE("%p increasing refcount to %u.\n", This
, ref
);
208 static ULONG WINAPI
IDirect3DDeviceImpl_3_AddRef(IDirect3DDevice3
*iface
)
210 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
211 TRACE("iface %p.\n", iface
);
213 return IDirect3DDevice7_AddRef(&This
->IDirect3DDevice7_iface
);
216 static ULONG WINAPI
IDirect3DDeviceImpl_2_AddRef(IDirect3DDevice2
*iface
)
218 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
219 TRACE("iface %p.\n", iface
);
221 return IDirect3DDevice7_AddRef(&This
->IDirect3DDevice7_iface
);
224 static ULONG WINAPI
IDirect3DDeviceImpl_1_AddRef(IDirect3DDevice
*iface
)
226 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
227 TRACE("iface %p.\n", iface
);
229 return IDirect3DDevice7_AddRef(&This
->IDirect3DDevice7_iface
);
232 /*****************************************************************************
233 * IDirect3DDevice7::Release
235 * Decreases the refcount of the interface
236 * When the refcount is reduced to 0, the object is destroyed.
238 * Exists in Version 1, 2, 3 and 7
243 *****************************************************************************/
245 IDirect3DDeviceImpl_7_Release(IDirect3DDevice7
*iface
)
247 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
248 ULONG ref
= InterlockedDecrement(&This
->ref
);
250 TRACE("%p decreasing refcount to %u.\n", This
, ref
);
252 /* This method doesn't destroy the WineD3DDevice, because it's still in use for
253 * 2D rendering. IDirectDrawSurface7::Release will destroy the WineD3DDevice
254 * when the render target is released
260 wined3d_mutex_lock();
262 /* There is no need to unset any resources here, wined3d will take
263 * care of that on Uninit3D(). */
265 /* Free the index buffer. */
266 wined3d_buffer_decref(This
->indexbuffer
);
268 /* Set the device up to render to the front buffer since the back
269 * buffer will vanish soon. */
270 wined3d_device_set_render_target(This
->wined3d_device
, 0,
271 This
->ddraw
->wined3d_frontbuffer
, TRUE
);
273 /* Release the WineD3DDevice. This won't destroy it. */
274 if (!wined3d_device_decref(This
->wined3d_device
))
275 ERR("The wined3d device (%p) was destroyed unexpectedly.\n", This
->wined3d_device
);
277 /* The texture handles should be unset by now, but there might be some bits
278 * missing in our reference counting(needs test). Do a sanity check. */
279 for (i
= 0; i
< This
->handle_table
.entry_count
; ++i
)
281 struct ddraw_handle_entry
*entry
= &This
->handle_table
.entries
[i
];
285 case DDRAW_HANDLE_FREE
:
288 case DDRAW_HANDLE_MATERIAL
:
290 struct d3d_material
*m
= entry
->object
;
291 FIXME("Material handle %#x (%p) not unset properly.\n", i
+ 1, m
);
296 case DDRAW_HANDLE_MATRIX
:
298 /* No FIXME here because this might happen because of sloppy applications. */
299 WARN("Leftover matrix handle %#x (%p), deleting.\n", i
+ 1, entry
->object
);
300 IDirect3DDevice_DeleteMatrix(&This
->IDirect3DDevice_iface
, i
+ 1);
304 case DDRAW_HANDLE_STATEBLOCK
:
306 /* No FIXME here because this might happen because of sloppy applications. */
307 WARN("Leftover stateblock handle %#x (%p), deleting.\n", i
+ 1, entry
->object
);
308 IDirect3DDevice7_DeleteStateBlock(iface
, i
+ 1);
312 case DDRAW_HANDLE_SURFACE
:
314 struct ddraw_surface
*surf
= entry
->object
;
315 FIXME("Texture handle %#x (%p) not unset properly.\n", i
+ 1, surf
);
321 FIXME("Handle %#x (%p) has unknown type %#x.\n", i
+ 1, entry
->object
, entry
->type
);
326 ddraw_handle_table_destroy(&This
->handle_table
);
328 TRACE("Releasing target %p.\n", This
->target
);
329 /* Release the render target and the WineD3D render target
330 * (See IDirect3D7::CreateDevice for more comments on this)
332 IDirectDrawSurface7_Release(&This
->target
->IDirectDrawSurface7_iface
);
333 TRACE("Target release done\n");
335 This
->ddraw
->d3ddevice
= NULL
;
337 /* Now free the structure */
338 HeapFree(GetProcessHeap(), 0, This
);
339 wined3d_mutex_unlock();
346 static ULONG WINAPI
IDirect3DDeviceImpl_3_Release(IDirect3DDevice3
*iface
)
348 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
349 TRACE("iface %p.\n", iface
);
351 return IDirect3DDevice7_Release(&This
->IDirect3DDevice7_iface
);
354 static ULONG WINAPI
IDirect3DDeviceImpl_2_Release(IDirect3DDevice2
*iface
)
356 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
357 TRACE("iface %p.\n", iface
);
359 return IDirect3DDevice7_Release(&This
->IDirect3DDevice7_iface
);
362 static ULONG WINAPI
IDirect3DDeviceImpl_1_Release(IDirect3DDevice
*iface
)
364 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
365 TRACE("iface %p.\n", iface
);
367 return IDirect3DDevice7_Release(&This
->IDirect3DDevice7_iface
);
370 /*****************************************************************************
371 * IDirect3DDevice Methods
372 *****************************************************************************/
374 /*****************************************************************************
375 * IDirect3DDevice::Initialize
377 * Initializes a Direct3DDevice. This implementation is a no-op, as all
378 * initialization is done at create time.
380 * Exists in Version 1
383 * No idea what they mean, as the MSDN page is gone
387 *****************************************************************************/
388 static HRESULT WINAPI
389 IDirect3DDeviceImpl_1_Initialize(IDirect3DDevice
*iface
,
390 IDirect3D
*Direct3D
, GUID
*guid
,
393 /* It shouldn't be crucial, but print a FIXME, I'm interested if
394 * any game calls it and when. */
395 FIXME("iface %p, d3d %p, guid %s, device_desc %p nop!\n",
396 iface
, Direct3D
, debugstr_guid(guid
), Desc
);
401 /*****************************************************************************
402 * IDirect3DDevice7::GetCaps
404 * Retrieves the device's capabilities
406 * This implementation is used for Version 7 only, the older versions have
407 * their own implementation.
410 * Desc: Pointer to a D3DDEVICEDESC7 structure to fill
414 * D3DERR_* if a problem occurs. See WineD3D
416 *****************************************************************************/
418 IDirect3DDeviceImpl_7_GetCaps(IDirect3DDevice7
*iface
,
419 D3DDEVICEDESC7
*Desc
)
421 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
422 D3DDEVICEDESC OldDesc
;
424 TRACE("iface %p, device_desc %p.\n", iface
, Desc
);
428 WARN("Desc is NULL, returning DDERR_INVALIDPARAMS.\n");
429 return DDERR_INVALIDPARAMS
;
432 /* Call the same function used by IDirect3D, this saves code */
433 return IDirect3DImpl_GetCaps(This
->ddraw
->wined3d
, &OldDesc
, Desc
);
436 static HRESULT WINAPI
437 IDirect3DDeviceImpl_7_GetCaps_FPUSetup(IDirect3DDevice7
*iface
,
438 D3DDEVICEDESC7
*Desc
)
440 return IDirect3DDeviceImpl_7_GetCaps(iface
, Desc
);
443 static HRESULT WINAPI
444 IDirect3DDeviceImpl_7_GetCaps_FPUPreserve(IDirect3DDevice7
*iface
,
445 D3DDEVICEDESC7
*Desc
)
450 old_fpucw
= d3d_fpu_setup();
451 hr
= IDirect3DDeviceImpl_7_GetCaps(iface
, Desc
);
452 set_fpu_control_word(old_fpucw
);
456 /*****************************************************************************
457 * IDirect3DDevice3::GetCaps
459 * Retrieves the capabilities of the hardware device and the emulation
460 * device. For Wine, hardware and emulation are the same (it's all HW).
462 * This implementation is used for Version 1, 2, and 3. Version 7 has its own
465 * HWDesc: Structure to fill with the HW caps
466 * HelDesc: Structure to fill with the hardware emulation caps
470 * D3DERR_* if a problem occurs. See WineD3D
472 *****************************************************************************/
474 /* There are 3 versions of D3DDEVICEDESC. All 3 share the same name because
475 * Microsoft just expanded the existing structure without naming them
476 * D3DDEVICEDESC2 and D3DDEVICEDESC3. Which version is used have depends
477 * on the version of the DirectX SDK. DirectX 6+ and Wine use the latest
478 * one with 252 bytes.
480 * All 3 versions are allowed as parameters and only the specified amount of
483 * Note that Direct3D7 and earlier are not available in native Win64
484 * ddraw.dll builds, so possible size differences between 32 bit and
485 * 64 bit are a non-issue.
487 static inline BOOL
check_d3ddevicedesc_size(DWORD size
)
489 if (size
== FIELD_OFFSET(D3DDEVICEDESC
, dwMinTextureWidth
) /* 172 */
490 || size
== FIELD_OFFSET(D3DDEVICEDESC
, dwMaxTextureRepeat
) /* 204 */
491 || size
== sizeof(D3DDEVICEDESC
) /* 252 */) return TRUE
;
495 static HRESULT WINAPI
496 IDirect3DDeviceImpl_3_GetCaps(IDirect3DDevice3
*iface
,
497 D3DDEVICEDESC
*HWDesc
,
498 D3DDEVICEDESC
*HelDesc
)
500 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
501 D3DDEVICEDESC oldDesc
;
502 D3DDEVICEDESC7 newDesc
;
505 TRACE("iface %p, hw_desc %p, hel_desc %p.\n", iface
, HWDesc
, HelDesc
);
509 WARN("HWDesc is NULL, returning DDERR_INVALIDPARAMS.\n");
510 return DDERR_INVALIDPARAMS
;
512 if (!check_d3ddevicedesc_size(HWDesc
->dwSize
))
514 WARN("HWDesc->dwSize is %u, returning DDERR_INVALIDPARAMS.\n", HWDesc
->dwSize
);
515 return DDERR_INVALIDPARAMS
;
519 WARN("HelDesc is NULL, returning DDERR_INVALIDPARAMS.\n");
520 return DDERR_INVALIDPARAMS
;
522 if (!check_d3ddevicedesc_size(HelDesc
->dwSize
))
524 WARN("HelDesc->dwSize is %u, returning DDERR_INVALIDPARAMS.\n", HelDesc
->dwSize
);
525 return DDERR_INVALIDPARAMS
;
528 hr
= IDirect3DImpl_GetCaps(This
->ddraw
->wined3d
, &oldDesc
, &newDesc
);
529 if(hr
!= D3D_OK
) return hr
;
531 DD_STRUCT_COPY_BYSIZE(HWDesc
, &oldDesc
);
532 DD_STRUCT_COPY_BYSIZE(HelDesc
, &oldDesc
);
536 static HRESULT WINAPI
IDirect3DDeviceImpl_2_GetCaps(IDirect3DDevice2
*iface
,
537 D3DDEVICEDESC
*D3DHWDevDesc
, D3DDEVICEDESC
*D3DHELDevDesc
)
539 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
540 TRACE("iface %p, hw_desc %p, hel_desc %p.\n", iface
, D3DHWDevDesc
, D3DHELDevDesc
);
541 return IDirect3DDevice3_GetCaps(&This
->IDirect3DDevice3_iface
, D3DHWDevDesc
, D3DHELDevDesc
);
544 static HRESULT WINAPI
IDirect3DDeviceImpl_1_GetCaps(IDirect3DDevice
*iface
,
545 D3DDEVICEDESC
*D3DHWDevDesc
, D3DDEVICEDESC
*D3DHELDevDesc
)
547 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
548 TRACE("iface %p, hw_desc %p, hel_desc %p.\n", iface
, D3DHWDevDesc
, D3DHELDevDesc
);
549 return IDirect3DDevice3_GetCaps(&This
->IDirect3DDevice3_iface
, D3DHWDevDesc
, D3DHELDevDesc
);
552 /*****************************************************************************
553 * IDirect3DDevice2::SwapTextureHandles
555 * Swaps the texture handles of 2 Texture interfaces. Version 1 and 2
558 * Tex1, Tex2: The 2 Textures to swap
563 *****************************************************************************/
564 static HRESULT WINAPI
565 IDirect3DDeviceImpl_2_SwapTextureHandles(IDirect3DDevice2
*iface
,
566 IDirect3DTexture2
*Tex1
,
567 IDirect3DTexture2
*Tex2
)
569 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
570 struct ddraw_surface
*surf1
= unsafe_impl_from_IDirect3DTexture2(Tex1
);
571 struct ddraw_surface
*surf2
= unsafe_impl_from_IDirect3DTexture2(Tex2
);
574 TRACE("iface %p, tex1 %p, tex2 %p.\n", iface
, Tex1
, Tex2
);
576 wined3d_mutex_lock();
578 h1
= surf1
->Handle
- 1;
579 h2
= surf2
->Handle
- 1;
580 This
->handle_table
.entries
[h1
].object
= surf2
;
581 This
->handle_table
.entries
[h2
].object
= surf1
;
582 surf2
->Handle
= h1
+ 1;
583 surf1
->Handle
= h2
+ 1;
585 wined3d_mutex_unlock();
590 static HRESULT WINAPI
IDirect3DDeviceImpl_1_SwapTextureHandles(IDirect3DDevice
*iface
,
591 IDirect3DTexture
*D3DTex1
, IDirect3DTexture
*D3DTex2
)
593 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
594 struct ddraw_surface
*surf1
= unsafe_impl_from_IDirect3DTexture(D3DTex1
);
595 struct ddraw_surface
*surf2
= unsafe_impl_from_IDirect3DTexture(D3DTex2
);
596 IDirect3DTexture2
*t1
= surf1
? &surf1
->IDirect3DTexture2_iface
: NULL
;
597 IDirect3DTexture2
*t2
= surf2
? &surf2
->IDirect3DTexture2_iface
: NULL
;
599 TRACE("iface %p, tex1 %p, tex2 %p.\n", iface
, D3DTex1
, D3DTex2
);
601 return IDirect3DDevice2_SwapTextureHandles(&This
->IDirect3DDevice2_iface
, t1
, t2
);
604 /*****************************************************************************
605 * IDirect3DDevice3::GetStats
607 * This method seems to retrieve some stats from the device.
608 * The MSDN documentation doesn't exist any more, but the D3DSTATS
609 * structure suggests that the amount of drawn primitives and processed
610 * vertices is returned.
612 * Exists in Version 1, 2 and 3
615 * Stats: Pointer to a D3DSTATS structure to be filled
619 * DDERR_INVALIDPARAMS if Stats == NULL
621 *****************************************************************************/
622 static HRESULT WINAPI
623 IDirect3DDeviceImpl_3_GetStats(IDirect3DDevice3
*iface
,
626 FIXME("iface %p, stats %p stub!\n", iface
, Stats
);
629 return DDERR_INVALIDPARAMS
;
631 /* Fill the Stats with 0 */
632 Stats
->dwTrianglesDrawn
= 0;
633 Stats
->dwLinesDrawn
= 0;
634 Stats
->dwPointsDrawn
= 0;
635 Stats
->dwSpansDrawn
= 0;
636 Stats
->dwVerticesProcessed
= 0;
641 static HRESULT WINAPI
IDirect3DDeviceImpl_2_GetStats(IDirect3DDevice2
*iface
, D3DSTATS
*Stats
)
643 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
645 TRACE("iface %p, stats %p.\n", iface
, Stats
);
647 return IDirect3DDevice3_GetStats(&This
->IDirect3DDevice3_iface
, Stats
);
650 static HRESULT WINAPI
IDirect3DDeviceImpl_1_GetStats(IDirect3DDevice
*iface
, D3DSTATS
*Stats
)
652 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
654 TRACE("iface %p, stats %p.\n", iface
, Stats
);
656 return IDirect3DDevice3_GetStats(&This
->IDirect3DDevice3_iface
, Stats
);
659 /*****************************************************************************
660 * IDirect3DDevice::CreateExecuteBuffer
662 * Creates an IDirect3DExecuteBuffer, used for rendering with a
668 * Desc: Buffer description
669 * ExecuteBuffer: Address to return the Interface pointer at
670 * UnkOuter: Must be NULL. Basically for aggregation, which ddraw doesn't
674 * CLASS_E_NOAGGREGATION if UnkOuter != NULL
675 * DDERR_OUTOFMEMORY if we ran out of memory
678 *****************************************************************************/
679 static HRESULT WINAPI
680 IDirect3DDeviceImpl_1_CreateExecuteBuffer(IDirect3DDevice
*iface
,
681 D3DEXECUTEBUFFERDESC
*Desc
,
682 IDirect3DExecuteBuffer
**ExecuteBuffer
,
685 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
686 IDirect3DExecuteBufferImpl
* object
;
689 TRACE("iface %p, buffer_desc %p, buffer %p, outer_unknown %p.\n",
690 iface
, Desc
, ExecuteBuffer
, UnkOuter
);
693 return CLASS_E_NOAGGREGATION
;
695 /* Allocate the new Execute Buffer */
696 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirect3DExecuteBufferImpl
));
699 ERR("Out of memory when allocating a IDirect3DExecuteBufferImpl structure\n");
700 return DDERR_OUTOFMEMORY
;
703 hr
= d3d_execute_buffer_init(object
, This
, Desc
);
706 WARN("Failed to initialize execute buffer, hr %#x.\n", hr
);
707 HeapFree(GetProcessHeap(), 0, object
);
711 *ExecuteBuffer
= &object
->IDirect3DExecuteBuffer_iface
;
713 TRACE(" Returning IDirect3DExecuteBuffer at %p, implementation is at %p\n", *ExecuteBuffer
, object
);
718 /*****************************************************************************
719 * IDirect3DDevice::Execute
721 * Executes all the stuff in an execute buffer.
724 * ExecuteBuffer: The buffer to execute
725 * Viewport: The viewport used for rendering
729 * DDERR_INVALIDPARAMS if ExecuteBuffer == NULL
732 *****************************************************************************/
733 static HRESULT WINAPI
IDirect3DDeviceImpl_1_Execute(IDirect3DDevice
*iface
,
734 IDirect3DExecuteBuffer
*ExecuteBuffer
, IDirect3DViewport
*Viewport
, DWORD Flags
)
736 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
737 IDirect3DExecuteBufferImpl
*buffer
= unsafe_impl_from_IDirect3DExecuteBuffer(ExecuteBuffer
);
738 struct d3d_viewport
*viewport_impl
= unsafe_impl_from_IDirect3DViewport(Viewport
);
741 TRACE("iface %p, buffer %p, viewport %p, flags %#x.\n", iface
, ExecuteBuffer
, Viewport
, Flags
);
744 return DDERR_INVALIDPARAMS
;
747 wined3d_mutex_lock();
748 hr
= d3d_execute_buffer_execute(buffer
, This
, viewport_impl
);
749 wined3d_mutex_unlock();
754 /*****************************************************************************
755 * IDirect3DDevice3::AddViewport
757 * Add a Direct3DViewport to the device's viewport list. These viewports
758 * are wrapped to IDirect3DDevice7 viewports in viewport.c
760 * Exists in Version 1, 2 and 3. Note that IDirect3DViewport 1, 2 and 3
761 * are the same interfaces.
764 * Viewport: The viewport to add
767 * DDERR_INVALIDPARAMS if Viewport == NULL
770 *****************************************************************************/
771 static HRESULT WINAPI
772 IDirect3DDeviceImpl_3_AddViewport(IDirect3DDevice3
*iface
,
773 IDirect3DViewport3
*Viewport
)
775 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
776 struct d3d_viewport
*vp
= unsafe_impl_from_IDirect3DViewport3(Viewport
);
778 TRACE("iface %p, viewport %p.\n", iface
, Viewport
);
782 return DDERR_INVALIDPARAMS
;
784 wined3d_mutex_lock();
785 list_add_head(&This
->viewport_list
, &vp
->entry
);
786 vp
->active_device
= This
; /* Viewport must be usable for Clear() after AddViewport,
787 so set active_device here. */
788 wined3d_mutex_unlock();
793 static HRESULT WINAPI
IDirect3DDeviceImpl_2_AddViewport(IDirect3DDevice2
*iface
,
794 IDirect3DViewport2
*Direct3DViewport2
)
796 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
797 struct d3d_viewport
*vp
= unsafe_impl_from_IDirect3DViewport2(Direct3DViewport2
);
799 TRACE("iface %p, viewport %p.\n", iface
, Direct3DViewport2
);
801 return IDirect3DDevice3_AddViewport(&This
->IDirect3DDevice3_iface
, &vp
->IDirect3DViewport3_iface
);
804 static HRESULT WINAPI
IDirect3DDeviceImpl_1_AddViewport(IDirect3DDevice
*iface
,
805 IDirect3DViewport
*Direct3DViewport
)
807 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
808 struct d3d_viewport
*vp
= unsafe_impl_from_IDirect3DViewport(Direct3DViewport
);
810 TRACE("iface %p, viewport %p.\n", iface
, Direct3DViewport
);
812 return IDirect3DDevice3_AddViewport(&This
->IDirect3DDevice3_iface
, &vp
->IDirect3DViewport3_iface
);
815 /*****************************************************************************
816 * IDirect3DDevice3::DeleteViewport
818 * Deletes a Direct3DViewport from the device's viewport list.
820 * Exists in Version 1, 2 and 3. Note that all Viewport interface versions
824 * Viewport: The viewport to delete
828 * DDERR_INVALIDPARAMS if the viewport wasn't found in the list
830 *****************************************************************************/
831 static HRESULT WINAPI
IDirect3DDeviceImpl_3_DeleteViewport(IDirect3DDevice3
*iface
, IDirect3DViewport3
*viewport
)
833 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
834 struct d3d_viewport
*vp
= unsafe_impl_from_IDirect3DViewport3(viewport
);
836 TRACE("iface %p, viewport %p.\n", iface
, viewport
);
838 wined3d_mutex_lock();
840 if (vp
->active_device
!= This
)
842 WARN("Viewport %p active device is %p.\n", vp
, vp
->active_device
);
843 wined3d_mutex_unlock();
844 return DDERR_INVALIDPARAMS
;
847 vp
->active_device
= NULL
;
848 list_remove(&vp
->entry
);
850 wined3d_mutex_unlock();
855 static HRESULT WINAPI
IDirect3DDeviceImpl_2_DeleteViewport(IDirect3DDevice2
*iface
,
856 IDirect3DViewport2
*Direct3DViewport2
)
858 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
859 struct d3d_viewport
*vp
= unsafe_impl_from_IDirect3DViewport2(Direct3DViewport2
);
861 TRACE("iface %p, viewport %p.\n", iface
, Direct3DViewport2
);
863 return IDirect3DDevice3_DeleteViewport(&This
->IDirect3DDevice3_iface
, &vp
->IDirect3DViewport3_iface
);
866 static HRESULT WINAPI
IDirect3DDeviceImpl_1_DeleteViewport(IDirect3DDevice
*iface
,
867 IDirect3DViewport
*Direct3DViewport
)
869 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
870 struct d3d_viewport
*vp
= unsafe_impl_from_IDirect3DViewport(Direct3DViewport
);
872 TRACE("iface %p, viewport %p.\n", iface
, Direct3DViewport
);
874 return IDirect3DDevice3_DeleteViewport(&This
->IDirect3DDevice3_iface
, &vp
->IDirect3DViewport3_iface
);
877 /*****************************************************************************
878 * IDirect3DDevice3::NextViewport
880 * Returns a viewport from the viewport list, depending on the
881 * passed viewport and the flags.
883 * Exists in Version 1, 2 and 3. Note that all Viewport interface versions
887 * Viewport: Viewport to use for beginning the search
888 * Flags: D3DNEXT_NEXT, D3DNEXT_HEAD or D3DNEXT_TAIL
892 * DDERR_INVALIDPARAMS if the flags were wrong, or Viewport was NULL
894 *****************************************************************************/
895 static HRESULT WINAPI
896 IDirect3DDeviceImpl_3_NextViewport(IDirect3DDevice3
*iface
,
897 IDirect3DViewport3
*Viewport3
,
898 IDirect3DViewport3
**lplpDirect3DViewport3
,
901 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
902 struct d3d_viewport
*vp
= unsafe_impl_from_IDirect3DViewport3(Viewport3
);
903 struct d3d_viewport
*next
;
906 TRACE("iface %p, viewport %p, next %p, flags %#x.\n",
907 iface
, Viewport3
, lplpDirect3DViewport3
, Flags
);
911 *lplpDirect3DViewport3
= NULL
;
912 return DDERR_INVALIDPARAMS
;
916 wined3d_mutex_lock();
920 entry
= list_next(&This
->viewport_list
, &vp
->entry
);
924 entry
= list_head(&This
->viewport_list
);
928 entry
= list_tail(&This
->viewport_list
);
932 WARN("Invalid flags %#x.\n", Flags
);
933 *lplpDirect3DViewport3
= NULL
;
934 wined3d_mutex_unlock();
935 return DDERR_INVALIDPARAMS
;
940 next
= LIST_ENTRY(entry
, struct d3d_viewport
, entry
);
941 *lplpDirect3DViewport3
= &next
->IDirect3DViewport3_iface
;
944 *lplpDirect3DViewport3
= NULL
;
946 wined3d_mutex_unlock();
951 static HRESULT WINAPI
IDirect3DDeviceImpl_2_NextViewport(IDirect3DDevice2
*iface
,
952 IDirect3DViewport2
*Viewport2
, IDirect3DViewport2
**lplpDirect3DViewport2
, DWORD Flags
)
954 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
955 struct d3d_viewport
*vp
= unsafe_impl_from_IDirect3DViewport2(Viewport2
);
956 IDirect3DViewport3
*res
;
959 TRACE("iface %p, viewport %p, next %p, flags %#x.\n",
960 iface
, Viewport2
, lplpDirect3DViewport2
, Flags
);
962 hr
= IDirect3DDevice3_NextViewport(&This
->IDirect3DDevice3_iface
,
963 &vp
->IDirect3DViewport3_iface
, &res
, Flags
);
964 *lplpDirect3DViewport2
= (IDirect3DViewport2
*)res
;
968 static HRESULT WINAPI
IDirect3DDeviceImpl_1_NextViewport(IDirect3DDevice
*iface
,
969 IDirect3DViewport
*Viewport
, IDirect3DViewport
**lplpDirect3DViewport
, DWORD Flags
)
971 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
972 struct d3d_viewport
*vp
= unsafe_impl_from_IDirect3DViewport(Viewport
);
973 IDirect3DViewport3
*res
;
976 TRACE("iface %p, viewport %p, next %p, flags %#x.\n",
977 iface
, Viewport
, lplpDirect3DViewport
, Flags
);
979 hr
= IDirect3DDevice3_NextViewport(&This
->IDirect3DDevice3_iface
,
980 &vp
->IDirect3DViewport3_iface
, &res
, Flags
);
981 *lplpDirect3DViewport
= (IDirect3DViewport
*)res
;
985 /*****************************************************************************
986 * IDirect3DDevice::Pick
988 * Executes an execute buffer without performing rendering. Instead, a
989 * list of primitives that intersect with (x1,y1) of the passed rectangle
990 * is created. IDirect3DDevice::GetPickRecords can be used to retrieve
996 * ExecuteBuffer: Buffer to execute
997 * Viewport: Viewport to use for execution
998 * Flags: None are defined, according to the SDK
999 * Rect: Specifies the coordinates to be picked. Only x1 and y2 are used,
1000 * x2 and y2 are ignored.
1003 * D3D_OK because it's a stub
1005 *****************************************************************************/
1006 static HRESULT WINAPI
1007 IDirect3DDeviceImpl_1_Pick(IDirect3DDevice
*iface
,
1008 IDirect3DExecuteBuffer
*ExecuteBuffer
,
1009 IDirect3DViewport
*Viewport
,
1013 FIXME("iface %p, buffer %p, viewport %p, flags %#x, rect %s stub!\n",
1014 iface
, ExecuteBuffer
, Viewport
, Flags
, wine_dbgstr_rect((RECT
*)Rect
));
1019 /*****************************************************************************
1020 * IDirect3DDevice::GetPickRecords
1022 * Retrieves the pick records generated by IDirect3DDevice::GetPickRecords
1027 * Count: Pointer to a DWORD containing the numbers of pick records to
1029 * D3DPickRec: Address to store the resulting D3DPICKRECORD array.
1032 * D3D_OK, because it's a stub
1034 *****************************************************************************/
1035 static HRESULT WINAPI
1036 IDirect3DDeviceImpl_1_GetPickRecords(IDirect3DDevice
*iface
,
1038 D3DPICKRECORD
*D3DPickRec
)
1040 FIXME("iface %p, count %p, records %p stub!\n", iface
, Count
, D3DPickRec
);
1045 /*****************************************************************************
1046 * IDirect3DDevice7::EnumTextureformats
1048 * Enumerates the supported texture formats. It has a list of all possible
1049 * formats and calls IWineD3D::CheckDeviceFormat for each format to see if
1050 * WineD3D supports it. If so, then it is passed to the app.
1052 * This is for Version 7 and 3, older versions have a different
1053 * callback function and their own implementation
1056 * Callback: Callback to call for each enumerated format
1057 * Arg: Argument to pass to the callback
1061 * DDERR_INVALIDPARAMS if Callback == NULL
1063 *****************************************************************************/
1065 IDirect3DDeviceImpl_7_EnumTextureFormats(IDirect3DDevice7
*iface
,
1066 LPD3DENUMPIXELFORMATSCALLBACK Callback
,
1069 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
1070 struct wined3d_display_mode mode
;
1074 static const enum wined3d_format_id FormatList
[] =
1077 WINED3DFMT_B5G5R5X1_UNORM
,
1078 WINED3DFMT_B5G5R5A1_UNORM
,
1079 WINED3DFMT_B4G4R4A4_UNORM
,
1080 WINED3DFMT_B5G6R5_UNORM
,
1082 WINED3DFMT_B8G8R8X8_UNORM
,
1083 WINED3DFMT_B8G8R8A8_UNORM
,
1085 WINED3DFMT_B2G3R3_UNORM
,
1093 static const enum wined3d_format_id BumpFormatList
[] =
1095 WINED3DFMT_R8G8_SNORM
,
1096 WINED3DFMT_R5G5_SNORM_L6_UNORM
,
1097 WINED3DFMT_R8G8_SNORM_L8X8_UNORM
,
1098 WINED3DFMT_R16G16_SNORM
,
1099 WINED3DFMT_R10G11B11_SNORM
,
1100 WINED3DFMT_R10G10B10_SNORM_A2_UNORM
1103 TRACE("iface %p, callback %p, context %p.\n", iface
, Callback
, Arg
);
1106 return DDERR_INVALIDPARAMS
;
1108 wined3d_mutex_lock();
1110 memset(&mode
, 0, sizeof(mode
));
1111 hr
= wined3d_device_get_display_mode(This
->ddraw
->wined3d_device
, 0, &mode
);
1114 wined3d_mutex_unlock();
1115 WARN("Cannot get the current adapter format\n");
1119 for (i
= 0; i
< sizeof(FormatList
) / sizeof(*FormatList
); ++i
)
1121 hr
= wined3d_check_device_format(This
->ddraw
->wined3d
, WINED3DADAPTER_DEFAULT
, WINED3D_DEVICE_TYPE_HAL
,
1122 mode
.format_id
, 0, WINED3D_RTYPE_TEXTURE
, FormatList
[i
], WINED3D_SURFACE_TYPE_OPENGL
);
1125 DDPIXELFORMAT pformat
;
1127 memset(&pformat
, 0, sizeof(pformat
));
1128 pformat
.dwSize
= sizeof(pformat
);
1129 PixelFormat_WineD3DtoDD(&pformat
, FormatList
[i
]);
1131 TRACE("Enumerating WineD3DFormat %d\n", FormatList
[i
]);
1132 hr
= Callback(&pformat
, Arg
);
1133 if(hr
!= DDENUMRET_OK
)
1135 TRACE("Format enumeration cancelled by application\n");
1136 wined3d_mutex_unlock();
1142 for (i
= 0; i
< sizeof(BumpFormatList
) / sizeof(*BumpFormatList
); ++i
)
1144 hr
= wined3d_check_device_format(This
->ddraw
->wined3d
, WINED3DADAPTER_DEFAULT
,
1145 WINED3D_DEVICE_TYPE_HAL
, mode
.format_id
, WINED3DUSAGE_QUERY_LEGACYBUMPMAP
,
1146 WINED3D_RTYPE_TEXTURE
, BumpFormatList
[i
], WINED3D_SURFACE_TYPE_OPENGL
);
1149 DDPIXELFORMAT pformat
;
1151 memset(&pformat
, 0, sizeof(pformat
));
1152 pformat
.dwSize
= sizeof(pformat
);
1153 PixelFormat_WineD3DtoDD(&pformat
, BumpFormatList
[i
]);
1155 TRACE("Enumerating WineD3DFormat %d\n", BumpFormatList
[i
]);
1156 hr
= Callback(&pformat
, Arg
);
1157 if(hr
!= DDENUMRET_OK
)
1159 TRACE("Format enumeration cancelled by application\n");
1160 wined3d_mutex_unlock();
1165 TRACE("End of enumeration\n");
1166 wined3d_mutex_unlock();
1171 static HRESULT WINAPI
1172 IDirect3DDeviceImpl_7_EnumTextureFormats_FPUSetup(IDirect3DDevice7
*iface
,
1173 LPD3DENUMPIXELFORMATSCALLBACK Callback
,
1176 return IDirect3DDeviceImpl_7_EnumTextureFormats(iface
, Callback
, Arg
);
1179 static HRESULT WINAPI
1180 IDirect3DDeviceImpl_7_EnumTextureFormats_FPUPreserve(IDirect3DDevice7
*iface
,
1181 LPD3DENUMPIXELFORMATSCALLBACK Callback
,
1187 old_fpucw
= d3d_fpu_setup();
1188 hr
= IDirect3DDeviceImpl_7_EnumTextureFormats(iface
, Callback
, Arg
);
1189 set_fpu_control_word(old_fpucw
);
1194 static HRESULT WINAPI
IDirect3DDeviceImpl_3_EnumTextureFormats(IDirect3DDevice3
*iface
,
1195 LPD3DENUMPIXELFORMATSCALLBACK Callback
, void *Arg
)
1197 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
1199 TRACE("iface %p, callback %p, context %p.\n", iface
, Callback
, Arg
);
1201 return IDirect3DDevice7_EnumTextureFormats(&This
->IDirect3DDevice7_iface
, Callback
, Arg
);
1204 /*****************************************************************************
1205 * IDirect3DDevice2::EnumTextureformats
1207 * EnumTextureFormats for Version 1 and 2, see
1208 * IDirect3DDevice7::EnumTexureFormats for a more detailed description.
1210 * This version has a different callback and does not enumerate FourCC
1213 *****************************************************************************/
1214 static HRESULT WINAPI
1215 IDirect3DDeviceImpl_2_EnumTextureFormats(IDirect3DDevice2
*iface
,
1216 LPD3DENUMTEXTUREFORMATSCALLBACK Callback
,
1219 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
1220 struct wined3d_display_mode mode
;
1224 static const enum wined3d_format_id FormatList
[] =
1227 WINED3DFMT_B5G5R5X1_UNORM
,
1228 WINED3DFMT_B5G5R5A1_UNORM
,
1229 WINED3DFMT_B4G4R4A4_UNORM
,
1230 WINED3DFMT_B5G6R5_UNORM
,
1232 WINED3DFMT_B8G8R8X8_UNORM
,
1233 WINED3DFMT_B8G8R8A8_UNORM
,
1235 WINED3DFMT_B2G3R3_UNORM
,
1237 /* FOURCC codes - Not in this version*/
1240 TRACE("iface %p, callback %p, context %p.\n", iface
, Callback
, Arg
);
1243 return DDERR_INVALIDPARAMS
;
1245 wined3d_mutex_lock();
1247 memset(&mode
, 0, sizeof(mode
));
1248 hr
= wined3d_device_get_display_mode(This
->ddraw
->wined3d_device
, 0, &mode
);
1251 wined3d_mutex_unlock();
1252 WARN("Cannot get the current adapter format\n");
1256 for (i
= 0; i
< sizeof(FormatList
) / sizeof(*FormatList
); ++i
)
1258 hr
= wined3d_check_device_format(This
->ddraw
->wined3d
, 0, WINED3D_DEVICE_TYPE_HAL
,
1259 mode
.format_id
, 0, WINED3D_RTYPE_TEXTURE
, FormatList
[i
], WINED3D_SURFACE_TYPE_OPENGL
);
1262 DDSURFACEDESC sdesc
;
1264 memset(&sdesc
, 0, sizeof(sdesc
));
1265 sdesc
.dwSize
= sizeof(sdesc
);
1266 sdesc
.dwFlags
= DDSD_PIXELFORMAT
| DDSD_CAPS
;
1267 sdesc
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
1268 sdesc
.ddpfPixelFormat
.dwSize
= sizeof(sdesc
.ddpfPixelFormat
);
1269 PixelFormat_WineD3DtoDD(&sdesc
.ddpfPixelFormat
, FormatList
[i
]);
1271 TRACE("Enumerating WineD3DFormat %d\n", FormatList
[i
]);
1272 hr
= Callback(&sdesc
, Arg
);
1273 if(hr
!= DDENUMRET_OK
)
1275 TRACE("Format enumeration cancelled by application\n");
1276 wined3d_mutex_unlock();
1281 TRACE("End of enumeration\n");
1282 wined3d_mutex_unlock();
1287 static HRESULT WINAPI
IDirect3DDeviceImpl_1_EnumTextureFormats(IDirect3DDevice
*iface
,
1288 LPD3DENUMTEXTUREFORMATSCALLBACK Callback
, void *Arg
)
1290 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
1292 TRACE("iface %p, callback %p, context %p.\n", iface
, Callback
, Arg
);
1294 return IDirect3DDevice2_EnumTextureFormats(&This
->IDirect3DDevice2_iface
, Callback
, Arg
);
1297 /*****************************************************************************
1298 * IDirect3DDevice::CreateMatrix
1300 * Creates a matrix handle. A handle is created and memory for a D3DMATRIX is
1301 * allocated for the handle.
1306 * D3DMatHandle: Address to return the handle at
1310 * DDERR_INVALIDPARAMS if D3DMatHandle = NULL
1312 *****************************************************************************/
1313 static HRESULT WINAPI
1314 IDirect3DDeviceImpl_1_CreateMatrix(IDirect3DDevice
*iface
, D3DMATRIXHANDLE
*D3DMatHandle
)
1316 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
1320 TRACE("iface %p, matrix_handle %p.\n", iface
, D3DMatHandle
);
1323 return DDERR_INVALIDPARAMS
;
1325 Matrix
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(D3DMATRIX
));
1328 ERR("Out of memory when allocating a D3DMATRIX\n");
1329 return DDERR_OUTOFMEMORY
;
1332 wined3d_mutex_lock();
1334 h
= ddraw_allocate_handle(&This
->handle_table
, Matrix
, DDRAW_HANDLE_MATRIX
);
1335 if (h
== DDRAW_INVALID_HANDLE
)
1337 ERR("Failed to allocate a matrix handle.\n");
1338 HeapFree(GetProcessHeap(), 0, Matrix
);
1339 wined3d_mutex_unlock();
1340 return DDERR_OUTOFMEMORY
;
1343 *D3DMatHandle
= h
+ 1;
1345 TRACE(" returning matrix handle %d\n", *D3DMatHandle
);
1347 wined3d_mutex_unlock();
1352 /*****************************************************************************
1353 * IDirect3DDevice::SetMatrix
1355 * Sets a matrix for a matrix handle. The matrix is copied into the memory
1356 * allocated for the handle
1361 * D3DMatHandle: Handle to set the matrix to
1362 * D3DMatrix: Matrix to set
1366 * DDERR_INVALIDPARAMS if the handle of the matrix is invalid or the matrix
1369 *****************************************************************************/
1370 static HRESULT WINAPI
1371 IDirect3DDeviceImpl_1_SetMatrix(IDirect3DDevice
*iface
,
1372 D3DMATRIXHANDLE D3DMatHandle
,
1373 D3DMATRIX
*D3DMatrix
)
1375 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
1378 TRACE("iface %p, matrix_handle %#x, matrix %p.\n", iface
, D3DMatHandle
, D3DMatrix
);
1380 if (!D3DMatrix
) return DDERR_INVALIDPARAMS
;
1382 wined3d_mutex_lock();
1384 m
= ddraw_get_object(&This
->handle_table
, D3DMatHandle
- 1, DDRAW_HANDLE_MATRIX
);
1387 WARN("Invalid matrix handle.\n");
1388 wined3d_mutex_unlock();
1389 return DDERR_INVALIDPARAMS
;
1392 if (TRACE_ON(ddraw
))
1393 dump_D3DMATRIX(D3DMatrix
);
1397 if (D3DMatHandle
== This
->world
)
1398 wined3d_device_set_transform(This
->wined3d_device
,
1399 WINED3D_TS_WORLD_MATRIX(0), (struct wined3d_matrix
*)D3DMatrix
);
1401 if (D3DMatHandle
== This
->view
)
1402 wined3d_device_set_transform(This
->wined3d_device
,
1403 WINED3D_TS_VIEW
, (struct wined3d_matrix
*)D3DMatrix
);
1405 if (D3DMatHandle
== This
->proj
)
1406 wined3d_device_set_transform(This
->wined3d_device
,
1407 WINED3D_TS_PROJECTION
, (struct wined3d_matrix
*)D3DMatrix
);
1409 wined3d_mutex_unlock();
1414 /*****************************************************************************
1415 * IDirect3DDevice::GetMatrix
1417 * Returns the content of a D3DMATRIX handle
1422 * D3DMatHandle: Matrix handle to read the content from
1423 * D3DMatrix: Address to store the content at
1427 * DDERR_INVALIDPARAMS if D3DMatHandle is invalid or D3DMatrix is NULL
1429 *****************************************************************************/
1430 static HRESULT WINAPI
1431 IDirect3DDeviceImpl_1_GetMatrix(IDirect3DDevice
*iface
,
1432 D3DMATRIXHANDLE D3DMatHandle
,
1433 D3DMATRIX
*D3DMatrix
)
1435 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
1438 TRACE("iface %p, matrix_handle %#x, matrix %p.\n", iface
, D3DMatHandle
, D3DMatrix
);
1440 if (!D3DMatrix
) return DDERR_INVALIDPARAMS
;
1442 wined3d_mutex_lock();
1444 m
= ddraw_get_object(&This
->handle_table
, D3DMatHandle
- 1, DDRAW_HANDLE_MATRIX
);
1447 WARN("Invalid matrix handle.\n");
1448 wined3d_mutex_unlock();
1449 return DDERR_INVALIDPARAMS
;
1454 wined3d_mutex_unlock();
1459 /*****************************************************************************
1460 * IDirect3DDevice::DeleteMatrix
1462 * Destroys a Matrix handle. Frees the memory and unsets the handle data
1467 * D3DMatHandle: Handle to destroy
1471 * DDERR_INVALIDPARAMS if D3DMatHandle is invalid
1473 *****************************************************************************/
1474 static HRESULT WINAPI
1475 IDirect3DDeviceImpl_1_DeleteMatrix(IDirect3DDevice
*iface
,
1476 D3DMATRIXHANDLE D3DMatHandle
)
1478 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
1481 TRACE("iface %p, matrix_handle %#x.\n", iface
, D3DMatHandle
);
1483 wined3d_mutex_lock();
1485 m
= ddraw_free_handle(&This
->handle_table
, D3DMatHandle
- 1, DDRAW_HANDLE_MATRIX
);
1488 WARN("Invalid matrix handle.\n");
1489 wined3d_mutex_unlock();
1490 return DDERR_INVALIDPARAMS
;
1493 wined3d_mutex_unlock();
1495 HeapFree(GetProcessHeap(), 0, m
);
1500 /*****************************************************************************
1501 * IDirect3DDevice7::BeginScene
1503 * This method must be called before any rendering is performed.
1504 * IDirect3DDevice::EndScene has to be called after the scene is complete
1506 * Version 1, 2, 3 and 7
1509 * D3D_OK on success, for details see IWineD3DDevice::BeginScene
1510 * D3DERR_SCENE_IN_SCENE if WineD3D returns an error(Only in case of an already
1513 *****************************************************************************/
1515 IDirect3DDeviceImpl_7_BeginScene(IDirect3DDevice7
*iface
)
1517 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
1520 TRACE("iface %p.\n", iface
);
1522 wined3d_mutex_lock();
1523 hr
= wined3d_device_begin_scene(This
->wined3d_device
);
1524 wined3d_mutex_unlock();
1526 if(hr
== WINED3D_OK
) return D3D_OK
;
1527 else return D3DERR_SCENE_IN_SCENE
; /* TODO: Other possible causes of failure */
1530 static HRESULT WINAPI
1531 IDirect3DDeviceImpl_7_BeginScene_FPUSetup(IDirect3DDevice7
*iface
)
1533 return IDirect3DDeviceImpl_7_BeginScene(iface
);
1536 static HRESULT WINAPI
1537 IDirect3DDeviceImpl_7_BeginScene_FPUPreserve(IDirect3DDevice7
*iface
)
1542 old_fpucw
= d3d_fpu_setup();
1543 hr
= IDirect3DDeviceImpl_7_BeginScene(iface
);
1544 set_fpu_control_word(old_fpucw
);
1549 static HRESULT WINAPI
IDirect3DDeviceImpl_3_BeginScene(IDirect3DDevice3
*iface
)
1551 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
1552 TRACE("iface %p.\n", iface
);
1554 return IDirect3DDevice7_BeginScene(&This
->IDirect3DDevice7_iface
);
1557 static HRESULT WINAPI
IDirect3DDeviceImpl_2_BeginScene(IDirect3DDevice2
*iface
)
1559 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
1560 TRACE("iface %p.\n", iface
);
1562 return IDirect3DDevice7_BeginScene(&This
->IDirect3DDevice7_iface
);
1565 static HRESULT WINAPI
IDirect3DDeviceImpl_1_BeginScene(IDirect3DDevice
*iface
)
1567 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
1568 TRACE("iface %p.\n", iface
);
1570 return IDirect3DDevice7_BeginScene(&This
->IDirect3DDevice7_iface
);
1573 /*****************************************************************************
1574 * IDirect3DDevice7::EndScene
1576 * Ends a scene that has been begun with IDirect3DDevice7::BeginScene.
1577 * This method must be called after rendering is finished.
1579 * Version 1, 2, 3 and 7
1582 * D3D_OK on success, for details see IWineD3DDevice::EndScene
1583 * D3DERR_SCENE_NOT_IN_SCENE is returned if WineD3D returns an error. It does
1584 * that only if the scene was already ended.
1586 *****************************************************************************/
1588 IDirect3DDeviceImpl_7_EndScene(IDirect3DDevice7
*iface
)
1590 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
1593 TRACE("iface %p.\n", iface
);
1595 wined3d_mutex_lock();
1596 hr
= wined3d_device_end_scene(This
->wined3d_device
);
1597 wined3d_mutex_unlock();
1599 if(hr
== WINED3D_OK
) return D3D_OK
;
1600 else return D3DERR_SCENE_NOT_IN_SCENE
;
1603 static HRESULT WINAPI DECLSPEC_HOTPATCH
1604 IDirect3DDeviceImpl_7_EndScene_FPUSetup(IDirect3DDevice7
*iface
)
1606 return IDirect3DDeviceImpl_7_EndScene(iface
);
1609 static HRESULT WINAPI DECLSPEC_HOTPATCH
1610 IDirect3DDeviceImpl_7_EndScene_FPUPreserve(IDirect3DDevice7
*iface
)
1615 old_fpucw
= d3d_fpu_setup();
1616 hr
= IDirect3DDeviceImpl_7_EndScene(iface
);
1617 set_fpu_control_word(old_fpucw
);
1622 static HRESULT WINAPI DECLSPEC_HOTPATCH
IDirect3DDeviceImpl_3_EndScene(IDirect3DDevice3
*iface
)
1624 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
1625 TRACE("iface %p.\n", iface
);
1627 return IDirect3DDevice7_EndScene(&This
->IDirect3DDevice7_iface
);
1630 static HRESULT WINAPI DECLSPEC_HOTPATCH
IDirect3DDeviceImpl_2_EndScene(IDirect3DDevice2
*iface
)
1632 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
1633 TRACE("iface %p.\n", iface
);
1635 return IDirect3DDevice7_EndScene(&This
->IDirect3DDevice7_iface
);
1638 static HRESULT WINAPI DECLSPEC_HOTPATCH
IDirect3DDeviceImpl_1_EndScene(IDirect3DDevice
*iface
)
1640 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
1641 TRACE("iface %p.\n", iface
);
1643 return IDirect3DDevice7_EndScene(&This
->IDirect3DDevice7_iface
);
1646 /*****************************************************************************
1647 * IDirect3DDevice7::GetDirect3D
1649 * Returns the IDirect3D(= interface to the DirectDraw object) used to create
1653 * Direct3D7: Address to store the interface pointer at
1657 * DDERR_INVALIDPARAMS if Direct3D7 == NULL
1659 *****************************************************************************/
1660 static HRESULT WINAPI
1661 IDirect3DDeviceImpl_7_GetDirect3D(IDirect3DDevice7
*iface
,
1662 IDirect3D7
**Direct3D7
)
1664 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
1666 TRACE("iface %p, d3d %p.\n", iface
, Direct3D7
);
1669 return DDERR_INVALIDPARAMS
;
1671 *Direct3D7
= &This
->ddraw
->IDirect3D7_iface
;
1672 IDirect3D7_AddRef(*Direct3D7
);
1674 TRACE(" returning interface %p\n", *Direct3D7
);
1678 static HRESULT WINAPI
IDirect3DDeviceImpl_3_GetDirect3D(IDirect3DDevice3
*iface
,
1679 IDirect3D3
**Direct3D3
)
1681 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
1683 TRACE("iface %p, d3d %p.\n", iface
, Direct3D3
);
1686 return DDERR_INVALIDPARAMS
;
1688 IDirect3D3_AddRef(&This
->ddraw
->IDirect3D3_iface
);
1689 *Direct3D3
= &This
->ddraw
->IDirect3D3_iface
;
1690 TRACE(" returning interface %p\n", *Direct3D3
);
1694 static HRESULT WINAPI
IDirect3DDeviceImpl_2_GetDirect3D(IDirect3DDevice2
*iface
,
1695 IDirect3D2
**Direct3D2
)
1697 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
1699 TRACE("iface %p, d3d %p.\n", iface
, Direct3D2
);
1702 return DDERR_INVALIDPARAMS
;
1704 IDirect3D2_AddRef(&This
->ddraw
->IDirect3D2_iface
);
1705 *Direct3D2
= &This
->ddraw
->IDirect3D2_iface
;
1706 TRACE(" returning interface %p\n", *Direct3D2
);
1710 static HRESULT WINAPI
IDirect3DDeviceImpl_1_GetDirect3D(IDirect3DDevice
*iface
,
1711 IDirect3D
**Direct3D
)
1713 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice(iface
);
1715 TRACE("iface %p, d3d %p.\n", iface
, Direct3D
);
1718 return DDERR_INVALIDPARAMS
;
1720 IDirect3D_AddRef(&This
->ddraw
->IDirect3D_iface
);
1721 *Direct3D
= &This
->ddraw
->IDirect3D_iface
;
1722 TRACE(" returning interface %p\n", *Direct3D
);
1726 /*****************************************************************************
1727 * IDirect3DDevice3::SetCurrentViewport
1729 * Sets a Direct3DViewport as the current viewport.
1730 * For the thunks note that all viewport interface versions are equal
1733 * Direct3DViewport3: The viewport to set
1739 * (Is a NULL viewport valid?)
1741 *****************************************************************************/
1742 static HRESULT WINAPI
1743 IDirect3DDeviceImpl_3_SetCurrentViewport(IDirect3DDevice3
*iface
,
1744 IDirect3DViewport3
*Direct3DViewport3
)
1746 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
1747 struct d3d_viewport
*vp
= unsafe_impl_from_IDirect3DViewport3(Direct3DViewport3
);
1749 TRACE("iface %p, viewport %p.\n", iface
, Direct3DViewport3
);
1751 wined3d_mutex_lock();
1752 /* Do nothing if the specified viewport is the same as the current one */
1753 if (This
->current_viewport
== vp
)
1755 wined3d_mutex_unlock();
1759 if (vp
->active_device
!= This
)
1761 WARN("Viewport %p active device is %p.\n", vp
, vp
->active_device
);
1762 wined3d_mutex_unlock();
1763 return DDERR_INVALIDPARAMS
;
1766 /* Release previous viewport and AddRef the new one */
1767 if (This
->current_viewport
)
1769 TRACE("ViewportImpl is at %p, interface is at %p\n", This
->current_viewport
,
1770 &This
->current_viewport
->IDirect3DViewport3_iface
);
1771 IDirect3DViewport3_Release(&This
->current_viewport
->IDirect3DViewport3_iface
);
1773 IDirect3DViewport3_AddRef(Direct3DViewport3
);
1775 /* Set this viewport as the current viewport */
1776 This
->current_viewport
= vp
;
1778 /* Activate this viewport */
1779 viewport_activate(This
->current_viewport
, FALSE
);
1781 wined3d_mutex_unlock();
1786 static HRESULT WINAPI
IDirect3DDeviceImpl_2_SetCurrentViewport(IDirect3DDevice2
*iface
,
1787 IDirect3DViewport2
*Direct3DViewport2
)
1789 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
1790 struct d3d_viewport
*vp
= unsafe_impl_from_IDirect3DViewport2(Direct3DViewport2
);
1792 TRACE("iface %p, viewport %p.\n", iface
, Direct3DViewport2
);
1794 return IDirect3DDevice3_SetCurrentViewport(&This
->IDirect3DDevice3_iface
,
1795 &vp
->IDirect3DViewport3_iface
);
1798 /*****************************************************************************
1799 * IDirect3DDevice3::GetCurrentViewport
1801 * Returns the currently active viewport.
1806 * Direct3DViewport3: Address to return the interface pointer at
1810 * DDERR_INVALIDPARAMS if Direct3DViewport == NULL
1812 *****************************************************************************/
1813 static HRESULT WINAPI
1814 IDirect3DDeviceImpl_3_GetCurrentViewport(IDirect3DDevice3
*iface
,
1815 IDirect3DViewport3
**Direct3DViewport3
)
1817 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
1819 TRACE("iface %p, viewport %p.\n", iface
, Direct3DViewport3
);
1821 if(!Direct3DViewport3
)
1822 return DDERR_INVALIDPARAMS
;
1824 wined3d_mutex_lock();
1825 *Direct3DViewport3
= &This
->current_viewport
->IDirect3DViewport3_iface
;
1827 /* AddRef the returned viewport */
1828 if(*Direct3DViewport3
) IDirect3DViewport3_AddRef(*Direct3DViewport3
);
1830 TRACE(" returning interface %p\n", *Direct3DViewport3
);
1832 wined3d_mutex_unlock();
1837 static HRESULT WINAPI
IDirect3DDeviceImpl_2_GetCurrentViewport(IDirect3DDevice2
*iface
,
1838 IDirect3DViewport2
**Direct3DViewport2
)
1840 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
1843 TRACE("iface %p, viewport %p.\n", iface
, Direct3DViewport2
);
1845 hr
= IDirect3DDevice3_GetCurrentViewport(&This
->IDirect3DDevice3_iface
,
1846 (IDirect3DViewport3
**)Direct3DViewport2
);
1847 if(hr
!= D3D_OK
) return hr
;
1851 /*****************************************************************************
1852 * IDirect3DDevice7::SetRenderTarget
1854 * Sets the render target for the Direct3DDevice.
1855 * For the thunks note that IDirectDrawSurface7 == IDirectDrawSurface4 and
1856 * IDirectDrawSurface3 == IDirectDrawSurface
1858 * Version 2, 3 and 7
1861 * NewTarget: Pointer to an IDirectDrawSurface7 interface to set as the new
1866 * D3D_OK on success, for details see IWineD3DDevice::SetRenderTarget
1868 *****************************************************************************/
1869 static HRESULT
d3d_device_set_render_target(IDirect3DDeviceImpl
*This
, struct ddraw_surface
*target
)
1873 wined3d_mutex_lock();
1875 if (This
->target
== target
)
1877 TRACE("No-op SetRenderTarget operation, not doing anything\n");
1878 wined3d_mutex_unlock();
1881 This
->target
= target
;
1882 hr
= wined3d_device_set_render_target(This
->wined3d_device
, 0,
1883 target
? target
->wined3d_surface
: NULL
, FALSE
);
1886 wined3d_mutex_unlock();
1889 IDirect3DDeviceImpl_UpdateDepthStencil(This
);
1891 wined3d_mutex_unlock();
1897 IDirect3DDeviceImpl_7_SetRenderTarget(IDirect3DDevice7
*iface
,
1898 IDirectDrawSurface7
*NewTarget
,
1901 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
1902 struct ddraw_surface
*target
= unsafe_impl_from_IDirectDrawSurface7(NewTarget
);
1904 TRACE("iface %p, target %p, flags %#x.\n", iface
, NewTarget
, Flags
);
1905 /* Flags: Not used */
1907 IDirectDrawSurface7_AddRef(NewTarget
);
1908 IDirectDrawSurface7_Release(&This
->target
->IDirectDrawSurface7_iface
);
1909 return d3d_device_set_render_target(This
, target
);
1912 static HRESULT WINAPI
1913 IDirect3DDeviceImpl_7_SetRenderTarget_FPUSetup(IDirect3DDevice7
*iface
,
1914 IDirectDrawSurface7
*NewTarget
,
1917 return IDirect3DDeviceImpl_7_SetRenderTarget(iface
, NewTarget
, Flags
);
1920 static HRESULT WINAPI
1921 IDirect3DDeviceImpl_7_SetRenderTarget_FPUPreserve(IDirect3DDevice7
*iface
,
1922 IDirectDrawSurface7
*NewTarget
,
1928 old_fpucw
= d3d_fpu_setup();
1929 hr
= IDirect3DDeviceImpl_7_SetRenderTarget(iface
, NewTarget
, Flags
);
1930 set_fpu_control_word(old_fpucw
);
1935 static HRESULT WINAPI
IDirect3DDeviceImpl_3_SetRenderTarget(IDirect3DDevice3
*iface
,
1936 IDirectDrawSurface4
*NewRenderTarget
, DWORD Flags
)
1938 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
1939 struct ddraw_surface
*target
= unsafe_impl_from_IDirectDrawSurface4(NewRenderTarget
);
1941 TRACE("iface %p, target %p, flags %#x.\n", iface
, NewRenderTarget
, Flags
);
1943 IDirectDrawSurface4_AddRef(NewRenderTarget
);
1944 IDirectDrawSurface4_Release(&This
->target
->IDirectDrawSurface4_iface
);
1945 return d3d_device_set_render_target(This
, target
);
1948 static HRESULT WINAPI
IDirect3DDeviceImpl_2_SetRenderTarget(IDirect3DDevice2
*iface
,
1949 IDirectDrawSurface
*NewRenderTarget
, DWORD Flags
)
1951 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
1952 struct ddraw_surface
*target
= unsafe_impl_from_IDirectDrawSurface(NewRenderTarget
);
1954 TRACE("iface %p, target %p, flags %#x.\n", iface
, NewRenderTarget
, Flags
);
1956 IDirectDrawSurface_AddRef(NewRenderTarget
);
1957 IDirectDrawSurface_Release(&This
->target
->IDirectDrawSurface_iface
);
1958 return d3d_device_set_render_target(This
, target
);
1961 /*****************************************************************************
1962 * IDirect3DDevice7::GetRenderTarget
1964 * Returns the current render target.
1965 * This is handled locally, because the WineD3D render target's parent
1968 * Version 2, 3 and 7
1971 * RenderTarget: Address to store the surface interface pointer
1975 * DDERR_INVALIDPARAMS if RenderTarget == NULL
1977 *****************************************************************************/
1978 static HRESULT WINAPI
1979 IDirect3DDeviceImpl_7_GetRenderTarget(IDirect3DDevice7
*iface
,
1980 IDirectDrawSurface7
**RenderTarget
)
1982 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
1984 TRACE("iface %p, target %p.\n", iface
, RenderTarget
);
1987 return DDERR_INVALIDPARAMS
;
1989 wined3d_mutex_lock();
1990 *RenderTarget
= &This
->target
->IDirectDrawSurface7_iface
;
1991 IDirectDrawSurface7_AddRef(*RenderTarget
);
1992 wined3d_mutex_unlock();
1997 static HRESULT WINAPI
IDirect3DDeviceImpl_3_GetRenderTarget(IDirect3DDevice3
*iface
,
1998 IDirectDrawSurface4
**RenderTarget
)
2000 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
2001 IDirectDrawSurface7
*RenderTarget7
;
2002 struct ddraw_surface
*RenderTargetImpl
;
2005 TRACE("iface %p, target %p.\n", iface
, RenderTarget
);
2008 return DDERR_INVALIDPARAMS
;
2010 hr
= IDirect3DDevice7_GetRenderTarget(&This
->IDirect3DDevice7_iface
, &RenderTarget7
);
2011 if(hr
!= D3D_OK
) return hr
;
2012 RenderTargetImpl
= impl_from_IDirectDrawSurface7(RenderTarget7
);
2013 *RenderTarget
= &RenderTargetImpl
->IDirectDrawSurface4_iface
;
2014 IDirectDrawSurface4_AddRef(*RenderTarget
);
2015 IDirectDrawSurface7_Release(RenderTarget7
);
2019 static HRESULT WINAPI
IDirect3DDeviceImpl_2_GetRenderTarget(IDirect3DDevice2
*iface
,
2020 IDirectDrawSurface
**RenderTarget
)
2022 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
2023 IDirectDrawSurface7
*RenderTarget7
;
2024 struct ddraw_surface
*RenderTargetImpl
;
2027 TRACE("iface %p, target %p.\n", iface
, RenderTarget
);
2030 return DDERR_INVALIDPARAMS
;
2032 hr
= IDirect3DDevice7_GetRenderTarget(&This
->IDirect3DDevice7_iface
, &RenderTarget7
);
2033 if(hr
!= D3D_OK
) return hr
;
2034 RenderTargetImpl
= impl_from_IDirectDrawSurface7(RenderTarget7
);
2035 *RenderTarget
= &RenderTargetImpl
->IDirectDrawSurface_iface
;
2036 IDirectDrawSurface_AddRef(*RenderTarget
);
2037 IDirectDrawSurface7_Release(RenderTarget7
);
2041 /*****************************************************************************
2042 * IDirect3DDevice3::Begin
2044 * Begins a description block of vertices. This is similar to glBegin()
2045 * and glEnd(). After a call to IDirect3DDevice3::End, the vertices
2046 * described with IDirect3DDevice::Vertex are drawn.
2051 * PrimitiveType: The type of primitives to draw
2052 * VertexTypeDesc: A flexible vertex format description of the vertices
2053 * Flags: Some flags..
2058 *****************************************************************************/
2059 static HRESULT WINAPI
2060 IDirect3DDeviceImpl_3_Begin(IDirect3DDevice3
*iface
,
2061 D3DPRIMITIVETYPE PrimitiveType
,
2062 DWORD VertexTypeDesc
,
2065 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
2067 TRACE("iface %p, primitive_type %#x, FVF %#x, flags %#x.\n",
2068 iface
, PrimitiveType
, VertexTypeDesc
, Flags
);
2070 wined3d_mutex_lock();
2071 This
->primitive_type
= PrimitiveType
;
2072 This
->vertex_type
= VertexTypeDesc
;
2073 This
->render_flags
= Flags
;
2074 This
->vertex_size
= get_flexible_vertex_size(This
->vertex_type
);
2075 This
->nb_vertices
= 0;
2076 wined3d_mutex_unlock();
2081 static HRESULT WINAPI
IDirect3DDeviceImpl_2_Begin(IDirect3DDevice2
*iface
, D3DPRIMITIVETYPE d3dpt
,
2082 D3DVERTEXTYPE dwVertexTypeDesc
, DWORD dwFlags
)
2085 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
2087 TRACE("iface %p, primitive_type %#x, vertex_type %#x, flags %#x.\n",
2088 iface
, d3dpt
, dwVertexTypeDesc
, dwFlags
);
2090 switch(dwVertexTypeDesc
)
2092 case D3DVT_VERTEX
: FVF
= D3DFVF_VERTEX
; break;
2093 case D3DVT_LVERTEX
: FVF
= D3DFVF_LVERTEX
; break;
2094 case D3DVT_TLVERTEX
: FVF
= D3DFVF_TLVERTEX
; break;
2096 ERR("Unexpected vertex type %d\n", dwVertexTypeDesc
);
2097 return DDERR_INVALIDPARAMS
; /* Should never happen */
2100 return IDirect3DDevice3_Begin(&This
->IDirect3DDevice3_iface
, d3dpt
, FVF
, dwFlags
);
2103 /*****************************************************************************
2104 * IDirect3DDevice3::BeginIndexed
2106 * Draws primitives based on vertices in a vertex array which are specified
2112 * PrimitiveType: Primitive type to draw
2113 * VertexType: A FVF description of the vertex format
2114 * Vertices: pointer to an array containing the vertices
2115 * NumVertices: The number of vertices in the vertex array
2116 * Flags: Some flags ...
2119 * D3D_OK, because it's a stub
2121 *****************************************************************************/
2122 static HRESULT WINAPI
2123 IDirect3DDeviceImpl_3_BeginIndexed(IDirect3DDevice3
*iface
,
2124 D3DPRIMITIVETYPE PrimitiveType
,
2130 FIXME("iface %p, primitive_type %#x, FVF %#x, vertices %p, vertex_count %u, flags %#x stub!\n",
2131 iface
, PrimitiveType
, VertexType
, Vertices
, NumVertices
, Flags
);
2137 static HRESULT WINAPI
IDirect3DDeviceImpl_2_BeginIndexed(IDirect3DDevice2
*iface
,
2138 D3DPRIMITIVETYPE d3dptPrimitiveType
, D3DVERTEXTYPE d3dvtVertexType
,
2139 void *lpvVertices
, DWORD dwNumVertices
, DWORD dwFlags
)
2142 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
2144 TRACE("iface %p, primitive_type %#x, vertex_type %#x, vertices %p, vertex_count %u, flags %#x stub!\n",
2145 iface
, d3dptPrimitiveType
, d3dvtVertexType
, lpvVertices
, dwNumVertices
, dwFlags
);
2147 switch(d3dvtVertexType
)
2149 case D3DVT_VERTEX
: FVF
= D3DFVF_VERTEX
; break;
2150 case D3DVT_LVERTEX
: FVF
= D3DFVF_LVERTEX
; break;
2151 case D3DVT_TLVERTEX
: FVF
= D3DFVF_TLVERTEX
; break;
2153 ERR("Unexpected vertex type %d\n", d3dvtVertexType
);
2154 return DDERR_INVALIDPARAMS
; /* Should never happen */
2157 return IDirect3DDevice3_BeginIndexed(&This
->IDirect3DDevice3_iface
,
2158 d3dptPrimitiveType
, FVF
, lpvVertices
, dwNumVertices
, dwFlags
);
2161 /*****************************************************************************
2162 * IDirect3DDevice3::Vertex
2164 * Draws a vertex as described by IDirect3DDevice3::Begin. It places all
2165 * drawn vertices in a vertex buffer. If the buffer is too small, its
2166 * size is increased.
2171 * Vertex: Pointer to the vertex
2174 * D3D_OK, on success
2175 * DDERR_INVALIDPARAMS if Vertex is NULL
2177 *****************************************************************************/
2178 static HRESULT WINAPI
2179 IDirect3DDeviceImpl_3_Vertex(IDirect3DDevice3
*iface
,
2182 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
2184 TRACE("iface %p, vertex %p.\n", iface
, Vertex
);
2187 return DDERR_INVALIDPARAMS
;
2189 wined3d_mutex_lock();
2190 if ((This
->nb_vertices
+1)*This
->vertex_size
> This
->buffer_size
)
2193 This
->buffer_size
= This
->buffer_size
? This
->buffer_size
* 2 : This
->vertex_size
* 3;
2194 old_buffer
= This
->vertex_buffer
;
2195 This
->vertex_buffer
= HeapAlloc(GetProcessHeap(), 0, This
->buffer_size
);
2198 CopyMemory(This
->vertex_buffer
, old_buffer
, This
->nb_vertices
* This
->vertex_size
);
2199 HeapFree(GetProcessHeap(), 0, old_buffer
);
2203 CopyMemory(This
->vertex_buffer
+ This
->nb_vertices
++ * This
->vertex_size
, Vertex
, This
->vertex_size
);
2204 wined3d_mutex_unlock();
2209 static HRESULT WINAPI
IDirect3DDeviceImpl_2_Vertex(IDirect3DDevice2
*iface
, void *lpVertexType
)
2211 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
2213 TRACE("iface %p, vertex %p.\n", iface
, lpVertexType
);
2215 return IDirect3DDevice3_Vertex(&This
->IDirect3DDevice3_iface
, lpVertexType
);
2218 /*****************************************************************************
2219 * IDirect3DDevice3::Index
2221 * Specifies an index to a vertex to be drawn. The vertex array has to
2222 * be specified with BeginIndexed first.
2225 * VertexIndex: The index of the vertex to draw
2228 * D3D_OK because it's a stub
2230 *****************************************************************************/
2231 static HRESULT WINAPI
2232 IDirect3DDeviceImpl_3_Index(IDirect3DDevice3
*iface
,
2235 FIXME("iface %p, index %#x stub!\n", iface
, VertexIndex
);
2240 static HRESULT WINAPI
IDirect3DDeviceImpl_2_Index(IDirect3DDevice2
*iface
, WORD wVertexIndex
)
2242 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
2244 TRACE("iface %p, index %#x.\n", iface
, wVertexIndex
);
2246 return IDirect3DDevice3_Index(&This
->IDirect3DDevice3_iface
, wVertexIndex
);
2249 /*****************************************************************************
2250 * IDirect3DDevice3::End
2252 * Ends a draw begun with IDirect3DDevice3::Begin or
2253 * IDirect3DDevice::BeginIndexed. The vertices specified with
2254 * IDirect3DDevice::Vertex or IDirect3DDevice::Index are drawn using
2255 * the IDirect3DDevice7::DrawPrimitive method. So far only
2256 * non-indexed mode is supported
2261 * Flags: Some flags, as usual. Don't know which are defined
2264 * The return value of IDirect3DDevice7::DrawPrimitive
2266 *****************************************************************************/
2267 static HRESULT WINAPI
2268 IDirect3DDeviceImpl_3_End(IDirect3DDevice3
*iface
,
2271 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
2273 TRACE("iface %p, flags %#x.\n", iface
, Flags
);
2275 return IDirect3DDevice7_DrawPrimitive(&This
->IDirect3DDevice7_iface
, This
->primitive_type
,
2276 This
->vertex_type
, This
->vertex_buffer
, This
->nb_vertices
, This
->render_flags
);
2279 static HRESULT WINAPI
IDirect3DDeviceImpl_2_End(IDirect3DDevice2
*iface
, DWORD dwFlags
)
2281 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
2283 TRACE("iface %p, flags %#x.\n", iface
, dwFlags
);
2285 return IDirect3DDevice3_End(&This
->IDirect3DDevice3_iface
, dwFlags
);
2288 /*****************************************************************************
2289 * IDirect3DDevice7::GetRenderState
2291 * Returns the value of a render state. The possible render states are
2292 * defined in include/d3dtypes.h
2294 * Version 2, 3 and 7
2297 * RenderStateType: Render state to return the current setting of
2298 * Value: Address to store the value at
2301 * D3D_OK on success, for details see IWineD3DDevice::GetRenderState
2302 * DDERR_INVALIDPARAMS if Value == NULL
2304 *****************************************************************************/
2305 static HRESULT
IDirect3DDeviceImpl_7_GetRenderState(IDirect3DDevice7
*iface
,
2306 D3DRENDERSTATETYPE RenderStateType
, DWORD
*Value
)
2308 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
2311 TRACE("iface %p, state %#x, value %p.\n", iface
, RenderStateType
, Value
);
2314 return DDERR_INVALIDPARAMS
;
2316 wined3d_mutex_lock();
2317 switch(RenderStateType
)
2319 case D3DRENDERSTATE_TEXTUREMAG
:
2321 enum wined3d_texture_filter_type tex_mag
;
2323 hr
= wined3d_device_get_sampler_state(This
->wined3d_device
, 0, WINED3D_SAMP_MAG_FILTER
, &tex_mag
);
2327 case WINED3D_TEXF_POINT
:
2328 *Value
= D3DFILTER_NEAREST
;
2330 case WINED3D_TEXF_LINEAR
:
2331 *Value
= D3DFILTER_LINEAR
;
2334 ERR("Unhandled texture mag %d !\n",tex_mag
);
2340 case D3DRENDERSTATE_TEXTUREMIN
:
2342 enum wined3d_texture_filter_type tex_min
;
2343 enum wined3d_texture_filter_type tex_mip
;
2345 hr
= wined3d_device_get_sampler_state(This
->wined3d_device
,
2346 0, WINED3D_SAMP_MIN_FILTER
, &tex_min
);
2349 wined3d_mutex_unlock();
2352 hr
= wined3d_device_get_sampler_state(This
->wined3d_device
,
2353 0, WINED3D_SAMP_MIP_FILTER
, &tex_mip
);
2357 case WINED3D_TEXF_POINT
:
2360 case WINED3D_TEXF_NONE
:
2361 *Value
= D3DFILTER_NEAREST
;
2363 case WINED3D_TEXF_POINT
:
2364 *Value
= D3DFILTER_MIPNEAREST
;
2366 case WINED3D_TEXF_LINEAR
:
2367 *Value
= D3DFILTER_LINEARMIPNEAREST
;
2370 ERR("Unhandled mip filter %#x.\n", tex_mip
);
2371 *Value
= D3DFILTER_NEAREST
;
2375 case WINED3D_TEXF_LINEAR
:
2378 case WINED3D_TEXF_NONE
:
2379 *Value
= D3DFILTER_LINEAR
;
2381 case WINED3D_TEXF_POINT
:
2382 *Value
= D3DFILTER_MIPLINEAR
;
2384 case WINED3D_TEXF_LINEAR
:
2385 *Value
= D3DFILTER_LINEARMIPLINEAR
;
2388 ERR("Unhandled mip filter %#x.\n", tex_mip
);
2389 *Value
= D3DFILTER_LINEAR
;
2394 ERR("Unhandled texture min filter %#x.\n",tex_min
);
2395 *Value
= D3DFILTER_NEAREST
;
2401 case D3DRENDERSTATE_TEXTUREADDRESS
:
2402 case D3DRENDERSTATE_TEXTUREADDRESSU
:
2403 hr
= wined3d_device_get_sampler_state(This
->wined3d_device
,
2404 0, WINED3D_SAMP_ADDRESS_U
, Value
);
2406 case D3DRENDERSTATE_TEXTUREADDRESSV
:
2407 hr
= wined3d_device_get_sampler_state(This
->wined3d_device
,
2408 0, WINED3D_SAMP_ADDRESS_V
, Value
);
2411 case D3DRENDERSTATE_BORDERCOLOR
:
2412 FIXME("Unhandled render state D3DRENDERSTATE_BORDERCOLOR.\n");
2416 case D3DRENDERSTATE_TEXTUREHANDLE
:
2417 case D3DRENDERSTATE_TEXTUREMAPBLEND
:
2418 WARN("Render state %#x is invalid in d3d7.\n", RenderStateType
);
2419 hr
= DDERR_INVALIDPARAMS
;
2422 case D3DRENDERSTATE_ZBIAS
:
2423 hr
= wined3d_device_get_render_state(This
->wined3d_device
, WINED3D_RS_DEPTHBIAS
, Value
);
2427 if (RenderStateType
>= D3DRENDERSTATE_STIPPLEPATTERN00
2428 && RenderStateType
<= D3DRENDERSTATE_STIPPLEPATTERN31
)
2430 FIXME("Unhandled stipple pattern render state (%#x).\n",
2435 hr
= wined3d_device_get_render_state(This
->wined3d_device
, RenderStateType
, Value
);
2437 wined3d_mutex_unlock();
2442 static HRESULT WINAPI
2443 IDirect3DDeviceImpl_7_GetRenderState_FPUSetup(IDirect3DDevice7
*iface
,
2444 D3DRENDERSTATETYPE RenderStateType
,
2447 return IDirect3DDeviceImpl_7_GetRenderState(iface
, RenderStateType
, Value
);
2450 static HRESULT WINAPI
2451 IDirect3DDeviceImpl_7_GetRenderState_FPUPreserve(IDirect3DDevice7
*iface
,
2452 D3DRENDERSTATETYPE RenderStateType
,
2458 old_fpucw
= d3d_fpu_setup();
2459 hr
= IDirect3DDeviceImpl_7_GetRenderState(iface
, RenderStateType
, Value
);
2460 set_fpu_control_word(old_fpucw
);
2465 static HRESULT WINAPI
2466 IDirect3DDeviceImpl_3_GetRenderState(IDirect3DDevice3
*iface
,
2467 D3DRENDERSTATETYPE dwRenderStateType
,
2468 DWORD
*lpdwRenderState
)
2470 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
2473 TRACE("iface %p, state %#x, value %p.\n", iface
, dwRenderStateType
, lpdwRenderState
);
2475 switch(dwRenderStateType
)
2477 case D3DRENDERSTATE_TEXTUREHANDLE
:
2479 /* This state is wrapped to SetTexture in SetRenderState, so
2480 * it has to be wrapped to GetTexture here. */
2481 struct wined3d_texture
*tex
= NULL
;
2482 *lpdwRenderState
= 0;
2484 wined3d_mutex_lock();
2485 hr
= wined3d_device_get_texture(This
->wined3d_device
, 0, &tex
);
2486 if (SUCCEEDED(hr
) && tex
)
2488 /* The parent of the texture is the IDirectDrawSurface7
2489 * interface of the ddraw surface. */
2490 struct ddraw_surface
*parent
= wined3d_texture_get_parent(tex
);
2491 if (parent
) *lpdwRenderState
= parent
->Handle
;
2492 wined3d_texture_decref(tex
);
2494 wined3d_mutex_unlock();
2499 case D3DRENDERSTATE_TEXTUREMAPBLEND
:
2501 /* D3DRENDERSTATE_TEXTUREMAPBLEND is mapped to texture state stages in SetRenderState; reverse
2502 the mapping to get the value. */
2503 DWORD colorop
, colorarg1
, colorarg2
;
2504 DWORD alphaop
, alphaarg1
, alphaarg2
;
2506 wined3d_mutex_lock();
2508 This
->legacyTextureBlending
= TRUE
;
2510 wined3d_device_get_texture_stage_state(This
->wined3d_device
, 0, WINED3D_TSS_COLOR_OP
, &colorop
);
2511 wined3d_device_get_texture_stage_state(This
->wined3d_device
, 0, WINED3D_TSS_COLOR_ARG1
, &colorarg1
);
2512 wined3d_device_get_texture_stage_state(This
->wined3d_device
, 0, WINED3D_TSS_COLOR_ARG2
, &colorarg2
);
2513 wined3d_device_get_texture_stage_state(This
->wined3d_device
, 0, WINED3D_TSS_ALPHA_OP
, &alphaop
);
2514 wined3d_device_get_texture_stage_state(This
->wined3d_device
, 0, WINED3D_TSS_ALPHA_ARG1
, &alphaarg1
);
2515 wined3d_device_get_texture_stage_state(This
->wined3d_device
, 0, WINED3D_TSS_ALPHA_ARG2
, &alphaarg2
);
2517 if (colorop
== WINED3D_TOP_SELECT_ARG1
&& colorarg1
== WINED3DTA_TEXTURE
2518 && alphaop
== WINED3D_TOP_SELECT_ARG1
&& alphaarg1
== WINED3DTA_TEXTURE
)
2519 *lpdwRenderState
= D3DTBLEND_DECAL
;
2520 else if (colorop
== WINED3D_TOP_SELECT_ARG1
&& colorarg1
== WINED3DTA_TEXTURE
2521 && alphaop
== WINED3D_TOP_MODULATE
2522 && alphaarg1
== WINED3DTA_TEXTURE
&& alphaarg2
== WINED3DTA_CURRENT
)
2523 *lpdwRenderState
= D3DTBLEND_DECALALPHA
;
2524 else if (colorop
== WINED3D_TOP_MODULATE
2525 && colorarg1
== WINED3DTA_TEXTURE
&& colorarg2
== WINED3DTA_CURRENT
2526 && alphaop
== WINED3D_TOP_MODULATE
2527 && alphaarg1
== WINED3DTA_TEXTURE
&& alphaarg2
== WINED3DTA_CURRENT
)
2528 *lpdwRenderState
= D3DTBLEND_MODULATEALPHA
;
2531 struct wined3d_texture
*tex
= NULL
;
2533 BOOL tex_alpha
= FALSE
;
2534 DDPIXELFORMAT ddfmt
;
2536 hr
= wined3d_device_get_texture(This
->wined3d_device
, 0, &tex
);
2538 if(hr
== WINED3D_OK
&& tex
)
2540 struct wined3d_resource
*sub_resource
;
2542 if ((sub_resource
= wined3d_texture_get_sub_resource(tex
, 0)))
2544 struct wined3d_resource_desc desc
;
2546 wined3d_resource_get_desc(sub_resource
, &desc
);
2547 ddfmt
.dwSize
= sizeof(ddfmt
);
2548 PixelFormat_WineD3DtoDD(&ddfmt
, desc
.format
);
2549 if (ddfmt
.u5
.dwRGBAlphaBitMask
) tex_alpha
= TRUE
;
2552 wined3d_texture_decref(tex
);
2555 if (!(colorop
== WINED3D_TOP_MODULATE
2556 && colorarg1
== WINED3DTA_TEXTURE
&& colorarg2
== WINED3DTA_CURRENT
2557 && alphaop
== (tex_alpha
? WINED3D_TOP_SELECT_ARG1
: WINED3D_TOP_SELECT_ARG2
)
2558 && alphaarg1
== WINED3DTA_TEXTURE
&& alphaarg2
== WINED3DTA_CURRENT
))
2559 ERR("Unexpected texture stage state setup, returning D3DTBLEND_MODULATE - likely erroneous.\n");
2561 *lpdwRenderState
= D3DTBLEND_MODULATE
;
2564 wined3d_mutex_unlock();
2570 return IDirect3DDevice7_GetRenderState(&This
->IDirect3DDevice7_iface
, dwRenderStateType
, lpdwRenderState
);
2574 static HRESULT WINAPI
IDirect3DDeviceImpl_2_GetRenderState(IDirect3DDevice2
*iface
,
2575 D3DRENDERSTATETYPE dwRenderStateType
, DWORD
*lpdwRenderState
)
2577 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
2579 TRACE("iface %p, state %#x, value %p.\n", iface
, dwRenderStateType
, lpdwRenderState
);
2581 return IDirect3DDevice3_GetRenderState(&This
->IDirect3DDevice3_iface
,
2582 dwRenderStateType
, lpdwRenderState
);
2585 /*****************************************************************************
2586 * IDirect3DDevice7::SetRenderState
2588 * Sets a render state. The possible render states are defined in
2589 * include/d3dtypes.h
2591 * Version 2, 3 and 7
2594 * RenderStateType: State to set
2595 * Value: Value to assign to that state
2598 * D3D_OK on success,
2599 * for details see IWineD3DDevice::SetRenderState
2601 *****************************************************************************/
2603 IDirect3DDeviceImpl_7_SetRenderState(IDirect3DDevice7
*iface
,
2604 D3DRENDERSTATETYPE RenderStateType
,
2607 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
2610 TRACE("iface %p, state %#x, value %#x.\n", iface
, RenderStateType
, Value
);
2612 wined3d_mutex_lock();
2613 /* Some render states need special care */
2614 switch(RenderStateType
)
2617 * The ddraw texture filter mapping works like this:
2618 * D3DFILTER_NEAREST Point min/mag, no mip
2619 * D3DFILTER_MIPNEAREST Point min/mag, point mip
2620 * D3DFILTER_LINEARMIPNEAREST: Point min/mag, linear mip
2622 * D3DFILTER_LINEAR Linear min/mag, no mip
2623 * D3DFILTER_MIPLINEAR Linear min/mag, point mip
2624 * D3DFILTER_LINEARMIPLINEAR Linear min/mag, linear mip
2626 * This is the opposite of the GL naming convention,
2627 * D3DFILTER_LINEARMIPNEAREST corresponds to GL_NEAREST_MIPMAP_LINEAR.
2629 case D3DRENDERSTATE_TEXTUREMAG
:
2631 enum wined3d_texture_filter_type tex_mag
;
2635 case D3DFILTER_NEAREST
:
2636 case D3DFILTER_MIPNEAREST
:
2637 case D3DFILTER_LINEARMIPNEAREST
:
2638 tex_mag
= WINED3D_TEXF_POINT
;
2640 case D3DFILTER_LINEAR
:
2641 case D3DFILTER_MIPLINEAR
:
2642 case D3DFILTER_LINEARMIPLINEAR
:
2643 tex_mag
= WINED3D_TEXF_LINEAR
;
2646 tex_mag
= WINED3D_TEXF_POINT
;
2647 ERR("Unhandled texture mag %d !\n",Value
);
2651 hr
= wined3d_device_set_sampler_state(This
->wined3d_device
, 0, WINED3D_SAMP_MAG_FILTER
, tex_mag
);
2655 case D3DRENDERSTATE_TEXTUREMIN
:
2657 enum wined3d_texture_filter_type tex_min
;
2658 enum wined3d_texture_filter_type tex_mip
;
2660 switch ((D3DTEXTUREFILTER
)Value
)
2662 case D3DFILTER_NEAREST
:
2663 tex_min
= WINED3D_TEXF_POINT
;
2664 tex_mip
= WINED3D_TEXF_NONE
;
2666 case D3DFILTER_LINEAR
:
2667 tex_min
= WINED3D_TEXF_LINEAR
;
2668 tex_mip
= WINED3D_TEXF_NONE
;
2670 case D3DFILTER_MIPNEAREST
:
2671 tex_min
= WINED3D_TEXF_POINT
;
2672 tex_mip
= WINED3D_TEXF_POINT
;
2674 case D3DFILTER_MIPLINEAR
:
2675 tex_min
= WINED3D_TEXF_LINEAR
;
2676 tex_mip
= WINED3D_TEXF_POINT
;
2678 case D3DFILTER_LINEARMIPNEAREST
:
2679 tex_min
= WINED3D_TEXF_POINT
;
2680 tex_mip
= WINED3D_TEXF_LINEAR
;
2682 case D3DFILTER_LINEARMIPLINEAR
:
2683 tex_min
= WINED3D_TEXF_LINEAR
;
2684 tex_mip
= WINED3D_TEXF_LINEAR
;
2688 ERR("Unhandled texture min %d !\n",Value
);
2689 tex_min
= WINED3D_TEXF_POINT
;
2690 tex_mip
= WINED3D_TEXF_NONE
;
2694 wined3d_device_set_sampler_state(This
->wined3d_device
,
2695 0, WINED3D_SAMP_MIP_FILTER
, tex_mip
);
2696 hr
= wined3d_device_set_sampler_state(This
->wined3d_device
,
2697 0, WINED3D_SAMP_MIN_FILTER
, tex_min
);
2701 case D3DRENDERSTATE_TEXTUREADDRESS
:
2702 wined3d_device_set_sampler_state(This
->wined3d_device
,
2703 0, WINED3D_SAMP_ADDRESS_V
, Value
);
2705 case D3DRENDERSTATE_TEXTUREADDRESSU
:
2706 hr
= wined3d_device_set_sampler_state(This
->wined3d_device
,
2707 0, WINED3D_SAMP_ADDRESS_U
, Value
);
2709 case D3DRENDERSTATE_TEXTUREADDRESSV
:
2710 hr
= wined3d_device_set_sampler_state(This
->wined3d_device
,
2711 0, WINED3D_SAMP_ADDRESS_V
, Value
);
2714 case D3DRENDERSTATE_BORDERCOLOR
:
2715 /* This should probably just forward to the corresponding sampler
2716 * state. Needs tests. */
2717 FIXME("Unhandled render state D3DRENDERSTATE_BORDERCOLOR.\n");
2721 case D3DRENDERSTATE_TEXTUREHANDLE
:
2722 case D3DRENDERSTATE_TEXTUREMAPBLEND
:
2723 WARN("Render state %#x is invalid in d3d7.\n", RenderStateType
);
2724 hr
= DDERR_INVALIDPARAMS
;
2727 case D3DRENDERSTATE_ZBIAS
:
2728 hr
= wined3d_device_set_render_state(This
->wined3d_device
, WINED3D_RS_DEPTHBIAS
, Value
);
2732 if (RenderStateType
>= D3DRENDERSTATE_STIPPLEPATTERN00
2733 && RenderStateType
<= D3DRENDERSTATE_STIPPLEPATTERN31
)
2735 FIXME("Unhandled stipple pattern render state (%#x).\n",
2741 hr
= wined3d_device_set_render_state(This
->wined3d_device
, RenderStateType
, Value
);
2744 wined3d_mutex_unlock();
2749 static HRESULT WINAPI
2750 IDirect3DDeviceImpl_7_SetRenderState_FPUSetup(IDirect3DDevice7
*iface
,
2751 D3DRENDERSTATETYPE RenderStateType
,
2754 return IDirect3DDeviceImpl_7_SetRenderState(iface
, RenderStateType
, Value
);
2757 static HRESULT WINAPI
2758 IDirect3DDeviceImpl_7_SetRenderState_FPUPreserve(IDirect3DDevice7
*iface
,
2759 D3DRENDERSTATETYPE RenderStateType
,
2765 old_fpucw
= d3d_fpu_setup();
2766 hr
= IDirect3DDeviceImpl_7_SetRenderState(iface
, RenderStateType
, Value
);
2767 set_fpu_control_word(old_fpucw
);
2772 static HRESULT WINAPI
2773 IDirect3DDeviceImpl_3_SetRenderState(IDirect3DDevice3
*iface
,
2774 D3DRENDERSTATETYPE RenderStateType
,
2777 /* Note about D3DRENDERSTATE_TEXTUREMAPBLEND implementation: most of values
2778 for this state can be directly mapped to texture stage colorop and alphaop, but
2779 D3DTBLEND_MODULATE is tricky: it uses alpha from texture when available and alpha
2780 from diffuse otherwise. So changing the texture must be monitored in SetTexture to modify
2781 alphaarg when needed.
2783 Aliens vs Predator 1 depends on accurate D3DTBLEND_MODULATE emulation
2785 Legacy texture blending (TEXTUREMAPBLEND) and texture stage states: directx6 docs state that
2786 TEXTUREMAPBLEND is deprecated, yet can still be used. Games must not use both or results
2787 are undefined. D3DTBLEND_MODULATE mode in particular is dependent on texture pixel format and
2788 requires fixup of stage 0 texture states when texture changes, but this fixup can interfere
2789 with games not using this deprecated state. So a flag 'legacyTextureBlending' has to be kept
2790 in device - TRUE if the app is using TEXTUREMAPBLEND.
2792 Tests show that setting TEXTUREMAPBLEND on native doesn't seem to change values returned by
2793 GetTextureStageState and vice versa. Not so on Wine, but it is 'undefined' anyway so, probably, ok,
2794 unless some broken game will be found that cares. */
2797 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
2799 TRACE("iface %p, state %#x, value %#x.\n", iface
, RenderStateType
, Value
);
2801 wined3d_mutex_lock();
2803 switch(RenderStateType
)
2805 case D3DRENDERSTATE_TEXTUREHANDLE
:
2807 struct ddraw_surface
*surf
;
2811 hr
= wined3d_device_set_texture(This
->wined3d_device
, 0, NULL
);
2815 surf
= ddraw_get_object(&This
->handle_table
, Value
- 1, DDRAW_HANDLE_SURFACE
);
2818 WARN("Invalid texture handle.\n");
2819 hr
= DDERR_INVALIDPARAMS
;
2823 hr
= IDirect3DDevice3_SetTexture(iface
, 0, &surf
->IDirect3DTexture2_iface
);
2827 case D3DRENDERSTATE_TEXTUREMAPBLEND
:
2829 This
->legacyTextureBlending
= TRUE
;
2831 switch ( (D3DTEXTUREBLEND
) Value
)
2833 case D3DTBLEND_MODULATE
:
2835 struct wined3d_texture
*tex
= NULL
;
2836 BOOL tex_alpha
= FALSE
;
2837 DDPIXELFORMAT ddfmt
;
2839 hr
= wined3d_device_get_texture(This
->wined3d_device
, 0, &tex
);
2841 if(hr
== WINED3D_OK
&& tex
)
2843 struct wined3d_resource
*sub_resource
;
2845 if ((sub_resource
= wined3d_texture_get_sub_resource(tex
, 0)))
2847 struct wined3d_resource_desc desc
;
2849 wined3d_resource_get_desc(sub_resource
, &desc
);
2850 ddfmt
.dwSize
= sizeof(ddfmt
);
2851 PixelFormat_WineD3DtoDD(&ddfmt
, desc
.format
);
2852 if (ddfmt
.u5
.dwRGBAlphaBitMask
) tex_alpha
= TRUE
;
2855 wined3d_texture_decref(tex
);
2859 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2860 0, WINED3D_TSS_ALPHA_OP
, WINED3D_TOP_SELECT_ARG1
);
2862 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2863 0, WINED3D_TSS_ALPHA_OP
, WINED3D_TOP_SELECT_ARG2
);
2864 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2865 0, WINED3D_TSS_ALPHA_ARG1
, WINED3DTA_TEXTURE
);
2866 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2867 0, WINED3D_TSS_ALPHA_ARG2
, WINED3DTA_CURRENT
);
2868 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2869 0, WINED3D_TSS_COLOR_ARG1
, WINED3DTA_TEXTURE
);
2870 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2871 0, WINED3D_TSS_COLOR_ARG2
, WINED3DTA_CURRENT
);
2872 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2873 0, WINED3D_TSS_COLOR_OP
, WINED3D_TOP_MODULATE
);
2878 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2879 0, WINED3D_TSS_COLOR_OP
, WINED3D_TOP_ADD
);
2880 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2881 0, WINED3D_TSS_COLOR_ARG1
, WINED3DTA_TEXTURE
);
2882 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2883 0, WINED3D_TSS_COLOR_ARG2
, WINED3DTA_CURRENT
);
2884 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2885 0, WINED3D_TSS_ALPHA_OP
, WINED3D_TOP_SELECT_ARG2
);
2886 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2887 0, WINED3D_TSS_ALPHA_ARG2
, WINED3DTA_CURRENT
);
2890 case D3DTBLEND_MODULATEALPHA
:
2891 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2892 0, WINED3D_TSS_COLOR_ARG1
, WINED3DTA_TEXTURE
);
2893 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2894 0, WINED3D_TSS_ALPHA_ARG1
, WINED3DTA_TEXTURE
);
2895 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2896 0, WINED3D_TSS_COLOR_ARG2
, WINED3DTA_CURRENT
);
2897 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2898 0, WINED3D_TSS_ALPHA_ARG2
, WINED3DTA_CURRENT
);
2899 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2900 0, WINED3D_TSS_COLOR_OP
, WINED3D_TOP_MODULATE
);
2901 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2902 0, WINED3D_TSS_ALPHA_OP
, WINED3D_TOP_MODULATE
);
2905 case D3DTBLEND_COPY
:
2906 case D3DTBLEND_DECAL
:
2907 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2908 0, WINED3D_TSS_COLOR_ARG1
, WINED3DTA_TEXTURE
);
2909 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2910 0, WINED3D_TSS_ALPHA_ARG1
, WINED3DTA_TEXTURE
);
2911 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2912 0, WINED3D_TSS_COLOR_OP
, WINED3D_TOP_SELECT_ARG1
);
2913 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2914 0, WINED3D_TSS_ALPHA_OP
, WINED3D_TOP_SELECT_ARG1
);
2917 case D3DTBLEND_DECALALPHA
:
2918 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2919 0, WINED3D_TSS_COLOR_OP
, WINED3D_TOP_BLEND_TEXTURE_ALPHA
);
2920 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2921 0, WINED3D_TSS_COLOR_ARG1
, WINED3DTA_TEXTURE
);
2922 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2923 0, WINED3D_TSS_COLOR_ARG2
, WINED3DTA_CURRENT
);
2924 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2925 0, WINED3D_TSS_ALPHA_OP
, WINED3D_TOP_SELECT_ARG2
);
2926 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
2927 0, WINED3D_TSS_ALPHA_ARG2
, WINED3DTA_CURRENT
);
2931 ERR("Unhandled texture environment %d !\n",Value
);
2939 hr
= IDirect3DDevice7_SetRenderState(&This
->IDirect3DDevice7_iface
, RenderStateType
, Value
);
2942 wined3d_mutex_unlock();
2947 static HRESULT WINAPI
IDirect3DDeviceImpl_2_SetRenderState(IDirect3DDevice2
*iface
,
2948 D3DRENDERSTATETYPE RenderStateType
, DWORD Value
)
2950 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
2952 TRACE("iface %p, state %#x, value %#x.\n", iface
, RenderStateType
, Value
);
2954 return IDirect3DDevice3_SetRenderState(&This
->IDirect3DDevice3_iface
, RenderStateType
, Value
);
2957 /*****************************************************************************
2958 * Direct3DDevice3::SetLightState
2960 * Sets a light state for Direct3DDevice3 and Direct3DDevice2. The
2961 * light states are forwarded to Direct3DDevice7 render states
2966 * LightStateType: The light state to change
2967 * Value: The value to assign to that light state
2971 * DDERR_INVALIDPARAMS if the parameters were incorrect
2972 * Also check IDirect3DDevice7::SetRenderState
2974 *****************************************************************************/
2975 static HRESULT WINAPI
2976 IDirect3DDeviceImpl_3_SetLightState(IDirect3DDevice3
*iface
,
2977 D3DLIGHTSTATETYPE LightStateType
,
2980 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
2983 TRACE("iface %p, state %#x, value %#x.\n", iface
, LightStateType
, Value
);
2985 if (!LightStateType
|| (LightStateType
> D3DLIGHTSTATE_COLORVERTEX
))
2987 TRACE("Unexpected Light State Type\n");
2988 return DDERR_INVALIDPARAMS
;
2991 wined3d_mutex_lock();
2992 if (LightStateType
== D3DLIGHTSTATE_MATERIAL
/* 1 */)
2994 struct d3d_material
*m
= ddraw_get_object(&This
->handle_table
, Value
- 1, DDRAW_HANDLE_MATERIAL
);
2997 WARN("Invalid material handle.\n");
2998 wined3d_mutex_unlock();
2999 return DDERR_INVALIDPARAMS
;
3002 TRACE(" activating material %p.\n", m
);
3003 material_activate(m
);
3005 This
->material
= Value
;
3007 else if (LightStateType
== D3DLIGHTSTATE_COLORMODEL
/* 3 */)
3012 ERR("DDCOLOR_MONO should not happen!\n");
3015 /* We are already in this mode */
3016 TRACE("Setting color model to RGB (no-op).\n");
3019 ERR("Unknown color model!\n");
3020 wined3d_mutex_unlock();
3021 return DDERR_INVALIDPARAMS
;
3026 D3DRENDERSTATETYPE rs
;
3027 switch (LightStateType
)
3029 case D3DLIGHTSTATE_AMBIENT
: /* 2 */
3030 rs
= D3DRENDERSTATE_AMBIENT
;
3032 case D3DLIGHTSTATE_FOGMODE
: /* 4 */
3033 rs
= D3DRENDERSTATE_FOGVERTEXMODE
;
3035 case D3DLIGHTSTATE_FOGSTART
: /* 5 */
3036 rs
= D3DRENDERSTATE_FOGSTART
;
3038 case D3DLIGHTSTATE_FOGEND
: /* 6 */
3039 rs
= D3DRENDERSTATE_FOGEND
;
3041 case D3DLIGHTSTATE_FOGDENSITY
: /* 7 */
3042 rs
= D3DRENDERSTATE_FOGDENSITY
;
3044 case D3DLIGHTSTATE_COLORVERTEX
: /* 8 */
3045 rs
= D3DRENDERSTATE_COLORVERTEX
;
3048 ERR("Unknown D3DLIGHTSTATETYPE %d.\n", LightStateType
);
3049 wined3d_mutex_unlock();
3050 return DDERR_INVALIDPARAMS
;
3053 hr
= IDirect3DDevice7_SetRenderState(&This
->IDirect3DDevice7_iface
, rs
, Value
);
3054 wined3d_mutex_unlock();
3057 wined3d_mutex_unlock();
3062 static HRESULT WINAPI
IDirect3DDeviceImpl_2_SetLightState(IDirect3DDevice2
*iface
,
3063 D3DLIGHTSTATETYPE LightStateType
, DWORD Value
)
3065 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
3067 TRACE("iface %p, state %#x, value %#x.\n", iface
, LightStateType
, Value
);
3069 return IDirect3DDevice3_SetLightState(&This
->IDirect3DDevice3_iface
, LightStateType
, Value
);
3072 /*****************************************************************************
3073 * IDirect3DDevice3::GetLightState
3075 * Returns the current setting of a light state. The state is read from
3076 * the Direct3DDevice7 render state.
3081 * LightStateType: The light state to return
3082 * Value: The address to store the light state setting at
3086 * DDDERR_INVALIDPARAMS if the parameters were incorrect
3087 * Also see IDirect3DDevice7::GetRenderState
3089 *****************************************************************************/
3090 static HRESULT WINAPI
3091 IDirect3DDeviceImpl_3_GetLightState(IDirect3DDevice3
*iface
,
3092 D3DLIGHTSTATETYPE LightStateType
,
3095 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
3098 TRACE("iface %p, state %#x, value %p.\n", iface
, LightStateType
, Value
);
3100 if (!LightStateType
|| (LightStateType
> D3DLIGHTSTATE_COLORVERTEX
))
3102 TRACE("Unexpected Light State Type\n");
3103 return DDERR_INVALIDPARAMS
;
3107 return DDERR_INVALIDPARAMS
;
3109 wined3d_mutex_lock();
3110 if (LightStateType
== D3DLIGHTSTATE_MATERIAL
/* 1 */)
3112 *Value
= This
->material
;
3114 else if (LightStateType
== D3DLIGHTSTATE_COLORMODEL
/* 3 */)
3116 *Value
= D3DCOLOR_RGB
;
3120 D3DRENDERSTATETYPE rs
;
3121 switch (LightStateType
)
3123 case D3DLIGHTSTATE_AMBIENT
: /* 2 */
3124 rs
= D3DRENDERSTATE_AMBIENT
;
3126 case D3DLIGHTSTATE_FOGMODE
: /* 4 */
3127 rs
= D3DRENDERSTATE_FOGVERTEXMODE
;
3129 case D3DLIGHTSTATE_FOGSTART
: /* 5 */
3130 rs
= D3DRENDERSTATE_FOGSTART
;
3132 case D3DLIGHTSTATE_FOGEND
: /* 6 */
3133 rs
= D3DRENDERSTATE_FOGEND
;
3135 case D3DLIGHTSTATE_FOGDENSITY
: /* 7 */
3136 rs
= D3DRENDERSTATE_FOGDENSITY
;
3138 case D3DLIGHTSTATE_COLORVERTEX
: /* 8 */
3139 rs
= D3DRENDERSTATE_COLORVERTEX
;
3142 ERR("Unknown D3DLIGHTSTATETYPE %d.\n", LightStateType
);
3143 wined3d_mutex_unlock();
3144 return DDERR_INVALIDPARAMS
;
3147 hr
= IDirect3DDevice7_GetRenderState(&This
->IDirect3DDevice7_iface
, rs
, Value
);
3148 wined3d_mutex_unlock();
3151 wined3d_mutex_unlock();
3156 static HRESULT WINAPI
IDirect3DDeviceImpl_2_GetLightState(IDirect3DDevice2
*iface
,
3157 D3DLIGHTSTATETYPE LightStateType
, DWORD
*Value
)
3159 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
3161 TRACE("iface %p, state %#x, value %p.\n", iface
, LightStateType
, Value
);
3163 return IDirect3DDevice3_GetLightState(&This
->IDirect3DDevice3_iface
, LightStateType
, Value
);
3166 /*****************************************************************************
3167 * IDirect3DDevice7::SetTransform
3169 * Assigns a D3DMATRIX to a transform type. The transform types are defined
3170 * in include/d3dtypes.h.
3171 * The D3DTRANSFORMSTATE_WORLD (=1) is translated to D3DTS_WORLDMATRIX(0)
3172 * (=255) for wined3d, because the 1 transform state was removed in d3d8
3173 * and WineD3D already understands the replacement D3DTS_WORLDMATRIX(0)
3175 * Version 2, 3 and 7
3178 * TransformStateType: transform state to set
3179 * Matrix: Matrix to assign to the state
3183 * DDERR_INVALIDPARAMS if Matrix == NULL
3184 * For details see IWineD3DDevice::SetTransform
3186 *****************************************************************************/
3188 IDirect3DDeviceImpl_7_SetTransform(IDirect3DDevice7
*iface
,
3189 D3DTRANSFORMSTATETYPE TransformStateType
,
3192 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
3193 D3DTRANSFORMSTATETYPE type
;
3196 TRACE("iface %p, state %#x, matrix %p.\n", iface
, TransformStateType
, Matrix
);
3198 switch (TransformStateType
)
3200 case D3DTRANSFORMSTATE_WORLD
:
3201 type
= WINED3D_TS_WORLD_MATRIX(0);
3203 case D3DTRANSFORMSTATE_WORLD1
:
3204 type
= WINED3D_TS_WORLD_MATRIX(1);
3206 case D3DTRANSFORMSTATE_WORLD2
:
3207 type
= WINED3D_TS_WORLD_MATRIX(2);
3209 case D3DTRANSFORMSTATE_WORLD3
:
3210 type
= WINED3D_TS_WORLD_MATRIX(3);
3213 type
= TransformStateType
;
3217 return DDERR_INVALIDPARAMS
;
3219 /* Note: D3DMATRIX is compatible with struct wined3d_matrix. */
3220 wined3d_mutex_lock();
3221 hr
= wined3d_device_set_transform(This
->wined3d_device
, type
, (struct wined3d_matrix
*)Matrix
);
3222 wined3d_mutex_unlock();
3227 static HRESULT WINAPI
3228 IDirect3DDeviceImpl_7_SetTransform_FPUSetup(IDirect3DDevice7
*iface
,
3229 D3DTRANSFORMSTATETYPE TransformStateType
,
3232 return IDirect3DDeviceImpl_7_SetTransform(iface
, TransformStateType
, Matrix
);
3235 static HRESULT WINAPI
3236 IDirect3DDeviceImpl_7_SetTransform_FPUPreserve(IDirect3DDevice7
*iface
,
3237 D3DTRANSFORMSTATETYPE TransformStateType
,
3243 old_fpucw
= d3d_fpu_setup();
3244 hr
= IDirect3DDeviceImpl_7_SetTransform(iface
, TransformStateType
, Matrix
);
3245 set_fpu_control_word(old_fpucw
);
3250 static HRESULT WINAPI
IDirect3DDeviceImpl_3_SetTransform(IDirect3DDevice3
*iface
,
3251 D3DTRANSFORMSTATETYPE state
, D3DMATRIX
*matrix
)
3253 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
3255 TRACE("iface %p, state %#x, matrix %p.\n", iface
, state
, matrix
);
3258 return DDERR_INVALIDPARAMS
;
3260 if (state
== D3DTRANSFORMSTATE_PROJECTION
)
3262 D3DMATRIX projection
;
3265 wined3d_mutex_lock();
3266 multiply_matrix(&projection
, &This
->legacy_clipspace
, matrix
);
3267 hr
= wined3d_device_set_transform(This
->wined3d_device
,
3268 WINED3D_TS_PROJECTION
, (struct wined3d_matrix
*)&projection
);
3270 This
->legacy_projection
= *matrix
;
3271 wined3d_mutex_unlock();
3276 return IDirect3DDevice7_SetTransform(&This
->IDirect3DDevice7_iface
, state
, matrix
);
3279 static HRESULT WINAPI
IDirect3DDeviceImpl_2_SetTransform(IDirect3DDevice2
*iface
,
3280 D3DTRANSFORMSTATETYPE TransformStateType
, D3DMATRIX
*D3DMatrix
)
3282 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
3284 TRACE("iface %p, state %#x, matrix %p.\n", iface
, TransformStateType
, D3DMatrix
);
3286 return IDirect3DDevice7_SetTransform(&This
->IDirect3DDevice7_iface
, TransformStateType
, D3DMatrix
);
3289 /*****************************************************************************
3290 * IDirect3DDevice7::GetTransform
3292 * Returns the matrix assigned to a transform state
3293 * D3DTRANSFORMSTATE_WORLD is translated to D3DTS_WORLDMATRIX(0), see
3297 * TransformStateType: State to read the matrix from
3298 * Matrix: Address to store the matrix at
3302 * DDERR_INVALIDPARAMS if Matrix == NULL
3303 * For details, see IWineD3DDevice::GetTransform
3305 *****************************************************************************/
3307 IDirect3DDeviceImpl_7_GetTransform(IDirect3DDevice7
*iface
,
3308 D3DTRANSFORMSTATETYPE TransformStateType
,
3311 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
3312 D3DTRANSFORMSTATETYPE type
;
3315 TRACE("iface %p, state %#x, matrix %p.\n", iface
, TransformStateType
, Matrix
);
3317 switch(TransformStateType
)
3319 case D3DTRANSFORMSTATE_WORLD
:
3320 type
= WINED3D_TS_WORLD_MATRIX(0);
3322 case D3DTRANSFORMSTATE_WORLD1
:
3323 type
= WINED3D_TS_WORLD_MATRIX(1);
3325 case D3DTRANSFORMSTATE_WORLD2
:
3326 type
= WINED3D_TS_WORLD_MATRIX(2);
3328 case D3DTRANSFORMSTATE_WORLD3
:
3329 type
= WINED3D_TS_WORLD_MATRIX(3);
3332 type
= TransformStateType
;
3336 return DDERR_INVALIDPARAMS
;
3338 /* Note: D3DMATRIX is compatible with struct wined3d_matrix. */
3339 wined3d_mutex_lock();
3340 hr
= wined3d_device_get_transform(This
->wined3d_device
, type
, (struct wined3d_matrix
*)Matrix
);
3341 wined3d_mutex_unlock();
3346 static HRESULT WINAPI
3347 IDirect3DDeviceImpl_7_GetTransform_FPUSetup(IDirect3DDevice7
*iface
,
3348 D3DTRANSFORMSTATETYPE TransformStateType
,
3351 return IDirect3DDeviceImpl_7_GetTransform(iface
, TransformStateType
, Matrix
);
3354 static HRESULT WINAPI
3355 IDirect3DDeviceImpl_7_GetTransform_FPUPreserve(IDirect3DDevice7
*iface
,
3356 D3DTRANSFORMSTATETYPE TransformStateType
,
3362 old_fpucw
= d3d_fpu_setup();
3363 hr
= IDirect3DDeviceImpl_7_GetTransform(iface
, TransformStateType
, Matrix
);
3364 set_fpu_control_word(old_fpucw
);
3369 static HRESULT WINAPI
IDirect3DDeviceImpl_3_GetTransform(IDirect3DDevice3
*iface
,
3370 D3DTRANSFORMSTATETYPE state
, D3DMATRIX
*matrix
)
3372 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
3374 TRACE("iface %p, state %#x, matrix %p.\n", iface
, state
, matrix
);
3377 return DDERR_INVALIDPARAMS
;
3379 if (state
== D3DTRANSFORMSTATE_PROJECTION
)
3381 wined3d_mutex_lock();
3382 *matrix
= This
->legacy_projection
;
3383 wined3d_mutex_unlock();
3387 return IDirect3DDevice7_GetTransform(&This
->IDirect3DDevice7_iface
, state
, matrix
);
3390 static HRESULT WINAPI
IDirect3DDeviceImpl_2_GetTransform(IDirect3DDevice2
*iface
,
3391 D3DTRANSFORMSTATETYPE TransformStateType
, D3DMATRIX
*D3DMatrix
)
3393 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
3395 TRACE("iface %p, state %#x, matrix %p.\n", iface
, TransformStateType
, D3DMatrix
);
3397 return IDirect3DDevice7_GetTransform(&This
->IDirect3DDevice7_iface
, TransformStateType
, D3DMatrix
);
3400 /*****************************************************************************
3401 * IDirect3DDevice7::MultiplyTransform
3403 * Multiplies the already-set transform matrix of a transform state
3404 * with another matrix. For the world matrix, see SetTransform
3406 * Version 2, 3 and 7
3409 * TransformStateType: Transform state to multiply
3410 * D3DMatrix Matrix to multiply with.
3414 * DDERR_INVALIDPARAMS if D3DMatrix is NULL
3415 * For details, see IWineD3DDevice::MultiplyTransform
3417 *****************************************************************************/
3419 IDirect3DDeviceImpl_7_MultiplyTransform(IDirect3DDevice7
*iface
,
3420 D3DTRANSFORMSTATETYPE TransformStateType
,
3421 D3DMATRIX
*D3DMatrix
)
3423 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
3425 D3DTRANSFORMSTATETYPE type
;
3427 TRACE("iface %p, state %#x, matrix %p.\n", iface
, TransformStateType
, D3DMatrix
);
3429 switch(TransformStateType
)
3431 case D3DTRANSFORMSTATE_WORLD
:
3432 type
= WINED3D_TS_WORLD_MATRIX(0);
3434 case D3DTRANSFORMSTATE_WORLD1
:
3435 type
= WINED3D_TS_WORLD_MATRIX(1);
3437 case D3DTRANSFORMSTATE_WORLD2
:
3438 type
= WINED3D_TS_WORLD_MATRIX(2);
3440 case D3DTRANSFORMSTATE_WORLD3
:
3441 type
= WINED3D_TS_WORLD_MATRIX(3);
3444 type
= TransformStateType
;
3447 /* Note: D3DMATRIX is compatible with struct wined3d_matrix. */
3448 wined3d_mutex_lock();
3449 hr
= wined3d_device_multiply_transform(This
->wined3d_device
,
3450 type
, (struct wined3d_matrix
*)D3DMatrix
);
3451 wined3d_mutex_unlock();
3456 static HRESULT WINAPI
3457 IDirect3DDeviceImpl_7_MultiplyTransform_FPUSetup(IDirect3DDevice7
*iface
,
3458 D3DTRANSFORMSTATETYPE TransformStateType
,
3459 D3DMATRIX
*D3DMatrix
)
3461 return IDirect3DDeviceImpl_7_MultiplyTransform(iface
, TransformStateType
, D3DMatrix
);
3464 static HRESULT WINAPI
3465 IDirect3DDeviceImpl_7_MultiplyTransform_FPUPreserve(IDirect3DDevice7
*iface
,
3466 D3DTRANSFORMSTATETYPE TransformStateType
,
3467 D3DMATRIX
*D3DMatrix
)
3472 old_fpucw
= d3d_fpu_setup();
3473 hr
= IDirect3DDeviceImpl_7_MultiplyTransform(iface
, TransformStateType
, D3DMatrix
);
3474 set_fpu_control_word(old_fpucw
);
3479 static HRESULT WINAPI
IDirect3DDeviceImpl_3_MultiplyTransform(IDirect3DDevice3
*iface
,
3480 D3DTRANSFORMSTATETYPE state
, D3DMATRIX
*matrix
)
3482 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
3484 TRACE("iface %p, state %#x, matrix %p.\n", iface
, state
, matrix
);
3486 if (state
== D3DTRANSFORMSTATE_PROJECTION
)
3488 D3DMATRIX projection
, tmp
;
3491 wined3d_mutex_lock();
3492 multiply_matrix(&tmp
, &This
->legacy_projection
, matrix
);
3493 multiply_matrix(&projection
, &This
->legacy_clipspace
, &tmp
);
3494 hr
= wined3d_device_set_transform(This
->wined3d_device
,
3495 WINED3D_TS_PROJECTION
, (struct wined3d_matrix
*)&projection
);
3497 This
->legacy_projection
= tmp
;
3498 wined3d_mutex_unlock();
3503 return IDirect3DDevice7_MultiplyTransform(&This
->IDirect3DDevice7_iface
, state
, matrix
);
3506 static HRESULT WINAPI
IDirect3DDeviceImpl_2_MultiplyTransform(IDirect3DDevice2
*iface
,
3507 D3DTRANSFORMSTATETYPE TransformStateType
, D3DMATRIX
*D3DMatrix
)
3509 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
3511 TRACE("iface %p, state %#x, matrix %p.\n", iface
, TransformStateType
, D3DMatrix
);
3513 return IDirect3DDevice7_MultiplyTransform(&This
->IDirect3DDevice7_iface
, TransformStateType
, D3DMatrix
);
3516 /*****************************************************************************
3517 * IDirect3DDevice7::DrawPrimitive
3519 * Draws primitives based on vertices in an application-provided pointer
3521 * Version 2, 3 and 7. The IDirect3DDevice2 thunk converts the fixed vertex type into
3522 * an FVF format for D3D7
3525 * PrimitiveType: The type of the primitives to draw
3526 * Vertex type: Flexible vertex format vertex description
3527 * Vertices: Pointer to the vertex array
3528 * VertexCount: The number of vertices to draw
3529 * Flags: As usual a few flags
3533 * DDERR_INVALIDPARAMS if Vertices is NULL
3534 * For details, see IWineD3DDevice::DrawPrimitiveUP
3536 *****************************************************************************/
3538 IDirect3DDeviceImpl_7_DrawPrimitive(IDirect3DDevice7
*iface
,
3539 D3DPRIMITIVETYPE PrimitiveType
,
3545 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
3549 TRACE("iface %p, primitive_type %#x, FVF %#x, vertices %p, vertex_count %u, flags %#x.\n",
3550 iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Flags
);
3553 return DDERR_INVALIDPARAMS
;
3555 /* Get the stride */
3556 stride
= get_flexible_vertex_size(VertexType
);
3559 wined3d_mutex_lock();
3560 hr
= wined3d_device_set_vertex_declaration(This
->wined3d_device
, ddraw_find_decl(This
->ddraw
, VertexType
));
3563 wined3d_mutex_unlock();
3567 /* This method translates to the user pointer draw of WineD3D */
3568 wined3d_device_set_primitive_type(This
->wined3d_device
, PrimitiveType
);
3569 hr
= wined3d_device_draw_primitive_up(This
->wined3d_device
, VertexCount
, Vertices
, stride
);
3570 wined3d_mutex_unlock();
3575 static HRESULT WINAPI
3576 IDirect3DDeviceImpl_7_DrawPrimitive_FPUSetup(IDirect3DDevice7
*iface
,
3577 D3DPRIMITIVETYPE PrimitiveType
,
3583 return IDirect3DDeviceImpl_7_DrawPrimitive(iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Flags
);
3586 static HRESULT WINAPI
3587 IDirect3DDeviceImpl_7_DrawPrimitive_FPUPreserve(IDirect3DDevice7
*iface
,
3588 D3DPRIMITIVETYPE PrimitiveType
,
3597 old_fpucw
= d3d_fpu_setup();
3598 hr
= IDirect3DDeviceImpl_7_DrawPrimitive(iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Flags
);
3599 set_fpu_control_word(old_fpucw
);
3604 static HRESULT WINAPI
IDirect3DDeviceImpl_3_DrawPrimitive(IDirect3DDevice3
*iface
,
3605 D3DPRIMITIVETYPE PrimitiveType
, DWORD VertexType
, void *Vertices
, DWORD VertexCount
,
3608 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
3609 TRACE("iface %p, primitive_type %#x, FVF %#x, vertices %p, vertex_count %u, flags %#x.\n",
3610 iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Flags
);
3612 return IDirect3DDevice7_DrawPrimitive(&This
->IDirect3DDevice7_iface
,
3613 PrimitiveType
, VertexType
, Vertices
, VertexCount
, Flags
);
3616 static HRESULT WINAPI
IDirect3DDeviceImpl_2_DrawPrimitive(IDirect3DDevice2
*iface
,
3617 D3DPRIMITIVETYPE PrimitiveType
, D3DVERTEXTYPE VertexType
, void *Vertices
,
3618 DWORD VertexCount
, DWORD Flags
)
3620 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
3623 TRACE("iface %p, primitive_type %#x, vertex_type %#x, vertices %p, vertex_count %u, flags %#x.\n",
3624 iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Flags
);
3628 case D3DVT_VERTEX
: FVF
= D3DFVF_VERTEX
; break;
3629 case D3DVT_LVERTEX
: FVF
= D3DFVF_LVERTEX
; break;
3630 case D3DVT_TLVERTEX
: FVF
= D3DFVF_TLVERTEX
; break;
3632 ERR("Unexpected vertex type %d\n", VertexType
);
3633 return DDERR_INVALIDPARAMS
; /* Should never happen */
3636 return IDirect3DDevice7_DrawPrimitive(&This
->IDirect3DDevice7_iface
,
3637 PrimitiveType
, FVF
, Vertices
, VertexCount
, Flags
);
3640 /*****************************************************************************
3641 * IDirect3DDevice7::DrawIndexedPrimitive
3643 * Draws vertices from an application-provided pointer, based on the index
3644 * numbers in a WORD array.
3646 * Version 2, 3 and 7. The version 7 thunk translates the vertex type into
3647 * an FVF format for D3D7
3650 * PrimitiveType: The primitive type to draw
3651 * VertexType: The FVF vertex description
3652 * Vertices: Pointer to the vertex array
3654 * Indices: Pointer to the index array
3655 * IndexCount: Number of indices = Number of vertices to draw
3656 * Flags: As usual, some flags
3660 * DDERR_INVALIDPARAMS if Vertices or Indices is NULL
3661 * For details, see IWineD3DDevice::DrawIndexedPrimitiveUP
3663 *****************************************************************************/
3665 IDirect3DDeviceImpl_7_DrawIndexedPrimitive(IDirect3DDevice7
*iface
,
3666 D3DPRIMITIVETYPE PrimitiveType
,
3674 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
3677 TRACE("iface %p, primitive_type %#x, FVF %#x, vertices %p, vertex_count %u, indices %p, index_count %u, flags %#x.\n",
3678 iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Indices
, IndexCount
, Flags
);
3680 /* Set the D3DDevice's FVF */
3681 wined3d_mutex_lock();
3682 hr
= wined3d_device_set_vertex_declaration(This
->wined3d_device
, ddraw_find_decl(This
->ddraw
, VertexType
));
3685 ERR(" (%p) Setting the FVF failed, hr = %x!\n", This
, hr
);
3686 wined3d_mutex_unlock();
3690 wined3d_device_set_primitive_type(This
->wined3d_device
, PrimitiveType
);
3691 hr
= wined3d_device_draw_indexed_primitive_up(This
->wined3d_device
, IndexCount
, Indices
,
3692 WINED3DFMT_R16_UINT
, Vertices
, get_flexible_vertex_size(VertexType
));
3693 wined3d_mutex_unlock();
3698 static HRESULT WINAPI
3699 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUSetup(IDirect3DDevice7
*iface
,
3700 D3DPRIMITIVETYPE PrimitiveType
,
3708 return IDirect3DDeviceImpl_7_DrawIndexedPrimitive(iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Indices
, IndexCount
, Flags
);
3711 static HRESULT WINAPI
3712 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUPreserve(IDirect3DDevice7
*iface
,
3713 D3DPRIMITIVETYPE PrimitiveType
,
3724 old_fpucw
= d3d_fpu_setup();
3725 hr
= IDirect3DDeviceImpl_7_DrawIndexedPrimitive(iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Indices
, IndexCount
, Flags
);
3726 set_fpu_control_word(old_fpucw
);
3731 static HRESULT WINAPI
IDirect3DDeviceImpl_3_DrawIndexedPrimitive(IDirect3DDevice3
*iface
,
3732 D3DPRIMITIVETYPE PrimitiveType
, DWORD VertexType
, void *Vertices
, DWORD VertexCount
,
3733 WORD
*Indices
, DWORD IndexCount
, DWORD Flags
)
3735 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
3736 TRACE("iface %p, primitive_type %#x, FVF %#x, vertices %p, vertex_count %u, indices %p, index_count %u, flags %#x.\n",
3737 iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Indices
, IndexCount
, Flags
);
3739 return IDirect3DDevice7_DrawIndexedPrimitive(&This
->IDirect3DDevice7_iface
,
3740 PrimitiveType
, VertexType
, Vertices
, VertexCount
, Indices
, IndexCount
, Flags
);
3743 static HRESULT WINAPI
IDirect3DDeviceImpl_2_DrawIndexedPrimitive(IDirect3DDevice2
*iface
,
3744 D3DPRIMITIVETYPE PrimitiveType
, D3DVERTEXTYPE VertexType
, void *Vertices
,
3745 DWORD VertexCount
, WORD
*Indices
, DWORD IndexCount
, DWORD Flags
)
3747 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
3750 TRACE("iface %p, primitive_type %#x, vertex_type %#x, vertices %p, vertex_count %u, indices %p, index_count %u, flags %#x.\n",
3751 iface
, PrimitiveType
, VertexType
, Vertices
, VertexCount
, Indices
, IndexCount
, Flags
);
3755 case D3DVT_VERTEX
: FVF
= D3DFVF_VERTEX
; break;
3756 case D3DVT_LVERTEX
: FVF
= D3DFVF_LVERTEX
; break;
3757 case D3DVT_TLVERTEX
: FVF
= D3DFVF_TLVERTEX
; break;
3759 ERR("Unexpected vertex type %d\n", VertexType
);
3760 return DDERR_INVALIDPARAMS
; /* Should never happen */
3763 return IDirect3DDevice7_DrawIndexedPrimitive(&This
->IDirect3DDevice7_iface
,
3764 PrimitiveType
, FVF
, Vertices
, VertexCount
, Indices
, IndexCount
, Flags
);
3767 /*****************************************************************************
3768 * IDirect3DDevice7::SetClipStatus
3770 * Sets the clip status. This defines things as clipping conditions and
3771 * the extents of the clipping region.
3773 * Version 2, 3 and 7
3779 * D3D_OK because it's a stub
3780 * (DDERR_INVALIDPARAMS if ClipStatus == NULL)
3782 *****************************************************************************/
3783 static HRESULT WINAPI
3784 IDirect3DDeviceImpl_7_SetClipStatus(IDirect3DDevice7
*iface
,
3785 D3DCLIPSTATUS
*ClipStatus
)
3787 FIXME("iface %p, clip_status %p stub!\n", iface
, ClipStatus
);
3789 /* D3DCLIPSTATUS and WINED3DCLIPSTATUS are different. I don't know how to convert them
3790 * Perhaps this needs a new data type and an additional IWineD3DDevice method
3792 /* return IWineD3DDevice_SetClipStatus(This->wineD3DDevice, ClipStatus);*/
3796 static HRESULT WINAPI
IDirect3DDeviceImpl_3_SetClipStatus(IDirect3DDevice3
*iface
,
3797 D3DCLIPSTATUS
*ClipStatus
)
3799 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
3800 TRACE("iface %p, clip_status %p.\n", iface
, ClipStatus
);
3802 return IDirect3DDevice7_SetClipStatus(&This
->IDirect3DDevice7_iface
, ClipStatus
);
3805 static HRESULT WINAPI
IDirect3DDeviceImpl_2_SetClipStatus(IDirect3DDevice2
*iface
,
3806 D3DCLIPSTATUS
*ClipStatus
)
3808 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
3809 TRACE("iface %p, clip_status %p.\n", iface
, ClipStatus
);
3811 return IDirect3DDevice7_SetClipStatus(&This
->IDirect3DDevice7_iface
, ClipStatus
);
3814 /*****************************************************************************
3815 * IDirect3DDevice7::GetClipStatus
3817 * Returns the clip status
3820 * ClipStatus: Address to write the clip status to
3823 * D3D_OK because it's a stub
3825 *****************************************************************************/
3826 static HRESULT WINAPI
3827 IDirect3DDeviceImpl_7_GetClipStatus(IDirect3DDevice7
*iface
,
3828 D3DCLIPSTATUS
*ClipStatus
)
3830 FIXME("iface %p, clip_status %p stub!\n", iface
, ClipStatus
);
3832 /* D3DCLIPSTATUS and WINED3DCLIPSTATUS are different. I don't know how to convert them */
3833 /* return IWineD3DDevice_GetClipStatus(This->wineD3DDevice, ClipStatus);*/
3837 static HRESULT WINAPI
IDirect3DDeviceImpl_3_GetClipStatus(IDirect3DDevice3
*iface
,
3838 D3DCLIPSTATUS
*ClipStatus
)
3840 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
3841 TRACE("iface %p, clip_status %p.\n", iface
, ClipStatus
);
3843 return IDirect3DDevice7_GetClipStatus(&This
->IDirect3DDevice7_iface
, ClipStatus
);
3846 static HRESULT WINAPI
IDirect3DDeviceImpl_2_GetClipStatus(IDirect3DDevice2
*iface
,
3847 D3DCLIPSTATUS
*ClipStatus
)
3849 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice2(iface
);
3850 TRACE("iface %p, clip_status %p.\n", iface
, ClipStatus
);
3852 return IDirect3DDevice7_GetClipStatus(&This
->IDirect3DDevice7_iface
, ClipStatus
);
3855 /*****************************************************************************
3856 * IDirect3DDevice::DrawPrimitiveStrided
3858 * Draws vertices described by a D3DDRAWPRIMITIVESTRIDEDDATA structure.
3863 * PrimitiveType: The primitive type to draw
3864 * VertexType: The FVF description of the vertices to draw (for the stride??)
3865 * D3DDrawPrimStrideData: A D3DDRAWPRIMITIVESTRIDEDDATA structure describing
3866 * the vertex data locations
3867 * VertexCount: The number of vertices to draw
3871 * D3D_OK, because it's a stub
3872 * (DDERR_INVALIDPARAMS if D3DDrawPrimStrideData is NULL)
3873 * (For details, see IWineD3DDevice::DrawPrimitiveStrided)
3875 *****************************************************************************/
3877 IDirect3DDeviceImpl_7_DrawPrimitiveStrided(IDirect3DDevice7
*iface
,
3878 D3DPRIMITIVETYPE PrimitiveType
,
3880 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
,
3884 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
3885 struct wined3d_strided_data wined3d_strided
;
3889 TRACE("iface %p, primitive_type %#x, FVF %#x, strided_data %p, vertex_count %u, flags %#x.\n",
3890 iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Flags
);
3892 memset(&wined3d_strided
, 0, sizeof(wined3d_strided
));
3893 /* Get the strided data right. the wined3d structure is a bit bigger
3894 * Watch out: The contents of the strided data are determined by the fvf,
3895 * not by the members set in D3DDrawPrimStrideData. So it's valid
3896 * to have diffuse.lpvData set to 0xdeadbeef if the diffuse flag is
3897 * not set in the fvf.
3899 if(VertexType
& D3DFVF_POSITION_MASK
)
3901 wined3d_strided
.position
.format
= WINED3DFMT_R32G32B32_FLOAT
;
3902 wined3d_strided
.position
.data
= D3DDrawPrimStrideData
->position
.lpvData
;
3903 wined3d_strided
.position
.stride
= D3DDrawPrimStrideData
->position
.dwStride
;
3904 if (VertexType
& D3DFVF_XYZRHW
)
3906 wined3d_strided
.position
.format
= WINED3DFMT_R32G32B32A32_FLOAT
;
3907 wined3d_strided
.position_transformed
= TRUE
;
3911 wined3d_strided
.position_transformed
= FALSE
;
3915 if (VertexType
& D3DFVF_NORMAL
)
3917 wined3d_strided
.normal
.format
= WINED3DFMT_R32G32B32_FLOAT
;
3918 wined3d_strided
.normal
.data
= D3DDrawPrimStrideData
->normal
.lpvData
;
3919 wined3d_strided
.normal
.stride
= D3DDrawPrimStrideData
->normal
.dwStride
;
3922 if (VertexType
& D3DFVF_DIFFUSE
)
3924 wined3d_strided
.diffuse
.format
= WINED3DFMT_B8G8R8A8_UNORM
;
3925 wined3d_strided
.diffuse
.data
= D3DDrawPrimStrideData
->diffuse
.lpvData
;
3926 wined3d_strided
.diffuse
.stride
= D3DDrawPrimStrideData
->diffuse
.dwStride
;
3929 if (VertexType
& D3DFVF_SPECULAR
)
3931 wined3d_strided
.specular
.format
= WINED3DFMT_B8G8R8A8_UNORM
;
3932 wined3d_strided
.specular
.data
= D3DDrawPrimStrideData
->specular
.lpvData
;
3933 wined3d_strided
.specular
.stride
= D3DDrawPrimStrideData
->specular
.dwStride
;
3936 for (i
= 0; i
< GET_TEXCOUNT_FROM_FVF(VertexType
); ++i
)
3938 switch (GET_TEXCOORD_SIZE_FROM_FVF(VertexType
, i
))
3940 case 1: wined3d_strided
.tex_coords
[i
].format
= WINED3DFMT_R32_FLOAT
; break;
3941 case 2: wined3d_strided
.tex_coords
[i
].format
= WINED3DFMT_R32G32_FLOAT
; break;
3942 case 3: wined3d_strided
.tex_coords
[i
].format
= WINED3DFMT_R32G32B32_FLOAT
; break;
3943 case 4: wined3d_strided
.tex_coords
[i
].format
= WINED3DFMT_R32G32B32A32_FLOAT
; break;
3944 default: ERR("Unexpected texture coordinate size %d\n",
3945 GET_TEXCOORD_SIZE_FROM_FVF(VertexType
, i
));
3947 wined3d_strided
.tex_coords
[i
].data
= D3DDrawPrimStrideData
->textureCoords
[i
].lpvData
;
3948 wined3d_strided
.tex_coords
[i
].stride
= D3DDrawPrimStrideData
->textureCoords
[i
].dwStride
;
3951 /* WineD3D doesn't need the FVF here */
3952 wined3d_mutex_lock();
3953 wined3d_device_set_primitive_type(This
->wined3d_device
, PrimitiveType
);
3954 hr
= wined3d_device_draw_primitive_strided(This
->wined3d_device
, VertexCount
, &wined3d_strided
);
3955 wined3d_mutex_unlock();
3960 static HRESULT WINAPI
3961 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUSetup(IDirect3DDevice7
*iface
,
3962 D3DPRIMITIVETYPE PrimitiveType
,
3964 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
,
3968 return IDirect3DDeviceImpl_7_DrawPrimitiveStrided(iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Flags
);
3971 static HRESULT WINAPI
3972 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUPreserve(IDirect3DDevice7
*iface
,
3973 D3DPRIMITIVETYPE PrimitiveType
,
3975 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
,
3982 old_fpucw
= d3d_fpu_setup();
3983 hr
= IDirect3DDeviceImpl_7_DrawPrimitiveStrided(iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Flags
);
3984 set_fpu_control_word(old_fpucw
);
3989 static HRESULT WINAPI
IDirect3DDeviceImpl_3_DrawPrimitiveStrided(IDirect3DDevice3
*iface
,
3990 D3DPRIMITIVETYPE PrimitiveType
, DWORD VertexType
,
3991 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
, DWORD VertexCount
, DWORD Flags
)
3993 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
3995 TRACE("iface %p, primitive_type %#x, FVF %#x, strided_data %p, vertex_count %u, flags %#x.\n",
3996 iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Flags
);
3998 return IDirect3DDevice7_DrawPrimitiveStrided(&This
->IDirect3DDevice7_iface
,
3999 PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Flags
);
4002 /*****************************************************************************
4003 * IDirect3DDevice7::DrawIndexedPrimitiveStrided
4005 * Draws primitives specified by strided data locations based on indices
4013 * D3D_OK, because it's a stub
4014 * (DDERR_INVALIDPARAMS if D3DDrawPrimStrideData is NULL)
4015 * (DDERR_INVALIDPARAMS if Indices is NULL)
4016 * (For more details, see IWineD3DDevice::DrawIndexedPrimitiveStrided)
4018 *****************************************************************************/
4020 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided(IDirect3DDevice7
*iface
,
4021 D3DPRIMITIVETYPE PrimitiveType
,
4023 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
,
4029 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
4030 struct wined3d_strided_data wined3d_strided
;
4034 TRACE("iface %p, primitive_type %#x, FVF %#x, strided_data %p, vertex_count %u, indices %p, index_count %u, flags %#x.\n",
4035 iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Indices
, IndexCount
, Flags
);
4037 memset(&wined3d_strided
, 0, sizeof(wined3d_strided
));
4038 /* Get the strided data right. the wined3d structure is a bit bigger
4039 * Watch out: The contents of the strided data are determined by the fvf,
4040 * not by the members set in D3DDrawPrimStrideData. So it's valid
4041 * to have diffuse.lpvData set to 0xdeadbeef if the diffuse flag is
4042 * not set in the fvf. */
4043 if (VertexType
& D3DFVF_POSITION_MASK
)
4045 wined3d_strided
.position
.format
= WINED3DFMT_R32G32B32_FLOAT
;
4046 wined3d_strided
.position
.data
= D3DDrawPrimStrideData
->position
.lpvData
;
4047 wined3d_strided
.position
.stride
= D3DDrawPrimStrideData
->position
.dwStride
;
4048 if (VertexType
& D3DFVF_XYZRHW
)
4050 wined3d_strided
.position
.format
= WINED3DFMT_R32G32B32A32_FLOAT
;
4051 wined3d_strided
.position_transformed
= TRUE
;
4055 wined3d_strided
.position_transformed
= FALSE
;
4059 if (VertexType
& D3DFVF_NORMAL
)
4061 wined3d_strided
.normal
.format
= WINED3DFMT_R32G32B32_FLOAT
;
4062 wined3d_strided
.normal
.data
= D3DDrawPrimStrideData
->normal
.lpvData
;
4063 wined3d_strided
.normal
.stride
= D3DDrawPrimStrideData
->normal
.dwStride
;
4066 if (VertexType
& D3DFVF_DIFFUSE
)
4068 wined3d_strided
.diffuse
.format
= WINED3DFMT_B8G8R8A8_UNORM
;
4069 wined3d_strided
.diffuse
.data
= D3DDrawPrimStrideData
->diffuse
.lpvData
;
4070 wined3d_strided
.diffuse
.stride
= D3DDrawPrimStrideData
->diffuse
.dwStride
;
4073 if (VertexType
& D3DFVF_SPECULAR
)
4075 wined3d_strided
.specular
.format
= WINED3DFMT_B8G8R8A8_UNORM
;
4076 wined3d_strided
.specular
.data
= D3DDrawPrimStrideData
->specular
.lpvData
;
4077 wined3d_strided
.specular
.stride
= D3DDrawPrimStrideData
->specular
.dwStride
;
4080 for (i
= 0; i
< GET_TEXCOUNT_FROM_FVF(VertexType
); ++i
)
4082 switch (GET_TEXCOORD_SIZE_FROM_FVF(VertexType
, i
))
4084 case 1: wined3d_strided
.tex_coords
[i
].format
= WINED3DFMT_R32_FLOAT
; break;
4085 case 2: wined3d_strided
.tex_coords
[i
].format
= WINED3DFMT_R32G32_FLOAT
; break;
4086 case 3: wined3d_strided
.tex_coords
[i
].format
= WINED3DFMT_R32G32B32_FLOAT
; break;
4087 case 4: wined3d_strided
.tex_coords
[i
].format
= WINED3DFMT_R32G32B32A32_FLOAT
; break;
4088 default: ERR("Unexpected texture coordinate size %d\n",
4089 GET_TEXCOORD_SIZE_FROM_FVF(VertexType
, i
));
4091 wined3d_strided
.tex_coords
[i
].data
= D3DDrawPrimStrideData
->textureCoords
[i
].lpvData
;
4092 wined3d_strided
.tex_coords
[i
].stride
= D3DDrawPrimStrideData
->textureCoords
[i
].dwStride
;
4095 /* WineD3D doesn't need the FVF here */
4096 wined3d_mutex_lock();
4097 wined3d_device_set_primitive_type(This
->wined3d_device
, PrimitiveType
);
4098 hr
= wined3d_device_draw_indexed_primitive_strided(This
->wined3d_device
,
4099 IndexCount
, &wined3d_strided
, VertexCount
, Indices
, WINED3DFMT_R16_UINT
);
4100 wined3d_mutex_unlock();
4105 static HRESULT WINAPI
4106 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUSetup(IDirect3DDevice7
*iface
,
4107 D3DPRIMITIVETYPE PrimitiveType
,
4109 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
,
4115 return IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided(iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Indices
, IndexCount
, Flags
);
4118 static HRESULT WINAPI
4119 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUPreserve(IDirect3DDevice7
*iface
,
4120 D3DPRIMITIVETYPE PrimitiveType
,
4122 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
,
4131 old_fpucw
= d3d_fpu_setup();
4132 hr
= IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided(iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Indices
, IndexCount
, Flags
);
4133 set_fpu_control_word(old_fpucw
);
4138 static HRESULT WINAPI
IDirect3DDeviceImpl_3_DrawIndexedPrimitiveStrided(IDirect3DDevice3
*iface
,
4139 D3DPRIMITIVETYPE PrimitiveType
, DWORD VertexType
,
4140 D3DDRAWPRIMITIVESTRIDEDDATA
*D3DDrawPrimStrideData
, DWORD VertexCount
, WORD
*Indices
,
4141 DWORD IndexCount
, DWORD Flags
)
4143 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
4145 TRACE("iface %p, primitive_type %#x, FVF %#x, strided_data %p, vertex_count %u, indices %p, index_count %u, flags %#x.\n",
4146 iface
, PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Indices
, IndexCount
, Flags
);
4148 return IDirect3DDevice7_DrawIndexedPrimitiveStrided(&This
->IDirect3DDevice7_iface
,
4149 PrimitiveType
, VertexType
, D3DDrawPrimStrideData
, VertexCount
, Indices
, IndexCount
, Flags
);
4152 /*****************************************************************************
4153 * IDirect3DDevice7::DrawPrimitiveVB
4155 * Draws primitives from a vertex buffer to the screen.
4160 * PrimitiveType: Type of primitive to be rendered.
4161 * D3DVertexBuf: Source Vertex Buffer
4162 * StartVertex: Index of the first vertex from the buffer to be rendered
4163 * NumVertices: Number of vertices to be rendered
4164 * Flags: Can be D3DDP_WAIT to wait until rendering has finished
4168 * DDERR_INVALIDPARAMS if D3DVertexBuf is NULL
4170 *****************************************************************************/
4172 IDirect3DDeviceImpl_7_DrawPrimitiveVB(IDirect3DDevice7
*iface
,
4173 D3DPRIMITIVETYPE PrimitiveType
,
4174 IDirect3DVertexBuffer7
*D3DVertexBuf
,
4179 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
4180 IDirect3DVertexBufferImpl
*vb
= unsafe_impl_from_IDirect3DVertexBuffer7(D3DVertexBuf
);
4184 TRACE("iface %p, primitive_type %#x, vb %p, start_vertex %u, vertex_count %u, flags %#x.\n",
4185 iface
, PrimitiveType
, D3DVertexBuf
, StartVertex
, NumVertices
, Flags
);
4190 ERR("(%p) No Vertex buffer specified\n", This
);
4191 return DDERR_INVALIDPARAMS
;
4193 stride
= get_flexible_vertex_size(vb
->fvf
);
4195 wined3d_mutex_lock();
4196 hr
= wined3d_device_set_vertex_declaration(This
->wined3d_device
, vb
->wineD3DVertexDeclaration
);
4199 ERR(" (%p) Setting the FVF failed, hr = %x!\n", This
, hr
);
4200 wined3d_mutex_unlock();
4204 /* Set the vertex stream source */
4205 hr
= wined3d_device_set_stream_source(This
->wined3d_device
, 0, vb
->wineD3DVertexBuffer
, 0, stride
);
4208 ERR("(%p) IDirect3DDevice::SetStreamSource failed with hr = %08x\n", This
, hr
);
4209 wined3d_mutex_unlock();
4213 /* Now draw the primitives */
4214 wined3d_device_set_primitive_type(This
->wined3d_device
, PrimitiveType
);
4215 hr
= wined3d_device_draw_primitive(This
->wined3d_device
, StartVertex
, NumVertices
);
4216 wined3d_mutex_unlock();
4221 static HRESULT WINAPI
4222 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUSetup(IDirect3DDevice7
*iface
,
4223 D3DPRIMITIVETYPE PrimitiveType
,
4224 IDirect3DVertexBuffer7
*D3DVertexBuf
,
4229 return IDirect3DDeviceImpl_7_DrawPrimitiveVB(iface
, PrimitiveType
, D3DVertexBuf
, StartVertex
, NumVertices
, Flags
);
4232 static HRESULT WINAPI
4233 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUPreserve(IDirect3DDevice7
*iface
,
4234 D3DPRIMITIVETYPE PrimitiveType
,
4235 IDirect3DVertexBuffer7
*D3DVertexBuf
,
4243 old_fpucw
= d3d_fpu_setup();
4244 hr
= IDirect3DDeviceImpl_7_DrawPrimitiveVB(iface
, PrimitiveType
, D3DVertexBuf
, StartVertex
, NumVertices
, Flags
);
4245 set_fpu_control_word(old_fpucw
);
4250 static HRESULT WINAPI
IDirect3DDeviceImpl_3_DrawPrimitiveVB(IDirect3DDevice3
*iface
,
4251 D3DPRIMITIVETYPE PrimitiveType
, IDirect3DVertexBuffer
*D3DVertexBuf
, DWORD StartVertex
,
4252 DWORD NumVertices
, DWORD Flags
)
4254 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
4255 IDirect3DVertexBufferImpl
*vb
= unsafe_impl_from_IDirect3DVertexBuffer(D3DVertexBuf
);
4257 TRACE("iface %p, primitive_type %#x, vb %p, start_vertex %u, vertex_count %u, flags %#x.\n",
4258 iface
, PrimitiveType
, D3DVertexBuf
, StartVertex
, NumVertices
, Flags
);
4260 return IDirect3DDevice7_DrawPrimitiveVB(&This
->IDirect3DDevice7_iface
,
4261 PrimitiveType
, &vb
->IDirect3DVertexBuffer7_iface
, StartVertex
, NumVertices
, Flags
);
4265 /*****************************************************************************
4266 * IDirect3DDevice7::DrawIndexedPrimitiveVB
4268 * Draws primitives from a vertex buffer to the screen
4271 * PrimitiveType: Type of primitive to be rendered.
4272 * D3DVertexBuf: Source Vertex Buffer
4273 * StartVertex: Index of the first vertex from the buffer to be rendered
4274 * NumVertices: Number of vertices to be rendered
4275 * Indices: Array of DWORDs used to index into the Vertices
4276 * IndexCount: Number of indices in Indices
4277 * Flags: Can be D3DDP_WAIT to wait until rendering has finished
4281 *****************************************************************************/
4283 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB(IDirect3DDevice7
*iface
,
4284 D3DPRIMITIVETYPE PrimitiveType
,
4285 IDirect3DVertexBuffer7
*D3DVertexBuf
,
4292 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
4293 IDirect3DVertexBufferImpl
*vb
= unsafe_impl_from_IDirect3DVertexBuffer7(D3DVertexBuf
);
4294 DWORD stride
= get_flexible_vertex_size(vb
->fvf
);
4295 struct wined3d_resource
*wined3d_resource
;
4296 struct wined3d_resource_desc desc
;
4297 WORD
*LockedIndices
;
4300 TRACE("iface %p, primitive_type %#x, vb %p, start_vertex %u, vertex_count %u, indices %p, index_count %u, flags %#x.\n",
4301 iface
, PrimitiveType
, D3DVertexBuf
, StartVertex
, NumVertices
, Indices
, IndexCount
, Flags
);
4304 * 1) Upload the Indices to the index buffer
4305 * 2) Set the index source
4306 * 3) Set the Vertex Buffer as the Stream source
4307 * 4) Call IWineD3DDevice::DrawIndexedPrimitive
4310 wined3d_mutex_lock();
4312 hr
= wined3d_device_set_vertex_declaration(This
->wined3d_device
, vb
->wineD3DVertexDeclaration
);
4315 ERR(" (%p) Setting the FVF failed, hr = %x!\n", This
, hr
);
4316 wined3d_mutex_unlock();
4320 /* check that the buffer is large enough to hold the indices,
4321 * reallocate if necessary. */
4322 wined3d_resource
= wined3d_buffer_get_resource(This
->indexbuffer
);
4323 wined3d_resource_get_desc(wined3d_resource
, &desc
);
4324 if (desc
.size
< IndexCount
* sizeof(WORD
))
4326 UINT size
= max(desc
.size
* 2, IndexCount
* sizeof(WORD
));
4327 struct wined3d_buffer
*buffer
;
4329 TRACE("Growing index buffer to %u bytes\n", size
);
4331 hr
= wined3d_buffer_create_ib(This
->wined3d_device
, size
, WINED3DUSAGE_DYNAMIC
/* Usage */,
4332 WINED3D_POOL_DEFAULT
, NULL
, &ddraw_null_wined3d_parent_ops
, &buffer
);
4335 ERR("(%p) IWineD3DDevice::CreateIndexBuffer failed with hr = %08x\n", This
, hr
);
4336 wined3d_mutex_unlock();
4340 wined3d_buffer_decref(This
->indexbuffer
);
4341 This
->indexbuffer
= buffer
;
4344 /* Copy the index stream into the index buffer. A new IWineD3DDevice
4345 * method could be created which takes an user pointer containing the
4346 * indices or a SetData-Method for the index buffer, which overrides the
4347 * index buffer data with our pointer. */
4348 hr
= wined3d_buffer_map(This
->indexbuffer
, 0, IndexCount
* sizeof(WORD
),
4349 (BYTE
**)&LockedIndices
, 0);
4352 ERR("Failed to map buffer, hr %#x.\n", hr
);
4353 wined3d_mutex_unlock();
4356 memcpy(LockedIndices
, Indices
, IndexCount
* sizeof(WORD
));
4357 wined3d_buffer_unmap(This
->indexbuffer
);
4359 /* Set the index stream */
4360 wined3d_device_set_base_vertex_index(This
->wined3d_device
, StartVertex
);
4361 hr
= wined3d_device_set_index_buffer(This
->wined3d_device
, This
->indexbuffer
, WINED3DFMT_R16_UINT
);
4363 /* Set the vertex stream source */
4364 hr
= wined3d_device_set_stream_source(This
->wined3d_device
, 0, vb
->wineD3DVertexBuffer
, 0, stride
);
4367 ERR("(%p) IDirect3DDevice::SetStreamSource failed with hr = %08x\n", This
, hr
);
4368 wined3d_mutex_unlock();
4373 wined3d_device_set_primitive_type(This
->wined3d_device
, PrimitiveType
);
4374 hr
= wined3d_device_draw_indexed_primitive(This
->wined3d_device
, 0, IndexCount
);
4376 wined3d_mutex_unlock();
4381 static HRESULT WINAPI
4382 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUSetup(IDirect3DDevice7
*iface
,
4383 D3DPRIMITIVETYPE PrimitiveType
,
4384 IDirect3DVertexBuffer7
*D3DVertexBuf
,
4391 return IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB(iface
, PrimitiveType
, D3DVertexBuf
, StartVertex
, NumVertices
, Indices
, IndexCount
, Flags
);
4394 static HRESULT WINAPI
4395 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUPreserve(IDirect3DDevice7
*iface
,
4396 D3DPRIMITIVETYPE PrimitiveType
,
4397 IDirect3DVertexBuffer7
*D3DVertexBuf
,
4407 old_fpucw
= d3d_fpu_setup();
4408 hr
= IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB(iface
, PrimitiveType
, D3DVertexBuf
, StartVertex
, NumVertices
, Indices
, IndexCount
, Flags
);
4409 set_fpu_control_word(old_fpucw
);
4414 static HRESULT WINAPI
IDirect3DDeviceImpl_3_DrawIndexedPrimitiveVB(IDirect3DDevice3
*iface
,
4415 D3DPRIMITIVETYPE PrimitiveType
, IDirect3DVertexBuffer
*D3DVertexBuf
, WORD
*Indices
,
4416 DWORD IndexCount
, DWORD Flags
)
4418 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
4419 IDirect3DVertexBufferImpl
*vb
= unsafe_impl_from_IDirect3DVertexBuffer(D3DVertexBuf
);
4421 TRACE("iface %p, primitive_type %#x, vb %p, indices %p, index_count %u, flags %#x.\n",
4422 iface
, PrimitiveType
, D3DVertexBuf
, Indices
, IndexCount
, Flags
);
4424 return IDirect3DDevice7_DrawIndexedPrimitiveVB(&This
->IDirect3DDevice7_iface
,
4425 PrimitiveType
, &vb
->IDirect3DVertexBuffer7_iface
, 0, IndexCount
, Indices
, IndexCount
,
4429 /*****************************************************************************
4430 * IDirect3DDevice7::ComputeSphereVisibility
4432 * Calculates the visibility of spheres in the current viewport. The spheres
4433 * are passed in the Centers and Radii arrays, the results are passed back
4434 * in the ReturnValues array. Return values are either completely visible,
4435 * partially visible or completely invisible.
4436 * The return value consist of a combination of D3DCLIP_* flags, or it's
4437 * 0 if the sphere is completely visible(according to the SDK, not checked)
4442 * Centers: Array containing the sphere centers
4443 * Radii: Array containing the sphere radii
4444 * NumSpheres: The number of centers and radii in the arrays
4446 * ReturnValues: Array to write the results to
4450 * (DDERR_INVALIDPARAMS if Centers, Radii or ReturnValues are NULL)
4451 * (D3DERR_INVALIDMATRIX if the combined world, view and proj matrix
4454 *****************************************************************************/
4456 static DWORD
in_plane(UINT plane
, D3DVECTOR normal
, D3DVALUE origin_plane
, D3DVECTOR center
, D3DVALUE radius
)
4458 float distance
, norm
;
4460 norm
= sqrt( normal
.u1
.x
* normal
.u1
.x
+ normal
.u2
.y
* normal
.u2
.y
+ normal
.u3
.z
* normal
.u3
.z
);
4461 distance
= ( origin_plane
+ normal
.u1
.x
* center
.u1
.x
+ normal
.u2
.y
* center
.u2
.y
+ normal
.u3
.z
* center
.u3
.z
) / norm
;
4463 if ( fabs( distance
) < radius
) return D3DSTATUS_CLIPUNIONLEFT
<< plane
;
4464 if ( distance
< -radius
) return (D3DSTATUS_CLIPUNIONLEFT
| D3DSTATUS_CLIPINTERSECTIONLEFT
) << plane
;
4468 static HRESULT WINAPI
4469 IDirect3DDeviceImpl_7_ComputeSphereVisibility(IDirect3DDevice7
*iface
,
4474 DWORD
*ReturnValues
)
4477 D3DVALUE origin_plane
[6];
4482 TRACE("iface %p, centers %p, radii %p, sphere_count %u, flags %#x, return_values %p.\n",
4483 iface
, Centers
, Radii
, NumSpheres
, Flags
, ReturnValues
);
4485 hr
= IDirect3DDeviceImpl_7_GetTransform(iface
, D3DTRANSFORMSTATE_WORLD
, &m
);
4486 if ( hr
!= DD_OK
) return DDERR_INVALIDPARAMS
;
4487 hr
= IDirect3DDeviceImpl_7_GetTransform(iface
, D3DTRANSFORMSTATE_VIEW
, &temp
);
4488 if ( hr
!= DD_OK
) return DDERR_INVALIDPARAMS
;
4489 multiply_matrix(&m
, &temp
, &m
);
4491 hr
= IDirect3DDeviceImpl_7_GetTransform(iface
, D3DTRANSFORMSTATE_PROJECTION
, &temp
);
4492 if ( hr
!= DD_OK
) return DDERR_INVALIDPARAMS
;
4493 multiply_matrix(&m
, &temp
, &m
);
4496 vec
[0].u1
.x
= m
._14
+ m
._11
;
4497 vec
[0].u2
.y
= m
._24
+ m
._21
;
4498 vec
[0].u3
.z
= m
._34
+ m
._31
;
4499 origin_plane
[0] = m
._44
+ m
._41
;
4502 vec
[1].u1
.x
= m
._14
- m
._11
;
4503 vec
[1].u2
.y
= m
._24
- m
._21
;
4504 vec
[1].u3
.z
= m
._34
- m
._31
;
4505 origin_plane
[1] = m
._44
- m
._41
;
4508 vec
[2].u1
.x
= m
._14
- m
._12
;
4509 vec
[2].u2
.y
= m
._24
- m
._22
;
4510 vec
[2].u3
.z
= m
._34
- m
._32
;
4511 origin_plane
[2] = m
._44
- m
._42
;
4514 vec
[3].u1
.x
= m
._14
+ m
._12
;
4515 vec
[3].u2
.y
= m
._24
+ m
._22
;
4516 vec
[3].u3
.z
= m
._34
+ m
._32
;
4517 origin_plane
[3] = m
._44
+ m
._42
;
4520 vec
[4].u1
.x
= m
._13
;
4521 vec
[4].u2
.y
= m
._23
;
4522 vec
[4].u3
.z
= m
._33
;
4523 origin_plane
[4] = m
._43
;
4526 vec
[5].u1
.x
= m
._14
- m
._13
;
4527 vec
[5].u2
.y
= m
._24
- m
._23
;
4528 vec
[5].u3
.z
= m
._34
- m
._33
;
4529 origin_plane
[5] = m
._44
- m
._43
;
4531 for(i
=0; i
<NumSpheres
; i
++)
4533 ReturnValues
[i
] = 0;
4534 for(j
=0; j
<6; j
++) ReturnValues
[i
] |= in_plane(j
, vec
[j
], origin_plane
[j
], Centers
[i
], Radii
[i
]);
4540 static HRESULT WINAPI
IDirect3DDeviceImpl_3_ComputeSphereVisibility(IDirect3DDevice3
*iface
,
4541 D3DVECTOR
*Centers
, D3DVALUE
*Radii
, DWORD NumSpheres
, DWORD Flags
, DWORD
*ReturnValues
)
4543 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
4545 TRACE("iface %p, centers %p, radii %p, sphere_count %u, flags %#x, return_values %p.\n",
4546 iface
, Centers
, Radii
, NumSpheres
, Flags
, ReturnValues
);
4548 return IDirect3DDevice7_ComputeSphereVisibility(&This
->IDirect3DDevice7_iface
,
4549 Centers
, Radii
, NumSpheres
, Flags
, ReturnValues
);
4552 /*****************************************************************************
4553 * IDirect3DDevice7::GetTexture
4555 * Returns the texture interface handle assigned to a texture stage.
4556 * The returned texture is AddRefed. This is taken from old ddraw,
4557 * not checked in Windows.
4562 * Stage: Texture stage to read the texture from
4563 * Texture: Address to store the interface pointer at
4567 * DDERR_INVALIDPARAMS if Texture is NULL
4568 * For details, see IWineD3DDevice::GetTexture
4570 *****************************************************************************/
4572 IDirect3DDeviceImpl_7_GetTexture(IDirect3DDevice7
*iface
,
4574 IDirectDrawSurface7
**Texture
)
4576 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
4577 struct wined3d_texture
*wined3d_texture
;
4580 TRACE("iface %p, stage %u, texture %p.\n", iface
, Stage
, Texture
);
4584 TRACE("Texture == NULL, failing with DDERR_INVALIDPARAMS\n");
4585 return DDERR_INVALIDPARAMS
;
4588 wined3d_mutex_lock();
4589 hr
= wined3d_device_get_texture(This
->wined3d_device
, Stage
, &wined3d_texture
);
4590 if (FAILED(hr
) || !wined3d_texture
)
4593 wined3d_mutex_unlock();
4597 *Texture
= wined3d_texture_get_parent(wined3d_texture
);
4598 IDirectDrawSurface7_AddRef(*Texture
);
4599 wined3d_texture_decref(wined3d_texture
);
4600 wined3d_mutex_unlock();
4605 static HRESULT WINAPI
4606 IDirect3DDeviceImpl_7_GetTexture_FPUSetup(IDirect3DDevice7
*iface
,
4608 IDirectDrawSurface7
**Texture
)
4610 return IDirect3DDeviceImpl_7_GetTexture(iface
, Stage
, Texture
);
4613 static HRESULT WINAPI
4614 IDirect3DDeviceImpl_7_GetTexture_FPUPreserve(IDirect3DDevice7
*iface
,
4616 IDirectDrawSurface7
**Texture
)
4621 old_fpucw
= d3d_fpu_setup();
4622 hr
= IDirect3DDeviceImpl_7_GetTexture(iface
, Stage
, Texture
);
4623 set_fpu_control_word(old_fpucw
);
4628 static HRESULT WINAPI
IDirect3DDeviceImpl_3_GetTexture(IDirect3DDevice3
*iface
, DWORD Stage
,
4629 IDirect3DTexture2
**Texture2
)
4631 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
4632 struct ddraw_surface
*ret_val_impl
;
4634 IDirectDrawSurface7
*ret_val
;
4636 TRACE("iface %p, stage %u, texture %p.\n", iface
, Stage
, Texture2
);
4638 ret
= IDirect3DDevice7_GetTexture(&This
->IDirect3DDevice7_iface
, Stage
, &ret_val
);
4640 ret_val_impl
= unsafe_impl_from_IDirectDrawSurface7(ret_val
);
4641 *Texture2
= ret_val_impl
? &ret_val_impl
->IDirect3DTexture2_iface
: NULL
;
4643 TRACE("Returning texture %p.\n", *Texture2
);
4648 /*****************************************************************************
4649 * IDirect3DDevice7::SetTexture
4651 * Assigns a texture to a texture stage. Is the texture AddRef-ed?
4656 * Stage: The stage to assign the texture to
4657 * Texture: Interface pointer to the texture surface
4661 * For details, see IWineD3DDevice::SetTexture
4663 *****************************************************************************/
4665 IDirect3DDeviceImpl_7_SetTexture(IDirect3DDevice7
*iface
,
4667 IDirectDrawSurface7
*Texture
)
4669 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
4670 struct ddraw_surface
*surf
= unsafe_impl_from_IDirectDrawSurface7(Texture
);
4673 TRACE("iface %p, stage %u, texture %p.\n", iface
, Stage
, Texture
);
4675 /* Texture may be NULL here */
4676 wined3d_mutex_lock();
4677 hr
= wined3d_device_set_texture(This
->wined3d_device
,
4678 Stage
, surf
? surf
->wined3d_texture
: NULL
);
4679 wined3d_mutex_unlock();
4684 static HRESULT WINAPI
4685 IDirect3DDeviceImpl_7_SetTexture_FPUSetup(IDirect3DDevice7
*iface
,
4687 IDirectDrawSurface7
*Texture
)
4689 return IDirect3DDeviceImpl_7_SetTexture(iface
, Stage
, Texture
);
4692 static HRESULT WINAPI
4693 IDirect3DDeviceImpl_7_SetTexture_FPUPreserve(IDirect3DDevice7
*iface
,
4695 IDirectDrawSurface7
*Texture
)
4700 old_fpucw
= d3d_fpu_setup();
4701 hr
= IDirect3DDeviceImpl_7_SetTexture(iface
, Stage
, Texture
);
4702 set_fpu_control_word(old_fpucw
);
4707 static HRESULT WINAPI
4708 IDirect3DDeviceImpl_3_SetTexture(IDirect3DDevice3
*iface
,
4710 IDirect3DTexture2
*Texture2
)
4712 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
4713 struct ddraw_surface
*tex
= unsafe_impl_from_IDirect3DTexture2(Texture2
);
4717 TRACE("iface %p, stage %u, texture %p.\n", iface
, Stage
, Texture2
);
4719 wined3d_mutex_lock();
4721 if (This
->legacyTextureBlending
)
4722 IDirect3DDevice3_GetRenderState(iface
, D3DRENDERSTATE_TEXTUREMAPBLEND
, &texmapblend
);
4724 hr
= IDirect3DDevice7_SetTexture(&This
->IDirect3DDevice7_iface
, Stage
, &tex
->IDirectDrawSurface7_iface
);
4726 if (This
->legacyTextureBlending
&& texmapblend
== D3DTBLEND_MODULATE
)
4728 /* This fixup is required by the way D3DTBLEND_MODULATE maps to texture stage states.
4729 See IDirect3DDeviceImpl_3_SetRenderState for details. */
4730 struct wined3d_texture
*tex
= NULL
;
4731 BOOL tex_alpha
= FALSE
;
4732 DDPIXELFORMAT ddfmt
;
4735 result
= wined3d_device_get_texture(This
->wined3d_device
, 0, &tex
);
4736 if (result
== WINED3D_OK
&& tex
)
4738 struct wined3d_resource
*sub_resource
;
4740 if ((sub_resource
= wined3d_texture_get_sub_resource(tex
, 0)))
4742 struct wined3d_resource_desc desc
;
4744 wined3d_resource_get_desc(sub_resource
, &desc
);
4745 ddfmt
.dwSize
= sizeof(ddfmt
);
4746 PixelFormat_WineD3DtoDD(&ddfmt
, desc
.format
);
4747 if (ddfmt
.u5
.dwRGBAlphaBitMask
) tex_alpha
= TRUE
;
4750 wined3d_texture_decref(tex
);
4753 /* Arg 1/2 are already set to WINED3DTA_TEXTURE/WINED3DTA_CURRENT in case of D3DTBLEND_MODULATE */
4755 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
4756 0, WINED3D_TSS_ALPHA_OP
, WINED3D_TOP_SELECT_ARG1
);
4758 wined3d_device_set_texture_stage_state(This
->wined3d_device
,
4759 0, WINED3D_TSS_ALPHA_OP
, WINED3D_TOP_SELECT_ARG2
);
4762 wined3d_mutex_unlock();
4767 static const struct tss_lookup
4770 enum wined3d_texture_stage_state state
;
4774 {FALSE
, WINED3D_TSS_INVALID
}, /* 0, unused */
4775 {FALSE
, WINED3D_TSS_COLOR_OP
}, /* 1, D3DTSS_COLOROP */
4776 {FALSE
, WINED3D_TSS_COLOR_ARG1
}, /* 2, D3DTSS_COLORARG1 */
4777 {FALSE
, WINED3D_TSS_COLOR_ARG2
}, /* 3, D3DTSS_COLORARG2 */
4778 {FALSE
, WINED3D_TSS_ALPHA_OP
}, /* 4, D3DTSS_ALPHAOP */
4779 {FALSE
, WINED3D_TSS_ALPHA_ARG1
}, /* 5, D3DTSS_ALPHAARG1 */
4780 {FALSE
, WINED3D_TSS_ALPHA_ARG2
}, /* 6, D3DTSS_ALPHAARG2 */
4781 {FALSE
, WINED3D_TSS_BUMPENV_MAT00
}, /* 7, D3DTSS_BUMPENVMAT00 */
4782 {FALSE
, WINED3D_TSS_BUMPENV_MAT01
}, /* 8, D3DTSS_BUMPENVMAT01 */
4783 {FALSE
, WINED3D_TSS_BUMPENV_MAT10
}, /* 9, D3DTSS_BUMPENVMAT10 */
4784 {FALSE
, WINED3D_TSS_BUMPENV_MAT11
}, /* 10, D3DTSS_BUMPENVMAT11 */
4785 {FALSE
, WINED3D_TSS_TEXCOORD_INDEX
}, /* 11, D3DTSS_TEXCOORDINDEX */
4786 {TRUE
, WINED3D_SAMP_ADDRESS_U
}, /* 12, D3DTSS_ADDRESS */
4787 {TRUE
, WINED3D_SAMP_ADDRESS_U
}, /* 13, D3DTSS_ADDRESSU */
4788 {TRUE
, WINED3D_SAMP_ADDRESS_V
}, /* 14, D3DTSS_ADDRESSV */
4789 {TRUE
, WINED3D_SAMP_BORDER_COLOR
}, /* 15, D3DTSS_BORDERCOLOR */
4790 {TRUE
, WINED3D_SAMP_MAG_FILTER
}, /* 16, D3DTSS_MAGFILTER */
4791 {TRUE
, WINED3D_SAMP_MIN_FILTER
}, /* 17, D3DTSS_MINFILTER */
4792 {TRUE
, WINED3D_SAMP_MIP_FILTER
}, /* 18, D3DTSS_MIPFILTER */
4793 {TRUE
, WINED3D_SAMP_MIPMAP_LOD_BIAS
}, /* 19, D3DTSS_MIPMAPLODBIAS */
4794 {TRUE
, WINED3D_SAMP_MAX_MIP_LEVEL
}, /* 20, D3DTSS_MAXMIPLEVEL */
4795 {TRUE
, WINED3D_SAMP_MAX_ANISOTROPY
}, /* 21, D3DTSS_MAXANISOTROPY */
4796 {FALSE
, WINED3D_TSS_BUMPENV_LSCALE
}, /* 22, D3DTSS_BUMPENVLSCALE */
4797 {FALSE
, WINED3D_TSS_BUMPENV_LOFFSET
}, /* 23, D3DTSS_BUMPENVLOFFSET */
4798 {FALSE
, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS
}, /* 24, D3DTSS_TEXTURETRANSFORMFLAGS */
4801 /*****************************************************************************
4802 * IDirect3DDevice7::GetTextureStageState
4804 * Retrieves a state from a texture stage.
4809 * Stage: The stage to retrieve the state from
4810 * TexStageStateType: The state type to retrieve
4811 * State: Address to store the state's value at
4815 * DDERR_INVALIDPARAMS if State is NULL
4816 * For details, see IWineD3DDevice::GetTextureStageState
4818 *****************************************************************************/
4820 IDirect3DDeviceImpl_7_GetTextureStageState(IDirect3DDevice7
*iface
,
4822 D3DTEXTURESTAGESTATETYPE TexStageStateType
,
4825 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
4827 const struct tss_lookup
*l
;
4829 TRACE("iface %p, stage %u, state %#x, value %p.\n",
4830 iface
, Stage
, TexStageStateType
, State
);
4833 return DDERR_INVALIDPARAMS
;
4835 if (TexStageStateType
> D3DTSS_TEXTURETRANSFORMFLAGS
)
4837 WARN("Invalid TexStageStateType %#x passed.\n", TexStageStateType
);
4841 l
= &tss_lookup
[TexStageStateType
];
4843 wined3d_mutex_lock();
4845 if (l
->sampler_state
)
4847 hr
= wined3d_device_get_sampler_state(This
->wined3d_device
, Stage
, l
->state
, State
);
4849 switch(TexStageStateType
)
4851 /* Mipfilter is a sampler state with different values */
4852 case D3DTSS_MIPFILTER
:
4856 case WINED3D_TEXF_NONE
:
4857 *State
= D3DTFP_NONE
;
4859 case WINED3D_TEXF_POINT
:
4860 *State
= D3DTFP_POINT
;
4862 case WINED3D_TEXF_LINEAR
:
4863 *State
= D3DTFP_LINEAR
;
4866 ERR("Unexpected mipfilter value %#x\n", *State
);
4867 *State
= D3DTFP_NONE
;
4873 /* Magfilter has slightly different values */
4874 case D3DTSS_MAGFILTER
:
4878 case WINED3D_TEXF_POINT
:
4879 *State
= D3DTFG_POINT
;
4881 case WINED3D_TEXF_LINEAR
:
4882 *State
= D3DTFG_LINEAR
;
4884 case WINED3D_TEXF_ANISOTROPIC
:
4885 *State
= D3DTFG_ANISOTROPIC
;
4887 case WINED3D_TEXF_FLAT_CUBIC
:
4888 *State
= D3DTFG_FLATCUBIC
;
4890 case WINED3D_TEXF_GAUSSIAN_CUBIC
:
4891 *State
= D3DTFG_GAUSSIANCUBIC
;
4894 ERR("Unexpected wined3d mag filter value %#x\n", *State
);
4895 *State
= D3DTFG_POINT
;
4907 hr
= wined3d_device_get_texture_stage_state(This
->wined3d_device
, Stage
, l
->state
, State
);
4910 wined3d_mutex_unlock();
4915 static HRESULT WINAPI
4916 IDirect3DDeviceImpl_7_GetTextureStageState_FPUSetup(IDirect3DDevice7
*iface
,
4918 D3DTEXTURESTAGESTATETYPE TexStageStateType
,
4921 return IDirect3DDeviceImpl_7_GetTextureStageState(iface
, Stage
, TexStageStateType
, State
);
4924 static HRESULT WINAPI
4925 IDirect3DDeviceImpl_7_GetTextureStageState_FPUPreserve(IDirect3DDevice7
*iface
,
4927 D3DTEXTURESTAGESTATETYPE TexStageStateType
,
4933 old_fpucw
= d3d_fpu_setup();
4934 hr
= IDirect3DDeviceImpl_7_GetTextureStageState(iface
, Stage
, TexStageStateType
, State
);
4935 set_fpu_control_word(old_fpucw
);
4940 static HRESULT WINAPI
IDirect3DDeviceImpl_3_GetTextureStageState(IDirect3DDevice3
*iface
,
4941 DWORD Stage
, D3DTEXTURESTAGESTATETYPE TexStageStateType
, DWORD
*State
)
4943 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
4945 TRACE("iface %p, stage %u, state %#x, value %p.\n",
4946 iface
, Stage
, TexStageStateType
, State
);
4948 return IDirect3DDevice7_GetTextureStageState(&This
->IDirect3DDevice7_iface
,
4949 Stage
, TexStageStateType
, State
);
4952 /*****************************************************************************
4953 * IDirect3DDevice7::SetTextureStageState
4955 * Sets a texture stage state. Some stage types need to be handled specially,
4956 * because they do not exist in WineD3D and were moved to another place
4961 * Stage: The stage to modify
4962 * TexStageStateType: The state to change
4963 * State: The new value for the state
4967 * For details, see IWineD3DDevice::SetTextureStageState
4969 *****************************************************************************/
4971 IDirect3DDeviceImpl_7_SetTextureStageState(IDirect3DDevice7
*iface
,
4973 D3DTEXTURESTAGESTATETYPE TexStageStateType
,
4976 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
4977 const struct tss_lookup
*l
;
4980 TRACE("iface %p, stage %u, state %#x, value %#x.\n",
4981 iface
, Stage
, TexStageStateType
, State
);
4983 if (TexStageStateType
> D3DTSS_TEXTURETRANSFORMFLAGS
)
4985 WARN("Invalid TexStageStateType %#x passed.\n", TexStageStateType
);
4989 l
= &tss_lookup
[TexStageStateType
];
4991 wined3d_mutex_lock();
4993 if (l
->sampler_state
)
4995 switch(TexStageStateType
)
4997 /* Mipfilter is a sampler state with different values */
4998 case D3DTSS_MIPFILTER
:
5003 State
= WINED3D_TEXF_NONE
;
5006 State
= WINED3D_TEXF_POINT
;
5008 case 0: /* Unchecked */
5010 State
= WINED3D_TEXF_LINEAR
;
5013 ERR("Unexpected mipfilter value %d\n", State
);
5014 State
= WINED3D_TEXF_NONE
;
5020 /* Magfilter has slightly different values */
5021 case D3DTSS_MAGFILTER
:
5026 State
= WINED3D_TEXF_POINT
;
5029 State
= WINED3D_TEXF_LINEAR
;
5031 case D3DTFG_FLATCUBIC
:
5032 State
= WINED3D_TEXF_FLAT_CUBIC
;
5034 case D3DTFG_GAUSSIANCUBIC
:
5035 State
= WINED3D_TEXF_GAUSSIAN_CUBIC
;
5037 case D3DTFG_ANISOTROPIC
:
5038 State
= WINED3D_TEXF_ANISOTROPIC
;
5041 ERR("Unexpected d3d7 mag filter type %d\n", State
);
5042 State
= WINED3D_TEXF_POINT
;
5048 case D3DTSS_ADDRESS
:
5049 wined3d_device_set_sampler_state(This
->wined3d_device
, Stage
, WINED3D_SAMP_ADDRESS_V
, State
);
5056 hr
= wined3d_device_set_sampler_state(This
->wined3d_device
, Stage
, l
->state
, State
);
5060 hr
= wined3d_device_set_texture_stage_state(This
->wined3d_device
, Stage
, l
->state
, State
);
5063 wined3d_mutex_unlock();
5068 static HRESULT WINAPI
5069 IDirect3DDeviceImpl_7_SetTextureStageState_FPUSetup(IDirect3DDevice7
*iface
,
5071 D3DTEXTURESTAGESTATETYPE TexStageStateType
,
5074 return IDirect3DDeviceImpl_7_SetTextureStageState(iface
, Stage
, TexStageStateType
, State
);
5077 static HRESULT WINAPI
5078 IDirect3DDeviceImpl_7_SetTextureStageState_FPUPreserve(IDirect3DDevice7
*iface
,
5080 D3DTEXTURESTAGESTATETYPE TexStageStateType
,
5086 old_fpucw
= d3d_fpu_setup();
5087 hr
= IDirect3DDeviceImpl_7_SetTextureStageState(iface
, Stage
, TexStageStateType
, State
);
5088 set_fpu_control_word(old_fpucw
);
5093 static HRESULT WINAPI
IDirect3DDeviceImpl_3_SetTextureStageState(IDirect3DDevice3
*iface
,
5094 DWORD Stage
, D3DTEXTURESTAGESTATETYPE TexStageStateType
, DWORD State
)
5096 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
5098 TRACE("iface %p, stage %u, state %#x, value %#x.\n",
5099 iface
, Stage
, TexStageStateType
, State
);
5101 return IDirect3DDevice7_SetTextureStageState(&This
->IDirect3DDevice7_iface
,
5102 Stage
, TexStageStateType
, State
);
5105 /*****************************************************************************
5106 * IDirect3DDevice7::ValidateDevice
5108 * SDK: "Reports the device's ability to render the currently set
5109 * texture-blending operations in a single pass". Whatever that means
5115 * NumPasses: Address to write the number of necessary passes for the
5116 * desired effect to.
5120 * See IWineD3DDevice::ValidateDevice for more details
5122 *****************************************************************************/
5124 IDirect3DDeviceImpl_7_ValidateDevice(IDirect3DDevice7
*iface
,
5127 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
5130 TRACE("iface %p, pass_count %p.\n", iface
, NumPasses
);
5132 wined3d_mutex_lock();
5133 hr
= wined3d_device_validate_device(This
->wined3d_device
, NumPasses
);
5134 wined3d_mutex_unlock();
5139 static HRESULT WINAPI
5140 IDirect3DDeviceImpl_7_ValidateDevice_FPUSetup(IDirect3DDevice7
*iface
,
5143 return IDirect3DDeviceImpl_7_ValidateDevice(iface
, NumPasses
);
5146 static HRESULT WINAPI
5147 IDirect3DDeviceImpl_7_ValidateDevice_FPUPreserve(IDirect3DDevice7
*iface
,
5153 old_fpucw
= d3d_fpu_setup();
5154 hr
= IDirect3DDeviceImpl_7_ValidateDevice(iface
, NumPasses
);
5155 set_fpu_control_word(old_fpucw
);
5160 static HRESULT WINAPI
IDirect3DDeviceImpl_3_ValidateDevice(IDirect3DDevice3
*iface
, DWORD
*Passes
)
5162 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice3(iface
);
5164 TRACE("iface %p, pass_count %p.\n", iface
, Passes
);
5166 return IDirect3DDevice7_ValidateDevice(&This
->IDirect3DDevice7_iface
, Passes
);
5169 /*****************************************************************************
5170 * IDirect3DDevice7::Clear
5172 * Fills the render target, the z buffer and the stencil buffer with a
5173 * clear color / value
5178 * Count: Number of rectangles in Rects must be 0 if Rects is NULL
5179 * Rects: Rectangles to clear. If NULL, the whole surface is cleared
5180 * Flags: Some flags, as usual
5181 * Color: Clear color for the render target
5182 * Z: Clear value for the Z buffer
5183 * Stencil: Clear value to store in each stencil buffer entry
5187 * For details, see IWineD3DDevice::Clear
5189 *****************************************************************************/
5190 static HRESULT
IDirect3DDeviceImpl_7_Clear(IDirect3DDevice7
*iface
, DWORD count
,
5191 D3DRECT
*rects
, DWORD flags
, D3DCOLOR color
, D3DVALUE z
, DWORD stencil
)
5193 const struct wined3d_color c
=
5195 ((color
>> 16) & 0xff) / 255.0f
,
5196 ((color
>> 8) & 0xff) / 255.0f
,
5197 (color
& 0xff) / 255.0f
,
5198 ((color
>> 24) & 0xff) / 255.0f
,
5200 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
5203 TRACE("iface %p, count %u, rects %p, flags %#x, color 0x%08x, z %.8e, stencil %#x.\n",
5204 iface
, count
, rects
, flags
, color
, z
, stencil
);
5206 wined3d_mutex_lock();
5207 hr
= wined3d_device_clear(This
->wined3d_device
, count
, (RECT
*)rects
, flags
, &c
, z
, stencil
);
5208 wined3d_mutex_unlock();
5213 static HRESULT WINAPI
5214 IDirect3DDeviceImpl_7_Clear_FPUSetup(IDirect3DDevice7
*iface
,
5222 return IDirect3DDeviceImpl_7_Clear(iface
, Count
, Rects
, Flags
, Color
, Z
, Stencil
);
5225 static HRESULT WINAPI
5226 IDirect3DDeviceImpl_7_Clear_FPUPreserve(IDirect3DDevice7
*iface
,
5237 old_fpucw
= d3d_fpu_setup();
5238 hr
= IDirect3DDeviceImpl_7_Clear(iface
, Count
, Rects
, Flags
, Color
, Z
, Stencil
);
5239 set_fpu_control_word(old_fpucw
);
5244 /*****************************************************************************
5245 * IDirect3DDevice7::SetViewport
5247 * Sets the current viewport.
5249 * Version 7 only, but IDirect3DViewport uses this call for older
5253 * Data: The new viewport to set
5257 * DDERR_INVALIDPARAMS if Data is NULL
5258 * For more details, see IWineDDDevice::SetViewport
5260 *****************************************************************************/
5262 IDirect3DDeviceImpl_7_SetViewport(IDirect3DDevice7
*iface
,
5265 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
5268 TRACE("iface %p, viewport %p.\n", iface
, Data
);
5271 return DDERR_INVALIDPARAMS
;
5273 /* Note: D3DVIEWPORT7 is compatible with struct wined3d_viewport. */
5274 wined3d_mutex_lock();
5275 hr
= wined3d_device_set_viewport(This
->wined3d_device
, (struct wined3d_viewport
*)Data
);
5276 wined3d_mutex_unlock();
5281 static HRESULT WINAPI
5282 IDirect3DDeviceImpl_7_SetViewport_FPUSetup(IDirect3DDevice7
*iface
,
5285 return IDirect3DDeviceImpl_7_SetViewport(iface
, Data
);
5288 static HRESULT WINAPI
5289 IDirect3DDeviceImpl_7_SetViewport_FPUPreserve(IDirect3DDevice7
*iface
,
5295 old_fpucw
= d3d_fpu_setup();
5296 hr
= IDirect3DDeviceImpl_7_SetViewport(iface
, Data
);
5297 set_fpu_control_word(old_fpucw
);
5302 /*****************************************************************************
5303 * IDirect3DDevice::GetViewport
5305 * Returns the current viewport
5310 * Data: D3D7Viewport structure to write the viewport information to
5314 * DDERR_INVALIDPARAMS if Data is NULL
5315 * For more details, see IWineD3DDevice::GetViewport
5317 *****************************************************************************/
5319 IDirect3DDeviceImpl_7_GetViewport(IDirect3DDevice7
*iface
,
5322 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
5325 TRACE("iface %p, viewport %p.\n", iface
, Data
);
5328 return DDERR_INVALIDPARAMS
;
5330 /* Note: D3DVIEWPORT7 is compatible with struct wined3d_viewport. */
5331 wined3d_mutex_lock();
5332 hr
= wined3d_device_get_viewport(This
->wined3d_device
, (struct wined3d_viewport
*)Data
);
5333 wined3d_mutex_unlock();
5335 return hr_ddraw_from_wined3d(hr
);
5338 static HRESULT WINAPI
5339 IDirect3DDeviceImpl_7_GetViewport_FPUSetup(IDirect3DDevice7
*iface
,
5342 return IDirect3DDeviceImpl_7_GetViewport(iface
, Data
);
5345 static HRESULT WINAPI
5346 IDirect3DDeviceImpl_7_GetViewport_FPUPreserve(IDirect3DDevice7
*iface
,
5352 old_fpucw
= d3d_fpu_setup();
5353 hr
= IDirect3DDeviceImpl_7_GetViewport(iface
, Data
);
5354 set_fpu_control_word(old_fpucw
);
5359 /*****************************************************************************
5360 * IDirect3DDevice7::SetMaterial
5367 * Mat: The material to set
5371 * DDERR_INVALIDPARAMS if Mat is NULL.
5372 * For more details, see IWineD3DDevice::SetMaterial
5374 *****************************************************************************/
5376 IDirect3DDeviceImpl_7_SetMaterial(IDirect3DDevice7
*iface
,
5379 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
5382 TRACE("iface %p, material %p.\n", iface
, Mat
);
5384 if (!Mat
) return DDERR_INVALIDPARAMS
;
5386 wined3d_mutex_lock();
5387 /* Note: D3DMATERIAL7 is compatible with struct wined3d_material. */
5388 hr
= wined3d_device_set_material(This
->wined3d_device
, (struct wined3d_material
*)Mat
);
5389 wined3d_mutex_unlock();
5391 return hr_ddraw_from_wined3d(hr
);
5394 static HRESULT WINAPI
5395 IDirect3DDeviceImpl_7_SetMaterial_FPUSetup(IDirect3DDevice7
*iface
,
5398 return IDirect3DDeviceImpl_7_SetMaterial(iface
, Mat
);
5401 static HRESULT WINAPI
5402 IDirect3DDeviceImpl_7_SetMaterial_FPUPreserve(IDirect3DDevice7
*iface
,
5408 old_fpucw
= d3d_fpu_setup();
5409 hr
= IDirect3DDeviceImpl_7_SetMaterial(iface
, Mat
);
5410 set_fpu_control_word(old_fpucw
);
5415 /*****************************************************************************
5416 * IDirect3DDevice7::GetMaterial
5418 * Returns the current material
5423 * Mat: D3DMATERIAL7 structure to write the material parameters to
5427 * DDERR_INVALIDPARAMS if Mat is NULL
5428 * For more details, see IWineD3DDevice::GetMaterial
5430 *****************************************************************************/
5432 IDirect3DDeviceImpl_7_GetMaterial(IDirect3DDevice7
*iface
,
5435 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
5438 TRACE("iface %p, material %p.\n", iface
, Mat
);
5440 wined3d_mutex_lock();
5441 /* Note: D3DMATERIAL7 is compatible with struct wined3d_material. */
5442 hr
= wined3d_device_get_material(This
->wined3d_device
, (struct wined3d_material
*)Mat
);
5443 wined3d_mutex_unlock();
5445 return hr_ddraw_from_wined3d(hr
);
5448 static HRESULT WINAPI
5449 IDirect3DDeviceImpl_7_GetMaterial_FPUSetup(IDirect3DDevice7
*iface
,
5452 return IDirect3DDeviceImpl_7_GetMaterial(iface
, Mat
);
5455 static HRESULT WINAPI
5456 IDirect3DDeviceImpl_7_GetMaterial_FPUPreserve(IDirect3DDevice7
*iface
,
5462 old_fpucw
= d3d_fpu_setup();
5463 hr
= IDirect3DDeviceImpl_7_GetMaterial(iface
, Mat
);
5464 set_fpu_control_word(old_fpucw
);
5469 /*****************************************************************************
5470 * IDirect3DDevice7::SetLight
5472 * Assigns a light to a light index, but doesn't activate it yet.
5474 * Version 7, IDirect3DLight uses this method for older versions
5477 * LightIndex: The index of the new light
5478 * Light: A D3DLIGHT7 structure describing the light
5482 * For more details, see IWineD3DDevice::SetLight
5484 *****************************************************************************/
5486 IDirect3DDeviceImpl_7_SetLight(IDirect3DDevice7
*iface
,
5490 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
5493 TRACE("iface %p, light_idx %u, light %p.\n", iface
, LightIndex
, Light
);
5495 wined3d_mutex_lock();
5496 /* Note: D3DLIGHT7 is compatible with struct wined3d_light. */
5497 hr
= wined3d_device_set_light(This
->wined3d_device
, LightIndex
, (struct wined3d_light
*)Light
);
5498 wined3d_mutex_unlock();
5500 return hr_ddraw_from_wined3d(hr
);
5503 static HRESULT WINAPI
5504 IDirect3DDeviceImpl_7_SetLight_FPUSetup(IDirect3DDevice7
*iface
,
5508 return IDirect3DDeviceImpl_7_SetLight(iface
, LightIndex
, Light
);
5511 static HRESULT WINAPI
5512 IDirect3DDeviceImpl_7_SetLight_FPUPreserve(IDirect3DDevice7
*iface
,
5519 old_fpucw
= d3d_fpu_setup();
5520 hr
= IDirect3DDeviceImpl_7_SetLight(iface
, LightIndex
, Light
);
5521 set_fpu_control_word(old_fpucw
);
5526 /*****************************************************************************
5527 * IDirect3DDevice7::GetLight
5529 * Returns the light assigned to a light index
5532 * Light: Structure to write the light information to
5536 * DDERR_INVALIDPARAMS if Light is NULL
5537 * For details, see IWineD3DDevice::GetLight
5539 *****************************************************************************/
5541 IDirect3DDeviceImpl_7_GetLight(IDirect3DDevice7
*iface
,
5545 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
5548 TRACE("iface %p, light_idx %u, light %p.\n", iface
, LightIndex
, Light
);
5550 wined3d_mutex_lock();
5551 /* Note: D3DLIGHT7 is compatible with struct wined3d_light. */
5552 rc
= wined3d_device_get_light(This
->wined3d_device
, LightIndex
, (struct wined3d_light
*)Light
);
5553 wined3d_mutex_unlock();
5555 /* Translate the result. WineD3D returns other values than D3D7 */
5556 return hr_ddraw_from_wined3d(rc
);
5559 static HRESULT WINAPI
5560 IDirect3DDeviceImpl_7_GetLight_FPUSetup(IDirect3DDevice7
*iface
,
5564 return IDirect3DDeviceImpl_7_GetLight(iface
, LightIndex
, Light
);
5567 static HRESULT WINAPI
5568 IDirect3DDeviceImpl_7_GetLight_FPUPreserve(IDirect3DDevice7
*iface
,
5575 old_fpucw
= d3d_fpu_setup();
5576 hr
= IDirect3DDeviceImpl_7_GetLight(iface
, LightIndex
, Light
);
5577 set_fpu_control_word(old_fpucw
);
5582 /*****************************************************************************
5583 * IDirect3DDevice7::BeginStateBlock
5585 * Begins recording to a stateblock
5591 * For details see IWineD3DDevice::BeginStateBlock
5593 *****************************************************************************/
5595 IDirect3DDeviceImpl_7_BeginStateBlock(IDirect3DDevice7
*iface
)
5597 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
5600 TRACE("iface %p.\n", iface
);
5602 wined3d_mutex_lock();
5603 hr
= wined3d_device_begin_stateblock(This
->wined3d_device
);
5604 wined3d_mutex_unlock();
5606 return hr_ddraw_from_wined3d(hr
);
5609 static HRESULT WINAPI
5610 IDirect3DDeviceImpl_7_BeginStateBlock_FPUSetup(IDirect3DDevice7
*iface
)
5612 return IDirect3DDeviceImpl_7_BeginStateBlock(iface
);
5615 static HRESULT WINAPI
5616 IDirect3DDeviceImpl_7_BeginStateBlock_FPUPreserve(IDirect3DDevice7
*iface
)
5621 old_fpucw
= d3d_fpu_setup();
5622 hr
= IDirect3DDeviceImpl_7_BeginStateBlock(iface
);
5623 set_fpu_control_word(old_fpucw
);
5628 /*****************************************************************************
5629 * IDirect3DDevice7::EndStateBlock
5631 * Stops recording to a state block and returns the created stateblock
5637 * BlockHandle: Address to store the stateblock's handle to
5641 * DDERR_INVALIDPARAMS if BlockHandle is NULL
5642 * See IWineD3DDevice::EndStateBlock for more details
5644 *****************************************************************************/
5646 IDirect3DDeviceImpl_7_EndStateBlock(IDirect3DDevice7
*iface
,
5649 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
5650 struct wined3d_stateblock
*wined3d_sb
;
5654 TRACE("iface %p, stateblock %p.\n", iface
, BlockHandle
);
5658 WARN("BlockHandle == NULL, returning DDERR_INVALIDPARAMS\n");
5659 return DDERR_INVALIDPARAMS
;
5662 wined3d_mutex_lock();
5664 hr
= wined3d_device_end_stateblock(This
->wined3d_device
, &wined3d_sb
);
5667 WARN("Failed to end stateblock, hr %#x.\n", hr
);
5668 wined3d_mutex_unlock();
5670 return hr_ddraw_from_wined3d(hr
);
5673 h
= ddraw_allocate_handle(&This
->handle_table
, wined3d_sb
, DDRAW_HANDLE_STATEBLOCK
);
5674 if (h
== DDRAW_INVALID_HANDLE
)
5676 ERR("Failed to allocate a stateblock handle.\n");
5677 wined3d_stateblock_decref(wined3d_sb
);
5678 wined3d_mutex_unlock();
5680 return DDERR_OUTOFMEMORY
;
5683 wined3d_mutex_unlock();
5684 *BlockHandle
= h
+ 1;
5686 return hr_ddraw_from_wined3d(hr
);
5689 static HRESULT WINAPI
5690 IDirect3DDeviceImpl_7_EndStateBlock_FPUSetup(IDirect3DDevice7
*iface
,
5693 return IDirect3DDeviceImpl_7_EndStateBlock(iface
, BlockHandle
);
5696 static HRESULT WINAPI
5697 IDirect3DDeviceImpl_7_EndStateBlock_FPUPreserve(IDirect3DDevice7
*iface
,
5703 old_fpucw
= d3d_fpu_setup();
5704 hr
= IDirect3DDeviceImpl_7_EndStateBlock(iface
, BlockHandle
);
5705 set_fpu_control_word(old_fpucw
);
5710 /*****************************************************************************
5711 * IDirect3DDevice7::PreLoad
5713 * Allows the app to signal that a texture will be used soon, to allow
5714 * the Direct3DDevice to load it to the video card in the meantime.
5719 * Texture: The texture to preload
5723 * DDERR_INVALIDPARAMS if Texture is NULL
5724 * See IWineD3DSurface::PreLoad for details
5726 *****************************************************************************/
5728 IDirect3DDeviceImpl_7_PreLoad(IDirect3DDevice7
*iface
,
5729 IDirectDrawSurface7
*Texture
)
5731 struct ddraw_surface
*surface
= unsafe_impl_from_IDirectDrawSurface7(Texture
);
5733 TRACE("iface %p, texture %p.\n", iface
, Texture
);
5736 return DDERR_INVALIDPARAMS
;
5738 wined3d_mutex_lock();
5739 wined3d_surface_preload(surface
->wined3d_surface
);
5740 wined3d_mutex_unlock();
5745 static HRESULT WINAPI
5746 IDirect3DDeviceImpl_7_PreLoad_FPUSetup(IDirect3DDevice7
*iface
,
5747 IDirectDrawSurface7
*Texture
)
5749 return IDirect3DDeviceImpl_7_PreLoad(iface
, Texture
);
5752 static HRESULT WINAPI
5753 IDirect3DDeviceImpl_7_PreLoad_FPUPreserve(IDirect3DDevice7
*iface
,
5754 IDirectDrawSurface7
*Texture
)
5759 old_fpucw
= d3d_fpu_setup();
5760 hr
= IDirect3DDeviceImpl_7_PreLoad(iface
, Texture
);
5761 set_fpu_control_word(old_fpucw
);
5766 /*****************************************************************************
5767 * IDirect3DDevice7::ApplyStateBlock
5769 * Activates the state stored in a state block handle.
5772 * BlockHandle: The stateblock handle to activate
5776 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is NULL
5778 *****************************************************************************/
5780 IDirect3DDeviceImpl_7_ApplyStateBlock(IDirect3DDevice7
*iface
,
5783 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
5784 struct wined3d_stateblock
*wined3d_sb
;
5787 TRACE("iface %p, stateblock %#x.\n", iface
, BlockHandle
);
5789 wined3d_mutex_lock();
5790 wined3d_sb
= ddraw_get_object(&This
->handle_table
, BlockHandle
- 1, DDRAW_HANDLE_STATEBLOCK
);
5793 WARN("Invalid stateblock handle.\n");
5794 wined3d_mutex_unlock();
5795 return D3DERR_INVALIDSTATEBLOCK
;
5798 hr
= wined3d_stateblock_apply(wined3d_sb
);
5799 wined3d_mutex_unlock();
5801 return hr_ddraw_from_wined3d(hr
);
5804 static HRESULT WINAPI
5805 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUSetup(IDirect3DDevice7
*iface
,
5808 return IDirect3DDeviceImpl_7_ApplyStateBlock(iface
, BlockHandle
);
5811 static HRESULT WINAPI
5812 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUPreserve(IDirect3DDevice7
*iface
,
5818 old_fpucw
= d3d_fpu_setup();
5819 hr
= IDirect3DDeviceImpl_7_ApplyStateBlock(iface
, BlockHandle
);
5820 set_fpu_control_word(old_fpucw
);
5825 /*****************************************************************************
5826 * IDirect3DDevice7::CaptureStateBlock
5828 * Updates a stateblock's values to the values currently set for the device
5833 * BlockHandle: Stateblock to update
5837 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is NULL
5838 * See IWineD3DDevice::CaptureStateBlock for more details
5840 *****************************************************************************/
5842 IDirect3DDeviceImpl_7_CaptureStateBlock(IDirect3DDevice7
*iface
,
5845 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
5846 struct wined3d_stateblock
*wined3d_sb
;
5849 TRACE("iface %p, stateblock %#x.\n", iface
, BlockHandle
);
5851 wined3d_mutex_lock();
5852 wined3d_sb
= ddraw_get_object(&This
->handle_table
, BlockHandle
- 1, DDRAW_HANDLE_STATEBLOCK
);
5855 WARN("Invalid stateblock handle.\n");
5856 wined3d_mutex_unlock();
5857 return D3DERR_INVALIDSTATEBLOCK
;
5860 hr
= wined3d_stateblock_capture(wined3d_sb
);
5861 wined3d_mutex_unlock();
5863 return hr_ddraw_from_wined3d(hr
);
5866 static HRESULT WINAPI
5867 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUSetup(IDirect3DDevice7
*iface
,
5870 return IDirect3DDeviceImpl_7_CaptureStateBlock(iface
, BlockHandle
);
5873 static HRESULT WINAPI
5874 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUPreserve(IDirect3DDevice7
*iface
,
5880 old_fpucw
= d3d_fpu_setup();
5881 hr
= IDirect3DDeviceImpl_7_CaptureStateBlock(iface
, BlockHandle
);
5882 set_fpu_control_word(old_fpucw
);
5887 /*****************************************************************************
5888 * IDirect3DDevice7::DeleteStateBlock
5890 * Deletes a stateblock handle. This means releasing the WineD3DStateBlock
5895 * BlockHandle: Stateblock handle to delete
5899 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is 0
5901 *****************************************************************************/
5903 IDirect3DDeviceImpl_7_DeleteStateBlock(IDirect3DDevice7
*iface
,
5906 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
5907 struct wined3d_stateblock
*wined3d_sb
;
5910 TRACE("iface %p, stateblock %#x.\n", iface
, BlockHandle
);
5912 wined3d_mutex_lock();
5914 wined3d_sb
= ddraw_free_handle(&This
->handle_table
, BlockHandle
- 1, DDRAW_HANDLE_STATEBLOCK
);
5917 WARN("Invalid stateblock handle.\n");
5918 wined3d_mutex_unlock();
5919 return D3DERR_INVALIDSTATEBLOCK
;
5922 if ((ref
= wined3d_stateblock_decref(wined3d_sb
)))
5924 ERR("Something is still holding stateblock %p (refcount %u).\n", wined3d_sb
, ref
);
5927 wined3d_mutex_unlock();
5932 static HRESULT WINAPI
5933 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUSetup(IDirect3DDevice7
*iface
,
5936 return IDirect3DDeviceImpl_7_DeleteStateBlock(iface
, BlockHandle
);
5939 static HRESULT WINAPI
5940 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUPreserve(IDirect3DDevice7
*iface
,
5946 old_fpucw
= d3d_fpu_setup();
5947 hr
= IDirect3DDeviceImpl_7_DeleteStateBlock(iface
, BlockHandle
);
5948 set_fpu_control_word(old_fpucw
);
5953 /*****************************************************************************
5954 * IDirect3DDevice7::CreateStateBlock
5956 * Creates a new state block handle.
5961 * Type: The state block type
5962 * BlockHandle: Address to write the created handle to
5966 * DDERR_INVALIDPARAMS if BlockHandle is NULL
5968 *****************************************************************************/
5970 IDirect3DDeviceImpl_7_CreateStateBlock(IDirect3DDevice7
*iface
,
5971 D3DSTATEBLOCKTYPE Type
,
5974 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
5975 struct wined3d_stateblock
*wined3d_sb
;
5979 TRACE("iface %p, type %#x, stateblock %p.\n", iface
, Type
, BlockHandle
);
5983 WARN("BlockHandle == NULL, returning DDERR_INVALIDPARAMS\n");
5984 return DDERR_INVALIDPARAMS
;
5986 if(Type
!= D3DSBT_ALL
&& Type
!= D3DSBT_PIXELSTATE
&&
5987 Type
!= D3DSBT_VERTEXSTATE
) {
5988 WARN("Unexpected stateblock type, returning DDERR_INVALIDPARAMS\n");
5989 return DDERR_INVALIDPARAMS
;
5992 wined3d_mutex_lock();
5994 /* The D3DSTATEBLOCKTYPE enum is fine here. */
5995 hr
= wined3d_stateblock_create(This
->wined3d_device
, Type
, &wined3d_sb
);
5998 WARN("Failed to create stateblock, hr %#x.\n", hr
);
5999 wined3d_mutex_unlock();
6000 return hr_ddraw_from_wined3d(hr
);
6003 h
= ddraw_allocate_handle(&This
->handle_table
, wined3d_sb
, DDRAW_HANDLE_STATEBLOCK
);
6004 if (h
== DDRAW_INVALID_HANDLE
)
6006 ERR("Failed to allocate stateblock handle.\n");
6007 wined3d_stateblock_decref(wined3d_sb
);
6008 wined3d_mutex_unlock();
6009 return DDERR_OUTOFMEMORY
;
6012 *BlockHandle
= h
+ 1;
6013 wined3d_mutex_unlock();
6015 return hr_ddraw_from_wined3d(hr
);
6018 static HRESULT WINAPI
6019 IDirect3DDeviceImpl_7_CreateStateBlock_FPUSetup(IDirect3DDevice7
*iface
,
6020 D3DSTATEBLOCKTYPE Type
,
6023 return IDirect3DDeviceImpl_7_CreateStateBlock(iface
, Type
, BlockHandle
);
6026 static HRESULT WINAPI
6027 IDirect3DDeviceImpl_7_CreateStateBlock_FPUPreserve(IDirect3DDevice7
*iface
,
6028 D3DSTATEBLOCKTYPE Type
,
6034 old_fpucw
= d3d_fpu_setup();
6035 hr
=IDirect3DDeviceImpl_7_CreateStateBlock(iface
, Type
, BlockHandle
);
6036 set_fpu_control_word(old_fpucw
);
6041 /* Helper function for IDirect3DDeviceImpl_7_Load. */
6042 static BOOL
is_mip_level_subset(struct ddraw_surface
*dest
, struct ddraw_surface
*src
)
6044 struct ddraw_surface
*src_level
, *dest_level
;
6045 IDirectDrawSurface7
*temp
;
6046 DDSURFACEDESC2 ddsd
;
6047 BOOL levelFound
; /* at least one suitable sublevel in dest found */
6049 /* To satisfy "destination is mip level subset of source" criteria (regular texture counts as 1 level),
6050 * 1) there must be at least one mip level in destination that matched dimensions of some mip level in source and
6051 * 2) there must be no destination levels that don't match any levels in source. Otherwise it's INVALIDPARAMS.
6058 for (;src_level
&& dest_level
;)
6060 if (src_level
->surface_desc
.dwWidth
== dest_level
->surface_desc
.dwWidth
&&
6061 src_level
->surface_desc
.dwHeight
== dest_level
->surface_desc
.dwHeight
)
6065 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
6066 ddsd
.ddsCaps
.dwCaps2
= DDSCAPS2_MIPMAPSUBLEVEL
;
6067 IDirectDrawSurface7_GetAttachedSurface(&dest_level
->IDirectDrawSurface7_iface
, &ddsd
.ddsCaps
, &temp
);
6069 if (dest_level
!= dest
) IDirectDrawSurface7_Release(&dest_level
->IDirectDrawSurface7_iface
);
6071 dest_level
= unsafe_impl_from_IDirectDrawSurface7(temp
);
6074 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
6075 ddsd
.ddsCaps
.dwCaps2
= DDSCAPS2_MIPMAPSUBLEVEL
;
6076 IDirectDrawSurface7_GetAttachedSurface(&src_level
->IDirectDrawSurface7_iface
, &ddsd
.ddsCaps
, &temp
);
6078 if (src_level
!= src
) IDirectDrawSurface7_Release(&src_level
->IDirectDrawSurface7_iface
);
6080 src_level
= unsafe_impl_from_IDirectDrawSurface7(temp
);
6083 if (src_level
&& src_level
!= src
) IDirectDrawSurface7_Release(&src_level
->IDirectDrawSurface7_iface
);
6084 if (dest_level
&& dest_level
!= dest
) IDirectDrawSurface7_Release(&dest_level
->IDirectDrawSurface7_iface
);
6086 return !dest_level
&& levelFound
;
6089 /* Helper function for IDirect3DDeviceImpl_7_Load. */
6090 static void copy_mipmap_chain(IDirect3DDeviceImpl
*device
, struct ddraw_surface
*dest
,
6091 struct ddraw_surface
*src
, const POINT
*DestPoint
, const RECT
*SrcRect
)
6093 struct ddraw_surface
*src_level
, *dest_level
;
6094 IDirectDrawSurface7
*temp
;
6095 DDSURFACEDESC2 ddsd
;
6099 IDirectDrawPalette
*pal
= NULL
, *pal_src
= NULL
;
6103 /* Copy palette, if possible. */
6104 IDirectDrawSurface7_GetPalette(&src
->IDirectDrawSurface7_iface
, &pal_src
);
6105 IDirectDrawSurface7_GetPalette(&dest
->IDirectDrawSurface7_iface
, &pal
);
6107 if (pal_src
!= NULL
&& pal
!= NULL
)
6109 PALETTEENTRY palent
[256];
6111 IDirectDrawPalette_GetEntries(pal_src
, 0, 0, 256, palent
);
6112 IDirectDrawPalette_SetEntries(pal
, 0, 0, 256, palent
);
6115 if (pal
) IDirectDrawPalette_Release(pal
);
6116 if (pal_src
) IDirectDrawPalette_Release(pal_src
);
6118 /* Copy colorkeys, if present. */
6119 for (ckeyflag
= DDCKEY_DESTBLT
; ckeyflag
<= DDCKEY_SRCOVERLAY
; ckeyflag
<<= 1)
6121 hr
= IDirectDrawSurface7_GetColorKey(&src
->IDirectDrawSurface7_iface
, ckeyflag
, &ddckey
);
6125 IDirectDrawSurface7_SetColorKey(&dest
->IDirectDrawSurface7_iface
, ckeyflag
, &ddckey
);
6133 src_rect
= *SrcRect
;
6135 for (;src_level
&& dest_level
;)
6137 if (src_level
->surface_desc
.dwWidth
== dest_level
->surface_desc
.dwWidth
&&
6138 src_level
->surface_desc
.dwHeight
== dest_level
->surface_desc
.dwHeight
)
6140 UINT src_w
= src_rect
.right
- src_rect
.left
;
6141 UINT src_h
= src_rect
.bottom
- src_rect
.top
;
6142 RECT dst_rect
= {point
.x
, point
.y
, point
.x
+ src_w
, point
.y
+ src_h
};
6144 if (FAILED(hr
= wined3d_surface_blt(dest_level
->wined3d_surface
, &dst_rect
,
6145 src_level
->wined3d_surface
, &src_rect
, 0, NULL
, WINED3D_TEXF_POINT
)))
6146 ERR("Blit failed, hr %#x.\n", hr
);
6148 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
6149 ddsd
.ddsCaps
.dwCaps2
= DDSCAPS2_MIPMAPSUBLEVEL
;
6150 IDirectDrawSurface7_GetAttachedSurface(&dest_level
->IDirectDrawSurface7_iface
, &ddsd
.ddsCaps
, &temp
);
6152 if (dest_level
!= dest
) IDirectDrawSurface7_Release(&dest_level
->IDirectDrawSurface7_iface
);
6154 dest_level
= unsafe_impl_from_IDirectDrawSurface7(temp
);
6157 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
6158 ddsd
.ddsCaps
.dwCaps2
= DDSCAPS2_MIPMAPSUBLEVEL
;
6159 IDirectDrawSurface7_GetAttachedSurface(&src_level
->IDirectDrawSurface7_iface
, &ddsd
.ddsCaps
, &temp
);
6161 if (src_level
!= src
) IDirectDrawSurface7_Release(&src_level
->IDirectDrawSurface7_iface
);
6163 src_level
= unsafe_impl_from_IDirectDrawSurface7(temp
);
6170 src_rect
.right
= (src_rect
.right
+ 1) / 2;
6171 src_rect
.bottom
= (src_rect
.bottom
+ 1) / 2;
6174 if (src_level
&& src_level
!= src
) IDirectDrawSurface7_Release(&src_level
->IDirectDrawSurface7_iface
);
6175 if (dest_level
&& dest_level
!= dest
) IDirectDrawSurface7_Release(&dest_level
->IDirectDrawSurface7_iface
);
6178 /*****************************************************************************
6179 * IDirect3DDevice7::Load
6181 * Loads a rectangular area from the source into the destination texture.
6182 * It can also copy the source to the faces of a cubic environment map
6187 * DestTex: Destination texture
6188 * DestPoint: Point in the destination where the source image should be
6190 * SrcTex: Source texture
6191 * SrcRect: Source rectangle
6192 * Flags: Cubemap faces to load (DDSCAPS2_CUBEMAP_ALLFACES, DDSCAPS2_CUBEMAP_POSITIVEX,
6193 * DDSCAPS2_CUBEMAP_NEGATIVEX, DDSCAPS2_CUBEMAP_POSITIVEY, DDSCAPS2_CUBEMAP_NEGATIVEY,
6194 * DDSCAPS2_CUBEMAP_POSITIVEZ, DDSCAPS2_CUBEMAP_NEGATIVEZ)
6198 * DDERR_INVALIDPARAMS if DestTex or SrcTex are NULL, broken coordinates or anything unexpected.
6201 *****************************************************************************/
6204 IDirect3DDeviceImpl_7_Load(IDirect3DDevice7
*iface
,
6205 IDirectDrawSurface7
*DestTex
,
6207 IDirectDrawSurface7
*SrcTex
,
6211 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
6212 struct ddraw_surface
*dest
= unsafe_impl_from_IDirectDrawSurface7(DestTex
);
6213 struct ddraw_surface
*src
= unsafe_impl_from_IDirectDrawSurface7(SrcTex
);
6217 TRACE("iface %p, dst_texture %p, dst_pos %s, src_texture %p, src_rect %s, flags %#x.\n",
6218 iface
, DestTex
, wine_dbgstr_point(DestPoint
), SrcTex
, wine_dbgstr_rect(SrcRect
), Flags
);
6220 if( (!src
) || (!dest
) )
6221 return DDERR_INVALIDPARAMS
;
6223 wined3d_mutex_lock();
6225 if (SrcRect
) srcrect
= *SrcRect
;
6228 srcrect
.left
= srcrect
.top
= 0;
6229 srcrect
.right
= src
->surface_desc
.dwWidth
;
6230 srcrect
.bottom
= src
->surface_desc
.dwHeight
;
6233 if (DestPoint
) destpoint
= *DestPoint
;
6236 destpoint
.x
= destpoint
.y
= 0;
6238 /* Check bad dimensions. DestPoint is validated against src, not dest, because
6239 * destination can be a subset of mip levels, in which case actual coordinates used
6240 * for it may be divided. If any dimension of dest is larger than source, it can't be
6241 * mip level subset, so an error can be returned early.
6243 if (srcrect
.left
>= srcrect
.right
|| srcrect
.top
>= srcrect
.bottom
||
6244 srcrect
.right
> src
->surface_desc
.dwWidth
||
6245 srcrect
.bottom
> src
->surface_desc
.dwHeight
||
6246 destpoint
.x
+ srcrect
.right
- srcrect
.left
> src
->surface_desc
.dwWidth
||
6247 destpoint
.y
+ srcrect
.bottom
- srcrect
.top
> src
->surface_desc
.dwHeight
||
6248 dest
->surface_desc
.dwWidth
> src
->surface_desc
.dwWidth
||
6249 dest
->surface_desc
.dwHeight
> src
->surface_desc
.dwHeight
)
6251 wined3d_mutex_unlock();
6252 return DDERR_INVALIDPARAMS
;
6255 /* Must be top level surfaces. */
6256 if (src
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_MIPMAPSUBLEVEL
||
6257 dest
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_MIPMAPSUBLEVEL
)
6259 wined3d_mutex_unlock();
6260 return DDERR_INVALIDPARAMS
;
6263 if (src
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_CUBEMAP
)
6265 struct ddraw_surface
*src_face
, *dest_face
;
6266 DWORD src_face_flag
, dest_face_flag
;
6267 IDirectDrawSurface7
*temp
;
6268 DDSURFACEDESC2 ddsd
;
6271 if (!(dest
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_CUBEMAP
))
6273 wined3d_mutex_unlock();
6274 return DDERR_INVALIDPARAMS
;
6277 /* Iterate through cube faces 2 times. First time is just to check INVALIDPARAMS conditions, second
6278 * time it's actual surface loading. */
6279 for (i
= 0; i
< 2; i
++)
6284 for (;dest_face
&& src_face
;)
6286 src_face_flag
= src_face
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_CUBEMAP_ALLFACES
;
6287 dest_face_flag
= dest_face
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_CUBEMAP_ALLFACES
;
6289 if (src_face_flag
== dest_face_flag
)
6293 /* Destination mip levels must be subset of source mip levels. */
6294 if (!is_mip_level_subset(dest_face
, src_face
))
6296 wined3d_mutex_unlock();
6297 return DDERR_INVALIDPARAMS
;
6300 else if (Flags
& dest_face_flag
)
6302 copy_mipmap_chain(This
, dest_face
, src_face
, &destpoint
, &srcrect
);
6305 if (src_face_flag
< DDSCAPS2_CUBEMAP_NEGATIVEZ
)
6307 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
6308 ddsd
.ddsCaps
.dwCaps2
= DDSCAPS2_CUBEMAP
| (src_face_flag
<< 1);
6309 IDirectDrawSurface7_GetAttachedSurface(&src
->IDirectDrawSurface7_iface
, &ddsd
.ddsCaps
, &temp
);
6311 if (src_face
!= src
) IDirectDrawSurface7_Release(&src_face
->IDirectDrawSurface7_iface
);
6313 src_face
= unsafe_impl_from_IDirectDrawSurface7(temp
);
6317 if (src_face
!= src
) IDirectDrawSurface7_Release(&src_face
->IDirectDrawSurface7_iface
);
6323 if (dest_face_flag
< DDSCAPS2_CUBEMAP_NEGATIVEZ
)
6325 ddsd
.ddsCaps
.dwCaps
= DDSCAPS_TEXTURE
;
6326 ddsd
.ddsCaps
.dwCaps2
= DDSCAPS2_CUBEMAP
| (dest_face_flag
<< 1);
6327 IDirectDrawSurface7_GetAttachedSurface(&dest
->IDirectDrawSurface7_iface
, &ddsd
.ddsCaps
, &temp
);
6329 if (dest_face
!= dest
) IDirectDrawSurface7_Release(&dest_face
->IDirectDrawSurface7_iface
);
6331 dest_face
= unsafe_impl_from_IDirectDrawSurface7(temp
);
6335 if (dest_face
!= dest
) IDirectDrawSurface7_Release(&dest_face
->IDirectDrawSurface7_iface
);
6343 /* Native returns error if src faces are not subset of dest faces. */
6346 wined3d_mutex_unlock();
6347 return DDERR_INVALIDPARAMS
;
6352 wined3d_mutex_unlock();
6355 else if (dest
->surface_desc
.ddsCaps
.dwCaps2
& DDSCAPS2_CUBEMAP
)
6357 wined3d_mutex_unlock();
6358 return DDERR_INVALIDPARAMS
;
6361 /* Handle non cube map textures. */
6363 /* Destination mip levels must be subset of source mip levels. */
6364 if (!is_mip_level_subset(dest
, src
))
6366 wined3d_mutex_unlock();
6367 return DDERR_INVALIDPARAMS
;
6370 copy_mipmap_chain(This
, dest
, src
, &destpoint
, &srcrect
);
6372 wined3d_mutex_unlock();
6377 static HRESULT WINAPI
6378 IDirect3DDeviceImpl_7_Load_FPUSetup(IDirect3DDevice7
*iface
,
6379 IDirectDrawSurface7
*DestTex
,
6381 IDirectDrawSurface7
*SrcTex
,
6385 return IDirect3DDeviceImpl_7_Load(iface
, DestTex
, DestPoint
, SrcTex
, SrcRect
, Flags
);
6388 static HRESULT WINAPI
6389 IDirect3DDeviceImpl_7_Load_FPUPreserve(IDirect3DDevice7
*iface
,
6390 IDirectDrawSurface7
*DestTex
,
6392 IDirectDrawSurface7
*SrcTex
,
6399 old_fpucw
= d3d_fpu_setup();
6400 hr
= IDirect3DDeviceImpl_7_Load(iface
, DestTex
, DestPoint
, SrcTex
, SrcRect
, Flags
);
6401 set_fpu_control_word(old_fpucw
);
6406 /*****************************************************************************
6407 * IDirect3DDevice7::LightEnable
6409 * Enables or disables a light
6411 * Version 7, IDirect3DLight uses this method too.
6414 * LightIndex: The index of the light to enable / disable
6415 * Enable: Enable or disable the light
6419 * For more details, see IWineD3DDevice::SetLightEnable
6421 *****************************************************************************/
6423 IDirect3DDeviceImpl_7_LightEnable(IDirect3DDevice7
*iface
,
6427 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
6430 TRACE("iface %p, light_idx %u, enabled %#x.\n", iface
, LightIndex
, Enable
);
6432 wined3d_mutex_lock();
6433 hr
= wined3d_device_set_light_enable(This
->wined3d_device
, LightIndex
, Enable
);
6434 wined3d_mutex_unlock();
6436 return hr_ddraw_from_wined3d(hr
);
6439 static HRESULT WINAPI
6440 IDirect3DDeviceImpl_7_LightEnable_FPUSetup(IDirect3DDevice7
*iface
,
6444 return IDirect3DDeviceImpl_7_LightEnable(iface
, LightIndex
, Enable
);
6447 static HRESULT WINAPI
6448 IDirect3DDeviceImpl_7_LightEnable_FPUPreserve(IDirect3DDevice7
*iface
,
6455 old_fpucw
= d3d_fpu_setup();
6456 hr
= IDirect3DDeviceImpl_7_LightEnable(iface
, LightIndex
, Enable
);
6457 set_fpu_control_word(old_fpucw
);
6462 /*****************************************************************************
6463 * IDirect3DDevice7::GetLightEnable
6465 * Retrieves if the light with the given index is enabled or not
6470 * LightIndex: Index of desired light
6471 * Enable: Pointer to a BOOL which contains the result
6475 * DDERR_INVALIDPARAMS if Enable is NULL
6476 * See IWineD3DDevice::GetLightEnable for more details
6478 *****************************************************************************/
6480 IDirect3DDeviceImpl_7_GetLightEnable(IDirect3DDevice7
*iface
,
6484 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
6487 TRACE("iface %p, light_idx %u, enabled %p.\n", iface
, LightIndex
, Enable
);
6490 return DDERR_INVALIDPARAMS
;
6492 wined3d_mutex_lock();
6493 hr
= wined3d_device_get_light_enable(This
->wined3d_device
, LightIndex
, Enable
);
6494 wined3d_mutex_unlock();
6496 return hr_ddraw_from_wined3d(hr
);
6499 static HRESULT WINAPI
6500 IDirect3DDeviceImpl_7_GetLightEnable_FPUSetup(IDirect3DDevice7
*iface
,
6504 return IDirect3DDeviceImpl_7_GetLightEnable(iface
, LightIndex
, Enable
);
6507 static HRESULT WINAPI
6508 IDirect3DDeviceImpl_7_GetLightEnable_FPUPreserve(IDirect3DDevice7
*iface
,
6515 old_fpucw
= d3d_fpu_setup();
6516 hr
= IDirect3DDeviceImpl_7_GetLightEnable(iface
, LightIndex
, Enable
);
6517 set_fpu_control_word(old_fpucw
);
6522 /*****************************************************************************
6523 * IDirect3DDevice7::SetClipPlane
6525 * Sets custom clipping plane
6530 * Index: The index of the clipping plane
6531 * PlaneEquation: An equation defining the clipping plane
6535 * DDERR_INVALIDPARAMS if PlaneEquation is NULL
6536 * See IWineD3DDevice::SetClipPlane for more details
6538 *****************************************************************************/
6540 IDirect3DDeviceImpl_7_SetClipPlane(IDirect3DDevice7
*iface
,
6542 D3DVALUE
* PlaneEquation
)
6544 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
6547 TRACE("iface %p, idx %u, plane %p.\n", iface
, Index
, PlaneEquation
);
6550 return DDERR_INVALIDPARAMS
;
6552 wined3d_mutex_lock();
6553 hr
= wined3d_device_set_clip_plane(This
->wined3d_device
, Index
, PlaneEquation
);
6554 wined3d_mutex_unlock();
6559 static HRESULT WINAPI
6560 IDirect3DDeviceImpl_7_SetClipPlane_FPUSetup(IDirect3DDevice7
*iface
,
6562 D3DVALUE
* PlaneEquation
)
6564 return IDirect3DDeviceImpl_7_SetClipPlane(iface
, Index
, PlaneEquation
);
6567 static HRESULT WINAPI
6568 IDirect3DDeviceImpl_7_SetClipPlane_FPUPreserve(IDirect3DDevice7
*iface
,
6570 D3DVALUE
* PlaneEquation
)
6575 old_fpucw
= d3d_fpu_setup();
6576 hr
= IDirect3DDeviceImpl_7_SetClipPlane(iface
, Index
, PlaneEquation
);
6577 set_fpu_control_word(old_fpucw
);
6582 /*****************************************************************************
6583 * IDirect3DDevice7::GetClipPlane
6585 * Returns the clipping plane with a specific index
6588 * Index: The index of the desired plane
6589 * PlaneEquation: Address to store the plane equation to
6593 * DDERR_INVALIDPARAMS if PlaneEquation is NULL
6594 * See IWineD3DDevice::GetClipPlane for more details
6596 *****************************************************************************/
6598 IDirect3DDeviceImpl_7_GetClipPlane(IDirect3DDevice7
*iface
,
6600 D3DVALUE
* PlaneEquation
)
6602 IDirect3DDeviceImpl
*This
= impl_from_IDirect3DDevice7(iface
);
6605 TRACE("iface %p, idx %u, plane %p.\n", iface
, Index
, PlaneEquation
);
6608 return DDERR_INVALIDPARAMS
;
6610 wined3d_mutex_lock();
6611 hr
= wined3d_device_get_clip_plane(This
->wined3d_device
, Index
, PlaneEquation
);
6612 wined3d_mutex_unlock();
6617 static HRESULT WINAPI
6618 IDirect3DDeviceImpl_7_GetClipPlane_FPUSetup(IDirect3DDevice7
*iface
,
6620 D3DVALUE
* PlaneEquation
)
6622 return IDirect3DDeviceImpl_7_GetClipPlane(iface
, Index
, PlaneEquation
);
6625 static HRESULT WINAPI
6626 IDirect3DDeviceImpl_7_GetClipPlane_FPUPreserve(IDirect3DDevice7
*iface
,
6628 D3DVALUE
* PlaneEquation
)
6633 old_fpucw
= d3d_fpu_setup();
6634 hr
= IDirect3DDeviceImpl_7_GetClipPlane(iface
, Index
, PlaneEquation
);
6635 set_fpu_control_word(old_fpucw
);
6640 /*****************************************************************************
6641 * IDirect3DDevice7::GetInfo
6643 * Retrieves some information about the device. The DirectX sdk says that
6644 * this version returns S_FALSE for all retail builds of DirectX, that's what
6645 * this implementation does.
6648 * DevInfoID: Information type requested
6649 * DevInfoStruct: Pointer to a structure to store the info to
6650 * Size: Size of the structure
6653 * S_FALSE, because it's a non-debug driver
6655 *****************************************************************************/
6656 static HRESULT WINAPI
6657 IDirect3DDeviceImpl_7_GetInfo(IDirect3DDevice7
*iface
,
6659 void *DevInfoStruct
,
6662 TRACE("iface %p, info_id %#x, info %p, info_size %u.\n",
6663 iface
, DevInfoID
, DevInfoStruct
, Size
);
6665 if (TRACE_ON(ddraw
))
6667 TRACE(" info requested : ");
6670 case D3DDEVINFOID_TEXTUREMANAGER
: TRACE("D3DDEVINFOID_TEXTUREMANAGER\n"); break;
6671 case D3DDEVINFOID_D3DTEXTUREMANAGER
: TRACE("D3DDEVINFOID_D3DTEXTUREMANAGER\n"); break;
6672 case D3DDEVINFOID_TEXTURING
: TRACE("D3DDEVINFOID_TEXTURING\n"); break;
6673 default: ERR(" invalid flag !!!\n"); return DDERR_INVALIDPARAMS
;
6677 return S_FALSE
; /* According to MSDN, this is valid for a non-debug driver */
6680 /* For performance optimization, devices created in FPUSETUP and FPUPRESERVE modes
6681 * have separate vtables. Simple functions where this doesn't matter like GetDirect3D
6682 * are not duplicated.
6684 * Device created with DDSCL_FPUSETUP (d3d7 default) - device methods assume that FPU
6685 * has already been setup for optimal d3d operation.
6687 * Device created with DDSCL_FPUPRESERVE - resets and restores FPU mode when necessary in
6688 * d3d calls (FPU may be in a mode non-suitable for d3d when the app calls d3d). Required
6689 * by Sacrifice (game). */
6690 static const struct IDirect3DDevice7Vtbl d3d_device7_fpu_setup_vtbl
=
6692 /*** IUnknown Methods ***/
6693 IDirect3DDeviceImpl_7_QueryInterface
,
6694 IDirect3DDeviceImpl_7_AddRef
,
6695 IDirect3DDeviceImpl_7_Release
,
6696 /*** IDirect3DDevice7 ***/
6697 IDirect3DDeviceImpl_7_GetCaps_FPUSetup
,
6698 IDirect3DDeviceImpl_7_EnumTextureFormats_FPUSetup
,
6699 IDirect3DDeviceImpl_7_BeginScene_FPUSetup
,
6700 IDirect3DDeviceImpl_7_EndScene_FPUSetup
,
6701 IDirect3DDeviceImpl_7_GetDirect3D
,
6702 IDirect3DDeviceImpl_7_SetRenderTarget_FPUSetup
,
6703 IDirect3DDeviceImpl_7_GetRenderTarget
,
6704 IDirect3DDeviceImpl_7_Clear_FPUSetup
,
6705 IDirect3DDeviceImpl_7_SetTransform_FPUSetup
,
6706 IDirect3DDeviceImpl_7_GetTransform_FPUSetup
,
6707 IDirect3DDeviceImpl_7_SetViewport_FPUSetup
,
6708 IDirect3DDeviceImpl_7_MultiplyTransform_FPUSetup
,
6709 IDirect3DDeviceImpl_7_GetViewport_FPUSetup
,
6710 IDirect3DDeviceImpl_7_SetMaterial_FPUSetup
,
6711 IDirect3DDeviceImpl_7_GetMaterial_FPUSetup
,
6712 IDirect3DDeviceImpl_7_SetLight_FPUSetup
,
6713 IDirect3DDeviceImpl_7_GetLight_FPUSetup
,
6714 IDirect3DDeviceImpl_7_SetRenderState_FPUSetup
,
6715 IDirect3DDeviceImpl_7_GetRenderState_FPUSetup
,
6716 IDirect3DDeviceImpl_7_BeginStateBlock_FPUSetup
,
6717 IDirect3DDeviceImpl_7_EndStateBlock_FPUSetup
,
6718 IDirect3DDeviceImpl_7_PreLoad_FPUSetup
,
6719 IDirect3DDeviceImpl_7_DrawPrimitive_FPUSetup
,
6720 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUSetup
,
6721 IDirect3DDeviceImpl_7_SetClipStatus
,
6722 IDirect3DDeviceImpl_7_GetClipStatus
,
6723 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUSetup
,
6724 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUSetup
,
6725 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUSetup
,
6726 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUSetup
,
6727 IDirect3DDeviceImpl_7_ComputeSphereVisibility
,
6728 IDirect3DDeviceImpl_7_GetTexture_FPUSetup
,
6729 IDirect3DDeviceImpl_7_SetTexture_FPUSetup
,
6730 IDirect3DDeviceImpl_7_GetTextureStageState_FPUSetup
,
6731 IDirect3DDeviceImpl_7_SetTextureStageState_FPUSetup
,
6732 IDirect3DDeviceImpl_7_ValidateDevice_FPUSetup
,
6733 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUSetup
,
6734 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUSetup
,
6735 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUSetup
,
6736 IDirect3DDeviceImpl_7_CreateStateBlock_FPUSetup
,
6737 IDirect3DDeviceImpl_7_Load_FPUSetup
,
6738 IDirect3DDeviceImpl_7_LightEnable_FPUSetup
,
6739 IDirect3DDeviceImpl_7_GetLightEnable_FPUSetup
,
6740 IDirect3DDeviceImpl_7_SetClipPlane_FPUSetup
,
6741 IDirect3DDeviceImpl_7_GetClipPlane_FPUSetup
,
6742 IDirect3DDeviceImpl_7_GetInfo
6745 static const struct IDirect3DDevice7Vtbl d3d_device7_fpu_preserve_vtbl
=
6747 /*** IUnknown Methods ***/
6748 IDirect3DDeviceImpl_7_QueryInterface
,
6749 IDirect3DDeviceImpl_7_AddRef
,
6750 IDirect3DDeviceImpl_7_Release
,
6751 /*** IDirect3DDevice7 ***/
6752 IDirect3DDeviceImpl_7_GetCaps_FPUPreserve
,
6753 IDirect3DDeviceImpl_7_EnumTextureFormats_FPUPreserve
,
6754 IDirect3DDeviceImpl_7_BeginScene_FPUPreserve
,
6755 IDirect3DDeviceImpl_7_EndScene_FPUPreserve
,
6756 IDirect3DDeviceImpl_7_GetDirect3D
,
6757 IDirect3DDeviceImpl_7_SetRenderTarget_FPUPreserve
,
6758 IDirect3DDeviceImpl_7_GetRenderTarget
,
6759 IDirect3DDeviceImpl_7_Clear_FPUPreserve
,
6760 IDirect3DDeviceImpl_7_SetTransform_FPUPreserve
,
6761 IDirect3DDeviceImpl_7_GetTransform_FPUPreserve
,
6762 IDirect3DDeviceImpl_7_SetViewport_FPUPreserve
,
6763 IDirect3DDeviceImpl_7_MultiplyTransform_FPUPreserve
,
6764 IDirect3DDeviceImpl_7_GetViewport_FPUPreserve
,
6765 IDirect3DDeviceImpl_7_SetMaterial_FPUPreserve
,
6766 IDirect3DDeviceImpl_7_GetMaterial_FPUPreserve
,
6767 IDirect3DDeviceImpl_7_SetLight_FPUPreserve
,
6768 IDirect3DDeviceImpl_7_GetLight_FPUPreserve
,
6769 IDirect3DDeviceImpl_7_SetRenderState_FPUPreserve
,
6770 IDirect3DDeviceImpl_7_GetRenderState_FPUPreserve
,
6771 IDirect3DDeviceImpl_7_BeginStateBlock_FPUPreserve
,
6772 IDirect3DDeviceImpl_7_EndStateBlock_FPUPreserve
,
6773 IDirect3DDeviceImpl_7_PreLoad_FPUPreserve
,
6774 IDirect3DDeviceImpl_7_DrawPrimitive_FPUPreserve
,
6775 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUPreserve
,
6776 IDirect3DDeviceImpl_7_SetClipStatus
,
6777 IDirect3DDeviceImpl_7_GetClipStatus
,
6778 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUPreserve
,
6779 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUPreserve
,
6780 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUPreserve
,
6781 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUPreserve
,
6782 IDirect3DDeviceImpl_7_ComputeSphereVisibility
,
6783 IDirect3DDeviceImpl_7_GetTexture_FPUPreserve
,
6784 IDirect3DDeviceImpl_7_SetTexture_FPUPreserve
,
6785 IDirect3DDeviceImpl_7_GetTextureStageState_FPUPreserve
,
6786 IDirect3DDeviceImpl_7_SetTextureStageState_FPUPreserve
,
6787 IDirect3DDeviceImpl_7_ValidateDevice_FPUPreserve
,
6788 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUPreserve
,
6789 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUPreserve
,
6790 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUPreserve
,
6791 IDirect3DDeviceImpl_7_CreateStateBlock_FPUPreserve
,
6792 IDirect3DDeviceImpl_7_Load_FPUPreserve
,
6793 IDirect3DDeviceImpl_7_LightEnable_FPUPreserve
,
6794 IDirect3DDeviceImpl_7_GetLightEnable_FPUPreserve
,
6795 IDirect3DDeviceImpl_7_SetClipPlane_FPUPreserve
,
6796 IDirect3DDeviceImpl_7_GetClipPlane_FPUPreserve
,
6797 IDirect3DDeviceImpl_7_GetInfo
6800 static const struct IDirect3DDevice3Vtbl d3d_device3_vtbl
=
6802 /*** IUnknown Methods ***/
6803 IDirect3DDeviceImpl_3_QueryInterface
,
6804 IDirect3DDeviceImpl_3_AddRef
,
6805 IDirect3DDeviceImpl_3_Release
,
6806 /*** IDirect3DDevice3 ***/
6807 IDirect3DDeviceImpl_3_GetCaps
,
6808 IDirect3DDeviceImpl_3_GetStats
,
6809 IDirect3DDeviceImpl_3_AddViewport
,
6810 IDirect3DDeviceImpl_3_DeleteViewport
,
6811 IDirect3DDeviceImpl_3_NextViewport
,
6812 IDirect3DDeviceImpl_3_EnumTextureFormats
,
6813 IDirect3DDeviceImpl_3_BeginScene
,
6814 IDirect3DDeviceImpl_3_EndScene
,
6815 IDirect3DDeviceImpl_3_GetDirect3D
,
6816 IDirect3DDeviceImpl_3_SetCurrentViewport
,
6817 IDirect3DDeviceImpl_3_GetCurrentViewport
,
6818 IDirect3DDeviceImpl_3_SetRenderTarget
,
6819 IDirect3DDeviceImpl_3_GetRenderTarget
,
6820 IDirect3DDeviceImpl_3_Begin
,
6821 IDirect3DDeviceImpl_3_BeginIndexed
,
6822 IDirect3DDeviceImpl_3_Vertex
,
6823 IDirect3DDeviceImpl_3_Index
,
6824 IDirect3DDeviceImpl_3_End
,
6825 IDirect3DDeviceImpl_3_GetRenderState
,
6826 IDirect3DDeviceImpl_3_SetRenderState
,
6827 IDirect3DDeviceImpl_3_GetLightState
,
6828 IDirect3DDeviceImpl_3_SetLightState
,
6829 IDirect3DDeviceImpl_3_SetTransform
,
6830 IDirect3DDeviceImpl_3_GetTransform
,
6831 IDirect3DDeviceImpl_3_MultiplyTransform
,
6832 IDirect3DDeviceImpl_3_DrawPrimitive
,
6833 IDirect3DDeviceImpl_3_DrawIndexedPrimitive
,
6834 IDirect3DDeviceImpl_3_SetClipStatus
,
6835 IDirect3DDeviceImpl_3_GetClipStatus
,
6836 IDirect3DDeviceImpl_3_DrawPrimitiveStrided
,
6837 IDirect3DDeviceImpl_3_DrawIndexedPrimitiveStrided
,
6838 IDirect3DDeviceImpl_3_DrawPrimitiveVB
,
6839 IDirect3DDeviceImpl_3_DrawIndexedPrimitiveVB
,
6840 IDirect3DDeviceImpl_3_ComputeSphereVisibility
,
6841 IDirect3DDeviceImpl_3_GetTexture
,
6842 IDirect3DDeviceImpl_3_SetTexture
,
6843 IDirect3DDeviceImpl_3_GetTextureStageState
,
6844 IDirect3DDeviceImpl_3_SetTextureStageState
,
6845 IDirect3DDeviceImpl_3_ValidateDevice
6848 static const struct IDirect3DDevice2Vtbl d3d_device2_vtbl
=
6850 /*** IUnknown Methods ***/
6851 IDirect3DDeviceImpl_2_QueryInterface
,
6852 IDirect3DDeviceImpl_2_AddRef
,
6853 IDirect3DDeviceImpl_2_Release
,
6854 /*** IDirect3DDevice2 ***/
6855 IDirect3DDeviceImpl_2_GetCaps
,
6856 IDirect3DDeviceImpl_2_SwapTextureHandles
,
6857 IDirect3DDeviceImpl_2_GetStats
,
6858 IDirect3DDeviceImpl_2_AddViewport
,
6859 IDirect3DDeviceImpl_2_DeleteViewport
,
6860 IDirect3DDeviceImpl_2_NextViewport
,
6861 IDirect3DDeviceImpl_2_EnumTextureFormats
,
6862 IDirect3DDeviceImpl_2_BeginScene
,
6863 IDirect3DDeviceImpl_2_EndScene
,
6864 IDirect3DDeviceImpl_2_GetDirect3D
,
6865 IDirect3DDeviceImpl_2_SetCurrentViewport
,
6866 IDirect3DDeviceImpl_2_GetCurrentViewport
,
6867 IDirect3DDeviceImpl_2_SetRenderTarget
,
6868 IDirect3DDeviceImpl_2_GetRenderTarget
,
6869 IDirect3DDeviceImpl_2_Begin
,
6870 IDirect3DDeviceImpl_2_BeginIndexed
,
6871 IDirect3DDeviceImpl_2_Vertex
,
6872 IDirect3DDeviceImpl_2_Index
,
6873 IDirect3DDeviceImpl_2_End
,
6874 IDirect3DDeviceImpl_2_GetRenderState
,
6875 IDirect3DDeviceImpl_2_SetRenderState
,
6876 IDirect3DDeviceImpl_2_GetLightState
,
6877 IDirect3DDeviceImpl_2_SetLightState
,
6878 IDirect3DDeviceImpl_2_SetTransform
,
6879 IDirect3DDeviceImpl_2_GetTransform
,
6880 IDirect3DDeviceImpl_2_MultiplyTransform
,
6881 IDirect3DDeviceImpl_2_DrawPrimitive
,
6882 IDirect3DDeviceImpl_2_DrawIndexedPrimitive
,
6883 IDirect3DDeviceImpl_2_SetClipStatus
,
6884 IDirect3DDeviceImpl_2_GetClipStatus
6887 static const struct IDirect3DDeviceVtbl d3d_device1_vtbl
=
6889 /*** IUnknown Methods ***/
6890 IDirect3DDeviceImpl_1_QueryInterface
,
6891 IDirect3DDeviceImpl_1_AddRef
,
6892 IDirect3DDeviceImpl_1_Release
,
6893 /*** IDirect3DDevice1 ***/
6894 IDirect3DDeviceImpl_1_Initialize
,
6895 IDirect3DDeviceImpl_1_GetCaps
,
6896 IDirect3DDeviceImpl_1_SwapTextureHandles
,
6897 IDirect3DDeviceImpl_1_CreateExecuteBuffer
,
6898 IDirect3DDeviceImpl_1_GetStats
,
6899 IDirect3DDeviceImpl_1_Execute
,
6900 IDirect3DDeviceImpl_1_AddViewport
,
6901 IDirect3DDeviceImpl_1_DeleteViewport
,
6902 IDirect3DDeviceImpl_1_NextViewport
,
6903 IDirect3DDeviceImpl_1_Pick
,
6904 IDirect3DDeviceImpl_1_GetPickRecords
,
6905 IDirect3DDeviceImpl_1_EnumTextureFormats
,
6906 IDirect3DDeviceImpl_1_CreateMatrix
,
6907 IDirect3DDeviceImpl_1_SetMatrix
,
6908 IDirect3DDeviceImpl_1_GetMatrix
,
6909 IDirect3DDeviceImpl_1_DeleteMatrix
,
6910 IDirect3DDeviceImpl_1_BeginScene
,
6911 IDirect3DDeviceImpl_1_EndScene
,
6912 IDirect3DDeviceImpl_1_GetDirect3D
6915 IDirect3DDeviceImpl
*unsafe_impl_from_IDirect3DDevice7(IDirect3DDevice7
*iface
)
6917 if (!iface
) return NULL
;
6918 assert((iface
->lpVtbl
== &d3d_device7_fpu_preserve_vtbl
) || (iface
->lpVtbl
== &d3d_device7_fpu_setup_vtbl
));
6919 return CONTAINING_RECORD(iface
, IDirect3DDeviceImpl
, IDirect3DDevice7_iface
);
6922 IDirect3DDeviceImpl
*unsafe_impl_from_IDirect3DDevice3(IDirect3DDevice3
*iface
)
6924 if (!iface
) return NULL
;
6925 assert(iface
->lpVtbl
== &d3d_device3_vtbl
);
6926 return CONTAINING_RECORD(iface
, IDirect3DDeviceImpl
, IDirect3DDevice3_iface
);
6929 IDirect3DDeviceImpl
*unsafe_impl_from_IDirect3DDevice2(IDirect3DDevice2
*iface
)
6931 if (!iface
) return NULL
;
6932 assert(iface
->lpVtbl
== &d3d_device2_vtbl
);
6933 return CONTAINING_RECORD(iface
, IDirect3DDeviceImpl
, IDirect3DDevice2_iface
);
6936 IDirect3DDeviceImpl
*unsafe_impl_from_IDirect3DDevice(IDirect3DDevice
*iface
)
6938 if (!iface
) return NULL
;
6939 assert(iface
->lpVtbl
== &d3d_device1_vtbl
);
6940 return CONTAINING_RECORD(iface
, IDirect3DDeviceImpl
, IDirect3DDevice_iface
);
6943 /*****************************************************************************
6944 * IDirect3DDeviceImpl_UpdateDepthStencil
6946 * Checks the current render target for attached depth stencils and sets the
6947 * WineD3D depth stencil accordingly.
6950 * The depth stencil state to set if creating the device
6952 *****************************************************************************/
6953 enum wined3d_depth_buffer_type
IDirect3DDeviceImpl_UpdateDepthStencil(IDirect3DDeviceImpl
*This
)
6955 IDirectDrawSurface7
*depthStencil
= NULL
;
6956 static DDSCAPS2 depthcaps
= { DDSCAPS_ZBUFFER
, 0, 0, 0 };
6957 struct ddraw_surface
*dsi
;
6959 IDirectDrawSurface7_GetAttachedSurface(&This
->target
->IDirectDrawSurface7_iface
, &depthcaps
, &depthStencil
);
6962 TRACE("Setting wined3d depth stencil to NULL\n");
6963 wined3d_device_set_depth_stencil(This
->wined3d_device
, NULL
);
6964 return WINED3D_ZB_FALSE
;
6967 dsi
= impl_from_IDirectDrawSurface7(depthStencil
);
6968 TRACE("Setting wined3d depth stencil to %p (wined3d %p)\n", dsi
, dsi
->wined3d_surface
);
6969 wined3d_device_set_depth_stencil(This
->wined3d_device
, dsi
->wined3d_surface
);
6971 IDirectDrawSurface7_Release(depthStencil
);
6972 return WINED3D_ZB_TRUE
;
6975 static HRESULT
d3d_device_init(IDirect3DDeviceImpl
*device
, struct ddraw
*ddraw
,
6976 struct ddraw_surface
*target
, UINT version
)
6978 static const D3DMATRIX ident
=
6980 1.0f
, 0.0f
, 0.0f
, 0.0f
,
6981 0.0f
, 1.0f
, 0.0f
, 0.0f
,
6982 0.0f
, 0.0f
, 1.0f
, 0.0f
,
6983 0.0f
, 0.0f
, 0.0f
, 1.0f
,
6987 if (ddraw
->cooperative_level
& DDSCL_FPUPRESERVE
)
6988 device
->IDirect3DDevice7_iface
.lpVtbl
= &d3d_device7_fpu_preserve_vtbl
;
6990 device
->IDirect3DDevice7_iface
.lpVtbl
= &d3d_device7_fpu_setup_vtbl
;
6992 device
->IDirect3DDevice3_iface
.lpVtbl
= &d3d_device3_vtbl
;
6993 device
->IDirect3DDevice2_iface
.lpVtbl
= &d3d_device2_vtbl
;
6994 device
->IDirect3DDevice_iface
.lpVtbl
= &d3d_device1_vtbl
;
6996 device
->version
= version
;
6997 device
->ddraw
= ddraw
;
6998 device
->target
= target
;
6999 list_init(&device
->viewport_list
);
7001 if (!ddraw_handle_table_init(&device
->handle_table
, 64))
7003 ERR("Failed to initialize handle table.\n");
7004 return DDERR_OUTOFMEMORY
;
7007 device
->legacyTextureBlending
= FALSE
;
7008 device
->legacy_projection
= ident
;
7009 device
->legacy_clipspace
= ident
;
7011 /* Create an index buffer, it's needed for indexed drawing */
7012 hr
= wined3d_buffer_create_ib(ddraw
->wined3d_device
, 0x40000 /* Length. Don't know how long it should be */,
7013 WINED3DUSAGE_DYNAMIC
/* Usage */, WINED3D_POOL_DEFAULT
, NULL
,
7014 &ddraw_null_wined3d_parent_ops
, &device
->indexbuffer
);
7017 ERR("Failed to create an index buffer, hr %#x.\n", hr
);
7018 ddraw_handle_table_destroy(&device
->handle_table
);
7022 /* This is for convenience. */
7023 device
->wined3d_device
= ddraw
->wined3d_device
;
7024 wined3d_device_incref(ddraw
->wined3d_device
);
7026 /* Render to the back buffer */
7027 hr
= wined3d_device_set_render_target(ddraw
->wined3d_device
, 0, target
->wined3d_surface
, TRUE
);
7030 ERR("Failed to set render target, hr %#x.\n", hr
);
7031 wined3d_buffer_decref(device
->indexbuffer
);
7032 ddraw_handle_table_destroy(&device
->handle_table
);
7036 /* FIXME: This is broken. The target AddRef() makes some sense, because
7037 * we store a pointer during initialization, but then that's also where
7038 * the AddRef() should be. We don't store ddraw->d3d_target anywhere. */
7039 /* AddRef the render target. Also AddRef the render target from ddraw,
7040 * because if it is released before the app releases the D3D device, the
7041 * D3D capabilities of wined3d will be uninitialized, which has bad effects.
7043 * In most cases, those surfaces are the same anyway, but this will simply
7044 * add another ref which is released when the device is destroyed. */
7045 IDirectDrawSurface7_AddRef(&target
->IDirectDrawSurface7_iface
);
7047 ddraw
->d3ddevice
= device
;
7049 wined3d_device_set_render_state(ddraw
->wined3d_device
, WINED3D_RS_ZENABLE
,
7050 IDirect3DDeviceImpl_UpdateDepthStencil(device
));
7055 HRESULT
d3d_device_create(struct ddraw
*ddraw
, struct ddraw_surface
*target
,
7056 UINT version
, IDirect3DDeviceImpl
**device
)
7058 IDirect3DDeviceImpl
*object
;
7061 TRACE("ddraw %p, target %p, version %u, device %p.\n", ddraw
, target
, version
, device
);
7063 if (DefaultSurfaceType
!= WINED3D_SURFACE_TYPE_OPENGL
)
7065 ERR_(winediag
)("The application wants to create a Direct3D device, "
7066 "but the current DirectDrawRenderer does not support this.\n");
7071 if (ddraw
->d3ddevice
)
7073 FIXME("Only one Direct3D device per DirectDraw object supported.\n");
7074 return DDERR_INVALIDPARAMS
;
7077 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*object
));
7080 ERR("Failed to allocate device memory.\n");
7081 return DDERR_OUTOFMEMORY
;
7084 hr
= d3d_device_init(object
, ddraw
, target
, version
);
7087 WARN("Failed to initialize device, hr %#x.\n", hr
);
7088 HeapFree(GetProcessHeap(), 0, object
);
7092 TRACE("Created device %p.\n", object
);