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);
38 const GUID IID_D3DDEVICE_WineD3D = {
42 { 0xb7,0x98,0xc6,0x8a,0x77,0x2d,0x72,0x2a }
45 static inline void set_fpu_control_word(WORD fpucw)
47 #if defined(__i386__) && defined(__GNUC__)
48 __asm__ volatile ("fldcw %0" : : "m" (fpucw));
49 #elif defined(__i386__) && defined(_MSC_VER)
54 static inline WORD d3d_fpu_setup(void)
58 #if defined(__i386__) && defined(__GNUC__)
59 __asm__ volatile ("fnstcw %0" : "=m" (oldcw));
60 #elif defined(__i386__) && defined(_MSC_VER)
63 static BOOL warned = FALSE;
66 FIXME("FPUPRESERVE not implemented for this platform / compiler\n");
72 set_fpu_control_word(0x37f);
77 /*****************************************************************************
78 * IUnknown Methods. Common for Version 1, 2, 3 and 7
79 *****************************************************************************/
81 /*****************************************************************************
82 * IDirect3DDevice7::QueryInterface
84 * Used to query other interfaces from a Direct3DDevice interface.
85 * It can return interface pointers to all Direct3DDevice versions as well
86 * as IDirectDraw and IDirect3D. For a link to QueryInterface
87 * rules see ddraw.c, IDirectDraw7::QueryInterface
89 * Exists in Version 1, 2, 3 and 7
92 * refiid: Interface ID queried for
93 * obj: Used to return the interface pointer
96 * D3D_OK or E_NOINTERFACE
98 *****************************************************************************/
100 IDirect3DDeviceImpl_7_QueryInterface(IDirect3DDevice7 *iface,
104 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
106 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(refiid), obj);
108 /* According to COM docs, if the QueryInterface fails, obj should be set to NULL */
112 return DDERR_INVALIDPARAMS;
114 if ( IsEqualGUID( &IID_IUnknown, refiid ) )
119 /* Check DirectDraw Interfaces. */
120 else if( IsEqualGUID( &IID_IDirectDraw7, refiid ) )
122 *obj = &This->ddraw->IDirectDraw7_iface;
123 TRACE("(%p) Returning IDirectDraw7 interface at %p\n", This, *obj);
125 else if ( IsEqualGUID( &IID_IDirectDraw4, refiid ) )
127 *obj = &This->ddraw->IDirectDraw4_iface;
128 TRACE("(%p) Returning IDirectDraw4 interface at %p\n", This, *obj);
130 else if ( IsEqualGUID( &IID_IDirectDraw2, refiid ) )
132 *obj = &This->ddraw->IDirectDraw2_iface;
133 TRACE("(%p) Returning IDirectDraw2 interface at %p\n", This, *obj);
135 else if( IsEqualGUID( &IID_IDirectDraw, refiid ) )
137 *obj = &This->ddraw->IDirectDraw_iface;
138 TRACE("(%p) Returning IDirectDraw interface at %p\n", This, *obj);
142 else if ( IsEqualGUID( &IID_IDirect3D , refiid ) )
144 *obj = &This->ddraw->IDirect3D_iface;
145 TRACE("(%p) Returning IDirect3D interface at %p\n", This, *obj);
147 else if ( IsEqualGUID( &IID_IDirect3D2 , refiid ) )
149 *obj = &This->ddraw->IDirect3D2_iface;
150 TRACE("(%p) Returning IDirect3D2 interface at %p\n", This, *obj);
152 else if ( IsEqualGUID( &IID_IDirect3D3 , refiid ) )
154 *obj = &This->ddraw->IDirect3D3_iface;
155 TRACE("(%p) Returning IDirect3D3 interface at %p\n", This, *obj);
157 else if ( IsEqualGUID( &IID_IDirect3D7 , refiid ) )
159 *obj = &This->ddraw->IDirect3D7_iface;
160 TRACE("(%p) Returning IDirect3D7 interface at %p\n", This, *obj);
164 else if ( IsEqualGUID( &IID_IDirect3DDevice , refiid ) )
166 *obj = &This->IDirect3DDevice_vtbl;
167 TRACE("(%p) Returning IDirect3DDevice interface at %p\n", This, *obj);
169 else if ( IsEqualGUID( &IID_IDirect3DDevice2 , refiid ) ) {
170 *obj = &This->IDirect3DDevice2_vtbl;
171 TRACE("(%p) Returning IDirect3DDevice2 interface at %p\n", This, *obj);
173 else if ( IsEqualGUID( &IID_IDirect3DDevice3 , refiid ) ) {
174 *obj = &This->IDirect3DDevice3_vtbl;
175 TRACE("(%p) Returning IDirect3DDevice3 interface at %p\n", This, *obj);
177 else if ( IsEqualGUID( &IID_IDirect3DDevice7 , refiid ) ) {
179 TRACE("(%p) Returning IDirect3DDevice7 interface at %p\n", This, *obj);
182 /* Unknown interface */
185 ERR("(%p)->(%s, %p): No interface found\n", This, debugstr_guid(refiid), obj);
186 return E_NOINTERFACE;
189 /* AddRef the returned interface */
190 IUnknown_AddRef( (IUnknown *) *obj);
194 static HRESULT WINAPI IDirect3DDeviceImpl_3_QueryInterface(IDirect3DDevice3 *iface, REFIID riid,
197 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), obj);
199 return IDirect3DDevice7_QueryInterface((IDirect3DDevice7 *)device_from_device3(iface), riid, obj);
202 static HRESULT WINAPI IDirect3DDeviceImpl_2_QueryInterface(IDirect3DDevice2 *iface, REFIID riid,
205 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), obj);
207 return IDirect3DDevice7_QueryInterface((IDirect3DDevice7 *)device_from_device2(iface), riid, obj);
210 static HRESULT WINAPI IDirect3DDeviceImpl_1_QueryInterface(IDirect3DDevice *iface, REFIID riid,
213 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), obp);
215 return IDirect3DDevice7_QueryInterface((IDirect3DDevice7 *)device_from_device1(iface), riid, obp);
218 /*****************************************************************************
219 * IDirect3DDevice7::AddRef
221 * Increases the refcount....
222 * The most exciting Method, definitely
224 * Exists in Version 1, 2, 3 and 7
229 *****************************************************************************/
231 IDirect3DDeviceImpl_7_AddRef(IDirect3DDevice7 *iface)
233 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
234 ULONG ref = InterlockedIncrement(&This->ref);
236 TRACE("%p increasing refcount to %u.\n", This, ref);
241 static ULONG WINAPI IDirect3DDeviceImpl_3_AddRef(IDirect3DDevice3 *iface)
243 TRACE("iface %p.\n", iface);
245 return IDirect3DDevice7_AddRef((IDirect3DDevice7 *)device_from_device3(iface));
248 static ULONG WINAPI IDirect3DDeviceImpl_2_AddRef(IDirect3DDevice2 *iface)
250 TRACE("iface %p.\n", iface);
252 return IDirect3DDevice7_AddRef((IDirect3DDevice7 *)device_from_device2(iface));
255 static ULONG WINAPI IDirect3DDeviceImpl_1_AddRef(IDirect3DDevice *iface)
257 TRACE("iface %p.\n", iface);
259 return IDirect3DDevice7_AddRef((IDirect3DDevice7 *)device_from_device1(iface));
262 /*****************************************************************************
263 * IDirect3DDevice7::Release
265 * Decreases the refcount of the interface
266 * When the refcount is reduced to 0, the object is destroyed.
268 * Exists in Version 1, 2, 3 and 7
273 *****************************************************************************/
275 IDirect3DDeviceImpl_7_Release(IDirect3DDevice7 *iface)
277 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
278 ULONG ref = InterlockedDecrement(&This->ref);
280 TRACE("%p decreasing refcount to %u.\n", This, ref);
282 /* This method doesn't destroy the WineD3DDevice, because it's still in use for
283 * 2D rendering. IDirectDrawSurface7::Release will destroy the WineD3DDevice
284 * when the render target is released
290 EnterCriticalSection(&ddraw_cs);
292 /* There is no need to unset any resources here, wined3d will take
293 * care of that on Uninit3D(). */
295 /* Free the index buffer. */
296 wined3d_buffer_decref(This->indexbuffer);
298 /* Set the device up to render to the front buffer since the back
299 * buffer will vanish soon. */
300 wined3d_device_set_render_target(This->wined3d_device, 0,
301 This->ddraw->d3d_target->wined3d_surface, TRUE);
303 /* Release the WineD3DDevice. This won't destroy it. */
304 if (!wined3d_device_decref(This->wined3d_device))
305 ERR("The wined3d device (%p) was destroyed unexpectedly.\n", This->wined3d_device);
307 /* The texture handles should be unset by now, but there might be some bits
308 * missing in our reference counting(needs test). Do a sanity check. */
309 for (i = 0; i < This->handle_table.entry_count; ++i)
311 struct ddraw_handle_entry *entry = &This->handle_table.entries[i];
315 case DDRAW_HANDLE_FREE:
318 case DDRAW_HANDLE_MATERIAL:
320 IDirect3DMaterialImpl *m = entry->object;
321 FIXME("Material handle %#x (%p) not unset properly.\n", i + 1, m);
326 case DDRAW_HANDLE_MATRIX:
328 /* No FIXME here because this might happen because of sloppy applications. */
329 WARN("Leftover matrix handle %#x (%p), deleting.\n", i + 1, entry->object);
330 IDirect3DDevice_DeleteMatrix((IDirect3DDevice *)&This->IDirect3DDevice_vtbl, i + 1);
334 case DDRAW_HANDLE_STATEBLOCK:
336 /* No FIXME here because this might happen because of sloppy applications. */
337 WARN("Leftover stateblock handle %#x (%p), deleting.\n", i + 1, entry->object);
338 IDirect3DDevice7_DeleteStateBlock(iface, i + 1);
342 case DDRAW_HANDLE_SURFACE:
344 IDirectDrawSurfaceImpl *surf = entry->object;
345 FIXME("Texture handle %#x (%p) not unset properly.\n", i + 1, surf);
351 FIXME("Handle %#x (%p) has unknown type %#x.\n", i + 1, entry->object, entry->type);
356 ddraw_handle_table_destroy(&This->handle_table);
358 TRACE("Releasing target %p %p\n", This->target, This->ddraw->d3d_target);
359 /* Release the render target and the WineD3D render target
360 * (See IDirect3D7::CreateDevice for more comments on this)
362 IDirectDrawSurface7_Release(&This->target->IDirectDrawSurface7_iface);
363 IDirectDrawSurface7_Release(&This->ddraw->d3d_target->IDirectDrawSurface7_iface);
364 TRACE("Target release done\n");
366 This->ddraw->d3ddevice = NULL;
368 /* Now free the structure */
369 HeapFree(GetProcessHeap(), 0, This);
370 LeaveCriticalSection(&ddraw_cs);
377 static ULONG WINAPI IDirect3DDeviceImpl_3_Release(IDirect3DDevice3 *iface)
379 TRACE("iface %p.\n", iface);
381 return IDirect3DDevice7_Release((IDirect3DDevice7 *)device_from_device3(iface));
384 static ULONG WINAPI IDirect3DDeviceImpl_2_Release(IDirect3DDevice2 *iface)
386 TRACE("iface %p.\n", iface);
388 return IDirect3DDevice7_Release((IDirect3DDevice7 *)device_from_device2(iface));
391 static ULONG WINAPI IDirect3DDeviceImpl_1_Release(IDirect3DDevice *iface)
393 TRACE("iface %p.\n", iface);
395 return IDirect3DDevice7_Release((IDirect3DDevice7 *)device_from_device1(iface));
398 /*****************************************************************************
399 * IDirect3DDevice Methods
400 *****************************************************************************/
402 /*****************************************************************************
403 * IDirect3DDevice::Initialize
405 * Initializes a Direct3DDevice. This implementation is a no-op, as all
406 * initialization is done at create time.
408 * Exists in Version 1
411 * No idea what they mean, as the MSDN page is gone
415 *****************************************************************************/
416 static HRESULT WINAPI
417 IDirect3DDeviceImpl_1_Initialize(IDirect3DDevice *iface,
418 IDirect3D *Direct3D, GUID *guid,
421 /* It shouldn't be crucial, but print a FIXME, I'm interested if
422 * any game calls it and when. */
423 FIXME("iface %p, d3d %p, guid %s, device_desc %p nop!\n",
424 iface, Direct3D, debugstr_guid(guid), Desc);
429 /*****************************************************************************
430 * IDirect3DDevice7::GetCaps
432 * Retrieves the device's capabilities
434 * This implementation is used for Version 7 only, the older versions have
435 * their own implementation.
438 * Desc: Pointer to a D3DDEVICEDESC7 structure to fill
442 * D3DERR_* if a problem occurs. See WineD3D
444 *****************************************************************************/
446 IDirect3DDeviceImpl_7_GetCaps(IDirect3DDevice7 *iface,
447 D3DDEVICEDESC7 *Desc)
449 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
450 D3DDEVICEDESC OldDesc;
452 TRACE("iface %p, device_desc %p.\n", iface, Desc);
454 /* Call the same function used by IDirect3D, this saves code */
455 return IDirect3DImpl_GetCaps(This->ddraw->wineD3D, &OldDesc, Desc);
458 static HRESULT WINAPI
459 IDirect3DDeviceImpl_7_GetCaps_FPUSetup(IDirect3DDevice7 *iface,
460 D3DDEVICEDESC7 *Desc)
462 return IDirect3DDeviceImpl_7_GetCaps(iface, Desc);
465 static HRESULT WINAPI
466 IDirect3DDeviceImpl_7_GetCaps_FPUPreserve(IDirect3DDevice7 *iface,
467 D3DDEVICEDESC7 *Desc)
472 old_fpucw = d3d_fpu_setup();
473 hr = IDirect3DDeviceImpl_7_GetCaps(iface, Desc);
474 set_fpu_control_word(old_fpucw);
478 /*****************************************************************************
479 * IDirect3DDevice3::GetCaps
481 * Retrieves the capabilities of the hardware device and the emulation
482 * device. For Wine, hardware and emulation are the same (it's all HW).
484 * This implementation is used for Version 1, 2, and 3. Version 7 has its own
487 * HWDesc: Structure to fill with the HW caps
488 * HelDesc: Structure to fill with the hardware emulation caps
492 * D3DERR_* if a problem occurs. See WineD3D
494 *****************************************************************************/
495 static HRESULT WINAPI
496 IDirect3DDeviceImpl_3_GetCaps(IDirect3DDevice3 *iface,
497 D3DDEVICEDESC *HWDesc,
498 D3DDEVICEDESC *HelDesc)
500 IDirect3DDeviceImpl *This = device_from_device3(iface);
501 D3DDEVICEDESC7 newDesc;
504 TRACE("iface %p, hw_desc %p, hel_desc %p.\n", iface, HWDesc, HelDesc);
506 hr = IDirect3DImpl_GetCaps(This->ddraw->wineD3D, HWDesc, &newDesc);
507 if(hr != D3D_OK) return hr;
513 static HRESULT WINAPI IDirect3DDeviceImpl_2_GetCaps(IDirect3DDevice2 *iface,
514 D3DDEVICEDESC *D3DHWDevDesc, D3DDEVICEDESC *D3DHELDevDesc)
516 IDirect3DDeviceImpl *This = device_from_device2(iface);
517 TRACE("iface %p, hw_desc %p, hel_desc %p.\n", iface, D3DHWDevDesc, D3DHELDevDesc);
518 return IDirect3DDevice3_GetCaps((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl, D3DHWDevDesc, D3DHELDevDesc);
521 static HRESULT WINAPI IDirect3DDeviceImpl_1_GetCaps(IDirect3DDevice *iface,
522 D3DDEVICEDESC *D3DHWDevDesc, D3DDEVICEDESC *D3DHELDevDesc)
524 IDirect3DDeviceImpl *This = device_from_device1(iface);
525 TRACE("iface %p, hw_desc %p, hel_desc %p.\n", iface, D3DHWDevDesc, D3DHELDevDesc);
526 return IDirect3DDevice3_GetCaps((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl, D3DHWDevDesc, D3DHELDevDesc);
529 /*****************************************************************************
530 * IDirect3DDevice2::SwapTextureHandles
532 * Swaps the texture handles of 2 Texture interfaces. Version 1 and 2
535 * Tex1, Tex2: The 2 Textures to swap
540 *****************************************************************************/
541 static HRESULT WINAPI
542 IDirect3DDeviceImpl_2_SwapTextureHandles(IDirect3DDevice2 *iface,
543 IDirect3DTexture2 *Tex1,
544 IDirect3DTexture2 *Tex2)
546 IDirect3DDeviceImpl *This = device_from_device2(iface);
547 IDirectDrawSurfaceImpl *surf1 = surface_from_texture2(Tex1);
548 IDirectDrawSurfaceImpl *surf2 = surface_from_texture2(Tex2);
551 TRACE("iface %p, tex1 %p, tex2 %p.\n", iface, Tex1, Tex2);
553 EnterCriticalSection(&ddraw_cs);
555 h1 = surf1->Handle - 1;
556 h2 = surf2->Handle - 1;
557 This->handle_table.entries[h1].object = surf2;
558 This->handle_table.entries[h2].object = surf1;
559 surf2->Handle = h1 + 1;
560 surf1->Handle = h2 + 1;
562 LeaveCriticalSection(&ddraw_cs);
567 static HRESULT WINAPI IDirect3DDeviceImpl_1_SwapTextureHandles(IDirect3DDevice *iface,
568 IDirect3DTexture *D3DTex1, IDirect3DTexture *D3DTex2)
570 IDirect3DDeviceImpl *This = device_from_device1(iface);
571 IDirectDrawSurfaceImpl *surf1 = surface_from_texture1(D3DTex1);
572 IDirectDrawSurfaceImpl *surf2 = surface_from_texture1(D3DTex2);
573 IDirect3DTexture2 *t1 = surf1 ? (IDirect3DTexture2 *)&surf1->IDirect3DTexture2_vtbl : NULL;
574 IDirect3DTexture2 *t2 = surf2 ? (IDirect3DTexture2 *)&surf2->IDirect3DTexture2_vtbl : NULL;
576 TRACE("iface %p, tex1 %p, tex2 %p.\n", iface, D3DTex1, D3DTex2);
578 return IDirect3DDevice2_SwapTextureHandles((IDirect3DDevice2 *)&This->IDirect3DDevice2_vtbl, t1, t2);
581 /*****************************************************************************
582 * IDirect3DDevice3::GetStats
584 * This method seems to retrieve some stats from the device.
585 * The MSDN documentation doesn't exist any more, but the D3DSTATS
586 * structure suggests that the amount of drawn primitives and processed
587 * vertices is returned.
589 * Exists in Version 1, 2 and 3
592 * Stats: Pointer to a D3DSTATS structure to be filled
596 * DDERR_INVALIDPARAMS if Stats == NULL
598 *****************************************************************************/
599 static HRESULT WINAPI
600 IDirect3DDeviceImpl_3_GetStats(IDirect3DDevice3 *iface,
603 FIXME("iface %p, stats %p stub!\n", iface, Stats);
606 return DDERR_INVALIDPARAMS;
608 /* Fill the Stats with 0 */
609 Stats->dwTrianglesDrawn = 0;
610 Stats->dwLinesDrawn = 0;
611 Stats->dwPointsDrawn = 0;
612 Stats->dwSpansDrawn = 0;
613 Stats->dwVerticesProcessed = 0;
618 static HRESULT WINAPI IDirect3DDeviceImpl_2_GetStats(IDirect3DDevice2 *iface, D3DSTATS *Stats)
620 IDirect3DDeviceImpl *This = device_from_device2(iface);
622 TRACE("iface %p, stats %p.\n", iface, Stats);
624 return IDirect3DDevice3_GetStats((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl, Stats);
627 static HRESULT WINAPI IDirect3DDeviceImpl_1_GetStats(IDirect3DDevice *iface, D3DSTATS *Stats)
629 IDirect3DDeviceImpl *This = device_from_device1(iface);
631 TRACE("iface %p, stats %p.\n", iface, Stats);
633 return IDirect3DDevice3_GetStats((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl, Stats);
636 /*****************************************************************************
637 * IDirect3DDevice::CreateExecuteBuffer
639 * Creates an IDirect3DExecuteBuffer, used for rendering with a
645 * Desc: Buffer description
646 * ExecuteBuffer: Address to return the Interface pointer at
647 * UnkOuter: Must be NULL. Basically for aggregation, which ddraw doesn't
651 * CLASS_E_NOAGGREGATION if UnkOuter != NULL
652 * DDERR_OUTOFMEMORY if we ran out of memory
655 *****************************************************************************/
656 static HRESULT WINAPI
657 IDirect3DDeviceImpl_1_CreateExecuteBuffer(IDirect3DDevice *iface,
658 D3DEXECUTEBUFFERDESC *Desc,
659 IDirect3DExecuteBuffer **ExecuteBuffer,
662 IDirect3DDeviceImpl *This = device_from_device1(iface);
663 IDirect3DExecuteBufferImpl* object;
666 TRACE("iface %p, buffer_desc %p, buffer %p, outer_unknown %p.\n",
667 iface, Desc, ExecuteBuffer, UnkOuter);
670 return CLASS_E_NOAGGREGATION;
672 /* Allocate the new Execute Buffer */
673 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DExecuteBufferImpl));
676 ERR("Out of memory when allocating a IDirect3DExecuteBufferImpl structure\n");
677 return DDERR_OUTOFMEMORY;
680 hr = d3d_execute_buffer_init(object, This, Desc);
683 WARN("Failed to initialize execute buffer, hr %#x.\n", hr);
684 HeapFree(GetProcessHeap(), 0, object);
688 *ExecuteBuffer = (IDirect3DExecuteBuffer *)object;
690 TRACE(" Returning IDirect3DExecuteBuffer at %p, implementation is at %p\n", *ExecuteBuffer, object);
695 /*****************************************************************************
696 * IDirect3DDevice::Execute
698 * Executes all the stuff in an execute buffer.
701 * ExecuteBuffer: The buffer to execute
702 * Viewport: The viewport used for rendering
706 * DDERR_INVALIDPARAMS if ExecuteBuffer == NULL
709 *****************************************************************************/
710 static HRESULT WINAPI
711 IDirect3DDeviceImpl_1_Execute(IDirect3DDevice *iface,
712 IDirect3DExecuteBuffer *ExecuteBuffer,
713 IDirect3DViewport *Viewport,
716 IDirect3DDeviceImpl *This = device_from_device1(iface);
717 IDirect3DExecuteBufferImpl *Direct3DExecuteBufferImpl = (IDirect3DExecuteBufferImpl *)ExecuteBuffer;
718 IDirect3DViewportImpl *Direct3DViewportImpl = (IDirect3DViewportImpl *)Viewport;
721 TRACE("iface %p, buffer %p, viewport %p, flags %#x.\n", iface, ExecuteBuffer, Viewport, Flags);
723 if(!Direct3DExecuteBufferImpl)
724 return DDERR_INVALIDPARAMS;
727 EnterCriticalSection(&ddraw_cs);
728 hr = d3d_execute_buffer_execute(Direct3DExecuteBufferImpl, This, Direct3DViewportImpl);
729 LeaveCriticalSection(&ddraw_cs);
734 /*****************************************************************************
735 * IDirect3DDevice3::AddViewport
737 * Add a Direct3DViewport to the device's viewport list. These viewports
738 * are wrapped to IDirect3DDevice7 viewports in viewport.c
740 * Exists in Version 1, 2 and 3. Note that IDirect3DViewport 1, 2 and 3
741 * are the same interfaces.
744 * Viewport: The viewport to add
747 * DDERR_INVALIDPARAMS if Viewport == NULL
750 *****************************************************************************/
751 static HRESULT WINAPI
752 IDirect3DDeviceImpl_3_AddViewport(IDirect3DDevice3 *iface,
753 IDirect3DViewport3 *Viewport)
755 IDirect3DDeviceImpl *This = device_from_device3(iface);
756 IDirect3DViewportImpl *vp = (IDirect3DViewportImpl *)Viewport;
758 TRACE("iface %p, viewport %p.\n", iface, Viewport);
762 return DDERR_INVALIDPARAMS;
764 EnterCriticalSection(&ddraw_cs);
765 list_add_head(&This->viewport_list, &vp->entry);
766 vp->active_device = This; /* Viewport must be usable for Clear() after AddViewport,
767 so set active_device here. */
768 LeaveCriticalSection(&ddraw_cs);
773 static HRESULT WINAPI IDirect3DDeviceImpl_2_AddViewport(IDirect3DDevice2 *iface,
774 IDirect3DViewport2 *Direct3DViewport2)
776 IDirect3DDeviceImpl *This = device_from_device2(iface);
777 IDirect3DViewportImpl *vp = (IDirect3DViewportImpl *)Direct3DViewport2;
779 TRACE("iface %p, viewport %p.\n", iface, Direct3DViewport2);
781 return IDirect3DDevice3_AddViewport((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl, (IDirect3DViewport3 *)vp);
784 static HRESULT WINAPI IDirect3DDeviceImpl_1_AddViewport(IDirect3DDevice *iface,
785 IDirect3DViewport *Direct3DViewport)
787 IDirect3DDeviceImpl *This = device_from_device1(iface);
788 IDirect3DViewportImpl *vp = (IDirect3DViewportImpl *)Direct3DViewport;
790 TRACE("iface %p, viewport %p.\n", iface, Direct3DViewport);
792 return IDirect3DDevice3_AddViewport((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl, (IDirect3DViewport3 *)vp);
795 /*****************************************************************************
796 * IDirect3DDevice3::DeleteViewport
798 * Deletes a Direct3DViewport from the device's viewport list.
800 * Exists in Version 1, 2 and 3. Note that all Viewport interface versions
804 * Viewport: The viewport to delete
808 * DDERR_INVALIDPARAMS if the viewport wasn't found in the list
810 *****************************************************************************/
811 static HRESULT WINAPI IDirect3DDeviceImpl_3_DeleteViewport(IDirect3DDevice3 *iface, IDirect3DViewport3 *viewport)
813 IDirect3DDeviceImpl *device = device_from_device3(iface);
814 IDirect3DViewportImpl *vp = (IDirect3DViewportImpl *)viewport;
816 TRACE("iface %p, viewport %p.\n", iface, viewport);
818 EnterCriticalSection(&ddraw_cs);
820 if (vp->active_device != device)
822 WARN("Viewport %p active device is %p.\n", vp, vp->active_device);
823 LeaveCriticalSection(&ddraw_cs);
824 return DDERR_INVALIDPARAMS;
827 vp->active_device = NULL;
828 list_remove(&vp->entry);
830 LeaveCriticalSection(&ddraw_cs);
834 static HRESULT WINAPI IDirect3DDeviceImpl_2_DeleteViewport(IDirect3DDevice2 *iface,
835 IDirect3DViewport2 *Direct3DViewport2)
837 IDirect3DDeviceImpl *This = device_from_device2(iface);
838 IDirect3DViewportImpl *vp = (IDirect3DViewportImpl *)Direct3DViewport2;
840 TRACE("iface %p, viewport %p.\n", iface, Direct3DViewport2);
842 return IDirect3DDevice3_DeleteViewport((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl, (IDirect3DViewport3 *)vp);
845 static HRESULT WINAPI IDirect3DDeviceImpl_1_DeleteViewport(IDirect3DDevice *iface,
846 IDirect3DViewport *Direct3DViewport)
848 IDirect3DDeviceImpl *This = device_from_device1(iface);
849 IDirect3DViewportImpl *vp = (IDirect3DViewportImpl *)Direct3DViewport;
851 TRACE("iface %p, viewport %p.\n", iface, Direct3DViewport);
853 return IDirect3DDevice3_DeleteViewport((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl, (IDirect3DViewport3 *)vp);
856 /*****************************************************************************
857 * IDirect3DDevice3::NextViewport
859 * Returns a viewport from the viewport list, depending on the
860 * passed viewport and the flags.
862 * Exists in Version 1, 2 and 3. Note that all Viewport interface versions
866 * Viewport: Viewport to use for beginning the search
867 * Flags: D3DNEXT_NEXT, D3DNEXT_HEAD or D3DNEXT_TAIL
871 * DDERR_INVALIDPARAMS if the flags were wrong, or Viewport was NULL
873 *****************************************************************************/
874 static HRESULT WINAPI
875 IDirect3DDeviceImpl_3_NextViewport(IDirect3DDevice3 *iface,
876 IDirect3DViewport3 *Viewport3,
877 IDirect3DViewport3 **lplpDirect3DViewport3,
880 IDirect3DDeviceImpl *This = device_from_device3(iface);
881 IDirect3DViewportImpl *vp = (IDirect3DViewportImpl *)Viewport3;
884 TRACE("iface %p, viewport %p, next %p, flags %#x.\n",
885 iface, Viewport3, lplpDirect3DViewport3, Flags);
889 *lplpDirect3DViewport3 = NULL;
890 return DDERR_INVALIDPARAMS;
894 EnterCriticalSection(&ddraw_cs);
898 entry = list_next(&This->viewport_list, &vp->entry);
902 entry = list_head(&This->viewport_list);
906 entry = list_tail(&This->viewport_list);
910 WARN("Invalid flags %#x.\n", Flags);
911 *lplpDirect3DViewport3 = NULL;
912 LeaveCriticalSection(&ddraw_cs);
913 return DDERR_INVALIDPARAMS;
917 *lplpDirect3DViewport3 = (IDirect3DViewport3 *)LIST_ENTRY(entry, IDirect3DViewportImpl, entry);
919 *lplpDirect3DViewport3 = NULL;
921 LeaveCriticalSection(&ddraw_cs);
925 static HRESULT WINAPI IDirect3DDeviceImpl_2_NextViewport(IDirect3DDevice2 *iface,
926 IDirect3DViewport2 *Viewport2, IDirect3DViewport2 **lplpDirect3DViewport2, DWORD Flags)
928 IDirect3DDeviceImpl *This = device_from_device2(iface);
929 IDirect3DViewportImpl *vp = (IDirect3DViewportImpl *)Viewport2;
930 IDirect3DViewport3 *res;
933 TRACE("iface %p, viewport %p, next %p, flags %#x.\n",
934 iface, Viewport2, lplpDirect3DViewport2, Flags);
936 hr = IDirect3DDevice3_NextViewport((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl,
937 (IDirect3DViewport3 *)vp, &res, Flags);
938 *lplpDirect3DViewport2 = (IDirect3DViewport2 *)res;
942 static HRESULT WINAPI IDirect3DDeviceImpl_1_NextViewport(IDirect3DDevice *iface,
943 IDirect3DViewport *Viewport, IDirect3DViewport **lplpDirect3DViewport, DWORD Flags)
945 IDirect3DDeviceImpl *This = device_from_device1(iface);
946 IDirect3DViewportImpl *vp = (IDirect3DViewportImpl *)Viewport;
947 IDirect3DViewport3 *res;
950 TRACE("iface %p, viewport %p, next %p, flags %#x.\n",
951 iface, Viewport, lplpDirect3DViewport, Flags);
953 hr = IDirect3DDevice3_NextViewport((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl,
954 (IDirect3DViewport3 *)vp, &res, Flags);
955 *lplpDirect3DViewport = (IDirect3DViewport *)res;
959 /*****************************************************************************
960 * IDirect3DDevice::Pick
962 * Executes an execute buffer without performing rendering. Instead, a
963 * list of primitives that intersect with (x1,y1) of the passed rectangle
964 * is created. IDirect3DDevice::GetPickRecords can be used to retrieve
970 * ExecuteBuffer: Buffer to execute
971 * Viewport: Viewport to use for execution
972 * Flags: None are defined, according to the SDK
973 * Rect: Specifies the coordinates to be picked. Only x1 and y2 are used,
974 * x2 and y2 are ignored.
977 * D3D_OK because it's a stub
979 *****************************************************************************/
980 static HRESULT WINAPI
981 IDirect3DDeviceImpl_1_Pick(IDirect3DDevice *iface,
982 IDirect3DExecuteBuffer *ExecuteBuffer,
983 IDirect3DViewport *Viewport,
987 FIXME("iface %p, buffer %p, viewport %p, flags %#x, rect %s stub!\n",
988 iface, ExecuteBuffer, Viewport, Flags, wine_dbgstr_rect((RECT *)Rect));
993 /*****************************************************************************
994 * IDirect3DDevice::GetPickRecords
996 * Retrieves the pick records generated by IDirect3DDevice::GetPickRecords
1001 * Count: Pointer to a DWORD containing the numbers of pick records to
1003 * D3DPickRec: Address to store the resulting D3DPICKRECORD array.
1006 * D3D_OK, because it's a stub
1008 *****************************************************************************/
1009 static HRESULT WINAPI
1010 IDirect3DDeviceImpl_1_GetPickRecords(IDirect3DDevice *iface,
1012 D3DPICKRECORD *D3DPickRec)
1014 FIXME("iface %p, count %p, records %p stub!\n", iface, Count, D3DPickRec);
1019 /*****************************************************************************
1020 * IDirect3DDevice7::EnumTextureformats
1022 * Enumerates the supported texture formats. It has a list of all possible
1023 * formats and calls IWineD3D::CheckDeviceFormat for each format to see if
1024 * WineD3D supports it. If so, then it is passed to the app.
1026 * This is for Version 7 and 3, older versions have a different
1027 * callback function and their own implementation
1030 * Callback: Callback to call for each enumerated format
1031 * Arg: Argument to pass to the callback
1035 * DDERR_INVALIDPARAMS if Callback == NULL
1037 *****************************************************************************/
1039 IDirect3DDeviceImpl_7_EnumTextureFormats(IDirect3DDevice7 *iface,
1040 LPD3DENUMPIXELFORMATSCALLBACK Callback,
1043 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
1045 WINED3DDISPLAYMODE mode;
1048 static const enum wined3d_format_id FormatList[] =
1051 WINED3DFMT_B8G8R8A8_UNORM,
1052 WINED3DFMT_B8G8R8X8_UNORM,
1054 WINED3DFMT_B8G8R8_UNORM,
1056 WINED3DFMT_B5G5R5A1_UNORM,
1057 WINED3DFMT_B4G4R4A4_UNORM,
1058 WINED3DFMT_B5G6R5_UNORM,
1059 WINED3DFMT_B5G5R5X1_UNORM,
1061 WINED3DFMT_B2G3R3_UNORM,
1069 static const enum wined3d_format_id BumpFormatList[] =
1071 WINED3DFMT_R8G8_SNORM,
1072 WINED3DFMT_R5G5_SNORM_L6_UNORM,
1073 WINED3DFMT_R8G8_SNORM_L8X8_UNORM,
1074 WINED3DFMT_R16G16_SNORM,
1075 WINED3DFMT_R10G11B11_SNORM,
1076 WINED3DFMT_R10G10B10_SNORM_A2_UNORM
1079 TRACE("iface %p, callback %p, context %p.\n", iface, Callback, Arg);
1082 return DDERR_INVALIDPARAMS;
1084 EnterCriticalSection(&ddraw_cs);
1086 memset(&mode, 0, sizeof(mode));
1087 hr = wined3d_device_get_display_mode(This->ddraw->wined3d_device, 0, &mode);
1090 LeaveCriticalSection(&ddraw_cs);
1091 WARN("Cannot get the current adapter format\n");
1095 for (i = 0; i < sizeof(FormatList) / sizeof(*FormatList); ++i)
1097 hr = wined3d_check_device_format(This->ddraw->wineD3D, WINED3DADAPTER_DEFAULT, WINED3DDEVTYPE_HAL,
1098 mode.Format, 0, WINED3DRTYPE_TEXTURE, FormatList[i], SURFACE_OPENGL);
1101 DDPIXELFORMAT pformat;
1103 memset(&pformat, 0, sizeof(pformat));
1104 pformat.dwSize = sizeof(pformat);
1105 PixelFormat_WineD3DtoDD(&pformat, FormatList[i]);
1107 TRACE("Enumerating WineD3DFormat %d\n", FormatList[i]);
1108 hr = Callback(&pformat, Arg);
1109 if(hr != DDENUMRET_OK)
1111 TRACE("Format enumeration cancelled by application\n");
1112 LeaveCriticalSection(&ddraw_cs);
1118 for (i = 0; i < sizeof(BumpFormatList) / sizeof(*BumpFormatList); ++i)
1120 hr = wined3d_check_device_format(This->ddraw->wineD3D, WINED3DADAPTER_DEFAULT,
1121 WINED3DDEVTYPE_HAL, mode.Format, WINED3DUSAGE_QUERY_LEGACYBUMPMAP,
1122 WINED3DRTYPE_TEXTURE, BumpFormatList[i], SURFACE_OPENGL);
1125 DDPIXELFORMAT pformat;
1127 memset(&pformat, 0, sizeof(pformat));
1128 pformat.dwSize = sizeof(pformat);
1129 PixelFormat_WineD3DtoDD(&pformat, BumpFormatList[i]);
1131 TRACE("Enumerating WineD3DFormat %d\n", BumpFormatList[i]);
1132 hr = Callback(&pformat, Arg);
1133 if(hr != DDENUMRET_OK)
1135 TRACE("Format enumeration cancelled by application\n");
1136 LeaveCriticalSection(&ddraw_cs);
1141 TRACE("End of enumeration\n");
1142 LeaveCriticalSection(&ddraw_cs);
1146 static HRESULT WINAPI
1147 IDirect3DDeviceImpl_7_EnumTextureFormats_FPUSetup(IDirect3DDevice7 *iface,
1148 LPD3DENUMPIXELFORMATSCALLBACK Callback,
1151 return IDirect3DDeviceImpl_7_EnumTextureFormats(iface, Callback, Arg);
1154 static HRESULT WINAPI
1155 IDirect3DDeviceImpl_7_EnumTextureFormats_FPUPreserve(IDirect3DDevice7 *iface,
1156 LPD3DENUMPIXELFORMATSCALLBACK Callback,
1162 old_fpucw = d3d_fpu_setup();
1163 hr = IDirect3DDeviceImpl_7_EnumTextureFormats(iface, Callback, Arg);
1164 set_fpu_control_word(old_fpucw);
1169 static HRESULT WINAPI IDirect3DDeviceImpl_3_EnumTextureFormats(IDirect3DDevice3 *iface,
1170 LPD3DENUMPIXELFORMATSCALLBACK Callback, void *Arg)
1172 IDirect3DDeviceImpl *This = device_from_device3(iface);
1174 TRACE("iface %p, callback %p, context %p.\n", iface, Callback, Arg);
1176 return IDirect3DDevice7_EnumTextureFormats((IDirect3DDevice7 *)This, Callback, Arg);
1179 /*****************************************************************************
1180 * IDirect3DDevice2::EnumTextureformats
1182 * EnumTextureFormats for Version 1 and 2, see
1183 * IDirect3DDevice7::EnumTexureFormats for a more detailed description.
1185 * This version has a different callback and does not enumerate FourCC
1188 *****************************************************************************/
1189 static HRESULT WINAPI
1190 IDirect3DDeviceImpl_2_EnumTextureFormats(IDirect3DDevice2 *iface,
1191 LPD3DENUMTEXTUREFORMATSCALLBACK Callback,
1194 IDirect3DDeviceImpl *This = device_from_device2(iface);
1197 WINED3DDISPLAYMODE mode;
1199 static const enum wined3d_format_id FormatList[] =
1202 WINED3DFMT_B8G8R8A8_UNORM,
1203 WINED3DFMT_B8G8R8X8_UNORM,
1205 WINED3DFMT_B8G8R8_UNORM,
1207 WINED3DFMT_B5G5R5A1_UNORM,
1208 WINED3DFMT_B4G4R4A4_UNORM,
1209 WINED3DFMT_B5G6R5_UNORM,
1210 WINED3DFMT_B5G5R5X1_UNORM,
1212 WINED3DFMT_B2G3R3_UNORM,
1214 /* FOURCC codes - Not in this version*/
1217 TRACE("iface %p, callback %p, context %p.\n", iface, Callback, Arg);
1220 return DDERR_INVALIDPARAMS;
1222 EnterCriticalSection(&ddraw_cs);
1224 memset(&mode, 0, sizeof(mode));
1225 hr = wined3d_device_get_display_mode(This->ddraw->wined3d_device, 0, &mode);
1228 LeaveCriticalSection(&ddraw_cs);
1229 WARN("Cannot get the current adapter format\n");
1233 for (i = 0; i < sizeof(FormatList) / sizeof(*FormatList); ++i)
1235 hr = wined3d_check_device_format(This->ddraw->wineD3D, 0, WINED3DDEVTYPE_HAL,
1236 mode.Format, 0, WINED3DRTYPE_TEXTURE, FormatList[i], SURFACE_OPENGL);
1239 DDSURFACEDESC sdesc;
1241 memset(&sdesc, 0, sizeof(sdesc));
1242 sdesc.dwSize = sizeof(sdesc);
1243 sdesc.dwFlags = DDSD_PIXELFORMAT | DDSD_CAPS;
1244 sdesc.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1245 sdesc.ddpfPixelFormat.dwSize = sizeof(sdesc.ddpfPixelFormat);
1246 PixelFormat_WineD3DtoDD(&sdesc.ddpfPixelFormat, FormatList[i]);
1248 TRACE("Enumerating WineD3DFormat %d\n", FormatList[i]);
1249 hr = Callback(&sdesc, Arg);
1250 if(hr != DDENUMRET_OK)
1252 TRACE("Format enumeration cancelled by application\n");
1253 LeaveCriticalSection(&ddraw_cs);
1258 TRACE("End of enumeration\n");
1259 LeaveCriticalSection(&ddraw_cs);
1263 static HRESULT WINAPI IDirect3DDeviceImpl_1_EnumTextureFormats(IDirect3DDevice *iface,
1264 LPD3DENUMTEXTUREFORMATSCALLBACK Callback, void *Arg)
1266 IDirect3DDeviceImpl *This = device_from_device1(iface);
1268 TRACE("iface %p, callback %p, context %p.\n", iface, Callback, Arg);
1270 return IDirect3DDevice2_EnumTextureFormats((IDirect3DDevice2 *)&This->IDirect3DDevice2_vtbl, Callback, Arg);
1273 /*****************************************************************************
1274 * IDirect3DDevice::CreateMatrix
1276 * Creates a matrix handle. A handle is created and memory for a D3DMATRIX is
1277 * allocated for the handle.
1282 * D3DMatHandle: Address to return the handle at
1286 * DDERR_INVALIDPARAMS if D3DMatHandle = NULL
1288 *****************************************************************************/
1289 static HRESULT WINAPI
1290 IDirect3DDeviceImpl_1_CreateMatrix(IDirect3DDevice *iface, D3DMATRIXHANDLE *D3DMatHandle)
1292 IDirect3DDeviceImpl *This = device_from_device1(iface);
1296 TRACE("iface %p, matrix_handle %p.\n", iface, D3DMatHandle);
1299 return DDERR_INVALIDPARAMS;
1301 Matrix = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(D3DMATRIX));
1304 ERR("Out of memory when allocating a D3DMATRIX\n");
1305 return DDERR_OUTOFMEMORY;
1308 EnterCriticalSection(&ddraw_cs);
1310 h = ddraw_allocate_handle(&This->handle_table, Matrix, DDRAW_HANDLE_MATRIX);
1311 if (h == DDRAW_INVALID_HANDLE)
1313 ERR("Failed to allocate a matrix handle.\n");
1314 HeapFree(GetProcessHeap(), 0, Matrix);
1315 LeaveCriticalSection(&ddraw_cs);
1316 return DDERR_OUTOFMEMORY;
1319 *D3DMatHandle = h + 1;
1321 TRACE(" returning matrix handle %d\n", *D3DMatHandle);
1323 LeaveCriticalSection(&ddraw_cs);
1327 /*****************************************************************************
1328 * IDirect3DDevice::SetMatrix
1330 * Sets a matrix for a matrix handle. The matrix is copied into the memory
1331 * allocated for the handle
1336 * D3DMatHandle: Handle to set the matrix to
1337 * D3DMatrix: Matrix to set
1341 * DDERR_INVALIDPARAMS if the handle of the matrix is invalid or the matrix
1344 *****************************************************************************/
1345 static HRESULT WINAPI
1346 IDirect3DDeviceImpl_1_SetMatrix(IDirect3DDevice *iface,
1347 D3DMATRIXHANDLE D3DMatHandle,
1348 D3DMATRIX *D3DMatrix)
1350 IDirect3DDeviceImpl *This = device_from_device1(iface);
1353 TRACE("iface %p, matrix_handle %#x, matrix %p.\n", iface, D3DMatHandle, D3DMatrix);
1355 if (!D3DMatrix) return DDERR_INVALIDPARAMS;
1357 EnterCriticalSection(&ddraw_cs);
1359 m = ddraw_get_object(&This->handle_table, D3DMatHandle - 1, DDRAW_HANDLE_MATRIX);
1362 WARN("Invalid matrix handle.\n");
1363 LeaveCriticalSection(&ddraw_cs);
1364 return DDERR_INVALIDPARAMS;
1367 if (TRACE_ON(ddraw))
1368 dump_D3DMATRIX(D3DMatrix);
1372 if (D3DMatHandle == This->world)
1373 wined3d_device_set_transform(This->wined3d_device, WINED3DTS_WORLDMATRIX(0), (WINED3DMATRIX *)D3DMatrix);
1375 if (D3DMatHandle == This->view)
1376 wined3d_device_set_transform(This->wined3d_device, WINED3DTS_VIEW, (WINED3DMATRIX *)D3DMatrix);
1378 if (D3DMatHandle == This->proj)
1379 wined3d_device_set_transform(This->wined3d_device, WINED3DTS_PROJECTION, (WINED3DMATRIX *)D3DMatrix);
1381 LeaveCriticalSection(&ddraw_cs);
1385 /*****************************************************************************
1386 * IDirect3DDevice::GetMatrix
1388 * Returns the content of a D3DMATRIX handle
1393 * D3DMatHandle: Matrix handle to read the content from
1394 * D3DMatrix: Address to store the content at
1398 * DDERR_INVALIDPARAMS if D3DMatHandle is invalid or D3DMatrix is NULL
1400 *****************************************************************************/
1401 static HRESULT WINAPI
1402 IDirect3DDeviceImpl_1_GetMatrix(IDirect3DDevice *iface,
1403 D3DMATRIXHANDLE D3DMatHandle,
1404 D3DMATRIX *D3DMatrix)
1406 IDirect3DDeviceImpl *This = device_from_device1(iface);
1409 TRACE("iface %p, matrix_handle %#x, matrix %p.\n", iface, D3DMatHandle, D3DMatrix);
1411 if (!D3DMatrix) return DDERR_INVALIDPARAMS;
1413 EnterCriticalSection(&ddraw_cs);
1415 m = ddraw_get_object(&This->handle_table, D3DMatHandle - 1, DDRAW_HANDLE_MATRIX);
1418 WARN("Invalid matrix handle.\n");
1419 LeaveCriticalSection(&ddraw_cs);
1420 return DDERR_INVALIDPARAMS;
1425 LeaveCriticalSection(&ddraw_cs);
1429 /*****************************************************************************
1430 * IDirect3DDevice::DeleteMatrix
1432 * Destroys a Matrix handle. Frees the memory and unsets the handle data
1437 * D3DMatHandle: Handle to destroy
1441 * DDERR_INVALIDPARAMS if D3DMatHandle is invalid
1443 *****************************************************************************/
1444 static HRESULT WINAPI
1445 IDirect3DDeviceImpl_1_DeleteMatrix(IDirect3DDevice *iface,
1446 D3DMATRIXHANDLE D3DMatHandle)
1448 IDirect3DDeviceImpl *This = device_from_device1(iface);
1451 TRACE("iface %p, matrix_handle %#x.\n", iface, D3DMatHandle);
1453 EnterCriticalSection(&ddraw_cs);
1455 m = ddraw_free_handle(&This->handle_table, D3DMatHandle - 1, DDRAW_HANDLE_MATRIX);
1458 WARN("Invalid matrix handle.\n");
1459 LeaveCriticalSection(&ddraw_cs);
1460 return DDERR_INVALIDPARAMS;
1463 LeaveCriticalSection(&ddraw_cs);
1465 HeapFree(GetProcessHeap(), 0, m);
1470 /*****************************************************************************
1471 * IDirect3DDevice7::BeginScene
1473 * This method must be called before any rendering is performed.
1474 * IDirect3DDevice::EndScene has to be called after the scene is complete
1476 * Version 1, 2, 3 and 7
1479 * D3D_OK on success, for details see IWineD3DDevice::BeginScene
1480 * D3DERR_SCENE_IN_SCENE if WineD3D returns an error(Only in case of an already
1483 *****************************************************************************/
1485 IDirect3DDeviceImpl_7_BeginScene(IDirect3DDevice7 *iface)
1487 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
1490 TRACE("iface %p.\n", iface);
1492 EnterCriticalSection(&ddraw_cs);
1493 hr = wined3d_device_begin_scene(This->wined3d_device);
1494 LeaveCriticalSection(&ddraw_cs);
1495 if(hr == WINED3D_OK) return D3D_OK;
1496 else return D3DERR_SCENE_IN_SCENE; /* TODO: Other possible causes of failure */
1499 static HRESULT WINAPI
1500 IDirect3DDeviceImpl_7_BeginScene_FPUSetup(IDirect3DDevice7 *iface)
1502 return IDirect3DDeviceImpl_7_BeginScene(iface);
1505 static HRESULT WINAPI
1506 IDirect3DDeviceImpl_7_BeginScene_FPUPreserve(IDirect3DDevice7 *iface)
1511 old_fpucw = d3d_fpu_setup();
1512 hr = IDirect3DDeviceImpl_7_BeginScene(iface);
1513 set_fpu_control_word(old_fpucw);
1518 static HRESULT WINAPI IDirect3DDeviceImpl_3_BeginScene(IDirect3DDevice3 *iface)
1520 TRACE("iface %p.\n", iface);
1522 return IDirect3DDevice7_BeginScene((IDirect3DDevice7 *)device_from_device3(iface));
1525 static HRESULT WINAPI IDirect3DDeviceImpl_2_BeginScene(IDirect3DDevice2 *iface)
1527 TRACE("iface %p.\n", iface);
1529 return IDirect3DDevice7_BeginScene((IDirect3DDevice7 *)device_from_device2(iface));
1532 static HRESULT WINAPI IDirect3DDeviceImpl_1_BeginScene(IDirect3DDevice *iface)
1534 TRACE("iface %p.\n", iface);
1536 return IDirect3DDevice7_BeginScene((IDirect3DDevice7 *)device_from_device1(iface));
1539 /*****************************************************************************
1540 * IDirect3DDevice7::EndScene
1542 * Ends a scene that has been begun with IDirect3DDevice7::BeginScene.
1543 * This method must be called after rendering is finished.
1545 * Version 1, 2, 3 and 7
1548 * D3D_OK on success, for details see IWineD3DDevice::EndScene
1549 * D3DERR_SCENE_NOT_IN_SCENE is returned if WineD3D returns an error. It does
1550 * that only if the scene was already ended.
1552 *****************************************************************************/
1554 IDirect3DDeviceImpl_7_EndScene(IDirect3DDevice7 *iface)
1556 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
1559 TRACE("iface %p.\n", iface);
1561 EnterCriticalSection(&ddraw_cs);
1562 hr = wined3d_device_end_scene(This->wined3d_device);
1563 LeaveCriticalSection(&ddraw_cs);
1564 if(hr == WINED3D_OK) return D3D_OK;
1565 else return D3DERR_SCENE_NOT_IN_SCENE;
1568 static HRESULT WINAPI DECLSPEC_HOTPATCH
1569 IDirect3DDeviceImpl_7_EndScene_FPUSetup(IDirect3DDevice7 *iface)
1571 return IDirect3DDeviceImpl_7_EndScene(iface);
1574 static HRESULT WINAPI DECLSPEC_HOTPATCH
1575 IDirect3DDeviceImpl_7_EndScene_FPUPreserve(IDirect3DDevice7 *iface)
1580 old_fpucw = d3d_fpu_setup();
1581 hr = IDirect3DDeviceImpl_7_EndScene(iface);
1582 set_fpu_control_word(old_fpucw);
1587 static HRESULT WINAPI DECLSPEC_HOTPATCH IDirect3DDeviceImpl_3_EndScene(IDirect3DDevice3 *iface)
1589 TRACE("iface %p.\n", iface);
1591 return IDirect3DDevice7_EndScene((IDirect3DDevice7 *)device_from_device3(iface));
1594 static HRESULT WINAPI DECLSPEC_HOTPATCH IDirect3DDeviceImpl_2_EndScene(IDirect3DDevice2 *iface)
1596 TRACE("iface %p.\n", iface);
1598 return IDirect3DDevice7_EndScene((IDirect3DDevice7 *)device_from_device2(iface));
1601 static HRESULT WINAPI DECLSPEC_HOTPATCH IDirect3DDeviceImpl_1_EndScene(IDirect3DDevice *iface)
1603 TRACE("iface %p.\n", iface);
1605 return IDirect3DDevice7_EndScene((IDirect3DDevice7 *)device_from_device1(iface));
1608 /*****************************************************************************
1609 * IDirect3DDevice7::GetDirect3D
1611 * Returns the IDirect3D(= interface to the DirectDraw object) used to create
1615 * Direct3D7: Address to store the interface pointer at
1619 * DDERR_INVALIDPARAMS if Direct3D7 == NULL
1621 *****************************************************************************/
1622 static HRESULT WINAPI
1623 IDirect3DDeviceImpl_7_GetDirect3D(IDirect3DDevice7 *iface,
1624 IDirect3D7 **Direct3D7)
1626 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
1628 TRACE("iface %p, d3d %p.\n", iface, Direct3D7);
1631 return DDERR_INVALIDPARAMS;
1633 *Direct3D7 = &This->ddraw->IDirect3D7_iface;
1634 IDirect3D7_AddRef(*Direct3D7);
1636 TRACE(" returning interface %p\n", *Direct3D7);
1640 static HRESULT WINAPI IDirect3DDeviceImpl_3_GetDirect3D(IDirect3DDevice3 *iface,
1641 IDirect3D3 **Direct3D3)
1643 IDirect3DDeviceImpl *This = device_from_device3(iface);
1645 TRACE("iface %p, d3d %p.\n", iface, Direct3D3);
1648 return DDERR_INVALIDPARAMS;
1650 IDirect3D3_AddRef(&This->ddraw->IDirect3D3_iface);
1651 *Direct3D3 = &This->ddraw->IDirect3D3_iface;
1652 TRACE(" returning interface %p\n", *Direct3D3);
1656 static HRESULT WINAPI IDirect3DDeviceImpl_2_GetDirect3D(IDirect3DDevice2 *iface,
1657 IDirect3D2 **Direct3D2)
1659 IDirect3DDeviceImpl *This = device_from_device2(iface);
1661 TRACE("iface %p, d3d %p.\n", iface, Direct3D2);
1664 return DDERR_INVALIDPARAMS;
1666 IDirect3D2_AddRef(&This->ddraw->IDirect3D2_iface);
1667 *Direct3D2 = &This->ddraw->IDirect3D2_iface;
1668 TRACE(" returning interface %p\n", *Direct3D2);
1672 static HRESULT WINAPI IDirect3DDeviceImpl_1_GetDirect3D(IDirect3DDevice *iface,
1673 IDirect3D **Direct3D)
1675 IDirect3DDeviceImpl *This = device_from_device1(iface);
1677 TRACE("iface %p, d3d %p.\n", iface, Direct3D);
1680 return DDERR_INVALIDPARAMS;
1682 IDirect3D_AddRef(&This->ddraw->IDirect3D_iface);
1683 *Direct3D = &This->ddraw->IDirect3D_iface;
1684 TRACE(" returning interface %p\n", *Direct3D);
1688 /*****************************************************************************
1689 * IDirect3DDevice3::SetCurrentViewport
1691 * Sets a Direct3DViewport as the current viewport.
1692 * For the thunks note that all viewport interface versions are equal
1695 * Direct3DViewport3: The viewport to set
1701 * (Is a NULL viewport valid?)
1703 *****************************************************************************/
1704 static HRESULT WINAPI
1705 IDirect3DDeviceImpl_3_SetCurrentViewport(IDirect3DDevice3 *iface,
1706 IDirect3DViewport3 *Direct3DViewport3)
1708 IDirect3DDeviceImpl *This = device_from_device3(iface);
1709 IDirect3DViewportImpl *vp = (IDirect3DViewportImpl *)Direct3DViewport3;
1711 TRACE("iface %p, viewport %p.\n", iface, Direct3DViewport3);
1713 EnterCriticalSection(&ddraw_cs);
1714 /* Do nothing if the specified viewport is the same as the current one */
1715 if (This->current_viewport == vp )
1717 LeaveCriticalSection(&ddraw_cs);
1721 if (vp->active_device != This)
1723 WARN("Viewport %p active device is %p.\n", vp, vp->active_device);
1724 LeaveCriticalSection(&ddraw_cs);
1725 return DDERR_INVALIDPARAMS;
1728 /* Release previous viewport and AddRef the new one */
1729 if (This->current_viewport)
1731 TRACE("ViewportImpl is at %p, interface is at %p\n", This->current_viewport,
1732 (IDirect3DViewport3 *)This->current_viewport);
1733 IDirect3DViewport3_Release((IDirect3DViewport3 *)This->current_viewport);
1735 IDirect3DViewport3_AddRef(Direct3DViewport3);
1737 /* Set this viewport as the current viewport */
1738 This->current_viewport = vp;
1740 /* Activate this viewport */
1741 viewport_activate(This->current_viewport, FALSE);
1743 LeaveCriticalSection(&ddraw_cs);
1747 static HRESULT WINAPI IDirect3DDeviceImpl_2_SetCurrentViewport(IDirect3DDevice2 *iface,
1748 IDirect3DViewport2 *Direct3DViewport2)
1750 IDirect3DDeviceImpl *This = device_from_device2(iface);
1751 IDirect3DViewportImpl *vp = (IDirect3DViewportImpl *)Direct3DViewport2;
1753 TRACE("iface %p, viewport %p.\n", iface, Direct3DViewport2);
1755 return IDirect3DDevice3_SetCurrentViewport((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl,
1756 (IDirect3DViewport3 *)vp);
1759 /*****************************************************************************
1760 * IDirect3DDevice3::GetCurrentViewport
1762 * Returns the currently active viewport.
1767 * Direct3DViewport3: Address to return the interface pointer at
1771 * DDERR_INVALIDPARAMS if Direct3DViewport == NULL
1773 *****************************************************************************/
1774 static HRESULT WINAPI
1775 IDirect3DDeviceImpl_3_GetCurrentViewport(IDirect3DDevice3 *iface,
1776 IDirect3DViewport3 **Direct3DViewport3)
1778 IDirect3DDeviceImpl *This = device_from_device3(iface);
1780 TRACE("iface %p, viewport %p.\n", iface, Direct3DViewport3);
1782 if(!Direct3DViewport3)
1783 return DDERR_INVALIDPARAMS;
1785 EnterCriticalSection(&ddraw_cs);
1786 *Direct3DViewport3 = (IDirect3DViewport3 *)This->current_viewport;
1788 /* AddRef the returned viewport */
1789 if(*Direct3DViewport3) IDirect3DViewport3_AddRef(*Direct3DViewport3);
1791 TRACE(" returning interface %p\n", *Direct3DViewport3);
1793 LeaveCriticalSection(&ddraw_cs);
1797 static HRESULT WINAPI IDirect3DDeviceImpl_2_GetCurrentViewport(IDirect3DDevice2 *iface,
1798 IDirect3DViewport2 **Direct3DViewport2)
1800 IDirect3DDeviceImpl *This = device_from_device2(iface);
1803 TRACE("iface %p, viewport %p.\n", iface, Direct3DViewport2);
1805 hr = IDirect3DDevice3_GetCurrentViewport((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl,
1806 (IDirect3DViewport3 **)Direct3DViewport2);
1807 if(hr != D3D_OK) return hr;
1811 /*****************************************************************************
1812 * IDirect3DDevice7::SetRenderTarget
1814 * Sets the render target for the Direct3DDevice.
1815 * For the thunks note that IDirectDrawSurface7 == IDirectDrawSurface4 and
1816 * IDirectDrawSurface3 == IDirectDrawSurface
1818 * Version 2, 3 and 7
1821 * NewTarget: Pointer to an IDirectDrawSurface7 interface to set as the new
1826 * D3D_OK on success, for details see IWineD3DDevice::SetRenderTarget
1828 *****************************************************************************/
1829 static HRESULT d3d_device_set_render_target(IDirect3DDeviceImpl *This, IDirectDrawSurfaceImpl *Target)
1833 EnterCriticalSection(&ddraw_cs);
1834 /* Flags: Not used */
1836 if(This->target == Target)
1838 TRACE("No-op SetRenderTarget operation, not doing anything\n");
1839 LeaveCriticalSection(&ddraw_cs);
1842 This->target = Target;
1843 hr = wined3d_device_set_render_target(This->wined3d_device, 0,
1844 Target ? Target->wined3d_surface : NULL, FALSE);
1847 LeaveCriticalSection(&ddraw_cs);
1850 IDirect3DDeviceImpl_UpdateDepthStencil(This);
1851 LeaveCriticalSection(&ddraw_cs);
1856 IDirect3DDeviceImpl_7_SetRenderTarget(IDirect3DDevice7 *iface,
1857 IDirectDrawSurface7 *NewTarget,
1860 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
1861 IDirectDrawSurfaceImpl *Target = unsafe_impl_from_IDirectDrawSurface7(NewTarget);
1863 TRACE("iface %p, target %p, flags %#x.\n", iface, NewTarget, Flags);
1864 /* Flags: Not used */
1866 IDirectDrawSurface7_AddRef(NewTarget);
1867 IDirectDrawSurface7_Release(&This->target->IDirectDrawSurface7_iface);
1868 return d3d_device_set_render_target(This, Target);
1871 static HRESULT WINAPI
1872 IDirect3DDeviceImpl_7_SetRenderTarget_FPUSetup(IDirect3DDevice7 *iface,
1873 IDirectDrawSurface7 *NewTarget,
1876 return IDirect3DDeviceImpl_7_SetRenderTarget(iface, NewTarget, Flags);
1879 static HRESULT WINAPI
1880 IDirect3DDeviceImpl_7_SetRenderTarget_FPUPreserve(IDirect3DDevice7 *iface,
1881 IDirectDrawSurface7 *NewTarget,
1887 old_fpucw = d3d_fpu_setup();
1888 hr = IDirect3DDeviceImpl_7_SetRenderTarget(iface, NewTarget, Flags);
1889 set_fpu_control_word(old_fpucw);
1894 static HRESULT WINAPI IDirect3DDeviceImpl_3_SetRenderTarget(IDirect3DDevice3 *iface,
1895 IDirectDrawSurface4 *NewRenderTarget, DWORD Flags)
1897 IDirect3DDeviceImpl *This = device_from_device3(iface);
1898 IDirectDrawSurfaceImpl *Target = unsafe_impl_from_IDirectDrawSurface4(NewRenderTarget);
1900 TRACE("iface %p, target %p, flags %#x.\n", iface, NewRenderTarget, Flags);
1902 IDirectDrawSurface4_AddRef(NewRenderTarget);
1903 IDirectDrawSurface4_Release(&This->target->IDirectDrawSurface4_iface);
1904 return d3d_device_set_render_target(This, Target);
1907 static HRESULT WINAPI IDirect3DDeviceImpl_2_SetRenderTarget(IDirect3DDevice2 *iface,
1908 IDirectDrawSurface *NewRenderTarget, DWORD Flags)
1910 IDirect3DDeviceImpl *This = device_from_device2(iface);
1911 IDirectDrawSurfaceImpl *Target = unsafe_impl_from_IDirectDrawSurface(NewRenderTarget);
1913 TRACE("iface %p, target %p, flags %#x.\n", iface, NewRenderTarget, Flags);
1915 IDirectDrawSurface_AddRef(NewRenderTarget);
1916 IDirectDrawSurface_Release(&This->target->IDirectDrawSurface_iface);
1917 return d3d_device_set_render_target(This, Target);
1920 /*****************************************************************************
1921 * IDirect3DDevice7::GetRenderTarget
1923 * Returns the current render target.
1924 * This is handled locally, because the WineD3D render target's parent
1927 * Version 2, 3 and 7
1930 * RenderTarget: Address to store the surface interface pointer
1934 * DDERR_INVALIDPARAMS if RenderTarget == NULL
1936 *****************************************************************************/
1937 static HRESULT WINAPI
1938 IDirect3DDeviceImpl_7_GetRenderTarget(IDirect3DDevice7 *iface,
1939 IDirectDrawSurface7 **RenderTarget)
1941 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
1943 TRACE("iface %p, target %p.\n", iface, RenderTarget);
1946 return DDERR_INVALIDPARAMS;
1948 EnterCriticalSection(&ddraw_cs);
1949 *RenderTarget = &This->target->IDirectDrawSurface7_iface;
1950 IDirectDrawSurface7_AddRef(*RenderTarget);
1952 LeaveCriticalSection(&ddraw_cs);
1956 static HRESULT WINAPI IDirect3DDeviceImpl_3_GetRenderTarget(IDirect3DDevice3 *iface,
1957 IDirectDrawSurface4 **RenderTarget)
1959 IDirect3DDeviceImpl *This = device_from_device3(iface);
1960 IDirectDrawSurface7 *RenderTarget7;
1961 IDirectDrawSurfaceImpl *RenderTargetImpl;
1964 TRACE("iface %p, target %p.\n", iface, RenderTarget);
1967 return DDERR_INVALIDPARAMS;
1969 hr = IDirect3DDevice7_GetRenderTarget((IDirect3DDevice7 *)This, &RenderTarget7);
1970 if(hr != D3D_OK) return hr;
1971 RenderTargetImpl = impl_from_IDirectDrawSurface7(RenderTarget7);
1972 *RenderTarget = &RenderTargetImpl->IDirectDrawSurface4_iface;
1973 IDirectDrawSurface4_AddRef(*RenderTarget);
1974 IDirectDrawSurface7_Release(RenderTarget7);
1978 static HRESULT WINAPI IDirect3DDeviceImpl_2_GetRenderTarget(IDirect3DDevice2 *iface,
1979 IDirectDrawSurface **RenderTarget)
1981 IDirect3DDeviceImpl *This = device_from_device2(iface);
1982 IDirectDrawSurface7 *RenderTarget7;
1983 IDirectDrawSurfaceImpl *RenderTargetImpl;
1986 TRACE("iface %p, target %p.\n", iface, RenderTarget);
1989 return DDERR_INVALIDPARAMS;
1991 hr = IDirect3DDevice7_GetRenderTarget((IDirect3DDevice7 *)This, &RenderTarget7);
1992 if(hr != D3D_OK) return hr;
1993 RenderTargetImpl = impl_from_IDirectDrawSurface7(RenderTarget7);
1994 *RenderTarget = &RenderTargetImpl->IDirectDrawSurface_iface;
1995 IDirectDrawSurface_AddRef(*RenderTarget);
1996 IDirectDrawSurface7_Release(RenderTarget7);
2000 /*****************************************************************************
2001 * IDirect3DDevice3::Begin
2003 * Begins a description block of vertices. This is similar to glBegin()
2004 * and glEnd(). After a call to IDirect3DDevice3::End, the vertices
2005 * described with IDirect3DDevice::Vertex are drawn.
2010 * PrimitiveType: The type of primitives to draw
2011 * VertexTypeDesc: A flexible vertex format description of the vertices
2012 * Flags: Some flags..
2017 *****************************************************************************/
2018 static HRESULT WINAPI
2019 IDirect3DDeviceImpl_3_Begin(IDirect3DDevice3 *iface,
2020 D3DPRIMITIVETYPE PrimitiveType,
2021 DWORD VertexTypeDesc,
2024 IDirect3DDeviceImpl *This = device_from_device3(iface);
2026 TRACE("iface %p, primitive_type %#x, FVF %#x, flags %#x.\n",
2027 iface, PrimitiveType, VertexTypeDesc, Flags);
2029 EnterCriticalSection(&ddraw_cs);
2030 This->primitive_type = PrimitiveType;
2031 This->vertex_type = VertexTypeDesc;
2032 This->render_flags = Flags;
2033 This->vertex_size = get_flexible_vertex_size(This->vertex_type);
2034 This->nb_vertices = 0;
2035 LeaveCriticalSection(&ddraw_cs);
2040 static HRESULT WINAPI IDirect3DDeviceImpl_2_Begin(IDirect3DDevice2 *iface, D3DPRIMITIVETYPE d3dpt,
2041 D3DVERTEXTYPE dwVertexTypeDesc, DWORD dwFlags)
2044 IDirect3DDeviceImpl *This = device_from_device2(iface);
2046 TRACE("iface %p, primitive_type %#x, vertex_type %#x, flags %#x.\n",
2047 iface, d3dpt, dwVertexTypeDesc, dwFlags);
2049 switch(dwVertexTypeDesc)
2051 case D3DVT_VERTEX: FVF = D3DFVF_VERTEX; break;
2052 case D3DVT_LVERTEX: FVF = D3DFVF_LVERTEX; break;
2053 case D3DVT_TLVERTEX: FVF = D3DFVF_TLVERTEX; break;
2055 ERR("Unexpected vertex type %d\n", dwVertexTypeDesc);
2056 return DDERR_INVALIDPARAMS; /* Should never happen */
2059 return IDirect3DDevice3_Begin((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl, d3dpt, FVF, dwFlags);
2062 /*****************************************************************************
2063 * IDirect3DDevice3::BeginIndexed
2065 * Draws primitives based on vertices in a vertex array which are specified
2071 * PrimitiveType: Primitive type to draw
2072 * VertexType: A FVF description of the vertex format
2073 * Vertices: pointer to an array containing the vertices
2074 * NumVertices: The number of vertices in the vertex array
2075 * Flags: Some flags ...
2078 * D3D_OK, because it's a stub
2080 *****************************************************************************/
2081 static HRESULT WINAPI
2082 IDirect3DDeviceImpl_3_BeginIndexed(IDirect3DDevice3 *iface,
2083 D3DPRIMITIVETYPE PrimitiveType,
2089 FIXME("iface %p, primitive_type %#x, FVF %#x, vertices %p, vertex_count %u, flags %#x stub!\n",
2090 iface, PrimitiveType, VertexType, Vertices, NumVertices, Flags);
2096 static HRESULT WINAPI IDirect3DDeviceImpl_2_BeginIndexed(IDirect3DDevice2 *iface,
2097 D3DPRIMITIVETYPE d3dptPrimitiveType, D3DVERTEXTYPE d3dvtVertexType,
2098 void *lpvVertices, DWORD dwNumVertices, DWORD dwFlags)
2101 IDirect3DDeviceImpl *This = device_from_device2(iface);
2103 TRACE("iface %p, primitive_type %#x, vertex_type %#x, vertices %p, vertex_count %u, flags %#x stub!\n",
2104 iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwNumVertices, dwFlags);
2106 switch(d3dvtVertexType)
2108 case D3DVT_VERTEX: FVF = D3DFVF_VERTEX; break;
2109 case D3DVT_LVERTEX: FVF = D3DFVF_LVERTEX; break;
2110 case D3DVT_TLVERTEX: FVF = D3DFVF_TLVERTEX; break;
2112 ERR("Unexpected vertex type %d\n", d3dvtVertexType);
2113 return DDERR_INVALIDPARAMS; /* Should never happen */
2116 return IDirect3DDevice3_BeginIndexed((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl,
2117 d3dptPrimitiveType, FVF, lpvVertices, dwNumVertices, dwFlags);
2120 /*****************************************************************************
2121 * IDirect3DDevice3::Vertex
2123 * Draws a vertex as described by IDirect3DDevice3::Begin. It places all
2124 * drawn vertices in a vertex buffer. If the buffer is too small, its
2125 * size is increased.
2130 * Vertex: Pointer to the vertex
2133 * D3D_OK, on success
2134 * DDERR_INVALIDPARAMS if Vertex is NULL
2136 *****************************************************************************/
2137 static HRESULT WINAPI
2138 IDirect3DDeviceImpl_3_Vertex(IDirect3DDevice3 *iface,
2141 IDirect3DDeviceImpl *This = device_from_device3(iface);
2143 TRACE("iface %p, vertex %p.\n", iface, Vertex);
2146 return DDERR_INVALIDPARAMS;
2148 EnterCriticalSection(&ddraw_cs);
2149 if ((This->nb_vertices+1)*This->vertex_size > This->buffer_size)
2152 This->buffer_size = This->buffer_size ? This->buffer_size * 2 : This->vertex_size * 3;
2153 old_buffer = This->vertex_buffer;
2154 This->vertex_buffer = HeapAlloc(GetProcessHeap(), 0, This->buffer_size);
2157 CopyMemory(This->vertex_buffer, old_buffer, This->nb_vertices * This->vertex_size);
2158 HeapFree(GetProcessHeap(), 0, old_buffer);
2162 CopyMemory(This->vertex_buffer + This->nb_vertices++ * This->vertex_size, Vertex, This->vertex_size);
2164 LeaveCriticalSection(&ddraw_cs);
2168 static HRESULT WINAPI IDirect3DDeviceImpl_2_Vertex(IDirect3DDevice2 *iface, void *lpVertexType)
2170 IDirect3DDeviceImpl *This = device_from_device2(iface);
2172 TRACE("iface %p, vertex %p.\n", iface, lpVertexType);
2174 return IDirect3DDevice3_Vertex((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl, lpVertexType);
2177 /*****************************************************************************
2178 * IDirect3DDevice3::Index
2180 * Specifies an index to a vertex to be drawn. The vertex array has to
2181 * be specified with BeginIndexed first.
2184 * VertexIndex: The index of the vertex to draw
2187 * D3D_OK because it's a stub
2189 *****************************************************************************/
2190 static HRESULT WINAPI
2191 IDirect3DDeviceImpl_3_Index(IDirect3DDevice3 *iface,
2194 FIXME("iface %p, index %#x stub!\n", iface, VertexIndex);
2199 static HRESULT WINAPI IDirect3DDeviceImpl_2_Index(IDirect3DDevice2 *iface, WORD wVertexIndex)
2201 IDirect3DDeviceImpl *This = device_from_device2(iface);
2203 TRACE("iface %p, index %#x.\n", iface, wVertexIndex);
2205 return IDirect3DDevice3_Index((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl, wVertexIndex);
2208 /*****************************************************************************
2209 * IDirect3DDevice3::End
2211 * Ends a draw begun with IDirect3DDevice3::Begin or
2212 * IDirect3DDevice::BeginIndexed. The vertices specified with
2213 * IDirect3DDevice::Vertex or IDirect3DDevice::Index are drawn using
2214 * the IDirect3DDevice7::DrawPrimitive method. So far only
2215 * non-indexed mode is supported
2220 * Flags: Some flags, as usual. Don't know which are defined
2223 * The return value of IDirect3DDevice7::DrawPrimitive
2225 *****************************************************************************/
2226 static HRESULT WINAPI
2227 IDirect3DDeviceImpl_3_End(IDirect3DDevice3 *iface,
2230 IDirect3DDeviceImpl *This = device_from_device3(iface);
2232 TRACE("iface %p, flags %#x.\n", iface, Flags);
2234 return IDirect3DDevice7_DrawPrimitive((IDirect3DDevice7 *)This, This->primitive_type,
2235 This->vertex_type, This->vertex_buffer, This->nb_vertices, This->render_flags);
2238 static HRESULT WINAPI IDirect3DDeviceImpl_2_End(IDirect3DDevice2 *iface, DWORD dwFlags)
2240 IDirect3DDeviceImpl *This = device_from_device2(iface);
2242 TRACE("iface %p, flags %#x.\n", iface, dwFlags);
2244 return IDirect3DDevice3_End((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl, dwFlags);
2247 /*****************************************************************************
2248 * IDirect3DDevice7::GetRenderState
2250 * Returns the value of a render state. The possible render states are
2251 * defined in include/d3dtypes.h
2253 * Version 2, 3 and 7
2256 * RenderStateType: Render state to return the current setting of
2257 * Value: Address to store the value at
2260 * D3D_OK on success, for details see IWineD3DDevice::GetRenderState
2261 * DDERR_INVALIDPARAMS if Value == NULL
2263 *****************************************************************************/
2264 static HRESULT IDirect3DDeviceImpl_7_GetRenderState(IDirect3DDevice7 *iface,
2265 D3DRENDERSTATETYPE RenderStateType, DWORD *Value)
2267 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
2270 TRACE("iface %p, state %#x, value %p.\n", iface, RenderStateType, Value);
2273 return DDERR_INVALIDPARAMS;
2275 EnterCriticalSection(&ddraw_cs);
2276 switch(RenderStateType)
2278 case D3DRENDERSTATE_TEXTUREMAG:
2280 WINED3DTEXTUREFILTERTYPE tex_mag;
2282 hr = wined3d_device_get_sampler_state(This->wined3d_device, 0, WINED3DSAMP_MAGFILTER, &tex_mag);
2286 case WINED3DTEXF_POINT:
2287 *Value = D3DFILTER_NEAREST;
2289 case WINED3DTEXF_LINEAR:
2290 *Value = D3DFILTER_LINEAR;
2293 ERR("Unhandled texture mag %d !\n",tex_mag);
2299 case D3DRENDERSTATE_TEXTUREMIN:
2301 WINED3DTEXTUREFILTERTYPE tex_min;
2302 WINED3DTEXTUREFILTERTYPE tex_mip;
2304 hr = wined3d_device_get_sampler_state(This->wined3d_device,
2305 0, WINED3DSAMP_MINFILTER, &tex_min);
2308 LeaveCriticalSection(&ddraw_cs);
2311 hr = wined3d_device_get_sampler_state(This->wined3d_device,
2312 0, WINED3DSAMP_MIPFILTER, &tex_mip);
2316 case WINED3DTEXF_POINT:
2319 case WINED3DTEXF_NONE:
2320 *Value = D3DFILTER_NEAREST;
2322 case WINED3DTEXF_POINT:
2323 *Value = D3DFILTER_MIPNEAREST;
2325 case WINED3DTEXF_LINEAR:
2326 *Value = D3DFILTER_LINEARMIPNEAREST;
2329 ERR("Unhandled mip filter %#x.\n", tex_mip);
2330 *Value = D3DFILTER_NEAREST;
2334 case WINED3DTEXF_LINEAR:
2337 case WINED3DTEXF_NONE:
2338 *Value = D3DFILTER_LINEAR;
2340 case WINED3DTEXF_POINT:
2341 *Value = D3DFILTER_MIPLINEAR;
2343 case WINED3DTEXF_LINEAR:
2344 *Value = D3DFILTER_LINEARMIPLINEAR;
2347 ERR("Unhandled mip filter %#x.\n", tex_mip);
2348 *Value = D3DFILTER_LINEAR;
2353 ERR("Unhandled texture min filter %#x.\n",tex_min);
2354 *Value = D3DFILTER_NEAREST;
2360 case D3DRENDERSTATE_TEXTUREADDRESS:
2361 case D3DRENDERSTATE_TEXTUREADDRESSU:
2362 hr = wined3d_device_get_sampler_state(This->wined3d_device,
2363 0, WINED3DSAMP_ADDRESSU, Value);
2365 case D3DRENDERSTATE_TEXTUREADDRESSV:
2366 hr = wined3d_device_get_sampler_state(This->wined3d_device,
2367 0, WINED3DSAMP_ADDRESSV, Value);
2370 case D3DRENDERSTATE_BORDERCOLOR:
2371 FIXME("Unhandled render state D3DRENDERSTATE_BORDERCOLOR.\n");
2375 case D3DRENDERSTATE_TEXTUREHANDLE:
2376 case D3DRENDERSTATE_TEXTUREMAPBLEND:
2377 WARN("Render state %#x is invalid in d3d7.\n", RenderStateType);
2378 hr = DDERR_INVALIDPARAMS;
2381 case D3DRENDERSTATE_ZBIAS:
2382 hr = wined3d_device_get_render_state(This->wined3d_device, WINED3DRS_DEPTHBIAS, Value);
2386 if (RenderStateType >= D3DRENDERSTATE_STIPPLEPATTERN00
2387 && RenderStateType <= D3DRENDERSTATE_STIPPLEPATTERN31)
2389 FIXME("Unhandled stipple pattern render state (%#x).\n",
2394 hr = wined3d_device_get_render_state(This->wined3d_device, RenderStateType, Value);
2396 LeaveCriticalSection(&ddraw_cs);
2400 static HRESULT WINAPI
2401 IDirect3DDeviceImpl_7_GetRenderState_FPUSetup(IDirect3DDevice7 *iface,
2402 D3DRENDERSTATETYPE RenderStateType,
2405 return IDirect3DDeviceImpl_7_GetRenderState(iface, RenderStateType, Value);
2408 static HRESULT WINAPI
2409 IDirect3DDeviceImpl_7_GetRenderState_FPUPreserve(IDirect3DDevice7 *iface,
2410 D3DRENDERSTATETYPE RenderStateType,
2416 old_fpucw = d3d_fpu_setup();
2417 hr = IDirect3DDeviceImpl_7_GetRenderState(iface, RenderStateType, Value);
2418 set_fpu_control_word(old_fpucw);
2423 static HRESULT WINAPI
2424 IDirect3DDeviceImpl_3_GetRenderState(IDirect3DDevice3 *iface,
2425 D3DRENDERSTATETYPE dwRenderStateType,
2426 DWORD *lpdwRenderState)
2428 IDirect3DDeviceImpl *This = device_from_device3(iface);
2431 TRACE("iface %p, state %#x, value %p.\n", iface, dwRenderStateType, lpdwRenderState);
2433 switch(dwRenderStateType)
2435 case D3DRENDERSTATE_TEXTUREHANDLE:
2437 /* This state is wrapped to SetTexture in SetRenderState, so
2438 * it has to be wrapped to GetTexture here. */
2439 struct wined3d_texture *tex = NULL;
2440 *lpdwRenderState = 0;
2442 EnterCriticalSection(&ddraw_cs);
2444 hr = wined3d_device_get_texture(This->wined3d_device, 0, &tex);
2445 if (SUCCEEDED(hr) && tex)
2447 /* The parent of the texture is the IDirectDrawSurface7
2448 * interface of the ddraw surface. */
2449 IDirectDrawSurfaceImpl *parent = wined3d_texture_get_parent(tex);
2450 if (parent) *lpdwRenderState = parent->Handle;
2451 wined3d_texture_decref(tex);
2454 LeaveCriticalSection(&ddraw_cs);
2459 case D3DRENDERSTATE_TEXTUREMAPBLEND:
2461 /* D3DRENDERSTATE_TEXTUREMAPBLEND is mapped to texture state stages in SetRenderState; reverse
2462 the mapping to get the value. */
2463 DWORD colorop, colorarg1, colorarg2;
2464 DWORD alphaop, alphaarg1, alphaarg2;
2466 EnterCriticalSection(&ddraw_cs);
2468 This->legacyTextureBlending = TRUE;
2470 wined3d_device_get_texture_stage_state(This->wined3d_device, 0, WINED3DTSS_COLOROP, &colorop);
2471 wined3d_device_get_texture_stage_state(This->wined3d_device, 0, WINED3DTSS_COLORARG1, &colorarg1);
2472 wined3d_device_get_texture_stage_state(This->wined3d_device, 0, WINED3DTSS_COLORARG2, &colorarg2);
2473 wined3d_device_get_texture_stage_state(This->wined3d_device, 0, WINED3DTSS_ALPHAOP, &alphaop);
2474 wined3d_device_get_texture_stage_state(This->wined3d_device, 0, WINED3DTSS_ALPHAARG1, &alphaarg1);
2475 wined3d_device_get_texture_stage_state(This->wined3d_device, 0, WINED3DTSS_ALPHAARG2, &alphaarg2);
2477 if (colorop == WINED3DTOP_SELECTARG1 && colorarg1 == WINED3DTA_TEXTURE &&
2478 alphaop == WINED3DTOP_SELECTARG1 && alphaarg1 == WINED3DTA_TEXTURE)
2480 *lpdwRenderState = D3DTBLEND_DECAL;
2482 else if (colorop == WINED3DTOP_SELECTARG1 && colorarg1 == WINED3DTA_TEXTURE &&
2483 alphaop == WINED3DTOP_MODULATE && alphaarg1 == WINED3DTA_TEXTURE && alphaarg2 == WINED3DTA_CURRENT)
2485 *lpdwRenderState = D3DTBLEND_DECALALPHA;
2487 else if (colorop == WINED3DTOP_MODULATE && colorarg1 == WINED3DTA_TEXTURE && colorarg2 == WINED3DTA_CURRENT &&
2488 alphaop == WINED3DTOP_MODULATE && alphaarg1 == WINED3DTA_TEXTURE && alphaarg2 == WINED3DTA_CURRENT)
2490 *lpdwRenderState = D3DTBLEND_MODULATEALPHA;
2494 struct wined3d_texture *tex = NULL;
2496 BOOL tex_alpha = FALSE;
2497 DDPIXELFORMAT ddfmt;
2499 hr = wined3d_device_get_texture(This->wined3d_device, 0, &tex);
2501 if(hr == WINED3D_OK && tex)
2503 struct wined3d_resource *sub_resource;
2505 if ((sub_resource = wined3d_texture_get_sub_resource(tex, 0)))
2507 struct wined3d_resource_desc desc;
2509 wined3d_resource_get_desc(sub_resource, &desc);
2510 ddfmt.dwSize = sizeof(ddfmt);
2511 PixelFormat_WineD3DtoDD(&ddfmt, desc.format);
2512 if (ddfmt.u5.dwRGBAlphaBitMask) tex_alpha = TRUE;
2515 wined3d_texture_decref(tex);
2518 if (!(colorop == WINED3DTOP_MODULATE && colorarg1 == WINED3DTA_TEXTURE && colorarg2 == WINED3DTA_CURRENT &&
2519 alphaop == (tex_alpha ? WINED3DTOP_SELECTARG1 : WINED3DTOP_SELECTARG2) &&
2520 alphaarg1 == WINED3DTA_TEXTURE && alphaarg2 == WINED3DTA_CURRENT))
2522 ERR("Unexpected texture stage state setup, returning D3DTBLEND_MODULATE - likely erroneous\n");
2525 *lpdwRenderState = D3DTBLEND_MODULATE;
2528 LeaveCriticalSection(&ddraw_cs);
2534 return IDirect3DDevice7_GetRenderState((IDirect3DDevice7 *)This, dwRenderStateType, lpdwRenderState);
2538 static HRESULT WINAPI IDirect3DDeviceImpl_2_GetRenderState(IDirect3DDevice2 *iface,
2539 D3DRENDERSTATETYPE dwRenderStateType, DWORD *lpdwRenderState)
2541 IDirect3DDeviceImpl *This = device_from_device2(iface);
2543 TRACE("iface %p, state %#x, value %p.\n", iface, dwRenderStateType, lpdwRenderState);
2545 return IDirect3DDevice3_GetRenderState((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl,
2546 dwRenderStateType, lpdwRenderState);
2549 /*****************************************************************************
2550 * IDirect3DDevice7::SetRenderState
2552 * Sets a render state. The possible render states are defined in
2553 * include/d3dtypes.h
2555 * Version 2, 3 and 7
2558 * RenderStateType: State to set
2559 * Value: Value to assign to that state
2562 * D3D_OK on success,
2563 * for details see IWineD3DDevice::SetRenderState
2565 *****************************************************************************/
2567 IDirect3DDeviceImpl_7_SetRenderState(IDirect3DDevice7 *iface,
2568 D3DRENDERSTATETYPE RenderStateType,
2571 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
2574 TRACE("iface %p, state %#x, value %#x.\n", iface, RenderStateType, Value);
2576 EnterCriticalSection(&ddraw_cs);
2577 /* Some render states need special care */
2578 switch(RenderStateType)
2581 * The ddraw texture filter mapping works like this:
2582 * D3DFILTER_NEAREST Point min/mag, no mip
2583 * D3DFILTER_MIPNEAREST Point min/mag, point mip
2584 * D3DFILTER_LINEARMIPNEAREST: Point min/mag, linear mip
2586 * D3DFILTER_LINEAR Linear min/mag, no mip
2587 * D3DFILTER_MIPLINEAR Linear min/mag, point mip
2588 * D3DFILTER_LINEARMIPLINEAR Linear min/mag, linear mip
2590 * This is the opposite of the GL naming convention,
2591 * D3DFILTER_LINEARMIPNEAREST corresponds to GL_NEAREST_MIPMAP_LINEAR.
2593 case D3DRENDERSTATE_TEXTUREMAG:
2595 WINED3DTEXTUREFILTERTYPE tex_mag;
2599 case D3DFILTER_NEAREST:
2600 case D3DFILTER_MIPNEAREST:
2601 case D3DFILTER_LINEARMIPNEAREST:
2602 tex_mag = WINED3DTEXF_POINT;
2604 case D3DFILTER_LINEAR:
2605 case D3DFILTER_MIPLINEAR:
2606 case D3DFILTER_LINEARMIPLINEAR:
2607 tex_mag = WINED3DTEXF_LINEAR;
2610 tex_mag = WINED3DTEXF_POINT;
2611 ERR("Unhandled texture mag %d !\n",Value);
2615 hr = wined3d_device_set_sampler_state(This->wined3d_device, 0, WINED3DSAMP_MAGFILTER, tex_mag);
2619 case D3DRENDERSTATE_TEXTUREMIN:
2621 WINED3DTEXTUREFILTERTYPE tex_min;
2622 WINED3DTEXTUREFILTERTYPE tex_mip;
2624 switch ((D3DTEXTUREFILTER) Value)
2626 case D3DFILTER_NEAREST:
2627 tex_min = WINED3DTEXF_POINT;
2628 tex_mip = WINED3DTEXF_NONE;
2630 case D3DFILTER_LINEAR:
2631 tex_min = WINED3DTEXF_LINEAR;
2632 tex_mip = WINED3DTEXF_NONE;
2634 case D3DFILTER_MIPNEAREST:
2635 tex_min = WINED3DTEXF_POINT;
2636 tex_mip = WINED3DTEXF_POINT;
2638 case D3DFILTER_MIPLINEAR:
2639 tex_min = WINED3DTEXF_LINEAR;
2640 tex_mip = WINED3DTEXF_POINT;
2642 case D3DFILTER_LINEARMIPNEAREST:
2643 tex_min = WINED3DTEXF_POINT;
2644 tex_mip = WINED3DTEXF_LINEAR;
2646 case D3DFILTER_LINEARMIPLINEAR:
2647 tex_min = WINED3DTEXF_LINEAR;
2648 tex_mip = WINED3DTEXF_LINEAR;
2652 ERR("Unhandled texture min %d !\n",Value);
2653 tex_min = WINED3DTEXF_POINT;
2654 tex_mip = WINED3DTEXF_NONE;
2658 wined3d_device_set_sampler_state(This->wined3d_device,
2659 0, WINED3DSAMP_MIPFILTER, tex_mip);
2660 hr = wined3d_device_set_sampler_state(This->wined3d_device,
2661 0, WINED3DSAMP_MINFILTER, tex_min);
2665 case D3DRENDERSTATE_TEXTUREADDRESS:
2666 wined3d_device_set_sampler_state(This->wined3d_device,
2667 0, WINED3DSAMP_ADDRESSV, Value);
2669 case D3DRENDERSTATE_TEXTUREADDRESSU:
2670 hr = wined3d_device_set_sampler_state(This->wined3d_device,
2671 0, WINED3DSAMP_ADDRESSU, Value);
2673 case D3DRENDERSTATE_TEXTUREADDRESSV:
2674 hr = wined3d_device_set_sampler_state(This->wined3d_device,
2675 0, WINED3DSAMP_ADDRESSV, Value);
2678 case D3DRENDERSTATE_BORDERCOLOR:
2679 /* This should probably just forward to the corresponding sampler
2680 * state. Needs tests. */
2681 FIXME("Unhandled render state D3DRENDERSTATE_BORDERCOLOR.\n");
2685 case D3DRENDERSTATE_TEXTUREHANDLE:
2686 case D3DRENDERSTATE_TEXTUREMAPBLEND:
2687 WARN("Render state %#x is invalid in d3d7.\n", RenderStateType);
2688 hr = DDERR_INVALIDPARAMS;
2691 case D3DRENDERSTATE_ZBIAS:
2692 hr = wined3d_device_set_render_state(This->wined3d_device, WINED3DRS_DEPTHBIAS, Value);
2696 if (RenderStateType >= D3DRENDERSTATE_STIPPLEPATTERN00
2697 && RenderStateType <= D3DRENDERSTATE_STIPPLEPATTERN31)
2699 FIXME("Unhandled stipple pattern render state (%#x).\n",
2705 hr = wined3d_device_set_render_state(This->wined3d_device, RenderStateType, Value);
2708 LeaveCriticalSection(&ddraw_cs);
2712 static HRESULT WINAPI
2713 IDirect3DDeviceImpl_7_SetRenderState_FPUSetup(IDirect3DDevice7 *iface,
2714 D3DRENDERSTATETYPE RenderStateType,
2717 return IDirect3DDeviceImpl_7_SetRenderState(iface, RenderStateType, Value);
2720 static HRESULT WINAPI
2721 IDirect3DDeviceImpl_7_SetRenderState_FPUPreserve(IDirect3DDevice7 *iface,
2722 D3DRENDERSTATETYPE RenderStateType,
2728 old_fpucw = d3d_fpu_setup();
2729 hr = IDirect3DDeviceImpl_7_SetRenderState(iface, RenderStateType, Value);
2730 set_fpu_control_word(old_fpucw);
2735 static HRESULT WINAPI
2736 IDirect3DDeviceImpl_3_SetRenderState(IDirect3DDevice3 *iface,
2737 D3DRENDERSTATETYPE RenderStateType,
2740 /* Note about D3DRENDERSTATE_TEXTUREMAPBLEND implementation: most of values
2741 for this state can be directly mapped to texture stage colorop and alphaop, but
2742 D3DTBLEND_MODULATE is tricky: it uses alpha from texture when available and alpha
2743 from diffuse otherwise. So changing the texture must be monitored in SetTexture to modify
2744 alphaarg when needed.
2746 Aliens vs Predator 1 depends on accurate D3DTBLEND_MODULATE emulation
2748 Legacy texture blending (TEXTUREMAPBLEND) and texture stage states: directx6 docs state that
2749 TEXTUREMAPBLEND is deprecated, yet can still be used. Games must not use both or results
2750 are undefined. D3DTBLEND_MODULATE mode in particular is dependent on texture pixel format and
2751 requires fixup of stage 0 texture states when texture changes, but this fixup can interfere
2752 with games not using this deprecated state. So a flag 'legacyTextureBlending' has to be kept
2753 in device - TRUE if the app is using TEXTUREMAPBLEND.
2755 Tests show that setting TEXTUREMAPBLEND on native doesn't seem to change values returned by
2756 GetTextureStageState and vice versa. Not so on Wine, but it is 'undefined' anyway so, probably, ok,
2757 unless some broken game will be found that cares. */
2760 IDirect3DDeviceImpl *This = device_from_device3(iface);
2762 TRACE("iface %p, state %#x, value %#x.\n", iface, RenderStateType, Value);
2764 EnterCriticalSection(&ddraw_cs);
2766 switch(RenderStateType)
2768 case D3DRENDERSTATE_TEXTUREHANDLE:
2770 IDirectDrawSurfaceImpl *surf;
2774 hr = wined3d_device_set_texture(This->wined3d_device, 0, NULL);
2778 surf = ddraw_get_object(&This->handle_table, Value - 1, DDRAW_HANDLE_SURFACE);
2781 WARN("Invalid texture handle.\n");
2782 hr = DDERR_INVALIDPARAMS;
2786 hr = IDirect3DDevice3_SetTexture(iface, 0, (IDirect3DTexture2 *)&surf->IDirect3DTexture2_vtbl);
2790 case D3DRENDERSTATE_TEXTUREMAPBLEND:
2792 This->legacyTextureBlending = TRUE;
2794 switch ( (D3DTEXTUREBLEND) Value)
2796 case D3DTBLEND_MODULATE:
2798 struct wined3d_texture *tex = NULL;
2799 BOOL tex_alpha = FALSE;
2800 DDPIXELFORMAT ddfmt;
2802 hr = wined3d_device_get_texture(This->wined3d_device, 0, &tex);
2804 if(hr == WINED3D_OK && tex)
2806 struct wined3d_resource *sub_resource;
2808 if ((sub_resource = wined3d_texture_get_sub_resource(tex, 0)))
2810 struct wined3d_resource_desc desc;
2812 wined3d_resource_get_desc(sub_resource, &desc);
2813 ddfmt.dwSize = sizeof(ddfmt);
2814 PixelFormat_WineD3DtoDD(&ddfmt, desc.format);
2815 if (ddfmt.u5.dwRGBAlphaBitMask) tex_alpha = TRUE;
2818 wined3d_texture_decref(tex);
2822 wined3d_device_set_texture_stage_state(This->wined3d_device,
2823 0, WINED3DTSS_ALPHAOP, WINED3DTOP_SELECTARG1);
2825 wined3d_device_set_texture_stage_state(This->wined3d_device,
2826 0, WINED3DTSS_ALPHAOP, WINED3DTOP_SELECTARG2);
2827 wined3d_device_set_texture_stage_state(This->wined3d_device,
2828 0, WINED3DTSS_ALPHAARG1, WINED3DTA_TEXTURE);
2829 wined3d_device_set_texture_stage_state(This->wined3d_device,
2830 0, WINED3DTSS_ALPHAARG2, WINED3DTA_CURRENT);
2831 wined3d_device_set_texture_stage_state(This->wined3d_device,
2832 0, WINED3DTSS_COLORARG1, WINED3DTA_TEXTURE);
2833 wined3d_device_set_texture_stage_state(This->wined3d_device,
2834 0, WINED3DTSS_COLORARG2, WINED3DTA_CURRENT);
2835 wined3d_device_set_texture_stage_state(This->wined3d_device,
2836 0, WINED3DTSS_COLOROP, WINED3DTOP_MODULATE);
2841 wined3d_device_set_texture_stage_state(This->wined3d_device,
2842 0, WINED3DTSS_COLOROP, WINED3DTOP_ADD);
2843 wined3d_device_set_texture_stage_state(This->wined3d_device,
2844 0, WINED3DTSS_COLORARG1, WINED3DTA_TEXTURE);
2845 wined3d_device_set_texture_stage_state(This->wined3d_device,
2846 0, WINED3DTSS_COLORARG2, WINED3DTA_CURRENT);
2847 wined3d_device_set_texture_stage_state(This->wined3d_device,
2848 0, WINED3DTSS_ALPHAOP, WINED3DTOP_SELECTARG2);
2849 wined3d_device_set_texture_stage_state(This->wined3d_device,
2850 0, WINED3DTSS_ALPHAARG2, WINED3DTA_CURRENT);
2853 case D3DTBLEND_MODULATEALPHA:
2854 wined3d_device_set_texture_stage_state(This->wined3d_device,
2855 0, WINED3DTSS_COLORARG1, WINED3DTA_TEXTURE);
2856 wined3d_device_set_texture_stage_state(This->wined3d_device,
2857 0, WINED3DTSS_ALPHAARG1, WINED3DTA_TEXTURE);
2858 wined3d_device_set_texture_stage_state(This->wined3d_device,
2859 0, WINED3DTSS_COLORARG2, WINED3DTA_CURRENT);
2860 wined3d_device_set_texture_stage_state(This->wined3d_device,
2861 0, WINED3DTSS_ALPHAARG2, WINED3DTA_CURRENT);
2862 wined3d_device_set_texture_stage_state(This->wined3d_device,
2863 0, WINED3DTSS_COLOROP, WINED3DTOP_MODULATE);
2864 wined3d_device_set_texture_stage_state(This->wined3d_device,
2865 0, WINED3DTSS_ALPHAOP, WINED3DTOP_MODULATE);
2868 case D3DTBLEND_COPY:
2869 case D3DTBLEND_DECAL:
2870 wined3d_device_set_texture_stage_state(This->wined3d_device,
2871 0, WINED3DTSS_COLORARG1, WINED3DTA_TEXTURE);
2872 wined3d_device_set_texture_stage_state(This->wined3d_device,
2873 0, WINED3DTSS_ALPHAARG1, WINED3DTA_TEXTURE);
2874 wined3d_device_set_texture_stage_state(This->wined3d_device,
2875 0, WINED3DTSS_COLOROP, WINED3DTOP_SELECTARG1);
2876 wined3d_device_set_texture_stage_state(This->wined3d_device,
2877 0, WINED3DTSS_ALPHAOP, WINED3DTOP_SELECTARG1);
2880 case D3DTBLEND_DECALALPHA:
2881 wined3d_device_set_texture_stage_state(This->wined3d_device,
2882 0, WINED3DTSS_COLOROP, WINED3DTOP_BLENDTEXTUREALPHA);
2883 wined3d_device_set_texture_stage_state(This->wined3d_device,
2884 0, WINED3DTSS_COLORARG1, WINED3DTA_TEXTURE);
2885 wined3d_device_set_texture_stage_state(This->wined3d_device,
2886 0, WINED3DTSS_COLORARG2, WINED3DTA_CURRENT);
2887 wined3d_device_set_texture_stage_state(This->wined3d_device,
2888 0, WINED3DTSS_ALPHAOP, WINED3DTOP_SELECTARG2);
2889 wined3d_device_set_texture_stage_state(This->wined3d_device,
2890 0, WINED3DTSS_ALPHAARG2, WINED3DTA_CURRENT);
2894 ERR("Unhandled texture environment %d !\n",Value);
2902 hr = IDirect3DDevice7_SetRenderState((IDirect3DDevice7 *)This, RenderStateType, Value);
2906 LeaveCriticalSection(&ddraw_cs);
2911 static HRESULT WINAPI IDirect3DDeviceImpl_2_SetRenderState(IDirect3DDevice2 *iface,
2912 D3DRENDERSTATETYPE RenderStateType, DWORD Value)
2914 IDirect3DDeviceImpl *This = device_from_device2(iface);
2916 TRACE("iface %p, state %#x, value %#x.\n", iface, RenderStateType, Value);
2918 return IDirect3DDevice3_SetRenderState((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl, RenderStateType, Value);
2921 /*****************************************************************************
2922 * Direct3DDevice3::SetLightState
2924 * Sets a light state for Direct3DDevice3 and Direct3DDevice2. The
2925 * light states are forwarded to Direct3DDevice7 render states
2930 * LightStateType: The light state to change
2931 * Value: The value to assign to that light state
2935 * DDERR_INVALIDPARAMS if the parameters were incorrect
2936 * Also check IDirect3DDevice7::SetRenderState
2938 *****************************************************************************/
2939 static HRESULT WINAPI
2940 IDirect3DDeviceImpl_3_SetLightState(IDirect3DDevice3 *iface,
2941 D3DLIGHTSTATETYPE LightStateType,
2944 IDirect3DDeviceImpl *This = device_from_device3(iface);
2947 TRACE("iface %p, state %#x, value %#x.\n", iface, LightStateType, Value);
2949 if (!LightStateType || (LightStateType > D3DLIGHTSTATE_COLORVERTEX))
2951 TRACE("Unexpected Light State Type\n");
2952 return DDERR_INVALIDPARAMS;
2955 EnterCriticalSection(&ddraw_cs);
2956 if (LightStateType == D3DLIGHTSTATE_MATERIAL /* 1 */)
2958 IDirect3DMaterialImpl *m = ddraw_get_object(&This->handle_table, Value - 1, DDRAW_HANDLE_MATERIAL);
2961 WARN("Invalid material handle.\n");
2962 LeaveCriticalSection(&ddraw_cs);
2963 return DDERR_INVALIDPARAMS;
2966 TRACE(" activating material %p.\n", m);
2967 material_activate(m);
2969 This->material = Value;
2971 else if (LightStateType == D3DLIGHTSTATE_COLORMODEL /* 3 */)
2976 ERR("DDCOLOR_MONO should not happen!\n");
2979 /* We are already in this mode */
2980 TRACE("Setting color model to RGB (no-op).\n");
2983 ERR("Unknown color model!\n");
2984 LeaveCriticalSection(&ddraw_cs);
2985 return DDERR_INVALIDPARAMS;
2990 D3DRENDERSTATETYPE rs;
2991 switch (LightStateType)
2993 case D3DLIGHTSTATE_AMBIENT: /* 2 */
2994 rs = D3DRENDERSTATE_AMBIENT;
2996 case D3DLIGHTSTATE_FOGMODE: /* 4 */
2997 rs = D3DRENDERSTATE_FOGVERTEXMODE;
2999 case D3DLIGHTSTATE_FOGSTART: /* 5 */
3000 rs = D3DRENDERSTATE_FOGSTART;
3002 case D3DLIGHTSTATE_FOGEND: /* 6 */
3003 rs = D3DRENDERSTATE_FOGEND;
3005 case D3DLIGHTSTATE_FOGDENSITY: /* 7 */
3006 rs = D3DRENDERSTATE_FOGDENSITY;
3008 case D3DLIGHTSTATE_COLORVERTEX: /* 8 */
3009 rs = D3DRENDERSTATE_COLORVERTEX;
3012 ERR("Unknown D3DLIGHTSTATETYPE %d.\n", LightStateType);
3013 LeaveCriticalSection(&ddraw_cs);
3014 return DDERR_INVALIDPARAMS;
3017 hr = IDirect3DDevice7_SetRenderState((IDirect3DDevice7 *)This, rs, Value);
3018 LeaveCriticalSection(&ddraw_cs);
3022 LeaveCriticalSection(&ddraw_cs);
3026 static HRESULT WINAPI IDirect3DDeviceImpl_2_SetLightState(IDirect3DDevice2 *iface,
3027 D3DLIGHTSTATETYPE LightStateType, DWORD Value)
3029 IDirect3DDeviceImpl *This = device_from_device2(iface);
3031 TRACE("iface %p, state %#x, value %#x.\n", iface, LightStateType, Value);
3033 return IDirect3DDevice3_SetLightState((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl, LightStateType, Value);
3036 /*****************************************************************************
3037 * IDirect3DDevice3::GetLightState
3039 * Returns the current setting of a light state. The state is read from
3040 * the Direct3DDevice7 render state.
3045 * LightStateType: The light state to return
3046 * Value: The address to store the light state setting at
3050 * DDDERR_INVALIDPARAMS if the parameters were incorrect
3051 * Also see IDirect3DDevice7::GetRenderState
3053 *****************************************************************************/
3054 static HRESULT WINAPI
3055 IDirect3DDeviceImpl_3_GetLightState(IDirect3DDevice3 *iface,
3056 D3DLIGHTSTATETYPE LightStateType,
3059 IDirect3DDeviceImpl *This = device_from_device3(iface);
3062 TRACE("iface %p, state %#x, value %p.\n", iface, LightStateType, Value);
3064 if (!LightStateType || (LightStateType > D3DLIGHTSTATE_COLORVERTEX))
3066 TRACE("Unexpected Light State Type\n");
3067 return DDERR_INVALIDPARAMS;
3071 return DDERR_INVALIDPARAMS;
3073 EnterCriticalSection(&ddraw_cs);
3074 if (LightStateType == D3DLIGHTSTATE_MATERIAL /* 1 */)
3076 *Value = This->material;
3078 else if (LightStateType == D3DLIGHTSTATE_COLORMODEL /* 3 */)
3080 *Value = D3DCOLOR_RGB;
3084 D3DRENDERSTATETYPE rs;
3085 switch (LightStateType)
3087 case D3DLIGHTSTATE_AMBIENT: /* 2 */
3088 rs = D3DRENDERSTATE_AMBIENT;
3090 case D3DLIGHTSTATE_FOGMODE: /* 4 */
3091 rs = D3DRENDERSTATE_FOGVERTEXMODE;
3093 case D3DLIGHTSTATE_FOGSTART: /* 5 */
3094 rs = D3DRENDERSTATE_FOGSTART;
3096 case D3DLIGHTSTATE_FOGEND: /* 6 */
3097 rs = D3DRENDERSTATE_FOGEND;
3099 case D3DLIGHTSTATE_FOGDENSITY: /* 7 */
3100 rs = D3DRENDERSTATE_FOGDENSITY;
3102 case D3DLIGHTSTATE_COLORVERTEX: /* 8 */
3103 rs = D3DRENDERSTATE_COLORVERTEX;
3106 ERR("Unknown D3DLIGHTSTATETYPE %d.\n", LightStateType);
3107 LeaveCriticalSection(&ddraw_cs);
3108 return DDERR_INVALIDPARAMS;
3111 hr = IDirect3DDevice7_GetRenderState((IDirect3DDevice7 *)This, rs, Value);
3112 LeaveCriticalSection(&ddraw_cs);
3116 LeaveCriticalSection(&ddraw_cs);
3120 static HRESULT WINAPI IDirect3DDeviceImpl_2_GetLightState(IDirect3DDevice2 *iface,
3121 D3DLIGHTSTATETYPE LightStateType, DWORD *Value)
3123 IDirect3DDeviceImpl *This = device_from_device2(iface);
3125 TRACE("iface %p, state %#x, value %p.\n", iface, LightStateType, Value);
3127 return IDirect3DDevice3_GetLightState((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl, LightStateType, Value);
3130 /*****************************************************************************
3131 * IDirect3DDevice7::SetTransform
3133 * Assigns a D3DMATRIX to a transform type. The transform types are defined
3134 * in include/d3dtypes.h.
3135 * The D3DTRANSFORMSTATE_WORLD (=1) is translated to D3DTS_WORLDMATRIX(0)
3136 * (=255) for wined3d, because the 1 transform state was removed in d3d8
3137 * and WineD3D already understands the replacement D3DTS_WORLDMATRIX(0)
3139 * Version 2, 3 and 7
3142 * TransformStateType: transform state to set
3143 * Matrix: Matrix to assign to the state
3147 * DDERR_INVALIDPARAMS if Matrix == NULL
3148 * For details see IWineD3DDevice::SetTransform
3150 *****************************************************************************/
3152 IDirect3DDeviceImpl_7_SetTransform(IDirect3DDevice7 *iface,
3153 D3DTRANSFORMSTATETYPE TransformStateType,
3156 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
3157 D3DTRANSFORMSTATETYPE type;
3160 TRACE("iface %p, state %#x, matrix %p.\n", iface, TransformStateType, Matrix);
3162 switch(TransformStateType)
3164 case D3DTRANSFORMSTATE_WORLD : type = WINED3DTS_WORLDMATRIX(0); break;
3165 case D3DTRANSFORMSTATE_WORLD1: type = WINED3DTS_WORLDMATRIX(1); break;
3166 case D3DTRANSFORMSTATE_WORLD2: type = WINED3DTS_WORLDMATRIX(2); break;
3167 case D3DTRANSFORMSTATE_WORLD3: type = WINED3DTS_WORLDMATRIX(3); break;
3168 default: type = TransformStateType;
3172 return DDERR_INVALIDPARAMS;
3174 /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
3175 EnterCriticalSection(&ddraw_cs);
3176 hr = wined3d_device_set_transform(This->wined3d_device, type, (WINED3DMATRIX *)Matrix);
3177 LeaveCriticalSection(&ddraw_cs);
3181 static HRESULT WINAPI
3182 IDirect3DDeviceImpl_7_SetTransform_FPUSetup(IDirect3DDevice7 *iface,
3183 D3DTRANSFORMSTATETYPE TransformStateType,
3186 return IDirect3DDeviceImpl_7_SetTransform(iface, TransformStateType, Matrix);
3189 static HRESULT WINAPI
3190 IDirect3DDeviceImpl_7_SetTransform_FPUPreserve(IDirect3DDevice7 *iface,
3191 D3DTRANSFORMSTATETYPE TransformStateType,
3197 old_fpucw = d3d_fpu_setup();
3198 hr = IDirect3DDeviceImpl_7_SetTransform(iface, TransformStateType, Matrix);
3199 set_fpu_control_word(old_fpucw);
3204 static HRESULT WINAPI IDirect3DDeviceImpl_3_SetTransform(IDirect3DDevice3 *iface,
3205 D3DTRANSFORMSTATETYPE TransformStateType, D3DMATRIX *D3DMatrix)
3207 IDirect3DDeviceImpl *This = device_from_device3(iface);
3209 TRACE("iface %p, state %#x, matrix %p.\n", iface, TransformStateType, D3DMatrix);
3211 return IDirect3DDevice7_SetTransform((IDirect3DDevice7 *)This, TransformStateType, D3DMatrix);
3214 static HRESULT WINAPI IDirect3DDeviceImpl_2_SetTransform(IDirect3DDevice2 *iface,
3215 D3DTRANSFORMSTATETYPE TransformStateType, D3DMATRIX *D3DMatrix)
3217 IDirect3DDeviceImpl *This = device_from_device2(iface);
3219 TRACE("iface %p, state %#x, matrix %p.\n", iface, TransformStateType, D3DMatrix);
3221 return IDirect3DDevice7_SetTransform((IDirect3DDevice7 *)This, TransformStateType, D3DMatrix);
3224 /*****************************************************************************
3225 * IDirect3DDevice7::GetTransform
3227 * Returns the matrix assigned to a transform state
3228 * D3DTRANSFORMSTATE_WORLD is translated to D3DTS_WORLDMATRIX(0), see
3232 * TransformStateType: State to read the matrix from
3233 * Matrix: Address to store the matrix at
3237 * DDERR_INVALIDPARAMS if Matrix == NULL
3238 * For details, see IWineD3DDevice::GetTransform
3240 *****************************************************************************/
3242 IDirect3DDeviceImpl_7_GetTransform(IDirect3DDevice7 *iface,
3243 D3DTRANSFORMSTATETYPE TransformStateType,
3246 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
3247 D3DTRANSFORMSTATETYPE type;
3250 TRACE("iface %p, state %#x, matrix %p.\n", iface, TransformStateType, Matrix);
3252 switch(TransformStateType)
3254 case D3DTRANSFORMSTATE_WORLD : type = WINED3DTS_WORLDMATRIX(0); break;
3255 case D3DTRANSFORMSTATE_WORLD1: type = WINED3DTS_WORLDMATRIX(1); break;
3256 case D3DTRANSFORMSTATE_WORLD2: type = WINED3DTS_WORLDMATRIX(2); break;
3257 case D3DTRANSFORMSTATE_WORLD3: type = WINED3DTS_WORLDMATRIX(3); break;
3258 default: type = TransformStateType;
3262 return DDERR_INVALIDPARAMS;
3264 /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
3265 EnterCriticalSection(&ddraw_cs);
3266 hr = wined3d_device_get_transform(This->wined3d_device, type, (WINED3DMATRIX *)Matrix);
3267 LeaveCriticalSection(&ddraw_cs);
3271 static HRESULT WINAPI
3272 IDirect3DDeviceImpl_7_GetTransform_FPUSetup(IDirect3DDevice7 *iface,
3273 D3DTRANSFORMSTATETYPE TransformStateType,
3276 return IDirect3DDeviceImpl_7_GetTransform(iface, TransformStateType, Matrix);
3279 static HRESULT WINAPI
3280 IDirect3DDeviceImpl_7_GetTransform_FPUPreserve(IDirect3DDevice7 *iface,
3281 D3DTRANSFORMSTATETYPE TransformStateType,
3287 old_fpucw = d3d_fpu_setup();
3288 hr = IDirect3DDeviceImpl_7_GetTransform(iface, TransformStateType, Matrix);
3289 set_fpu_control_word(old_fpucw);
3294 static HRESULT WINAPI IDirect3DDeviceImpl_3_GetTransform(IDirect3DDevice3 *iface,
3295 D3DTRANSFORMSTATETYPE TransformStateType, D3DMATRIX *D3DMatrix)
3297 IDirect3DDeviceImpl *This = device_from_device3(iface);
3299 TRACE("iface %p, state %#x, matrix %p.\n", iface, TransformStateType, D3DMatrix);
3301 return IDirect3DDevice7_GetTransform((IDirect3DDevice7 *)This, TransformStateType, D3DMatrix);
3304 static HRESULT WINAPI IDirect3DDeviceImpl_2_GetTransform(IDirect3DDevice2 *iface,
3305 D3DTRANSFORMSTATETYPE TransformStateType, D3DMATRIX *D3DMatrix)
3307 IDirect3DDeviceImpl *This = device_from_device2(iface);
3309 TRACE("iface %p, state %#x, matrix %p.\n", iface, TransformStateType, D3DMatrix);
3311 return IDirect3DDevice7_GetTransform((IDirect3DDevice7 *)This, TransformStateType, D3DMatrix);
3314 /*****************************************************************************
3315 * IDirect3DDevice7::MultiplyTransform
3317 * Multiplies the already-set transform matrix of a transform state
3318 * with another matrix. For the world matrix, see SetTransform
3320 * Version 2, 3 and 7
3323 * TransformStateType: Transform state to multiply
3324 * D3DMatrix Matrix to multiply with.
3328 * DDERR_INVALIDPARAMS if D3DMatrix is NULL
3329 * For details, see IWineD3DDevice::MultiplyTransform
3331 *****************************************************************************/
3333 IDirect3DDeviceImpl_7_MultiplyTransform(IDirect3DDevice7 *iface,
3334 D3DTRANSFORMSTATETYPE TransformStateType,
3335 D3DMATRIX *D3DMatrix)
3337 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
3339 D3DTRANSFORMSTATETYPE type;
3341 TRACE("iface %p, state %#x, matrix %p.\n", iface, TransformStateType, D3DMatrix);
3343 switch(TransformStateType)
3345 case D3DTRANSFORMSTATE_WORLD : type = WINED3DTS_WORLDMATRIX(0); break;
3346 case D3DTRANSFORMSTATE_WORLD1: type = WINED3DTS_WORLDMATRIX(1); break;
3347 case D3DTRANSFORMSTATE_WORLD2: type = WINED3DTS_WORLDMATRIX(2); break;
3348 case D3DTRANSFORMSTATE_WORLD3: type = WINED3DTS_WORLDMATRIX(3); break;
3349 default: type = TransformStateType;
3352 /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
3353 EnterCriticalSection(&ddraw_cs);
3354 hr = wined3d_device_multiply_transform(This->wined3d_device,
3355 type, (WINED3DMATRIX *)D3DMatrix);
3356 LeaveCriticalSection(&ddraw_cs);
3360 static HRESULT WINAPI
3361 IDirect3DDeviceImpl_7_MultiplyTransform_FPUSetup(IDirect3DDevice7 *iface,
3362 D3DTRANSFORMSTATETYPE TransformStateType,
3363 D3DMATRIX *D3DMatrix)
3365 return IDirect3DDeviceImpl_7_MultiplyTransform(iface, TransformStateType, D3DMatrix);
3368 static HRESULT WINAPI
3369 IDirect3DDeviceImpl_7_MultiplyTransform_FPUPreserve(IDirect3DDevice7 *iface,
3370 D3DTRANSFORMSTATETYPE TransformStateType,
3371 D3DMATRIX *D3DMatrix)
3376 old_fpucw = d3d_fpu_setup();
3377 hr = IDirect3DDeviceImpl_7_MultiplyTransform(iface, TransformStateType, D3DMatrix);
3378 set_fpu_control_word(old_fpucw);
3383 static HRESULT WINAPI IDirect3DDeviceImpl_3_MultiplyTransform(IDirect3DDevice3 *iface,
3384 D3DTRANSFORMSTATETYPE TransformStateType, D3DMATRIX *D3DMatrix)
3386 IDirect3DDeviceImpl *This = device_from_device3(iface);
3388 TRACE("iface %p, state %#x, matrix %p.\n", iface, TransformStateType, D3DMatrix);
3390 return IDirect3DDevice7_MultiplyTransform((IDirect3DDevice7 *)This, TransformStateType, D3DMatrix);
3393 static HRESULT WINAPI IDirect3DDeviceImpl_2_MultiplyTransform(IDirect3DDevice2 *iface,
3394 D3DTRANSFORMSTATETYPE TransformStateType, D3DMATRIX *D3DMatrix)
3396 IDirect3DDeviceImpl *This = device_from_device2(iface);
3398 TRACE("iface %p, state %#x, matrix %p.\n", iface, TransformStateType, D3DMatrix);
3400 return IDirect3DDevice7_MultiplyTransform((IDirect3DDevice7 *)This, TransformStateType, D3DMatrix);
3403 /*****************************************************************************
3404 * IDirect3DDevice7::DrawPrimitive
3406 * Draws primitives based on vertices in an application-provided pointer
3408 * Version 2, 3 and 7. The IDirect3DDevice2 thunk converts the fixed vertex type into
3409 * an FVF format for D3D7
3412 * PrimitiveType: The type of the primitives to draw
3413 * Vertex type: Flexible vertex format vertex description
3414 * Vertices: Pointer to the vertex array
3415 * VertexCount: The number of vertices to draw
3416 * Flags: As usual a few flags
3420 * DDERR_INVALIDPARAMS if Vertices is NULL
3421 * For details, see IWineD3DDevice::DrawPrimitiveUP
3423 *****************************************************************************/
3425 IDirect3DDeviceImpl_7_DrawPrimitive(IDirect3DDevice7 *iface,
3426 D3DPRIMITIVETYPE PrimitiveType,
3432 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
3436 TRACE("iface %p, primitive_type %#x, FVF %#x, vertices %p, vertex_count %u, flags %#x.\n",
3437 iface, PrimitiveType, VertexType, Vertices, VertexCount, Flags);
3440 return DDERR_INVALIDPARAMS;
3442 /* Get the stride */
3443 stride = get_flexible_vertex_size(VertexType);
3446 EnterCriticalSection(&ddraw_cs);
3447 hr = wined3d_device_set_vertex_declaration(This->wined3d_device, ddraw_find_decl(This->ddraw, VertexType));
3450 LeaveCriticalSection(&ddraw_cs);
3454 /* This method translates to the user pointer draw of WineD3D */
3455 wined3d_device_set_primitive_type(This->wined3d_device, PrimitiveType);
3456 hr = wined3d_device_draw_primitive_up(This->wined3d_device, VertexCount, Vertices, stride);
3457 LeaveCriticalSection(&ddraw_cs);
3461 static HRESULT WINAPI
3462 IDirect3DDeviceImpl_7_DrawPrimitive_FPUSetup(IDirect3DDevice7 *iface,
3463 D3DPRIMITIVETYPE PrimitiveType,
3469 return IDirect3DDeviceImpl_7_DrawPrimitive(iface, PrimitiveType, VertexType, Vertices, VertexCount, Flags);
3472 static HRESULT WINAPI
3473 IDirect3DDeviceImpl_7_DrawPrimitive_FPUPreserve(IDirect3DDevice7 *iface,
3474 D3DPRIMITIVETYPE PrimitiveType,
3483 old_fpucw = d3d_fpu_setup();
3484 hr = IDirect3DDeviceImpl_7_DrawPrimitive(iface, PrimitiveType, VertexType, Vertices, VertexCount, Flags);
3485 set_fpu_control_word(old_fpucw);
3490 static HRESULT WINAPI IDirect3DDeviceImpl_3_DrawPrimitive(IDirect3DDevice3 *iface,
3491 D3DPRIMITIVETYPE PrimitiveType, DWORD VertexType, void *Vertices, DWORD VertexCount,
3494 TRACE("iface %p, primitive_type %#x, FVF %#x, vertices %p, vertex_count %u, flags %#x.\n",
3495 iface, PrimitiveType, VertexType, Vertices, VertexCount, Flags);
3497 return IDirect3DDevice7_DrawPrimitive((IDirect3DDevice7 *)device_from_device3(iface),
3498 PrimitiveType, VertexType, Vertices, VertexCount, Flags);
3501 static HRESULT WINAPI IDirect3DDeviceImpl_2_DrawPrimitive(IDirect3DDevice2 *iface,
3502 D3DPRIMITIVETYPE PrimitiveType, D3DVERTEXTYPE VertexType, void *Vertices,
3503 DWORD VertexCount, DWORD Flags)
3507 TRACE("iface %p, primitive_type %#x, vertex_type %#x, vertices %p, vertex_count %u, flags %#x.\n",
3508 iface, PrimitiveType, VertexType, Vertices, VertexCount, Flags);
3512 case D3DVT_VERTEX: FVF = D3DFVF_VERTEX; break;
3513 case D3DVT_LVERTEX: FVF = D3DFVF_LVERTEX; break;
3514 case D3DVT_TLVERTEX: FVF = D3DFVF_TLVERTEX; break;
3516 ERR("Unexpected vertex type %d\n", VertexType);
3517 return DDERR_INVALIDPARAMS; /* Should never happen */
3520 return IDirect3DDevice7_DrawPrimitive((IDirect3DDevice7 *)device_from_device2(iface),
3521 PrimitiveType, FVF, Vertices, VertexCount, Flags);
3524 /*****************************************************************************
3525 * IDirect3DDevice7::DrawIndexedPrimitive
3527 * Draws vertices from an application-provided pointer, based on the index
3528 * numbers in a WORD array.
3530 * Version 2, 3 and 7. The version 7 thunk translates the vertex type into
3531 * an FVF format for D3D7
3534 * PrimitiveType: The primitive type to draw
3535 * VertexType: The FVF vertex description
3536 * Vertices: Pointer to the vertex array
3538 * Indices: Pointer to the index array
3539 * IndexCount: Number of indices = Number of vertices to draw
3540 * Flags: As usual, some flags
3544 * DDERR_INVALIDPARAMS if Vertices or Indices is NULL
3545 * For details, see IWineD3DDevice::DrawIndexedPrimitiveUP
3547 *****************************************************************************/
3549 IDirect3DDeviceImpl_7_DrawIndexedPrimitive(IDirect3DDevice7 *iface,
3550 D3DPRIMITIVETYPE PrimitiveType,
3558 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
3561 TRACE("iface %p, primitive_type %#x, FVF %#x, vertices %p, vertex_count %u, indices %p, index_count %u, flags %#x.\n",
3562 iface, PrimitiveType, VertexType, Vertices, VertexCount, Indices, IndexCount, Flags);
3564 /* Set the D3DDevice's FVF */
3565 EnterCriticalSection(&ddraw_cs);
3566 hr = wined3d_device_set_vertex_declaration(This->wined3d_device, ddraw_find_decl(This->ddraw, VertexType));
3569 ERR(" (%p) Setting the FVF failed, hr = %x!\n", This, hr);
3570 LeaveCriticalSection(&ddraw_cs);
3574 wined3d_device_set_primitive_type(This->wined3d_device, PrimitiveType);
3575 hr = wined3d_device_draw_indexed_primitive_up(This->wined3d_device, IndexCount, Indices,
3576 WINED3DFMT_R16_UINT, Vertices, get_flexible_vertex_size(VertexType));
3577 LeaveCriticalSection(&ddraw_cs);
3581 static HRESULT WINAPI
3582 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUSetup(IDirect3DDevice7 *iface,
3583 D3DPRIMITIVETYPE PrimitiveType,
3591 return IDirect3DDeviceImpl_7_DrawIndexedPrimitive(iface, PrimitiveType, VertexType, Vertices, VertexCount, Indices, IndexCount, Flags);
3594 static HRESULT WINAPI
3595 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUPreserve(IDirect3DDevice7 *iface,
3596 D3DPRIMITIVETYPE PrimitiveType,
3607 old_fpucw = d3d_fpu_setup();
3608 hr = IDirect3DDeviceImpl_7_DrawIndexedPrimitive(iface, PrimitiveType, VertexType, Vertices, VertexCount, Indices, IndexCount, Flags);
3609 set_fpu_control_word(old_fpucw);
3614 static HRESULT WINAPI IDirect3DDeviceImpl_3_DrawIndexedPrimitive(IDirect3DDevice3 *iface,
3615 D3DPRIMITIVETYPE PrimitiveType, DWORD VertexType, void *Vertices, DWORD VertexCount,
3616 WORD *Indices, DWORD IndexCount, DWORD Flags)
3618 TRACE("iface %p, primitive_type %#x, FVF %#x, vertices %p, vertex_count %u, indices %p, index_count %u, flags %#x.\n",
3619 iface, PrimitiveType, VertexType, Vertices, VertexCount, Indices, IndexCount, Flags);
3621 return IDirect3DDevice7_DrawIndexedPrimitive((IDirect3DDevice7 *)device_from_device3(iface),
3622 PrimitiveType, VertexType, Vertices, VertexCount, Indices, IndexCount, Flags);
3625 static HRESULT WINAPI IDirect3DDeviceImpl_2_DrawIndexedPrimitive(IDirect3DDevice2 *iface,
3626 D3DPRIMITIVETYPE PrimitiveType, D3DVERTEXTYPE VertexType, void *Vertices,
3627 DWORD VertexCount, WORD *Indices, DWORD IndexCount, DWORD Flags)
3631 TRACE("iface %p, primitive_type %#x, vertex_type %#x, vertices %p, vertex_count %u, indices %p, index_count %u, flags %#x.\n",
3632 iface, PrimitiveType, VertexType, Vertices, VertexCount, Indices, IndexCount, Flags);
3636 case D3DVT_VERTEX: FVF = D3DFVF_VERTEX; break;
3637 case D3DVT_LVERTEX: FVF = D3DFVF_LVERTEX; break;
3638 case D3DVT_TLVERTEX: FVF = D3DFVF_TLVERTEX; break;
3640 ERR("Unexpected vertex type %d\n", VertexType);
3641 return DDERR_INVALIDPARAMS; /* Should never happen */
3644 return IDirect3DDevice7_DrawIndexedPrimitive((IDirect3DDevice7 *)device_from_device2(iface),
3645 PrimitiveType, FVF, Vertices, VertexCount, Indices, IndexCount, Flags);
3648 /*****************************************************************************
3649 * IDirect3DDevice7::SetClipStatus
3651 * Sets the clip status. This defines things as clipping conditions and
3652 * the extents of the clipping region.
3654 * Version 2, 3 and 7
3660 * D3D_OK because it's a stub
3661 * (DDERR_INVALIDPARAMS if ClipStatus == NULL)
3663 *****************************************************************************/
3664 static HRESULT WINAPI
3665 IDirect3DDeviceImpl_7_SetClipStatus(IDirect3DDevice7 *iface,
3666 D3DCLIPSTATUS *ClipStatus)
3668 FIXME("iface %p, clip_status %p stub!\n", iface, ClipStatus);
3670 /* D3DCLIPSTATUS and WINED3DCLIPSTATUS are different. I don't know how to convert them
3671 * Perhaps this needs a new data type and an additional IWineD3DDevice method
3673 /* return IWineD3DDevice_SetClipStatus(This->wineD3DDevice, ClipStatus);*/
3677 static HRESULT WINAPI IDirect3DDeviceImpl_3_SetClipStatus(IDirect3DDevice3 *iface,
3678 D3DCLIPSTATUS *ClipStatus)
3680 TRACE("iface %p, clip_status %p.\n", iface, ClipStatus);
3682 return IDirect3DDevice7_SetClipStatus((IDirect3DDevice7 *)device_from_device3(iface), ClipStatus);
3685 static HRESULT WINAPI IDirect3DDeviceImpl_2_SetClipStatus(IDirect3DDevice2 *iface,
3686 D3DCLIPSTATUS *ClipStatus)
3688 TRACE("iface %p, clip_status %p.\n", iface, ClipStatus);
3690 return IDirect3DDevice7_SetClipStatus((IDirect3DDevice7 *)device_from_device2(iface), ClipStatus);
3693 /*****************************************************************************
3694 * IDirect3DDevice7::GetClipStatus
3696 * Returns the clip status
3699 * ClipStatus: Address to write the clip status to
3702 * D3D_OK because it's a stub
3704 *****************************************************************************/
3705 static HRESULT WINAPI
3706 IDirect3DDeviceImpl_7_GetClipStatus(IDirect3DDevice7 *iface,
3707 D3DCLIPSTATUS *ClipStatus)
3709 FIXME("iface %p, clip_status %p stub!\n", iface, ClipStatus);
3711 /* D3DCLIPSTATUS and WINED3DCLIPSTATUS are different. I don't know how to convert them */
3712 /* return IWineD3DDevice_GetClipStatus(This->wineD3DDevice, ClipStatus);*/
3716 static HRESULT WINAPI IDirect3DDeviceImpl_3_GetClipStatus(IDirect3DDevice3 *iface,
3717 D3DCLIPSTATUS *ClipStatus)
3719 TRACE("iface %p, clip_status %p.\n", iface, ClipStatus);
3721 return IDirect3DDevice7_GetClipStatus((IDirect3DDevice7 *)device_from_device3(iface), ClipStatus);
3724 static HRESULT WINAPI IDirect3DDeviceImpl_2_GetClipStatus(IDirect3DDevice2 *iface,
3725 D3DCLIPSTATUS *ClipStatus)
3727 TRACE("iface %p, clip_status %p.\n", iface, ClipStatus);
3729 return IDirect3DDevice7_GetClipStatus((IDirect3DDevice7 *)device_from_device2(iface), ClipStatus);
3732 /*****************************************************************************
3733 * IDirect3DDevice::DrawPrimitiveStrided
3735 * Draws vertices described by a D3DDRAWPRIMITIVESTRIDEDDATA structure.
3740 * PrimitiveType: The primitive type to draw
3741 * VertexType: The FVF description of the vertices to draw (for the stride??)
3742 * D3DDrawPrimStrideData: A D3DDRAWPRIMITIVESTRIDEDDATA structure describing
3743 * the vertex data locations
3744 * VertexCount: The number of vertices to draw
3748 * D3D_OK, because it's a stub
3749 * (DDERR_INVALIDPARAMS if D3DDrawPrimStrideData is NULL)
3750 * (For details, see IWineD3DDevice::DrawPrimitiveStrided)
3752 *****************************************************************************/
3754 IDirect3DDeviceImpl_7_DrawPrimitiveStrided(IDirect3DDevice7 *iface,
3755 D3DPRIMITIVETYPE PrimitiveType,
3757 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
3761 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
3762 WineDirect3DVertexStridedData WineD3DStrided;
3766 TRACE("iface %p, primitive_type %#x, FVF %#x, strided_data %p, vertex_count %u, flags %#x.\n",
3767 iface, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Flags);
3769 memset(&WineD3DStrided, 0, sizeof(WineD3DStrided));
3770 /* Get the strided data right. the wined3d structure is a bit bigger
3771 * Watch out: The contents of the strided data are determined by the fvf,
3772 * not by the members set in D3DDrawPrimStrideData. So it's valid
3773 * to have diffuse.lpvData set to 0xdeadbeef if the diffuse flag is
3774 * not set in the fvf.
3776 if(VertexType & D3DFVF_POSITION_MASK)
3778 WineD3DStrided.position.format = WINED3DFMT_R32G32B32_FLOAT;
3779 WineD3DStrided.position.lpData = D3DDrawPrimStrideData->position.lpvData;
3780 WineD3DStrided.position.dwStride = D3DDrawPrimStrideData->position.dwStride;
3781 if (VertexType & D3DFVF_XYZRHW)
3783 WineD3DStrided.position.format = WINED3DFMT_R32G32B32A32_FLOAT;
3784 WineD3DStrided.position_transformed = TRUE;
3786 WineD3DStrided.position_transformed = FALSE;
3789 if(VertexType & D3DFVF_NORMAL)
3791 WineD3DStrided.normal.format = WINED3DFMT_R32G32B32_FLOAT;
3792 WineD3DStrided.normal.lpData = D3DDrawPrimStrideData->normal.lpvData;
3793 WineD3DStrided.normal.dwStride = D3DDrawPrimStrideData->normal.dwStride;
3796 if(VertexType & D3DFVF_DIFFUSE)
3798 WineD3DStrided.diffuse.format = WINED3DFMT_B8G8R8A8_UNORM;
3799 WineD3DStrided.diffuse.lpData = D3DDrawPrimStrideData->diffuse.lpvData;
3800 WineD3DStrided.diffuse.dwStride = D3DDrawPrimStrideData->diffuse.dwStride;
3803 if(VertexType & D3DFVF_SPECULAR)
3805 WineD3DStrided.specular.format = WINED3DFMT_B8G8R8A8_UNORM;
3806 WineD3DStrided.specular.lpData = D3DDrawPrimStrideData->specular.lpvData;
3807 WineD3DStrided.specular.dwStride = D3DDrawPrimStrideData->specular.dwStride;
3810 for( i = 0; i < GET_TEXCOUNT_FROM_FVF(VertexType); i++)
3812 switch(GET_TEXCOORD_SIZE_FROM_FVF(VertexType, i))
3814 case 1: WineD3DStrided.texCoords[i].format = WINED3DFMT_R32_FLOAT; break;
3815 case 2: WineD3DStrided.texCoords[i].format = WINED3DFMT_R32G32_FLOAT; break;
3816 case 3: WineD3DStrided.texCoords[i].format = WINED3DFMT_R32G32B32_FLOAT; break;
3817 case 4: WineD3DStrided.texCoords[i].format = WINED3DFMT_R32G32B32A32_FLOAT; break;
3818 default: ERR("Unexpected texture coordinate size %d\n",
3819 GET_TEXCOORD_SIZE_FROM_FVF(VertexType, i));
3821 WineD3DStrided.texCoords[i].lpData = D3DDrawPrimStrideData->textureCoords[i].lpvData;
3822 WineD3DStrided.texCoords[i].dwStride = D3DDrawPrimStrideData->textureCoords[i].dwStride;
3825 /* WineD3D doesn't need the FVF here */
3826 EnterCriticalSection(&ddraw_cs);
3827 wined3d_device_set_primitive_type(This->wined3d_device, PrimitiveType);
3828 hr = wined3d_device_draw_primitive_strided(This->wined3d_device, VertexCount, &WineD3DStrided);
3829 LeaveCriticalSection(&ddraw_cs);
3833 static HRESULT WINAPI
3834 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUSetup(IDirect3DDevice7 *iface,
3835 D3DPRIMITIVETYPE PrimitiveType,
3837 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
3841 return IDirect3DDeviceImpl_7_DrawPrimitiveStrided(iface, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Flags);
3844 static HRESULT WINAPI
3845 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUPreserve(IDirect3DDevice7 *iface,
3846 D3DPRIMITIVETYPE PrimitiveType,
3848 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
3855 old_fpucw = d3d_fpu_setup();
3856 hr = IDirect3DDeviceImpl_7_DrawPrimitiveStrided(iface, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Flags);
3857 set_fpu_control_word(old_fpucw);
3862 static HRESULT WINAPI IDirect3DDeviceImpl_3_DrawPrimitiveStrided(IDirect3DDevice3 *iface,
3863 D3DPRIMITIVETYPE PrimitiveType, DWORD VertexType,
3864 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData, DWORD VertexCount, DWORD Flags)
3866 TRACE("iface %p, primitive_type %#x, FVF %#x, strided_data %p, vertex_count %u, flags %#x.\n",
3867 iface, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Flags);
3869 return IDirect3DDevice7_DrawPrimitiveStrided((IDirect3DDevice7 *)device_from_device3(iface),
3870 PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Flags);
3873 /*****************************************************************************
3874 * IDirect3DDevice7::DrawIndexedPrimitiveStrided
3876 * Draws primitives specified by strided data locations based on indices
3884 * D3D_OK, because it's a stub
3885 * (DDERR_INVALIDPARAMS if D3DDrawPrimStrideData is NULL)
3886 * (DDERR_INVALIDPARAMS if Indices is NULL)
3887 * (For more details, see IWineD3DDevice::DrawIndexedPrimitiveStrided)
3889 *****************************************************************************/
3891 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided(IDirect3DDevice7 *iface,
3892 D3DPRIMITIVETYPE PrimitiveType,
3894 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
3900 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
3901 WineDirect3DVertexStridedData WineD3DStrided;
3905 TRACE("iface %p, primitive_type %#x, FVF %#x, strided_data %p, vertex_count %u, indices %p, index_count %u, flags %#x.\n",
3906 iface, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Indices, IndexCount, Flags);
3908 memset(&WineD3DStrided, 0, sizeof(WineD3DStrided));
3909 /* Get the strided data right. the wined3d structure is a bit bigger
3910 * Watch out: The contents of the strided data are determined by the fvf,
3911 * not by the members set in D3DDrawPrimStrideData. So it's valid
3912 * to have diffuse.lpvData set to 0xdeadbeef if the diffuse flag is
3913 * not set in the fvf.
3915 if(VertexType & D3DFVF_POSITION_MASK)
3917 WineD3DStrided.position.format = WINED3DFMT_R32G32B32_FLOAT;
3918 WineD3DStrided.position.lpData = D3DDrawPrimStrideData->position.lpvData;
3919 WineD3DStrided.position.dwStride = D3DDrawPrimStrideData->position.dwStride;
3920 if (VertexType & D3DFVF_XYZRHW)
3922 WineD3DStrided.position.format = WINED3DFMT_R32G32B32A32_FLOAT;
3923 WineD3DStrided.position_transformed = TRUE;
3925 WineD3DStrided.position_transformed = FALSE;
3928 if(VertexType & D3DFVF_NORMAL)
3930 WineD3DStrided.normal.format = WINED3DFMT_R32G32B32_FLOAT;
3931 WineD3DStrided.normal.lpData = D3DDrawPrimStrideData->normal.lpvData;
3932 WineD3DStrided.normal.dwStride = D3DDrawPrimStrideData->normal.dwStride;
3935 if(VertexType & D3DFVF_DIFFUSE)
3937 WineD3DStrided.diffuse.format = WINED3DFMT_B8G8R8A8_UNORM;
3938 WineD3DStrided.diffuse.lpData = D3DDrawPrimStrideData->diffuse.lpvData;
3939 WineD3DStrided.diffuse.dwStride = D3DDrawPrimStrideData->diffuse.dwStride;
3942 if(VertexType & D3DFVF_SPECULAR)
3944 WineD3DStrided.specular.format = WINED3DFMT_B8G8R8A8_UNORM;
3945 WineD3DStrided.specular.lpData = D3DDrawPrimStrideData->specular.lpvData;
3946 WineD3DStrided.specular.dwStride = D3DDrawPrimStrideData->specular.dwStride;
3949 for( i = 0; i < GET_TEXCOUNT_FROM_FVF(VertexType); i++)
3951 switch(GET_TEXCOORD_SIZE_FROM_FVF(VertexType, i))
3953 case 1: WineD3DStrided.texCoords[i].format = WINED3DFMT_R32_FLOAT; break;
3954 case 2: WineD3DStrided.texCoords[i].format = WINED3DFMT_R32G32_FLOAT; break;
3955 case 3: WineD3DStrided.texCoords[i].format = WINED3DFMT_R32G32B32_FLOAT; break;
3956 case 4: WineD3DStrided.texCoords[i].format = WINED3DFMT_R32G32B32A32_FLOAT; break;
3957 default: ERR("Unexpected texture coordinate size %d\n",
3958 GET_TEXCOORD_SIZE_FROM_FVF(VertexType, i));
3960 WineD3DStrided.texCoords[i].lpData = D3DDrawPrimStrideData->textureCoords[i].lpvData;
3961 WineD3DStrided.texCoords[i].dwStride = D3DDrawPrimStrideData->textureCoords[i].dwStride;
3964 /* WineD3D doesn't need the FVF here */
3965 EnterCriticalSection(&ddraw_cs);
3966 wined3d_device_set_primitive_type(This->wined3d_device, PrimitiveType);
3967 hr = wined3d_device_draw_indexed_primitive_strided(This->wined3d_device,
3968 IndexCount, &WineD3DStrided, VertexCount, Indices, WINED3DFMT_R16_UINT);
3969 LeaveCriticalSection(&ddraw_cs);
3973 static HRESULT WINAPI
3974 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUSetup(IDirect3DDevice7 *iface,
3975 D3DPRIMITIVETYPE PrimitiveType,
3977 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
3983 return IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided(iface, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Indices, IndexCount, Flags);
3986 static HRESULT WINAPI
3987 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUPreserve(IDirect3DDevice7 *iface,
3988 D3DPRIMITIVETYPE PrimitiveType,
3990 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
3999 old_fpucw = d3d_fpu_setup();
4000 hr = IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided(iface, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Indices, IndexCount, Flags);
4001 set_fpu_control_word(old_fpucw);
4006 static HRESULT WINAPI IDirect3DDeviceImpl_3_DrawIndexedPrimitiveStrided(IDirect3DDevice3 *iface,
4007 D3DPRIMITIVETYPE PrimitiveType, DWORD VertexType,
4008 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData, DWORD VertexCount, WORD *Indices,
4009 DWORD IndexCount, DWORD Flags)
4011 TRACE("iface %p, primitive_type %#x, FVF %#x, strided_data %p, vertex_count %u, indices %p, index_count %u, flags %#x.\n",
4012 iface, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Indices, IndexCount, Flags);
4014 return IDirect3DDevice7_DrawIndexedPrimitiveStrided((IDirect3DDevice7 *)device_from_device3(iface),
4015 PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Indices, IndexCount, Flags);
4018 /*****************************************************************************
4019 * IDirect3DDevice7::DrawPrimitiveVB
4021 * Draws primitives from a vertex buffer to the screen.
4026 * PrimitiveType: Type of primitive to be rendered.
4027 * D3DVertexBuf: Source Vertex Buffer
4028 * StartVertex: Index of the first vertex from the buffer to be rendered
4029 * NumVertices: Number of vertices to be rendered
4030 * Flags: Can be D3DDP_WAIT to wait until rendering has finished
4034 * DDERR_INVALIDPARAMS if D3DVertexBuf is NULL
4036 *****************************************************************************/
4038 IDirect3DDeviceImpl_7_DrawPrimitiveVB(IDirect3DDevice7 *iface,
4039 D3DPRIMITIVETYPE PrimitiveType,
4040 IDirect3DVertexBuffer7 *D3DVertexBuf,
4045 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
4046 IDirect3DVertexBufferImpl *vb = unsafe_impl_from_IDirect3DVertexBuffer7(D3DVertexBuf);
4050 TRACE("iface %p, primitive_type %#x, vb %p, start_vertex %u, vertex_count %u, flags %#x.\n",
4051 iface, PrimitiveType, D3DVertexBuf, StartVertex, NumVertices, Flags);
4056 ERR("(%p) No Vertex buffer specified\n", This);
4057 return DDERR_INVALIDPARAMS;
4059 stride = get_flexible_vertex_size(vb->fvf);
4061 EnterCriticalSection(&ddraw_cs);
4062 hr = wined3d_device_set_vertex_declaration(This->wined3d_device, vb->wineD3DVertexDeclaration);
4065 ERR(" (%p) Setting the FVF failed, hr = %x!\n", This, hr);
4066 LeaveCriticalSection(&ddraw_cs);
4070 /* Set the vertex stream source */
4071 hr = wined3d_device_set_stream_source(This->wined3d_device, 0, vb->wineD3DVertexBuffer, 0, stride);
4074 ERR("(%p) IDirect3DDevice::SetStreamSource failed with hr = %08x\n", This, hr);
4075 LeaveCriticalSection(&ddraw_cs);
4079 /* Now draw the primitives */
4080 wined3d_device_set_primitive_type(This->wined3d_device, PrimitiveType);
4081 hr = wined3d_device_draw_primitive(This->wined3d_device, StartVertex, NumVertices);
4082 LeaveCriticalSection(&ddraw_cs);
4086 static HRESULT WINAPI
4087 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUSetup(IDirect3DDevice7 *iface,
4088 D3DPRIMITIVETYPE PrimitiveType,
4089 IDirect3DVertexBuffer7 *D3DVertexBuf,
4094 return IDirect3DDeviceImpl_7_DrawPrimitiveVB(iface, PrimitiveType, D3DVertexBuf, StartVertex, NumVertices, Flags);
4097 static HRESULT WINAPI
4098 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUPreserve(IDirect3DDevice7 *iface,
4099 D3DPRIMITIVETYPE PrimitiveType,
4100 IDirect3DVertexBuffer7 *D3DVertexBuf,
4108 old_fpucw = d3d_fpu_setup();
4109 hr = IDirect3DDeviceImpl_7_DrawPrimitiveVB(iface, PrimitiveType, D3DVertexBuf, StartVertex, NumVertices, Flags);
4110 set_fpu_control_word(old_fpucw);
4115 static HRESULT WINAPI IDirect3DDeviceImpl_3_DrawPrimitiveVB(IDirect3DDevice3 *iface,
4116 D3DPRIMITIVETYPE PrimitiveType, IDirect3DVertexBuffer *D3DVertexBuf, DWORD StartVertex,
4117 DWORD NumVertices, DWORD Flags)
4119 IDirect3DVertexBufferImpl *vb = unsafe_impl_from_IDirect3DVertexBuffer(D3DVertexBuf);
4121 TRACE("iface %p, primitive_type %#x, vb %p, start_vertex %u, vertex_count %u, flags %#x.\n",
4122 iface, PrimitiveType, D3DVertexBuf, StartVertex, NumVertices, Flags);
4124 return IDirect3DDevice7_DrawPrimitiveVB((IDirect3DDevice7 *)device_from_device3(iface),
4125 PrimitiveType, &vb->IDirect3DVertexBuffer7_iface, StartVertex, NumVertices, Flags);
4129 /*****************************************************************************
4130 * IDirect3DDevice7::DrawIndexedPrimitiveVB
4132 * Draws primitives from a vertex buffer to the screen
4135 * PrimitiveType: Type of primitive to be rendered.
4136 * D3DVertexBuf: Source Vertex Buffer
4137 * StartVertex: Index of the first vertex from the buffer to be rendered
4138 * NumVertices: Number of vertices to be rendered
4139 * Indices: Array of DWORDs used to index into the Vertices
4140 * IndexCount: Number of indices in Indices
4141 * Flags: Can be D3DDP_WAIT to wait until rendering has finished
4145 *****************************************************************************/
4147 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB(IDirect3DDevice7 *iface,
4148 D3DPRIMITIVETYPE PrimitiveType,
4149 IDirect3DVertexBuffer7 *D3DVertexBuf,
4156 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
4157 IDirect3DVertexBufferImpl *vb = unsafe_impl_from_IDirect3DVertexBuffer7(D3DVertexBuf);
4158 DWORD stride = get_flexible_vertex_size(vb->fvf);
4159 struct wined3d_resource *wined3d_resource;
4160 struct wined3d_resource_desc desc;
4161 WORD *LockedIndices;
4164 TRACE("iface %p, primitive_type %#x, vb %p, start_vertex %u, vertex_count %u, indices %p, index_count %u, flags %#x.\n",
4165 iface, PrimitiveType, D3DVertexBuf, StartVertex, NumVertices, Indices, IndexCount, Flags);
4168 * 1) Upload the Indices to the index buffer
4169 * 2) Set the index source
4170 * 3) Set the Vertex Buffer as the Stream source
4171 * 4) Call IWineD3DDevice::DrawIndexedPrimitive
4174 EnterCriticalSection(&ddraw_cs);
4176 hr = wined3d_device_set_vertex_declaration(This->wined3d_device, vb->wineD3DVertexDeclaration);
4179 ERR(" (%p) Setting the FVF failed, hr = %x!\n", This, hr);
4180 LeaveCriticalSection(&ddraw_cs);
4184 /* check that the buffer is large enough to hold the indices,
4185 * reallocate if necessary. */
4186 wined3d_resource = wined3d_buffer_get_resource(This->indexbuffer);
4187 wined3d_resource_get_desc(wined3d_resource, &desc);
4188 if (desc.size < IndexCount * sizeof(WORD))
4190 UINT size = max(desc.size * 2, IndexCount * sizeof(WORD));
4191 struct wined3d_buffer *buffer;
4193 TRACE("Growing index buffer to %u bytes\n", size);
4195 hr = wined3d_buffer_create_ib(This->wined3d_device, size, WINED3DUSAGE_DYNAMIC /* Usage */,
4196 WINED3DPOOL_DEFAULT, NULL, &ddraw_null_wined3d_parent_ops, &buffer);
4199 ERR("(%p) IWineD3DDevice::CreateIndexBuffer failed with hr = %08x\n", This, hr);
4200 LeaveCriticalSection(&ddraw_cs);
4204 wined3d_buffer_decref(This->indexbuffer);
4205 This->indexbuffer = buffer;
4208 /* Copy the index stream into the index buffer. A new IWineD3DDevice
4209 * method could be created which takes an user pointer containing the
4210 * indices or a SetData-Method for the index buffer, which overrides the
4211 * index buffer data with our pointer. */
4212 hr = wined3d_buffer_map(This->indexbuffer, 0, IndexCount * sizeof(WORD),
4213 (BYTE **)&LockedIndices, 0);
4216 ERR("Failed to map buffer, hr %#x.\n", hr);
4217 LeaveCriticalSection(&ddraw_cs);
4220 memcpy(LockedIndices, Indices, IndexCount * sizeof(WORD));
4221 wined3d_buffer_unmap(This->indexbuffer);
4223 /* Set the index stream */
4224 wined3d_device_set_base_vertex_index(This->wined3d_device, StartVertex);
4225 hr = wined3d_device_set_index_buffer(This->wined3d_device, This->indexbuffer, WINED3DFMT_R16_UINT);
4227 /* Set the vertex stream source */
4228 hr = wined3d_device_set_stream_source(This->wined3d_device, 0, vb->wineD3DVertexBuffer, 0, stride);
4231 ERR("(%p) IDirect3DDevice::SetStreamSource failed with hr = %08x\n", This, hr);
4232 LeaveCriticalSection(&ddraw_cs);
4237 wined3d_device_set_primitive_type(This->wined3d_device, PrimitiveType);
4238 hr = wined3d_device_draw_indexed_primitive(This->wined3d_device, 0, IndexCount);
4240 LeaveCriticalSection(&ddraw_cs);
4244 static HRESULT WINAPI
4245 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUSetup(IDirect3DDevice7 *iface,
4246 D3DPRIMITIVETYPE PrimitiveType,
4247 IDirect3DVertexBuffer7 *D3DVertexBuf,
4254 return IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB(iface, PrimitiveType, D3DVertexBuf, StartVertex, NumVertices, Indices, IndexCount, Flags);
4257 static HRESULT WINAPI
4258 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUPreserve(IDirect3DDevice7 *iface,
4259 D3DPRIMITIVETYPE PrimitiveType,
4260 IDirect3DVertexBuffer7 *D3DVertexBuf,
4270 old_fpucw = d3d_fpu_setup();
4271 hr = IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB(iface, PrimitiveType, D3DVertexBuf, StartVertex, NumVertices, Indices, IndexCount, Flags);
4272 set_fpu_control_word(old_fpucw);
4277 static HRESULT WINAPI IDirect3DDeviceImpl_3_DrawIndexedPrimitiveVB(IDirect3DDevice3 *iface,
4278 D3DPRIMITIVETYPE PrimitiveType, IDirect3DVertexBuffer *D3DVertexBuf, WORD *Indices,
4279 DWORD IndexCount, DWORD Flags)
4281 IDirect3DVertexBufferImpl *vb = unsafe_impl_from_IDirect3DVertexBuffer(D3DVertexBuf);
4283 TRACE("iface %p, primitive_type %#x, vb %p, indices %p, index_count %u, flags %#x.\n",
4284 iface, PrimitiveType, D3DVertexBuf, Indices, IndexCount, Flags);
4286 return IDirect3DDevice7_DrawIndexedPrimitiveVB((IDirect3DDevice7 *)device_from_device3(iface),
4287 PrimitiveType, &vb->IDirect3DVertexBuffer7_iface, 0, IndexCount, Indices, IndexCount,
4291 /*****************************************************************************
4292 * IDirect3DDevice7::ComputeSphereVisibility
4294 * Calculates the visibility of spheres in the current viewport. The spheres
4295 * are passed in the Centers and Radii arrays, the results are passed back
4296 * in the ReturnValues array. Return values are either completely visible,
4297 * partially visible or completely invisible.
4298 * The return value consist of a combination of D3DCLIP_* flags, or it's
4299 * 0 if the sphere is completely visible(according to the SDK, not checked)
4304 * Centers: Array containing the sphere centers
4305 * Radii: Array containing the sphere radii
4306 * NumSpheres: The number of centers and radii in the arrays
4308 * ReturnValues: Array to write the results to
4312 * (DDERR_INVALIDPARAMS if Centers, Radii or ReturnValues are NULL)
4313 * (D3DERR_INVALIDMATRIX if the combined world, view and proj matrix
4316 *****************************************************************************/
4318 static DWORD in_plane(UINT plane, D3DVECTOR normal, D3DVALUE origin_plane, D3DVECTOR center, D3DVALUE radius)
4320 float distance, norm;
4322 norm = sqrt( normal.u1.x * normal.u1.x + normal.u2.y * normal.u2.y + normal.u3.z * normal.u3.z );
4323 distance = ( origin_plane + normal.u1.x * center.u1.x + normal.u2.y * center.u2.y + normal.u3.z * center.u3.z ) / norm;
4325 if ( fabs( distance ) < radius ) return D3DSTATUS_CLIPUNIONLEFT << plane;
4326 if ( distance < -radius ) return (D3DSTATUS_CLIPUNIONLEFT | D3DSTATUS_CLIPINTERSECTIONLEFT) << plane;
4330 static HRESULT WINAPI
4331 IDirect3DDeviceImpl_7_ComputeSphereVisibility(IDirect3DDevice7 *iface,
4336 DWORD *ReturnValues)
4339 D3DVALUE origin_plane[6];
4344 TRACE("iface %p, centers %p, radii %p, sphere_count %u, flags %#x, return_values %p.\n",
4345 iface, Centers, Radii, NumSpheres, Flags, ReturnValues);
4347 hr = IDirect3DDeviceImpl_7_GetTransform(iface, D3DTRANSFORMSTATE_WORLD, &m);
4348 if ( hr != DD_OK ) return DDERR_INVALIDPARAMS;
4349 hr = IDirect3DDeviceImpl_7_GetTransform(iface, D3DTRANSFORMSTATE_VIEW, &temp);
4350 if ( hr != DD_OK ) return DDERR_INVALIDPARAMS;
4351 multiply_matrix(&m, &temp, &m);
4353 hr = IDirect3DDeviceImpl_7_GetTransform(iface, D3DTRANSFORMSTATE_PROJECTION, &temp);
4354 if ( hr != DD_OK ) return DDERR_INVALIDPARAMS;
4355 multiply_matrix(&m, &temp, &m);
4358 vec[0].u1.x = m._14 + m._11;
4359 vec[0].u2.y = m._24 + m._21;
4360 vec[0].u3.z = m._34 + m._31;
4361 origin_plane[0] = m._44 + m._41;
4364 vec[1].u1.x = m._14 - m._11;
4365 vec[1].u2.y = m._24 - m._21;
4366 vec[1].u3.z = m._34 - m._31;
4367 origin_plane[1] = m._44 - m._41;
4370 vec[2].u1.x = m._14 - m._12;
4371 vec[2].u2.y = m._24 - m._22;
4372 vec[2].u3.z = m._34 - m._32;
4373 origin_plane[2] = m._44 - m._42;
4376 vec[3].u1.x = m._14 + m._12;
4377 vec[3].u2.y = m._24 + m._22;
4378 vec[3].u3.z = m._34 + m._32;
4379 origin_plane[3] = m._44 + m._42;
4382 vec[4].u1.x = m._13;
4383 vec[4].u2.y = m._23;
4384 vec[4].u3.z = m._33;
4385 origin_plane[4] = m._43;
4388 vec[5].u1.x = m._14 - m._13;
4389 vec[5].u2.y = m._24 - m._23;
4390 vec[5].u3.z = m._34 - m._33;
4391 origin_plane[5] = m._44 - m._43;
4393 for(i=0; i<NumSpheres; i++)
4395 ReturnValues[i] = 0;
4396 for(j=0; j<6; j++) ReturnValues[i] |= in_plane(j, vec[j], origin_plane[j], Centers[i], Radii[i]);
4402 static HRESULT WINAPI IDirect3DDeviceImpl_3_ComputeSphereVisibility(IDirect3DDevice3 *iface,
4403 D3DVECTOR *Centers, D3DVALUE *Radii, DWORD NumSpheres, DWORD Flags, DWORD *ReturnValues)
4405 TRACE("iface %p, centers %p, radii %p, sphere_count %u, flags %#x, return_values %p.\n",
4406 iface, Centers, Radii, NumSpheres, Flags, ReturnValues);
4408 return IDirect3DDevice7_ComputeSphereVisibility((IDirect3DDevice7 *)device_from_device3(iface),
4409 Centers, Radii, NumSpheres, Flags, ReturnValues);
4412 /*****************************************************************************
4413 * IDirect3DDevice7::GetTexture
4415 * Returns the texture interface handle assigned to a texture stage.
4416 * The returned texture is AddRefed. This is taken from old ddraw,
4417 * not checked in Windows.
4422 * Stage: Texture stage to read the texture from
4423 * Texture: Address to store the interface pointer at
4427 * DDERR_INVALIDPARAMS if Texture is NULL
4428 * For details, see IWineD3DDevice::GetTexture
4430 *****************************************************************************/
4432 IDirect3DDeviceImpl_7_GetTexture(IDirect3DDevice7 *iface,
4434 IDirectDrawSurface7 **Texture)
4436 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
4437 struct wined3d_texture *wined3d_texture;
4440 TRACE("iface %p, stage %u, texture %p.\n", iface, Stage, Texture);
4444 TRACE("Texture == NULL, failing with DDERR_INVALIDPARAMS\n");
4445 return DDERR_INVALIDPARAMS;
4448 EnterCriticalSection(&ddraw_cs);
4449 hr = wined3d_device_get_texture(This->wined3d_device, Stage, &wined3d_texture);
4450 if (FAILED(hr) || !wined3d_texture)
4453 LeaveCriticalSection(&ddraw_cs);
4457 *Texture = wined3d_texture_get_parent(wined3d_texture);
4458 IDirectDrawSurface7_AddRef(*Texture);
4459 LeaveCriticalSection(&ddraw_cs);
4463 static HRESULT WINAPI
4464 IDirect3DDeviceImpl_7_GetTexture_FPUSetup(IDirect3DDevice7 *iface,
4466 IDirectDrawSurface7 **Texture)
4468 return IDirect3DDeviceImpl_7_GetTexture(iface, Stage, Texture);
4471 static HRESULT WINAPI
4472 IDirect3DDeviceImpl_7_GetTexture_FPUPreserve(IDirect3DDevice7 *iface,
4474 IDirectDrawSurface7 **Texture)
4479 old_fpucw = d3d_fpu_setup();
4480 hr = IDirect3DDeviceImpl_7_GetTexture(iface, Stage, Texture);
4481 set_fpu_control_word(old_fpucw);
4486 static HRESULT WINAPI IDirect3DDeviceImpl_3_GetTexture(IDirect3DDevice3 *iface, DWORD Stage,
4487 IDirect3DTexture2 **Texture2)
4490 IDirectDrawSurface7 *ret_val;
4491 IDirectDrawSurfaceImpl *ret_val_impl;
4493 TRACE("iface %p, stage %u, texture %p.\n", iface, Stage, Texture2);
4495 ret = IDirect3DDevice7_GetTexture((IDirect3DDevice7 *)device_from_device3(iface), Stage, &ret_val);
4497 ret_val_impl = unsafe_impl_from_IDirectDrawSurface7(ret_val);
4498 *Texture2 = ret_val_impl ? (IDirect3DTexture2 *)&ret_val_impl->IDirect3DTexture2_vtbl : NULL;
4500 TRACE("Returning texture %p.\n", *Texture2);
4505 /*****************************************************************************
4506 * IDirect3DDevice7::SetTexture
4508 * Assigns a texture to a texture stage. Is the texture AddRef-ed?
4513 * Stage: The stage to assign the texture to
4514 * Texture: Interface pointer to the texture surface
4518 * For details, see IWineD3DDevice::SetTexture
4520 *****************************************************************************/
4522 IDirect3DDeviceImpl_7_SetTexture(IDirect3DDevice7 *iface,
4524 IDirectDrawSurface7 *Texture)
4526 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
4527 IDirectDrawSurfaceImpl *surf = unsafe_impl_from_IDirectDrawSurface7(Texture);
4530 TRACE("iface %p, stage %u, texture %p.\n", iface, Stage, Texture);
4532 /* Texture may be NULL here */
4533 EnterCriticalSection(&ddraw_cs);
4534 hr = wined3d_device_set_texture(This->wined3d_device,
4535 Stage, surf ? surf->wined3d_texture : NULL);
4536 LeaveCriticalSection(&ddraw_cs);
4540 static HRESULT WINAPI
4541 IDirect3DDeviceImpl_7_SetTexture_FPUSetup(IDirect3DDevice7 *iface,
4543 IDirectDrawSurface7 *Texture)
4545 return IDirect3DDeviceImpl_7_SetTexture(iface, Stage, Texture);
4548 static HRESULT WINAPI
4549 IDirect3DDeviceImpl_7_SetTexture_FPUPreserve(IDirect3DDevice7 *iface,
4551 IDirectDrawSurface7 *Texture)
4556 old_fpucw = d3d_fpu_setup();
4557 hr = IDirect3DDeviceImpl_7_SetTexture(iface, Stage, Texture);
4558 set_fpu_control_word(old_fpucw);
4563 static HRESULT WINAPI
4564 IDirect3DDeviceImpl_3_SetTexture(IDirect3DDevice3 *iface,
4566 IDirect3DTexture2 *Texture2)
4568 IDirect3DDeviceImpl *This = device_from_device3(iface);
4569 IDirectDrawSurfaceImpl *tex = Texture2 ? surface_from_texture2(Texture2) : NULL;
4573 TRACE("iface %p, stage %u, texture %p.\n", iface, Stage, Texture2);
4575 EnterCriticalSection(&ddraw_cs);
4577 if (This->legacyTextureBlending)
4578 IDirect3DDevice3_GetRenderState(iface, D3DRENDERSTATE_TEXTUREMAPBLEND, &texmapblend);
4580 hr = IDirect3DDevice7_SetTexture((IDirect3DDevice7 *)This, Stage, &tex->IDirectDrawSurface7_iface);
4582 if (This->legacyTextureBlending && texmapblend == D3DTBLEND_MODULATE)
4584 /* This fixup is required by the way D3DTBLEND_MODULATE maps to texture stage states.
4585 See IDirect3DDeviceImpl_3_SetRenderState for details. */
4586 struct wined3d_texture *tex = NULL;
4587 BOOL tex_alpha = FALSE;
4588 DDPIXELFORMAT ddfmt;
4591 result = wined3d_device_get_texture(This->wined3d_device, 0, &tex);
4592 if (result == WINED3D_OK && tex)
4594 struct wined3d_resource *sub_resource;
4596 if ((sub_resource = wined3d_texture_get_sub_resource(tex, 0)))
4598 struct wined3d_resource_desc desc;
4600 wined3d_resource_get_desc(sub_resource, &desc);
4601 ddfmt.dwSize = sizeof(ddfmt);
4602 PixelFormat_WineD3DtoDD(&ddfmt, desc.format);
4603 if (ddfmt.u5.dwRGBAlphaBitMask) tex_alpha = TRUE;
4606 wined3d_texture_decref(tex);
4609 /* Arg 1/2 are already set to WINED3DTA_TEXTURE/WINED3DTA_CURRENT in case of D3DTBLEND_MODULATE */
4611 wined3d_device_set_texture_stage_state(This->wined3d_device, 0, WINED3DTSS_ALPHAOP, WINED3DTOP_SELECTARG1);
4613 wined3d_device_set_texture_stage_state(This->wined3d_device, 0, WINED3DTSS_ALPHAOP, WINED3DTOP_SELECTARG2);
4616 LeaveCriticalSection(&ddraw_cs);
4621 static const struct tss_lookup
4628 {FALSE, WINED3DTSS_FORCE_DWORD}, /* 0, unused */
4629 {FALSE, WINED3DTSS_COLOROP}, /* 1, D3DTSS_COLOROP */
4630 {FALSE, WINED3DTSS_COLORARG1}, /* 2, D3DTSS_COLORARG1 */
4631 {FALSE, WINED3DTSS_COLORARG2}, /* 3, D3DTSS_COLORARG2 */
4632 {FALSE, WINED3DTSS_ALPHAOP}, /* 4, D3DTSS_ALPHAOP */
4633 {FALSE, WINED3DTSS_ALPHAARG1}, /* 5, D3DTSS_ALPHAARG1 */
4634 {FALSE, WINED3DTSS_ALPHAARG2}, /* 6, D3DTSS_ALPHAARG2 */
4635 {FALSE, WINED3DTSS_BUMPENVMAT00}, /* 7, D3DTSS_BUMPENVMAT00 */
4636 {FALSE, WINED3DTSS_BUMPENVMAT01}, /* 8, D3DTSS_BUMPENVMAT01 */
4637 {FALSE, WINED3DTSS_BUMPENVMAT10}, /* 9, D3DTSS_BUMPENVMAT10 */
4638 {FALSE, WINED3DTSS_BUMPENVMAT11}, /* 10, D3DTSS_BUMPENVMAT11 */
4639 {FALSE, WINED3DTSS_TEXCOORDINDEX}, /* 11, D3DTSS_TEXCOORDINDEX */
4640 {TRUE, WINED3DSAMP_ADDRESSU}, /* 12, D3DTSS_ADDRESS */
4641 {TRUE, WINED3DSAMP_ADDRESSU}, /* 13, D3DTSS_ADDRESSU */
4642 {TRUE, WINED3DSAMP_ADDRESSV}, /* 14, D3DTSS_ADDRESSV */
4643 {TRUE, WINED3DSAMP_BORDERCOLOR}, /* 15, D3DTSS_BORDERCOLOR */
4644 {TRUE, WINED3DSAMP_MAGFILTER}, /* 16, D3DTSS_MAGFILTER */
4645 {TRUE, WINED3DSAMP_MINFILTER}, /* 17, D3DTSS_MINFILTER */
4646 {TRUE, WINED3DSAMP_MIPFILTER}, /* 18, D3DTSS_MIPFILTER */
4647 {TRUE, WINED3DSAMP_MIPMAPLODBIAS}, /* 19, D3DTSS_MIPMAPLODBIAS */
4648 {TRUE, WINED3DSAMP_MAXMIPLEVEL}, /* 20, D3DTSS_MAXMIPLEVEL */
4649 {TRUE, WINED3DSAMP_MAXANISOTROPY}, /* 21, D3DTSS_MAXANISOTROPY */
4650 {FALSE, WINED3DTSS_BUMPENVLSCALE}, /* 22, D3DTSS_BUMPENVLSCALE */
4651 {FALSE, WINED3DTSS_BUMPENVLOFFSET}, /* 23, D3DTSS_BUMPENVLOFFSET */
4652 {FALSE, WINED3DTSS_TEXTURETRANSFORMFLAGS}, /* 24, D3DTSS_TEXTURETRANSFORMFLAGS */
4655 /*****************************************************************************
4656 * IDirect3DDevice7::GetTextureStageState
4658 * Retrieves a state from a texture stage.
4663 * Stage: The stage to retrieve the state from
4664 * TexStageStateType: The state type to retrieve
4665 * State: Address to store the state's value at
4669 * DDERR_INVALIDPARAMS if State is NULL
4670 * For details, see IWineD3DDevice::GetTextureStageState
4672 *****************************************************************************/
4674 IDirect3DDeviceImpl_7_GetTextureStageState(IDirect3DDevice7 *iface,
4676 D3DTEXTURESTAGESTATETYPE TexStageStateType,
4679 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
4681 const struct tss_lookup *l;
4683 TRACE("iface %p, stage %u, state %#x, value %p.\n",
4684 iface, Stage, TexStageStateType, State);
4687 return DDERR_INVALIDPARAMS;
4689 if (TexStageStateType > D3DTSS_TEXTURETRANSFORMFLAGS)
4691 WARN("Invalid TexStageStateType %#x passed.\n", TexStageStateType);
4695 l = &tss_lookup[TexStageStateType];
4697 EnterCriticalSection(&ddraw_cs);
4699 if (l->sampler_state)
4701 hr = wined3d_device_get_sampler_state(This->wined3d_device, Stage, l->state, State);
4703 switch(TexStageStateType)
4705 /* Mipfilter is a sampler state with different values */
4706 case D3DTSS_MIPFILTER:
4710 case WINED3DTEXF_NONE: *State = D3DTFP_NONE; break;
4711 case WINED3DTEXF_POINT: *State = D3DTFP_POINT; break;
4712 case WINED3DTEXF_LINEAR: *State = D3DTFP_LINEAR; break;
4714 ERR("Unexpected mipfilter value %#x\n", *State);
4715 *State = D3DTFP_NONE;
4721 /* Magfilter has slightly different values */
4722 case D3DTSS_MAGFILTER:
4726 case WINED3DTEXF_POINT: *State = D3DTFG_POINT; break;
4727 case WINED3DTEXF_LINEAR: *State = D3DTFG_LINEAR; break;
4728 case WINED3DTEXF_ANISOTROPIC: *State = D3DTFG_ANISOTROPIC; break;
4729 case WINED3DTEXF_FLATCUBIC: *State = D3DTFG_FLATCUBIC; break;
4730 case WINED3DTEXF_GAUSSIANCUBIC: *State = D3DTFG_GAUSSIANCUBIC; break;
4732 ERR("Unexpected wined3d mag filter value %#x\n", *State);
4733 *State = D3DTFG_POINT;
4745 hr = wined3d_device_get_texture_stage_state(This->wined3d_device, Stage, l->state, State);
4748 LeaveCriticalSection(&ddraw_cs);
4752 static HRESULT WINAPI
4753 IDirect3DDeviceImpl_7_GetTextureStageState_FPUSetup(IDirect3DDevice7 *iface,
4755 D3DTEXTURESTAGESTATETYPE TexStageStateType,
4758 return IDirect3DDeviceImpl_7_GetTextureStageState(iface, Stage, TexStageStateType, State);
4761 static HRESULT WINAPI
4762 IDirect3DDeviceImpl_7_GetTextureStageState_FPUPreserve(IDirect3DDevice7 *iface,
4764 D3DTEXTURESTAGESTATETYPE TexStageStateType,
4770 old_fpucw = d3d_fpu_setup();
4771 hr = IDirect3DDeviceImpl_7_GetTextureStageState(iface, Stage, TexStageStateType, State);
4772 set_fpu_control_word(old_fpucw);
4777 static HRESULT WINAPI IDirect3DDeviceImpl_3_GetTextureStageState(IDirect3DDevice3 *iface,
4778 DWORD Stage, D3DTEXTURESTAGESTATETYPE TexStageStateType, DWORD *State)
4780 TRACE("iface %p, stage %u, state %#x, value %p.\n",
4781 iface, Stage, TexStageStateType, State);
4783 return IDirect3DDevice7_GetTextureStageState((IDirect3DDevice7 *)device_from_device3(iface),
4784 Stage, TexStageStateType, State);
4787 /*****************************************************************************
4788 * IDirect3DDevice7::SetTextureStageState
4790 * Sets a texture stage state. Some stage types need to be handled specially,
4791 * because they do not exist in WineD3D and were moved to another place
4796 * Stage: The stage to modify
4797 * TexStageStateType: The state to change
4798 * State: The new value for the state
4802 * For details, see IWineD3DDevice::SetTextureStageState
4804 *****************************************************************************/
4806 IDirect3DDeviceImpl_7_SetTextureStageState(IDirect3DDevice7 *iface,
4808 D3DTEXTURESTAGESTATETYPE TexStageStateType,
4811 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
4812 const struct tss_lookup *l;
4815 TRACE("iface %p, stage %u, state %#x, value %#x.\n",
4816 iface, Stage, TexStageStateType, State);
4818 if (TexStageStateType > D3DTSS_TEXTURETRANSFORMFLAGS)
4820 WARN("Invalid TexStageStateType %#x passed.\n", TexStageStateType);
4824 l = &tss_lookup[TexStageStateType];
4826 EnterCriticalSection(&ddraw_cs);
4828 if (l->sampler_state)
4830 switch(TexStageStateType)
4832 /* Mipfilter is a sampler state with different values */
4833 case D3DTSS_MIPFILTER:
4837 case D3DTFP_NONE: State = WINED3DTEXF_NONE; break;
4838 case D3DTFP_POINT: State = WINED3DTEXF_POINT; break;
4839 case 0: /* Unchecked */
4840 case D3DTFP_LINEAR: State = WINED3DTEXF_LINEAR; break;
4842 ERR("Unexpected mipfilter value %d\n", State);
4843 State = WINED3DTEXF_NONE;
4849 /* Magfilter has slightly different values */
4850 case D3DTSS_MAGFILTER:
4854 case D3DTFG_POINT: State = WINED3DTEXF_POINT; break;
4855 case D3DTFG_LINEAR: State = WINED3DTEXF_LINEAR; break;
4856 case D3DTFG_FLATCUBIC: State = WINED3DTEXF_FLATCUBIC; break;
4857 case D3DTFG_GAUSSIANCUBIC: State = WINED3DTEXF_GAUSSIANCUBIC; break;
4858 case D3DTFG_ANISOTROPIC: State = WINED3DTEXF_ANISOTROPIC; break;
4860 ERR("Unexpected d3d7 mag filter type %d\n", State);
4861 State = WINED3DTEXF_POINT;
4867 case D3DTSS_ADDRESS:
4868 wined3d_device_set_sampler_state(This->wined3d_device, Stage, WINED3DSAMP_ADDRESSV, State);
4875 hr = wined3d_device_set_sampler_state(This->wined3d_device, Stage, l->state, State);
4879 hr = wined3d_device_set_texture_stage_state(This->wined3d_device, Stage, l->state, State);
4882 LeaveCriticalSection(&ddraw_cs);
4886 static HRESULT WINAPI
4887 IDirect3DDeviceImpl_7_SetTextureStageState_FPUSetup(IDirect3DDevice7 *iface,
4889 D3DTEXTURESTAGESTATETYPE TexStageStateType,
4892 return IDirect3DDeviceImpl_7_SetTextureStageState(iface, Stage, TexStageStateType, State);
4895 static HRESULT WINAPI
4896 IDirect3DDeviceImpl_7_SetTextureStageState_FPUPreserve(IDirect3DDevice7 *iface,
4898 D3DTEXTURESTAGESTATETYPE TexStageStateType,
4904 old_fpucw = d3d_fpu_setup();
4905 hr = IDirect3DDeviceImpl_7_SetTextureStageState(iface, Stage, TexStageStateType, State);
4906 set_fpu_control_word(old_fpucw);
4911 static HRESULT WINAPI IDirect3DDeviceImpl_3_SetTextureStageState(IDirect3DDevice3 *iface,
4912 DWORD Stage, D3DTEXTURESTAGESTATETYPE TexStageStateType, DWORD State)
4914 TRACE("iface %p, stage %u, state %#x, value %#x.\n",
4915 iface, Stage, TexStageStateType, State);
4917 return IDirect3DDevice7_SetTextureStageState((IDirect3DDevice7 *)device_from_device3(iface),
4918 Stage, TexStageStateType, State);
4921 /*****************************************************************************
4922 * IDirect3DDevice7::ValidateDevice
4924 * SDK: "Reports the device's ability to render the currently set
4925 * texture-blending operations in a single pass". Whatever that means
4931 * NumPasses: Address to write the number of necessary passes for the
4932 * desired effect to.
4936 * See IWineD3DDevice::ValidateDevice for more details
4938 *****************************************************************************/
4940 IDirect3DDeviceImpl_7_ValidateDevice(IDirect3DDevice7 *iface,
4943 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
4946 TRACE("iface %p, pass_count %p.\n", iface, NumPasses);
4948 EnterCriticalSection(&ddraw_cs);
4949 hr = wined3d_device_validate_device(This->wined3d_device, NumPasses);
4950 LeaveCriticalSection(&ddraw_cs);
4954 static HRESULT WINAPI
4955 IDirect3DDeviceImpl_7_ValidateDevice_FPUSetup(IDirect3DDevice7 *iface,
4958 return IDirect3DDeviceImpl_7_ValidateDevice(iface, NumPasses);
4961 static HRESULT WINAPI
4962 IDirect3DDeviceImpl_7_ValidateDevice_FPUPreserve(IDirect3DDevice7 *iface,
4968 old_fpucw = d3d_fpu_setup();
4969 hr = IDirect3DDeviceImpl_7_ValidateDevice(iface, NumPasses);
4970 set_fpu_control_word(old_fpucw);
4975 static HRESULT WINAPI IDirect3DDeviceImpl_3_ValidateDevice(IDirect3DDevice3 *iface, DWORD *Passes)
4977 TRACE("iface %p, pass_count %p.\n", iface, Passes);
4979 return IDirect3DDevice7_ValidateDevice((IDirect3DDevice7 *)device_from_device3(iface), Passes);
4982 /*****************************************************************************
4983 * IDirect3DDevice7::Clear
4985 * Fills the render target, the z buffer and the stencil buffer with a
4986 * clear color / value
4991 * Count: Number of rectangles in Rects must be 0 if Rects is NULL
4992 * Rects: Rectangles to clear. If NULL, the whole surface is cleared
4993 * Flags: Some flags, as usual
4994 * Color: Clear color for the render target
4995 * Z: Clear value for the Z buffer
4996 * Stencil: Clear value to store in each stencil buffer entry
5000 * For details, see IWineD3DDevice::Clear
5002 *****************************************************************************/
5004 IDirect3DDeviceImpl_7_Clear(IDirect3DDevice7 *iface,
5012 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5015 TRACE("iface %p, count %u, rects %p, flags %#x, color 0x%08x, z %.8e, stencil %#x.\n",
5016 iface, Count, Rects, Flags, Color, Z, Stencil);
5018 EnterCriticalSection(&ddraw_cs);
5019 hr = wined3d_device_clear(This->wined3d_device, Count, (RECT *)Rects, Flags, Color, Z, Stencil);
5020 LeaveCriticalSection(&ddraw_cs);
5024 static HRESULT WINAPI
5025 IDirect3DDeviceImpl_7_Clear_FPUSetup(IDirect3DDevice7 *iface,
5033 return IDirect3DDeviceImpl_7_Clear(iface, Count, Rects, Flags, Color, Z, Stencil);
5036 static HRESULT WINAPI
5037 IDirect3DDeviceImpl_7_Clear_FPUPreserve(IDirect3DDevice7 *iface,
5048 old_fpucw = d3d_fpu_setup();
5049 hr = IDirect3DDeviceImpl_7_Clear(iface, Count, Rects, Flags, Color, Z, Stencil);
5050 set_fpu_control_word(old_fpucw);
5055 /*****************************************************************************
5056 * IDirect3DDevice7::SetViewport
5058 * Sets the current viewport.
5060 * Version 7 only, but IDirect3DViewport uses this call for older
5064 * Data: The new viewport to set
5068 * DDERR_INVALIDPARAMS if Data is NULL
5069 * For more details, see IWineDDDevice::SetViewport
5071 *****************************************************************************/
5073 IDirect3DDeviceImpl_7_SetViewport(IDirect3DDevice7 *iface,
5076 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5079 TRACE("iface %p, viewport %p.\n", iface, Data);
5082 return DDERR_INVALIDPARAMS;
5084 /* Note: D3DVIEWPORT7 is compatible with WINED3DVIEWPORT */
5085 EnterCriticalSection(&ddraw_cs);
5086 hr = wined3d_device_set_viewport(This->wined3d_device, (WINED3DVIEWPORT *)Data);
5087 LeaveCriticalSection(&ddraw_cs);
5091 static HRESULT WINAPI
5092 IDirect3DDeviceImpl_7_SetViewport_FPUSetup(IDirect3DDevice7 *iface,
5095 return IDirect3DDeviceImpl_7_SetViewport(iface, Data);
5098 static HRESULT WINAPI
5099 IDirect3DDeviceImpl_7_SetViewport_FPUPreserve(IDirect3DDevice7 *iface,
5105 old_fpucw = d3d_fpu_setup();
5106 hr = IDirect3DDeviceImpl_7_SetViewport(iface, Data);
5107 set_fpu_control_word(old_fpucw);
5112 /*****************************************************************************
5113 * IDirect3DDevice::GetViewport
5115 * Returns the current viewport
5120 * Data: D3D7Viewport structure to write the viewport information to
5124 * DDERR_INVALIDPARAMS if Data is NULL
5125 * For more details, see IWineD3DDevice::GetViewport
5127 *****************************************************************************/
5129 IDirect3DDeviceImpl_7_GetViewport(IDirect3DDevice7 *iface,
5132 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5135 TRACE("iface %p, viewport %p.\n", iface, Data);
5138 return DDERR_INVALIDPARAMS;
5140 /* Note: D3DVIEWPORT7 is compatible with WINED3DVIEWPORT */
5141 EnterCriticalSection(&ddraw_cs);
5142 hr = wined3d_device_get_viewport(This->wined3d_device, (WINED3DVIEWPORT *)Data);
5144 LeaveCriticalSection(&ddraw_cs);
5145 return hr_ddraw_from_wined3d(hr);
5148 static HRESULT WINAPI
5149 IDirect3DDeviceImpl_7_GetViewport_FPUSetup(IDirect3DDevice7 *iface,
5152 return IDirect3DDeviceImpl_7_GetViewport(iface, Data);
5155 static HRESULT WINAPI
5156 IDirect3DDeviceImpl_7_GetViewport_FPUPreserve(IDirect3DDevice7 *iface,
5162 old_fpucw = d3d_fpu_setup();
5163 hr = IDirect3DDeviceImpl_7_GetViewport(iface, Data);
5164 set_fpu_control_word(old_fpucw);
5169 /*****************************************************************************
5170 * IDirect3DDevice7::SetMaterial
5177 * Mat: The material to set
5181 * DDERR_INVALIDPARAMS if Mat is NULL.
5182 * For more details, see IWineD3DDevice::SetMaterial
5184 *****************************************************************************/
5186 IDirect3DDeviceImpl_7_SetMaterial(IDirect3DDevice7 *iface,
5189 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5192 TRACE("iface %p, material %p.\n", iface, Mat);
5194 if (!Mat) return DDERR_INVALIDPARAMS;
5195 /* Note: D3DMATERIAL7 is compatible with WINED3DMATERIAL */
5196 EnterCriticalSection(&ddraw_cs);
5197 hr = wined3d_device_set_material(This->wined3d_device, (WINED3DMATERIAL *)Mat);
5198 LeaveCriticalSection(&ddraw_cs);
5199 return hr_ddraw_from_wined3d(hr);
5202 static HRESULT WINAPI
5203 IDirect3DDeviceImpl_7_SetMaterial_FPUSetup(IDirect3DDevice7 *iface,
5206 return IDirect3DDeviceImpl_7_SetMaterial(iface, Mat);
5209 static HRESULT WINAPI
5210 IDirect3DDeviceImpl_7_SetMaterial_FPUPreserve(IDirect3DDevice7 *iface,
5216 old_fpucw = d3d_fpu_setup();
5217 hr = IDirect3DDeviceImpl_7_SetMaterial(iface, Mat);
5218 set_fpu_control_word(old_fpucw);
5223 /*****************************************************************************
5224 * IDirect3DDevice7::GetMaterial
5226 * Returns the current material
5231 * Mat: D3DMATERIAL7 structure to write the material parameters to
5235 * DDERR_INVALIDPARAMS if Mat is NULL
5236 * For more details, see IWineD3DDevice::GetMaterial
5238 *****************************************************************************/
5240 IDirect3DDeviceImpl_7_GetMaterial(IDirect3DDevice7 *iface,
5243 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5246 TRACE("iface %p, material %p.\n", iface, Mat);
5248 EnterCriticalSection(&ddraw_cs);
5249 /* Note: D3DMATERIAL7 is compatible with WINED3DMATERIAL */
5250 hr = wined3d_device_get_material(This->wined3d_device, (WINED3DMATERIAL *)Mat);
5251 LeaveCriticalSection(&ddraw_cs);
5252 return hr_ddraw_from_wined3d(hr);
5255 static HRESULT WINAPI
5256 IDirect3DDeviceImpl_7_GetMaterial_FPUSetup(IDirect3DDevice7 *iface,
5259 return IDirect3DDeviceImpl_7_GetMaterial(iface, Mat);
5262 static HRESULT WINAPI
5263 IDirect3DDeviceImpl_7_GetMaterial_FPUPreserve(IDirect3DDevice7 *iface,
5269 old_fpucw = d3d_fpu_setup();
5270 hr = IDirect3DDeviceImpl_7_GetMaterial(iface, Mat);
5271 set_fpu_control_word(old_fpucw);
5276 /*****************************************************************************
5277 * IDirect3DDevice7::SetLight
5279 * Assigns a light to a light index, but doesn't activate it yet.
5281 * Version 7, IDirect3DLight uses this method for older versions
5284 * LightIndex: The index of the new light
5285 * Light: A D3DLIGHT7 structure describing the light
5289 * For more details, see IWineD3DDevice::SetLight
5291 *****************************************************************************/
5293 IDirect3DDeviceImpl_7_SetLight(IDirect3DDevice7 *iface,
5297 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5300 TRACE("iface %p, light_idx %u, light %p.\n", iface, LightIndex, Light);
5302 EnterCriticalSection(&ddraw_cs);
5303 /* Note: D3DLIGHT7 is compatible with WINED3DLIGHT */
5304 hr = wined3d_device_set_light(This->wined3d_device, LightIndex, (WINED3DLIGHT *)Light);
5305 LeaveCriticalSection(&ddraw_cs);
5306 return hr_ddraw_from_wined3d(hr);
5309 static HRESULT WINAPI
5310 IDirect3DDeviceImpl_7_SetLight_FPUSetup(IDirect3DDevice7 *iface,
5314 return IDirect3DDeviceImpl_7_SetLight(iface, LightIndex, Light);
5317 static HRESULT WINAPI
5318 IDirect3DDeviceImpl_7_SetLight_FPUPreserve(IDirect3DDevice7 *iface,
5325 old_fpucw = d3d_fpu_setup();
5326 hr = IDirect3DDeviceImpl_7_SetLight(iface, LightIndex, Light);
5327 set_fpu_control_word(old_fpucw);
5332 /*****************************************************************************
5333 * IDirect3DDevice7::GetLight
5335 * Returns the light assigned to a light index
5338 * Light: Structure to write the light information to
5342 * DDERR_INVALIDPARAMS if Light is NULL
5343 * For details, see IWineD3DDevice::GetLight
5345 *****************************************************************************/
5347 IDirect3DDeviceImpl_7_GetLight(IDirect3DDevice7 *iface,
5351 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5354 TRACE("iface %p, light_idx %u, light %p.\n", iface, LightIndex, Light);
5356 EnterCriticalSection(&ddraw_cs);
5357 /* Note: D3DLIGHT7 is compatible with WINED3DLIGHT */
5358 rc = wined3d_device_get_light(This->wined3d_device, LightIndex, (WINED3DLIGHT *)Light);
5360 /* Translate the result. WineD3D returns other values than D3D7 */
5361 LeaveCriticalSection(&ddraw_cs);
5362 return hr_ddraw_from_wined3d(rc);
5365 static HRESULT WINAPI
5366 IDirect3DDeviceImpl_7_GetLight_FPUSetup(IDirect3DDevice7 *iface,
5370 return IDirect3DDeviceImpl_7_GetLight(iface, LightIndex, Light);
5373 static HRESULT WINAPI
5374 IDirect3DDeviceImpl_7_GetLight_FPUPreserve(IDirect3DDevice7 *iface,
5381 old_fpucw = d3d_fpu_setup();
5382 hr = IDirect3DDeviceImpl_7_GetLight(iface, LightIndex, Light);
5383 set_fpu_control_word(old_fpucw);
5388 /*****************************************************************************
5389 * IDirect3DDevice7::BeginStateBlock
5391 * Begins recording to a stateblock
5397 * For details see IWineD3DDevice::BeginStateBlock
5399 *****************************************************************************/
5401 IDirect3DDeviceImpl_7_BeginStateBlock(IDirect3DDevice7 *iface)
5403 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5406 TRACE("iface %p.\n", iface);
5408 EnterCriticalSection(&ddraw_cs);
5409 hr = wined3d_device_begin_stateblock(This->wined3d_device);
5410 LeaveCriticalSection(&ddraw_cs);
5411 return hr_ddraw_from_wined3d(hr);
5414 static HRESULT WINAPI
5415 IDirect3DDeviceImpl_7_BeginStateBlock_FPUSetup(IDirect3DDevice7 *iface)
5417 return IDirect3DDeviceImpl_7_BeginStateBlock(iface);
5420 static HRESULT WINAPI
5421 IDirect3DDeviceImpl_7_BeginStateBlock_FPUPreserve(IDirect3DDevice7 *iface)
5426 old_fpucw = d3d_fpu_setup();
5427 hr = IDirect3DDeviceImpl_7_BeginStateBlock(iface);
5428 set_fpu_control_word(old_fpucw);
5433 /*****************************************************************************
5434 * IDirect3DDevice7::EndStateBlock
5436 * Stops recording to a state block and returns the created stateblock
5442 * BlockHandle: Address to store the stateblock's handle to
5446 * DDERR_INVALIDPARAMS if BlockHandle is NULL
5447 * See IWineD3DDevice::EndStateBlock for more details
5449 *****************************************************************************/
5451 IDirect3DDeviceImpl_7_EndStateBlock(IDirect3DDevice7 *iface,
5454 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5455 struct wined3d_stateblock *wined3d_sb;
5459 TRACE("iface %p, stateblock %p.\n", iface, BlockHandle);
5463 WARN("BlockHandle == NULL, returning DDERR_INVALIDPARAMS\n");
5464 return DDERR_INVALIDPARAMS;
5467 EnterCriticalSection(&ddraw_cs);
5469 hr = wined3d_device_end_stateblock(This->wined3d_device, &wined3d_sb);
5472 WARN("Failed to end stateblock, hr %#x.\n", hr);
5473 LeaveCriticalSection(&ddraw_cs);
5475 return hr_ddraw_from_wined3d(hr);
5478 h = ddraw_allocate_handle(&This->handle_table, wined3d_sb, DDRAW_HANDLE_STATEBLOCK);
5479 if (h == DDRAW_INVALID_HANDLE)
5481 ERR("Failed to allocate a stateblock handle.\n");
5482 wined3d_stateblock_decref(wined3d_sb);
5483 LeaveCriticalSection(&ddraw_cs);
5485 return DDERR_OUTOFMEMORY;
5488 LeaveCriticalSection(&ddraw_cs);
5489 *BlockHandle = h + 1;
5491 return hr_ddraw_from_wined3d(hr);
5494 static HRESULT WINAPI
5495 IDirect3DDeviceImpl_7_EndStateBlock_FPUSetup(IDirect3DDevice7 *iface,
5498 return IDirect3DDeviceImpl_7_EndStateBlock(iface, BlockHandle);
5501 static HRESULT WINAPI
5502 IDirect3DDeviceImpl_7_EndStateBlock_FPUPreserve(IDirect3DDevice7 *iface,
5508 old_fpucw = d3d_fpu_setup();
5509 hr = IDirect3DDeviceImpl_7_EndStateBlock(iface, BlockHandle);
5510 set_fpu_control_word(old_fpucw);
5515 /*****************************************************************************
5516 * IDirect3DDevice7::PreLoad
5518 * Allows the app to signal that a texture will be used soon, to allow
5519 * the Direct3DDevice to load it to the video card in the meantime.
5524 * Texture: The texture to preload
5528 * DDERR_INVALIDPARAMS if Texture is NULL
5529 * See IWineD3DSurface::PreLoad for details
5531 *****************************************************************************/
5533 IDirect3DDeviceImpl_7_PreLoad(IDirect3DDevice7 *iface,
5534 IDirectDrawSurface7 *Texture)
5536 IDirectDrawSurfaceImpl *surf = unsafe_impl_from_IDirectDrawSurface7(Texture);
5538 TRACE("iface %p, texture %p.\n", iface, Texture);
5541 return DDERR_INVALIDPARAMS;
5543 EnterCriticalSection(&ddraw_cs);
5544 wined3d_surface_preload(surf->wined3d_surface);
5545 LeaveCriticalSection(&ddraw_cs);
5549 static HRESULT WINAPI
5550 IDirect3DDeviceImpl_7_PreLoad_FPUSetup(IDirect3DDevice7 *iface,
5551 IDirectDrawSurface7 *Texture)
5553 return IDirect3DDeviceImpl_7_PreLoad(iface, Texture);
5556 static HRESULT WINAPI
5557 IDirect3DDeviceImpl_7_PreLoad_FPUPreserve(IDirect3DDevice7 *iface,
5558 IDirectDrawSurface7 *Texture)
5563 old_fpucw = d3d_fpu_setup();
5564 hr = IDirect3DDeviceImpl_7_PreLoad(iface, Texture);
5565 set_fpu_control_word(old_fpucw);
5570 /*****************************************************************************
5571 * IDirect3DDevice7::ApplyStateBlock
5573 * Activates the state stored in a state block handle.
5576 * BlockHandle: The stateblock handle to activate
5580 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is NULL
5582 *****************************************************************************/
5584 IDirect3DDeviceImpl_7_ApplyStateBlock(IDirect3DDevice7 *iface,
5587 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5588 struct wined3d_stateblock *wined3d_sb;
5591 TRACE("iface %p, stateblock %#x.\n", iface, BlockHandle);
5593 EnterCriticalSection(&ddraw_cs);
5595 wined3d_sb = ddraw_get_object(&This->handle_table, BlockHandle - 1, DDRAW_HANDLE_STATEBLOCK);
5598 WARN("Invalid stateblock handle.\n");
5599 LeaveCriticalSection(&ddraw_cs);
5600 return D3DERR_INVALIDSTATEBLOCK;
5603 hr = wined3d_stateblock_apply(wined3d_sb);
5604 LeaveCriticalSection(&ddraw_cs);
5606 return hr_ddraw_from_wined3d(hr);
5609 static HRESULT WINAPI
5610 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUSetup(IDirect3DDevice7 *iface,
5613 return IDirect3DDeviceImpl_7_ApplyStateBlock(iface, BlockHandle);
5616 static HRESULT WINAPI
5617 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUPreserve(IDirect3DDevice7 *iface,
5623 old_fpucw = d3d_fpu_setup();
5624 hr = IDirect3DDeviceImpl_7_ApplyStateBlock(iface, BlockHandle);
5625 set_fpu_control_word(old_fpucw);
5630 /*****************************************************************************
5631 * IDirect3DDevice7::CaptureStateBlock
5633 * Updates a stateblock's values to the values currently set for the device
5638 * BlockHandle: Stateblock to update
5642 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is NULL
5643 * See IWineD3DDevice::CaptureStateBlock for more details
5645 *****************************************************************************/
5647 IDirect3DDeviceImpl_7_CaptureStateBlock(IDirect3DDevice7 *iface,
5650 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5651 struct wined3d_stateblock *wined3d_sb;
5654 TRACE("iface %p, stateblock %#x.\n", iface, BlockHandle);
5656 EnterCriticalSection(&ddraw_cs);
5658 wined3d_sb = ddraw_get_object(&This->handle_table, BlockHandle - 1, DDRAW_HANDLE_STATEBLOCK);
5661 WARN("Invalid stateblock handle.\n");
5662 LeaveCriticalSection(&ddraw_cs);
5663 return D3DERR_INVALIDSTATEBLOCK;
5666 hr = wined3d_stateblock_capture(wined3d_sb);
5667 LeaveCriticalSection(&ddraw_cs);
5668 return hr_ddraw_from_wined3d(hr);
5671 static HRESULT WINAPI
5672 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUSetup(IDirect3DDevice7 *iface,
5675 return IDirect3DDeviceImpl_7_CaptureStateBlock(iface, BlockHandle);
5678 static HRESULT WINAPI
5679 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUPreserve(IDirect3DDevice7 *iface,
5685 old_fpucw = d3d_fpu_setup();
5686 hr = IDirect3DDeviceImpl_7_CaptureStateBlock(iface, BlockHandle);
5687 set_fpu_control_word(old_fpucw);
5692 /*****************************************************************************
5693 * IDirect3DDevice7::DeleteStateBlock
5695 * Deletes a stateblock handle. This means releasing the WineD3DStateBlock
5700 * BlockHandle: Stateblock handle to delete
5704 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is 0
5706 *****************************************************************************/
5708 IDirect3DDeviceImpl_7_DeleteStateBlock(IDirect3DDevice7 *iface,
5711 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5712 struct wined3d_stateblock *wined3d_sb;
5715 TRACE("iface %p, stateblock %#x.\n", iface, BlockHandle);
5717 EnterCriticalSection(&ddraw_cs);
5719 wined3d_sb = ddraw_free_handle(&This->handle_table, BlockHandle - 1, DDRAW_HANDLE_STATEBLOCK);
5722 WARN("Invalid stateblock handle.\n");
5723 LeaveCriticalSection(&ddraw_cs);
5724 return D3DERR_INVALIDSTATEBLOCK;
5727 if ((ref = wined3d_stateblock_decref(wined3d_sb)))
5729 ERR("Something is still holding stateblock %p (refcount %u).\n", wined3d_sb, ref);
5732 LeaveCriticalSection(&ddraw_cs);
5736 static HRESULT WINAPI
5737 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUSetup(IDirect3DDevice7 *iface,
5740 return IDirect3DDeviceImpl_7_DeleteStateBlock(iface, BlockHandle);
5743 static HRESULT WINAPI
5744 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUPreserve(IDirect3DDevice7 *iface,
5750 old_fpucw = d3d_fpu_setup();
5751 hr = IDirect3DDeviceImpl_7_DeleteStateBlock(iface, BlockHandle);
5752 set_fpu_control_word(old_fpucw);
5757 /*****************************************************************************
5758 * IDirect3DDevice7::CreateStateBlock
5760 * Creates a new state block handle.
5765 * Type: The state block type
5766 * BlockHandle: Address to write the created handle to
5770 * DDERR_INVALIDPARAMS if BlockHandle is NULL
5772 *****************************************************************************/
5774 IDirect3DDeviceImpl_7_CreateStateBlock(IDirect3DDevice7 *iface,
5775 D3DSTATEBLOCKTYPE Type,
5778 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5779 struct wined3d_stateblock *wined3d_sb;
5783 TRACE("iface %p, type %#x, stateblock %p.\n", iface, Type, BlockHandle);
5787 WARN("BlockHandle == NULL, returning DDERR_INVALIDPARAMS\n");
5788 return DDERR_INVALIDPARAMS;
5790 if(Type != D3DSBT_ALL && Type != D3DSBT_PIXELSTATE &&
5791 Type != D3DSBT_VERTEXSTATE ) {
5792 WARN("Unexpected stateblock type, returning DDERR_INVALIDPARAMS\n");
5793 return DDERR_INVALIDPARAMS;
5796 EnterCriticalSection(&ddraw_cs);
5798 /* The D3DSTATEBLOCKTYPE enum is fine here. */
5799 hr = wined3d_stateblock_create(This->wined3d_device, Type, &wined3d_sb);
5802 WARN("Failed to create stateblock, hr %#x.\n", hr);
5803 LeaveCriticalSection(&ddraw_cs);
5804 return hr_ddraw_from_wined3d(hr);
5807 h = ddraw_allocate_handle(&This->handle_table, wined3d_sb, DDRAW_HANDLE_STATEBLOCK);
5808 if (h == DDRAW_INVALID_HANDLE)
5810 ERR("Failed to allocate stateblock handle.\n");
5811 wined3d_stateblock_decref(wined3d_sb);
5812 LeaveCriticalSection(&ddraw_cs);
5813 return DDERR_OUTOFMEMORY;
5816 *BlockHandle = h + 1;
5817 LeaveCriticalSection(&ddraw_cs);
5819 return hr_ddraw_from_wined3d(hr);
5822 static HRESULT WINAPI
5823 IDirect3DDeviceImpl_7_CreateStateBlock_FPUSetup(IDirect3DDevice7 *iface,
5824 D3DSTATEBLOCKTYPE Type,
5827 return IDirect3DDeviceImpl_7_CreateStateBlock(iface, Type, BlockHandle);
5830 static HRESULT WINAPI
5831 IDirect3DDeviceImpl_7_CreateStateBlock_FPUPreserve(IDirect3DDevice7 *iface,
5832 D3DSTATEBLOCKTYPE Type,
5838 old_fpucw = d3d_fpu_setup();
5839 hr =IDirect3DDeviceImpl_7_CreateStateBlock(iface, Type, BlockHandle);
5840 set_fpu_control_word(old_fpucw);
5845 /* Helper function for IDirect3DDeviceImpl_7_Load. */
5846 static BOOL is_mip_level_subset(IDirectDrawSurfaceImpl *dest,
5847 IDirectDrawSurfaceImpl *src)
5849 IDirectDrawSurfaceImpl *src_level, *dest_level;
5850 IDirectDrawSurface7 *temp;
5851 DDSURFACEDESC2 ddsd;
5852 BOOL levelFound; /* at least one suitable sublevel in dest found */
5854 /* To satisfy "destination is mip level subset of source" criteria (regular texture counts as 1 level),
5855 * 1) there must be at least one mip level in destination that matched dimensions of some mip level in source and
5856 * 2) there must be no destination levels that don't match any levels in source. Otherwise it's INVALIDPARAMS.
5863 for (;src_level && dest_level;)
5865 if (src_level->surface_desc.dwWidth == dest_level->surface_desc.dwWidth &&
5866 src_level->surface_desc.dwHeight == dest_level->surface_desc.dwHeight)
5870 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
5871 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_MIPMAPSUBLEVEL;
5872 IDirectDrawSurface7_GetAttachedSurface(&dest_level->IDirectDrawSurface7_iface, &ddsd.ddsCaps, &temp);
5874 if (dest_level != dest) IDirectDrawSurface7_Release(&dest_level->IDirectDrawSurface7_iface);
5876 dest_level = unsafe_impl_from_IDirectDrawSurface7(temp);
5879 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
5880 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_MIPMAPSUBLEVEL;
5881 IDirectDrawSurface7_GetAttachedSurface(&src_level->IDirectDrawSurface7_iface, &ddsd.ddsCaps, &temp);
5883 if (src_level != src) IDirectDrawSurface7_Release(&src_level->IDirectDrawSurface7_iface);
5885 src_level = unsafe_impl_from_IDirectDrawSurface7(temp);
5888 if (src_level && src_level != src) IDirectDrawSurface7_Release(&src_level->IDirectDrawSurface7_iface);
5889 if (dest_level && dest_level != dest) IDirectDrawSurface7_Release(&dest_level->IDirectDrawSurface7_iface);
5891 return !dest_level && levelFound;
5894 /* Helper function for IDirect3DDeviceImpl_7_Load. */
5895 static void copy_mipmap_chain(IDirect3DDeviceImpl *device,
5896 IDirectDrawSurfaceImpl *dest,
5897 IDirectDrawSurfaceImpl *src,
5898 const POINT *DestPoint,
5899 const RECT *SrcRect)
5901 IDirectDrawSurfaceImpl *src_level, *dest_level;
5902 IDirectDrawSurface7 *temp;
5903 DDSURFACEDESC2 ddsd;
5907 IDirectDrawPalette *pal = NULL, *pal_src = NULL;
5910 BOOL palette_missing = FALSE;
5912 /* Copy palette, if possible. */
5913 IDirectDrawSurface7_GetPalette(&src->IDirectDrawSurface7_iface, &pal_src);
5914 IDirectDrawSurface7_GetPalette(&dest->IDirectDrawSurface7_iface, &pal);
5916 if (pal_src != NULL && pal != NULL)
5918 PALETTEENTRY palent[256];
5920 IDirectDrawPalette_GetEntries(pal_src, 0, 0, 256, palent);
5921 IDirectDrawPalette_SetEntries(pal, 0, 0, 256, palent);
5924 if (dest->surface_desc.u4.ddpfPixelFormat.dwFlags & (DDPF_PALETTEINDEXED1 | DDPF_PALETTEINDEXED2 |
5925 DDPF_PALETTEINDEXED4 | DDPF_PALETTEINDEXED8 | DDPF_PALETTEINDEXEDTO8) && !pal)
5927 palette_missing = TRUE;
5930 if (pal) IDirectDrawPalette_Release(pal);
5931 if (pal_src) IDirectDrawPalette_Release(pal_src);
5933 /* Copy colorkeys, if present. */
5934 for (ckeyflag = DDCKEY_DESTBLT; ckeyflag <= DDCKEY_SRCOVERLAY; ckeyflag <<= 1)
5936 hr = IDirectDrawSurface7_GetColorKey(&src->IDirectDrawSurface7_iface, ckeyflag, &ddckey);
5940 IDirectDrawSurface7_SetColorKey(&dest->IDirectDrawSurface7_iface, ckeyflag, &ddckey);
5950 for (;src_level && dest_level;)
5952 if (src_level->surface_desc.dwWidth == dest_level->surface_desc.dwWidth &&
5953 src_level->surface_desc.dwHeight == dest_level->surface_desc.dwHeight)
5955 /* Try UpdateSurface that may perform a more direct OpenGL
5956 * loading. But skip this if destination is paletted texture and
5957 * has no palette. Some games like Sacrifice set palette after
5958 * Load, and it is a waste of effort to try to load texture
5959 * without palette and generates warnings in wined3d. */
5960 if (!palette_missing)
5961 hr = wined3d_device_update_surface(device->wined3d_device, src_level->wined3d_surface,
5962 &rect, dest_level->wined3d_surface, &point);
5964 if (palette_missing || FAILED(hr))
5966 /* UpdateSurface may fail e.g. if dest is in system memory. Fall back to BltFast that is less strict. */
5967 wined3d_surface_bltfast(dest_level->wined3d_surface, point.x, point.y,
5968 src_level->wined3d_surface, &rect, 0);
5971 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
5972 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_MIPMAPSUBLEVEL;
5973 IDirectDrawSurface7_GetAttachedSurface(&dest_level->IDirectDrawSurface7_iface, &ddsd.ddsCaps, &temp);
5975 if (dest_level != dest) IDirectDrawSurface7_Release(&dest_level->IDirectDrawSurface7_iface);
5977 dest_level = unsafe_impl_from_IDirectDrawSurface7(temp);
5980 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
5981 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_MIPMAPSUBLEVEL;
5982 IDirectDrawSurface7_GetAttachedSurface(&src_level->IDirectDrawSurface7_iface, &ddsd.ddsCaps, &temp);
5984 if (src_level != src) IDirectDrawSurface7_Release(&src_level->IDirectDrawSurface7_iface);
5986 src_level = unsafe_impl_from_IDirectDrawSurface7(temp);
5993 rect.right = (rect.right + 1) / 2;
5994 rect.bottom = (rect.bottom + 1) / 2;
5997 if (src_level && src_level != src) IDirectDrawSurface7_Release(&src_level->IDirectDrawSurface7_iface);
5998 if (dest_level && dest_level != dest) IDirectDrawSurface7_Release(&dest_level->IDirectDrawSurface7_iface);
6001 /*****************************************************************************
6002 * IDirect3DDevice7::Load
6004 * Loads a rectangular area from the source into the destination texture.
6005 * It can also copy the source to the faces of a cubic environment map
6010 * DestTex: Destination texture
6011 * DestPoint: Point in the destination where the source image should be
6013 * SrcTex: Source texture
6014 * SrcRect: Source rectangle
6015 * Flags: Cubemap faces to load (DDSCAPS2_CUBEMAP_ALLFACES, DDSCAPS2_CUBEMAP_POSITIVEX,
6016 * DDSCAPS2_CUBEMAP_NEGATIVEX, DDSCAPS2_CUBEMAP_POSITIVEY, DDSCAPS2_CUBEMAP_NEGATIVEY,
6017 * DDSCAPS2_CUBEMAP_POSITIVEZ, DDSCAPS2_CUBEMAP_NEGATIVEZ)
6021 * DDERR_INVALIDPARAMS if DestTex or SrcTex are NULL, broken coordinates or anything unexpected.
6024 *****************************************************************************/
6027 IDirect3DDeviceImpl_7_Load(IDirect3DDevice7 *iface,
6028 IDirectDrawSurface7 *DestTex,
6030 IDirectDrawSurface7 *SrcTex,
6034 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
6035 IDirectDrawSurfaceImpl *dest = unsafe_impl_from_IDirectDrawSurface7(DestTex);
6036 IDirectDrawSurfaceImpl *src = unsafe_impl_from_IDirectDrawSurface7(SrcTex);
6040 TRACE("iface %p, dst_texture %p, dst_pos %s, src_texture %p, src_rect %s, flags %#x.\n",
6041 iface, DestTex, wine_dbgstr_point(DestPoint), SrcTex, wine_dbgstr_rect(SrcRect), Flags);
6043 if( (!src) || (!dest) )
6044 return DDERR_INVALIDPARAMS;
6046 EnterCriticalSection(&ddraw_cs);
6048 if (SrcRect) srcrect = *SrcRect;
6051 srcrect.left = srcrect.top = 0;
6052 srcrect.right = src->surface_desc.dwWidth;
6053 srcrect.bottom = src->surface_desc.dwHeight;
6056 if (DestPoint) destpoint = *DestPoint;
6059 destpoint.x = destpoint.y = 0;
6061 /* Check bad dimensions. DestPoint is validated against src, not dest, because
6062 * destination can be a subset of mip levels, in which case actual coordinates used
6063 * for it may be divided. If any dimension of dest is larger than source, it can't be
6064 * mip level subset, so an error can be returned early.
6066 if (srcrect.left >= srcrect.right || srcrect.top >= srcrect.bottom ||
6067 srcrect.right > src->surface_desc.dwWidth ||
6068 srcrect.bottom > src->surface_desc.dwHeight ||
6069 destpoint.x + srcrect.right - srcrect.left > src->surface_desc.dwWidth ||
6070 destpoint.y + srcrect.bottom - srcrect.top > src->surface_desc.dwHeight ||
6071 dest->surface_desc.dwWidth > src->surface_desc.dwWidth ||
6072 dest->surface_desc.dwHeight > src->surface_desc.dwHeight)
6074 LeaveCriticalSection(&ddraw_cs);
6075 return DDERR_INVALIDPARAMS;
6078 /* Must be top level surfaces. */
6079 if (src->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_MIPMAPSUBLEVEL ||
6080 dest->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_MIPMAPSUBLEVEL)
6082 LeaveCriticalSection(&ddraw_cs);
6083 return DDERR_INVALIDPARAMS;
6086 if (src->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP)
6088 DWORD src_face_flag, dest_face_flag;
6089 IDirectDrawSurfaceImpl *src_face, *dest_face;
6090 IDirectDrawSurface7 *temp;
6091 DDSURFACEDESC2 ddsd;
6094 if (!(dest->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP))
6096 LeaveCriticalSection(&ddraw_cs);
6097 return DDERR_INVALIDPARAMS;
6100 /* Iterate through cube faces 2 times. First time is just to check INVALIDPARAMS conditions, second
6101 * time it's actual surface loading. */
6102 for (i = 0; i < 2; i++)
6107 for (;dest_face && src_face;)
6109 src_face_flag = src_face->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP_ALLFACES;
6110 dest_face_flag = dest_face->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP_ALLFACES;
6112 if (src_face_flag == dest_face_flag)
6116 /* Destination mip levels must be subset of source mip levels. */
6117 if (!is_mip_level_subset(dest_face, src_face))
6119 LeaveCriticalSection(&ddraw_cs);
6120 return DDERR_INVALIDPARAMS;
6123 else if (Flags & dest_face_flag)
6125 copy_mipmap_chain(This, dest_face, src_face, &destpoint, &srcrect);
6128 if (src_face_flag < DDSCAPS2_CUBEMAP_NEGATIVEZ)
6130 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
6131 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | (src_face_flag << 1);
6132 IDirectDrawSurface7_GetAttachedSurface(&src->IDirectDrawSurface7_iface, &ddsd.ddsCaps, &temp);
6134 if (src_face != src) IDirectDrawSurface7_Release(&src_face->IDirectDrawSurface7_iface);
6136 src_face = unsafe_impl_from_IDirectDrawSurface7(temp);
6140 if (src_face != src) IDirectDrawSurface7_Release(&src_face->IDirectDrawSurface7_iface);
6146 if (dest_face_flag < DDSCAPS2_CUBEMAP_NEGATIVEZ)
6148 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
6149 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | (dest_face_flag << 1);
6150 IDirectDrawSurface7_GetAttachedSurface(&dest->IDirectDrawSurface7_iface, &ddsd.ddsCaps, &temp);
6152 if (dest_face != dest) IDirectDrawSurface7_Release(&dest_face->IDirectDrawSurface7_iface);
6154 dest_face = unsafe_impl_from_IDirectDrawSurface7(temp);
6158 if (dest_face != dest) IDirectDrawSurface7_Release(&dest_face->IDirectDrawSurface7_iface);
6166 /* Native returns error if src faces are not subset of dest faces. */
6169 LeaveCriticalSection(&ddraw_cs);
6170 return DDERR_INVALIDPARAMS;
6175 LeaveCriticalSection(&ddraw_cs);
6178 else if (dest->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP)
6180 LeaveCriticalSection(&ddraw_cs);
6181 return DDERR_INVALIDPARAMS;
6184 /* Handle non cube map textures. */
6186 /* Destination mip levels must be subset of source mip levels. */
6187 if (!is_mip_level_subset(dest, src))
6189 LeaveCriticalSection(&ddraw_cs);
6190 return DDERR_INVALIDPARAMS;
6193 copy_mipmap_chain(This, dest, src, &destpoint, &srcrect);
6195 LeaveCriticalSection(&ddraw_cs);
6199 static HRESULT WINAPI
6200 IDirect3DDeviceImpl_7_Load_FPUSetup(IDirect3DDevice7 *iface,
6201 IDirectDrawSurface7 *DestTex,
6203 IDirectDrawSurface7 *SrcTex,
6207 return IDirect3DDeviceImpl_7_Load(iface, DestTex, DestPoint, SrcTex, SrcRect, Flags);
6210 static HRESULT WINAPI
6211 IDirect3DDeviceImpl_7_Load_FPUPreserve(IDirect3DDevice7 *iface,
6212 IDirectDrawSurface7 *DestTex,
6214 IDirectDrawSurface7 *SrcTex,
6221 old_fpucw = d3d_fpu_setup();
6222 hr = IDirect3DDeviceImpl_7_Load(iface, DestTex, DestPoint, SrcTex, SrcRect, Flags);
6223 set_fpu_control_word(old_fpucw);
6228 /*****************************************************************************
6229 * IDirect3DDevice7::LightEnable
6231 * Enables or disables a light
6233 * Version 7, IDirect3DLight uses this method too.
6236 * LightIndex: The index of the light to enable / disable
6237 * Enable: Enable or disable the light
6241 * For more details, see IWineD3DDevice::SetLightEnable
6243 *****************************************************************************/
6245 IDirect3DDeviceImpl_7_LightEnable(IDirect3DDevice7 *iface,
6249 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
6252 TRACE("iface %p, light_idx %u, enabled %#x.\n", iface, LightIndex, Enable);
6254 EnterCriticalSection(&ddraw_cs);
6255 hr = wined3d_device_set_light_enable(This->wined3d_device, LightIndex, Enable);
6256 LeaveCriticalSection(&ddraw_cs);
6257 return hr_ddraw_from_wined3d(hr);
6260 static HRESULT WINAPI
6261 IDirect3DDeviceImpl_7_LightEnable_FPUSetup(IDirect3DDevice7 *iface,
6265 return IDirect3DDeviceImpl_7_LightEnable(iface, LightIndex, Enable);
6268 static HRESULT WINAPI
6269 IDirect3DDeviceImpl_7_LightEnable_FPUPreserve(IDirect3DDevice7 *iface,
6276 old_fpucw = d3d_fpu_setup();
6277 hr = IDirect3DDeviceImpl_7_LightEnable(iface, LightIndex, Enable);
6278 set_fpu_control_word(old_fpucw);
6283 /*****************************************************************************
6284 * IDirect3DDevice7::GetLightEnable
6286 * Retrieves if the light with the given index is enabled or not
6291 * LightIndex: Index of desired light
6292 * Enable: Pointer to a BOOL which contains the result
6296 * DDERR_INVALIDPARAMS if Enable is NULL
6297 * See IWineD3DDevice::GetLightEnable for more details
6299 *****************************************************************************/
6301 IDirect3DDeviceImpl_7_GetLightEnable(IDirect3DDevice7 *iface,
6305 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
6308 TRACE("iface %p, light_idx %u, enabled %p.\n", iface, LightIndex, Enable);
6311 return DDERR_INVALIDPARAMS;
6313 EnterCriticalSection(&ddraw_cs);
6314 hr = wined3d_device_get_light_enable(This->wined3d_device, LightIndex, Enable);
6315 LeaveCriticalSection(&ddraw_cs);
6316 return hr_ddraw_from_wined3d(hr);
6319 static HRESULT WINAPI
6320 IDirect3DDeviceImpl_7_GetLightEnable_FPUSetup(IDirect3DDevice7 *iface,
6324 return IDirect3DDeviceImpl_7_GetLightEnable(iface, LightIndex, Enable);
6327 static HRESULT WINAPI
6328 IDirect3DDeviceImpl_7_GetLightEnable_FPUPreserve(IDirect3DDevice7 *iface,
6335 old_fpucw = d3d_fpu_setup();
6336 hr = IDirect3DDeviceImpl_7_GetLightEnable(iface, LightIndex, Enable);
6337 set_fpu_control_word(old_fpucw);
6342 /*****************************************************************************
6343 * IDirect3DDevice7::SetClipPlane
6345 * Sets custom clipping plane
6350 * Index: The index of the clipping plane
6351 * PlaneEquation: An equation defining the clipping plane
6355 * DDERR_INVALIDPARAMS if PlaneEquation is NULL
6356 * See IWineD3DDevice::SetClipPlane for more details
6358 *****************************************************************************/
6360 IDirect3DDeviceImpl_7_SetClipPlane(IDirect3DDevice7 *iface,
6362 D3DVALUE* PlaneEquation)
6364 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
6367 TRACE("iface %p, idx %u, plane %p.\n", iface, Index, PlaneEquation);
6370 return DDERR_INVALIDPARAMS;
6372 EnterCriticalSection(&ddraw_cs);
6373 hr = wined3d_device_set_clip_plane(This->wined3d_device, Index, PlaneEquation);
6374 LeaveCriticalSection(&ddraw_cs);
6378 static HRESULT WINAPI
6379 IDirect3DDeviceImpl_7_SetClipPlane_FPUSetup(IDirect3DDevice7 *iface,
6381 D3DVALUE* PlaneEquation)
6383 return IDirect3DDeviceImpl_7_SetClipPlane(iface, Index, PlaneEquation);
6386 static HRESULT WINAPI
6387 IDirect3DDeviceImpl_7_SetClipPlane_FPUPreserve(IDirect3DDevice7 *iface,
6389 D3DVALUE* PlaneEquation)
6394 old_fpucw = d3d_fpu_setup();
6395 hr = IDirect3DDeviceImpl_7_SetClipPlane(iface, Index, PlaneEquation);
6396 set_fpu_control_word(old_fpucw);
6401 /*****************************************************************************
6402 * IDirect3DDevice7::GetClipPlane
6404 * Returns the clipping plane with a specific index
6407 * Index: The index of the desired plane
6408 * PlaneEquation: Address to store the plane equation to
6412 * DDERR_INVALIDPARAMS if PlaneEquation is NULL
6413 * See IWineD3DDevice::GetClipPlane for more details
6415 *****************************************************************************/
6417 IDirect3DDeviceImpl_7_GetClipPlane(IDirect3DDevice7 *iface,
6419 D3DVALUE* PlaneEquation)
6421 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
6424 TRACE("iface %p, idx %u, plane %p.\n", iface, Index, PlaneEquation);
6427 return DDERR_INVALIDPARAMS;
6429 EnterCriticalSection(&ddraw_cs);
6430 hr = wined3d_device_get_clip_plane(This->wined3d_device, Index, PlaneEquation);
6431 LeaveCriticalSection(&ddraw_cs);
6435 static HRESULT WINAPI
6436 IDirect3DDeviceImpl_7_GetClipPlane_FPUSetup(IDirect3DDevice7 *iface,
6438 D3DVALUE* PlaneEquation)
6440 return IDirect3DDeviceImpl_7_GetClipPlane(iface, Index, PlaneEquation);
6443 static HRESULT WINAPI
6444 IDirect3DDeviceImpl_7_GetClipPlane_FPUPreserve(IDirect3DDevice7 *iface,
6446 D3DVALUE* PlaneEquation)
6451 old_fpucw = d3d_fpu_setup();
6452 hr = IDirect3DDeviceImpl_7_GetClipPlane(iface, Index, PlaneEquation);
6453 set_fpu_control_word(old_fpucw);
6458 /*****************************************************************************
6459 * IDirect3DDevice7::GetInfo
6461 * Retrieves some information about the device. The DirectX sdk says that
6462 * this version returns S_FALSE for all retail builds of DirectX, that's what
6463 * this implementation does.
6466 * DevInfoID: Information type requested
6467 * DevInfoStruct: Pointer to a structure to store the info to
6468 * Size: Size of the structure
6471 * S_FALSE, because it's a non-debug driver
6473 *****************************************************************************/
6474 static HRESULT WINAPI
6475 IDirect3DDeviceImpl_7_GetInfo(IDirect3DDevice7 *iface,
6477 void *DevInfoStruct,
6480 TRACE("iface %p, info_id %#x, info %p, info_size %u.\n",
6481 iface, DevInfoID, DevInfoStruct, Size);
6483 if (TRACE_ON(ddraw))
6485 TRACE(" info requested : ");
6488 case D3DDEVINFOID_TEXTUREMANAGER: TRACE("D3DDEVINFOID_TEXTUREMANAGER\n"); break;
6489 case D3DDEVINFOID_D3DTEXTUREMANAGER: TRACE("D3DDEVINFOID_D3DTEXTUREMANAGER\n"); break;
6490 case D3DDEVINFOID_TEXTURING: TRACE("D3DDEVINFOID_TEXTURING\n"); break;
6491 default: ERR(" invalid flag !!!\n"); return DDERR_INVALIDPARAMS;
6495 return S_FALSE; /* According to MSDN, this is valid for a non-debug driver */
6498 /* For performance optimization, devices created in FPUSETUP and FPUPRESERVE modes
6499 * have separate vtables. Simple functions where this doesn't matter like GetDirect3D
6500 * are not duplicated.
6502 * Device created with DDSCL_FPUSETUP (d3d7 default) - device methods assume that FPU
6503 * has already been setup for optimal d3d operation.
6505 * Device created with DDSCL_FPUPRESERVE - resets and restores FPU mode when necessary in
6506 * d3d calls (FPU may be in a mode non-suitable for d3d when the app calls d3d). Required
6507 * by Sacrifice (game). */
6508 static const struct IDirect3DDevice7Vtbl d3d_device7_fpu_setup_vtbl =
6510 /*** IUnknown Methods ***/
6511 IDirect3DDeviceImpl_7_QueryInterface,
6512 IDirect3DDeviceImpl_7_AddRef,
6513 IDirect3DDeviceImpl_7_Release,
6514 /*** IDirect3DDevice7 ***/
6515 IDirect3DDeviceImpl_7_GetCaps_FPUSetup,
6516 IDirect3DDeviceImpl_7_EnumTextureFormats_FPUSetup,
6517 IDirect3DDeviceImpl_7_BeginScene_FPUSetup,
6518 IDirect3DDeviceImpl_7_EndScene_FPUSetup,
6519 IDirect3DDeviceImpl_7_GetDirect3D,
6520 IDirect3DDeviceImpl_7_SetRenderTarget_FPUSetup,
6521 IDirect3DDeviceImpl_7_GetRenderTarget,
6522 IDirect3DDeviceImpl_7_Clear_FPUSetup,
6523 IDirect3DDeviceImpl_7_SetTransform_FPUSetup,
6524 IDirect3DDeviceImpl_7_GetTransform_FPUSetup,
6525 IDirect3DDeviceImpl_7_SetViewport_FPUSetup,
6526 IDirect3DDeviceImpl_7_MultiplyTransform_FPUSetup,
6527 IDirect3DDeviceImpl_7_GetViewport_FPUSetup,
6528 IDirect3DDeviceImpl_7_SetMaterial_FPUSetup,
6529 IDirect3DDeviceImpl_7_GetMaterial_FPUSetup,
6530 IDirect3DDeviceImpl_7_SetLight_FPUSetup,
6531 IDirect3DDeviceImpl_7_GetLight_FPUSetup,
6532 IDirect3DDeviceImpl_7_SetRenderState_FPUSetup,
6533 IDirect3DDeviceImpl_7_GetRenderState_FPUSetup,
6534 IDirect3DDeviceImpl_7_BeginStateBlock_FPUSetup,
6535 IDirect3DDeviceImpl_7_EndStateBlock_FPUSetup,
6536 IDirect3DDeviceImpl_7_PreLoad_FPUSetup,
6537 IDirect3DDeviceImpl_7_DrawPrimitive_FPUSetup,
6538 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUSetup,
6539 IDirect3DDeviceImpl_7_SetClipStatus,
6540 IDirect3DDeviceImpl_7_GetClipStatus,
6541 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUSetup,
6542 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUSetup,
6543 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUSetup,
6544 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUSetup,
6545 IDirect3DDeviceImpl_7_ComputeSphereVisibility,
6546 IDirect3DDeviceImpl_7_GetTexture_FPUSetup,
6547 IDirect3DDeviceImpl_7_SetTexture_FPUSetup,
6548 IDirect3DDeviceImpl_7_GetTextureStageState_FPUSetup,
6549 IDirect3DDeviceImpl_7_SetTextureStageState_FPUSetup,
6550 IDirect3DDeviceImpl_7_ValidateDevice_FPUSetup,
6551 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUSetup,
6552 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUSetup,
6553 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUSetup,
6554 IDirect3DDeviceImpl_7_CreateStateBlock_FPUSetup,
6555 IDirect3DDeviceImpl_7_Load_FPUSetup,
6556 IDirect3DDeviceImpl_7_LightEnable_FPUSetup,
6557 IDirect3DDeviceImpl_7_GetLightEnable_FPUSetup,
6558 IDirect3DDeviceImpl_7_SetClipPlane_FPUSetup,
6559 IDirect3DDeviceImpl_7_GetClipPlane_FPUSetup,
6560 IDirect3DDeviceImpl_7_GetInfo
6563 static const struct IDirect3DDevice7Vtbl d3d_device7_fpu_preserve_vtbl =
6565 /*** IUnknown Methods ***/
6566 IDirect3DDeviceImpl_7_QueryInterface,
6567 IDirect3DDeviceImpl_7_AddRef,
6568 IDirect3DDeviceImpl_7_Release,
6569 /*** IDirect3DDevice7 ***/
6570 IDirect3DDeviceImpl_7_GetCaps_FPUPreserve,
6571 IDirect3DDeviceImpl_7_EnumTextureFormats_FPUPreserve,
6572 IDirect3DDeviceImpl_7_BeginScene_FPUPreserve,
6573 IDirect3DDeviceImpl_7_EndScene_FPUPreserve,
6574 IDirect3DDeviceImpl_7_GetDirect3D,
6575 IDirect3DDeviceImpl_7_SetRenderTarget_FPUPreserve,
6576 IDirect3DDeviceImpl_7_GetRenderTarget,
6577 IDirect3DDeviceImpl_7_Clear_FPUPreserve,
6578 IDirect3DDeviceImpl_7_SetTransform_FPUPreserve,
6579 IDirect3DDeviceImpl_7_GetTransform_FPUPreserve,
6580 IDirect3DDeviceImpl_7_SetViewport_FPUPreserve,
6581 IDirect3DDeviceImpl_7_MultiplyTransform_FPUPreserve,
6582 IDirect3DDeviceImpl_7_GetViewport_FPUPreserve,
6583 IDirect3DDeviceImpl_7_SetMaterial_FPUPreserve,
6584 IDirect3DDeviceImpl_7_GetMaterial_FPUPreserve,
6585 IDirect3DDeviceImpl_7_SetLight_FPUPreserve,
6586 IDirect3DDeviceImpl_7_GetLight_FPUPreserve,
6587 IDirect3DDeviceImpl_7_SetRenderState_FPUPreserve,
6588 IDirect3DDeviceImpl_7_GetRenderState_FPUPreserve,
6589 IDirect3DDeviceImpl_7_BeginStateBlock_FPUPreserve,
6590 IDirect3DDeviceImpl_7_EndStateBlock_FPUPreserve,
6591 IDirect3DDeviceImpl_7_PreLoad_FPUPreserve,
6592 IDirect3DDeviceImpl_7_DrawPrimitive_FPUPreserve,
6593 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUPreserve,
6594 IDirect3DDeviceImpl_7_SetClipStatus,
6595 IDirect3DDeviceImpl_7_GetClipStatus,
6596 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUPreserve,
6597 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUPreserve,
6598 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUPreserve,
6599 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUPreserve,
6600 IDirect3DDeviceImpl_7_ComputeSphereVisibility,
6601 IDirect3DDeviceImpl_7_GetTexture_FPUPreserve,
6602 IDirect3DDeviceImpl_7_SetTexture_FPUPreserve,
6603 IDirect3DDeviceImpl_7_GetTextureStageState_FPUPreserve,
6604 IDirect3DDeviceImpl_7_SetTextureStageState_FPUPreserve,
6605 IDirect3DDeviceImpl_7_ValidateDevice_FPUPreserve,
6606 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUPreserve,
6607 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUPreserve,
6608 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUPreserve,
6609 IDirect3DDeviceImpl_7_CreateStateBlock_FPUPreserve,
6610 IDirect3DDeviceImpl_7_Load_FPUPreserve,
6611 IDirect3DDeviceImpl_7_LightEnable_FPUPreserve,
6612 IDirect3DDeviceImpl_7_GetLightEnable_FPUPreserve,
6613 IDirect3DDeviceImpl_7_SetClipPlane_FPUPreserve,
6614 IDirect3DDeviceImpl_7_GetClipPlane_FPUPreserve,
6615 IDirect3DDeviceImpl_7_GetInfo
6618 static const struct IDirect3DDevice3Vtbl d3d_device3_vtbl =
6620 /*** IUnknown Methods ***/
6621 IDirect3DDeviceImpl_3_QueryInterface,
6622 IDirect3DDeviceImpl_3_AddRef,
6623 IDirect3DDeviceImpl_3_Release,
6624 /*** IDirect3DDevice3 ***/
6625 IDirect3DDeviceImpl_3_GetCaps,
6626 IDirect3DDeviceImpl_3_GetStats,
6627 IDirect3DDeviceImpl_3_AddViewport,
6628 IDirect3DDeviceImpl_3_DeleteViewport,
6629 IDirect3DDeviceImpl_3_NextViewport,
6630 IDirect3DDeviceImpl_3_EnumTextureFormats,
6631 IDirect3DDeviceImpl_3_BeginScene,
6632 IDirect3DDeviceImpl_3_EndScene,
6633 IDirect3DDeviceImpl_3_GetDirect3D,
6634 IDirect3DDeviceImpl_3_SetCurrentViewport,
6635 IDirect3DDeviceImpl_3_GetCurrentViewport,
6636 IDirect3DDeviceImpl_3_SetRenderTarget,
6637 IDirect3DDeviceImpl_3_GetRenderTarget,
6638 IDirect3DDeviceImpl_3_Begin,
6639 IDirect3DDeviceImpl_3_BeginIndexed,
6640 IDirect3DDeviceImpl_3_Vertex,
6641 IDirect3DDeviceImpl_3_Index,
6642 IDirect3DDeviceImpl_3_End,
6643 IDirect3DDeviceImpl_3_GetRenderState,
6644 IDirect3DDeviceImpl_3_SetRenderState,
6645 IDirect3DDeviceImpl_3_GetLightState,
6646 IDirect3DDeviceImpl_3_SetLightState,
6647 IDirect3DDeviceImpl_3_SetTransform,
6648 IDirect3DDeviceImpl_3_GetTransform,
6649 IDirect3DDeviceImpl_3_MultiplyTransform,
6650 IDirect3DDeviceImpl_3_DrawPrimitive,
6651 IDirect3DDeviceImpl_3_DrawIndexedPrimitive,
6652 IDirect3DDeviceImpl_3_SetClipStatus,
6653 IDirect3DDeviceImpl_3_GetClipStatus,
6654 IDirect3DDeviceImpl_3_DrawPrimitiveStrided,
6655 IDirect3DDeviceImpl_3_DrawIndexedPrimitiveStrided,
6656 IDirect3DDeviceImpl_3_DrawPrimitiveVB,
6657 IDirect3DDeviceImpl_3_DrawIndexedPrimitiveVB,
6658 IDirect3DDeviceImpl_3_ComputeSphereVisibility,
6659 IDirect3DDeviceImpl_3_GetTexture,
6660 IDirect3DDeviceImpl_3_SetTexture,
6661 IDirect3DDeviceImpl_3_GetTextureStageState,
6662 IDirect3DDeviceImpl_3_SetTextureStageState,
6663 IDirect3DDeviceImpl_3_ValidateDevice
6666 static const struct IDirect3DDevice2Vtbl d3d_device2_vtbl =
6668 /*** IUnknown Methods ***/
6669 IDirect3DDeviceImpl_2_QueryInterface,
6670 IDirect3DDeviceImpl_2_AddRef,
6671 IDirect3DDeviceImpl_2_Release,
6672 /*** IDirect3DDevice2 ***/
6673 IDirect3DDeviceImpl_2_GetCaps,
6674 IDirect3DDeviceImpl_2_SwapTextureHandles,
6675 IDirect3DDeviceImpl_2_GetStats,
6676 IDirect3DDeviceImpl_2_AddViewport,
6677 IDirect3DDeviceImpl_2_DeleteViewport,
6678 IDirect3DDeviceImpl_2_NextViewport,
6679 IDirect3DDeviceImpl_2_EnumTextureFormats,
6680 IDirect3DDeviceImpl_2_BeginScene,
6681 IDirect3DDeviceImpl_2_EndScene,
6682 IDirect3DDeviceImpl_2_GetDirect3D,
6683 IDirect3DDeviceImpl_2_SetCurrentViewport,
6684 IDirect3DDeviceImpl_2_GetCurrentViewport,
6685 IDirect3DDeviceImpl_2_SetRenderTarget,
6686 IDirect3DDeviceImpl_2_GetRenderTarget,
6687 IDirect3DDeviceImpl_2_Begin,
6688 IDirect3DDeviceImpl_2_BeginIndexed,
6689 IDirect3DDeviceImpl_2_Vertex,
6690 IDirect3DDeviceImpl_2_Index,
6691 IDirect3DDeviceImpl_2_End,
6692 IDirect3DDeviceImpl_2_GetRenderState,
6693 IDirect3DDeviceImpl_2_SetRenderState,
6694 IDirect3DDeviceImpl_2_GetLightState,
6695 IDirect3DDeviceImpl_2_SetLightState,
6696 IDirect3DDeviceImpl_2_SetTransform,
6697 IDirect3DDeviceImpl_2_GetTransform,
6698 IDirect3DDeviceImpl_2_MultiplyTransform,
6699 IDirect3DDeviceImpl_2_DrawPrimitive,
6700 IDirect3DDeviceImpl_2_DrawIndexedPrimitive,
6701 IDirect3DDeviceImpl_2_SetClipStatus,
6702 IDirect3DDeviceImpl_2_GetClipStatus
6705 static const struct IDirect3DDeviceVtbl d3d_device1_vtbl =
6707 /*** IUnknown Methods ***/
6708 IDirect3DDeviceImpl_1_QueryInterface,
6709 IDirect3DDeviceImpl_1_AddRef,
6710 IDirect3DDeviceImpl_1_Release,
6711 /*** IDirect3DDevice1 ***/
6712 IDirect3DDeviceImpl_1_Initialize,
6713 IDirect3DDeviceImpl_1_GetCaps,
6714 IDirect3DDeviceImpl_1_SwapTextureHandles,
6715 IDirect3DDeviceImpl_1_CreateExecuteBuffer,
6716 IDirect3DDeviceImpl_1_GetStats,
6717 IDirect3DDeviceImpl_1_Execute,
6718 IDirect3DDeviceImpl_1_AddViewport,
6719 IDirect3DDeviceImpl_1_DeleteViewport,
6720 IDirect3DDeviceImpl_1_NextViewport,
6721 IDirect3DDeviceImpl_1_Pick,
6722 IDirect3DDeviceImpl_1_GetPickRecords,
6723 IDirect3DDeviceImpl_1_EnumTextureFormats,
6724 IDirect3DDeviceImpl_1_CreateMatrix,
6725 IDirect3DDeviceImpl_1_SetMatrix,
6726 IDirect3DDeviceImpl_1_GetMatrix,
6727 IDirect3DDeviceImpl_1_DeleteMatrix,
6728 IDirect3DDeviceImpl_1_BeginScene,
6729 IDirect3DDeviceImpl_1_EndScene,
6730 IDirect3DDeviceImpl_1_GetDirect3D
6733 /*****************************************************************************
6734 * IDirect3DDeviceImpl_UpdateDepthStencil
6736 * Checks the current render target for attached depth stencils and sets the
6737 * WineD3D depth stencil accordingly.
6740 * The depth stencil state to set if creating the device
6742 *****************************************************************************/
6744 IDirect3DDeviceImpl_UpdateDepthStencil(IDirect3DDeviceImpl *This)
6746 IDirectDrawSurface7 *depthStencil = NULL;
6747 IDirectDrawSurfaceImpl *dsi;
6748 static DDSCAPS2 depthcaps = { DDSCAPS_ZBUFFER, 0, 0, 0 };
6750 IDirectDrawSurface7_GetAttachedSurface(&This->target->IDirectDrawSurface7_iface, &depthcaps, &depthStencil);
6753 TRACE("Setting wined3d depth stencil to NULL\n");
6754 wined3d_device_set_depth_stencil(This->wined3d_device, NULL);
6755 return WINED3DZB_FALSE;
6758 dsi = impl_from_IDirectDrawSurface7(depthStencil);
6759 TRACE("Setting wined3d depth stencil to %p (wined3d %p)\n", dsi, dsi->wined3d_surface);
6760 wined3d_device_set_depth_stencil(This->wined3d_device, dsi->wined3d_surface);
6762 IDirectDrawSurface7_Release(depthStencil);
6763 return WINED3DZB_TRUE;
6766 HRESULT d3d_device_init(IDirect3DDeviceImpl *device, IDirectDrawImpl *ddraw, IDirectDrawSurfaceImpl *target)
6770 if (ddraw->cooperative_level & DDSCL_FPUPRESERVE)
6771 device->lpVtbl = &d3d_device7_fpu_preserve_vtbl;
6773 device->lpVtbl = &d3d_device7_fpu_setup_vtbl;
6775 device->IDirect3DDevice3_vtbl = &d3d_device3_vtbl;
6776 device->IDirect3DDevice2_vtbl = &d3d_device2_vtbl;
6777 device->IDirect3DDevice_vtbl = &d3d_device1_vtbl;
6779 device->ddraw = ddraw;
6780 device->target = target;
6781 list_init(&device->viewport_list);
6783 if (!ddraw_handle_table_init(&device->handle_table, 64))
6785 ERR("Failed to initialize handle table.\n");
6786 return DDERR_OUTOFMEMORY;
6789 device->legacyTextureBlending = FALSE;
6791 /* Create an index buffer, it's needed for indexed drawing */
6792 hr = wined3d_buffer_create_ib(ddraw->wined3d_device, 0x40000 /* Length. Don't know how long it should be */,
6793 WINED3DUSAGE_DYNAMIC /* Usage */, WINED3DPOOL_DEFAULT, NULL,
6794 &ddraw_null_wined3d_parent_ops, &device->indexbuffer);
6797 ERR("Failed to create an index buffer, hr %#x.\n", hr);
6798 ddraw_handle_table_destroy(&device->handle_table);
6802 /* This is for convenience. */
6803 device->wined3d_device = ddraw->wined3d_device;
6804 wined3d_device_incref(ddraw->wined3d_device);
6806 /* Render to the back buffer */
6807 hr = wined3d_device_set_render_target(ddraw->wined3d_device, 0, target->wined3d_surface, TRUE);
6810 ERR("Failed to set render target, hr %#x.\n", hr);
6811 wined3d_buffer_decref(device->indexbuffer);
6812 ddraw_handle_table_destroy(&device->handle_table);
6816 /* FIXME: This is broken. The target AddRef() makes some sense, because
6817 * we store a pointer during initialization, but then that's also where
6818 * the AddRef() should be. We don't store ddraw->d3d_target anywhere. */
6819 /* AddRef the render target. Also AddRef the render target from ddraw,
6820 * because if it is released before the app releases the D3D device, the
6821 * D3D capabilities of wined3d will be uninitialized, which has bad effects.
6823 * In most cases, those surfaces are the same anyway, but this will simply
6824 * add another ref which is released when the device is destroyed. */
6825 IDirectDrawSurface7_AddRef(&target->IDirectDrawSurface7_iface);
6826 IDirectDrawSurface7_AddRef(&ddraw->d3d_target->IDirectDrawSurface7_iface);
6828 ddraw->d3ddevice = device;
6830 wined3d_device_set_render_state(ddraw->wined3d_device, WINED3DRS_ZENABLE,
6831 IDirect3DDeviceImpl_UpdateDepthStencil(device));