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 const float zbias_factor = -0.000005f;
2267 IDirect3DDeviceImpl_7_GetRenderState(IDirect3DDevice7 *iface,
2268 D3DRENDERSTATETYPE RenderStateType,
2271 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
2274 TRACE("iface %p, state %#x, value %p.\n", iface, RenderStateType, Value);
2277 return DDERR_INVALIDPARAMS;
2279 EnterCriticalSection(&ddraw_cs);
2280 switch(RenderStateType)
2282 case D3DRENDERSTATE_TEXTUREMAG:
2284 WINED3DTEXTUREFILTERTYPE tex_mag;
2286 hr = wined3d_device_get_sampler_state(This->wined3d_device, 0, WINED3DSAMP_MAGFILTER, &tex_mag);
2290 case WINED3DTEXF_POINT:
2291 *Value = D3DFILTER_NEAREST;
2293 case WINED3DTEXF_LINEAR:
2294 *Value = D3DFILTER_LINEAR;
2297 ERR("Unhandled texture mag %d !\n",tex_mag);
2303 case D3DRENDERSTATE_TEXTUREMIN:
2305 WINED3DTEXTUREFILTERTYPE tex_min;
2306 WINED3DTEXTUREFILTERTYPE tex_mip;
2308 hr = wined3d_device_get_sampler_state(This->wined3d_device,
2309 0, WINED3DSAMP_MINFILTER, &tex_min);
2312 LeaveCriticalSection(&ddraw_cs);
2315 hr = wined3d_device_get_sampler_state(This->wined3d_device,
2316 0, WINED3DSAMP_MIPFILTER, &tex_mip);
2320 case WINED3DTEXF_POINT:
2323 case WINED3DTEXF_NONE:
2324 *Value = D3DFILTER_NEAREST;
2326 case WINED3DTEXF_POINT:
2327 *Value = D3DFILTER_MIPNEAREST;
2329 case WINED3DTEXF_LINEAR:
2330 *Value = D3DFILTER_LINEARMIPNEAREST;
2333 ERR("Unhandled mip filter %#x.\n", tex_mip);
2334 *Value = D3DFILTER_NEAREST;
2338 case WINED3DTEXF_LINEAR:
2341 case WINED3DTEXF_NONE:
2342 *Value = D3DFILTER_LINEAR;
2344 case WINED3DTEXF_POINT:
2345 *Value = D3DFILTER_MIPLINEAR;
2347 case WINED3DTEXF_LINEAR:
2348 *Value = D3DFILTER_LINEARMIPLINEAR;
2351 ERR("Unhandled mip filter %#x.\n", tex_mip);
2352 *Value = D3DFILTER_LINEAR;
2357 ERR("Unhandled texture min filter %#x.\n",tex_min);
2358 *Value = D3DFILTER_NEAREST;
2364 case D3DRENDERSTATE_TEXTUREADDRESS:
2365 case D3DRENDERSTATE_TEXTUREADDRESSU:
2366 hr = wined3d_device_get_sampler_state(This->wined3d_device,
2367 0, WINED3DSAMP_ADDRESSU, Value);
2369 case D3DRENDERSTATE_TEXTUREADDRESSV:
2370 hr = wined3d_device_get_sampler_state(This->wined3d_device,
2371 0, WINED3DSAMP_ADDRESSV, Value);
2374 case D3DRENDERSTATE_BORDERCOLOR:
2375 FIXME("Unhandled render state D3DRENDERSTATE_BORDERCOLOR.\n");
2379 case D3DRENDERSTATE_TEXTUREHANDLE:
2380 case D3DRENDERSTATE_TEXTUREMAPBLEND:
2381 WARN("Render state %#x is invalid in d3d7.\n", RenderStateType);
2382 hr = DDERR_INVALIDPARAMS;
2385 case D3DRENDERSTATE_ZBIAS:
2393 hr = wined3d_device_get_render_state(This->wined3d_device, WINED3DRS_DEPTHBIAS, &wined3d_value.d);
2395 *Value = wined3d_value.f / zbias_factor;
2400 if (RenderStateType >= D3DRENDERSTATE_STIPPLEPATTERN00
2401 && RenderStateType <= D3DRENDERSTATE_STIPPLEPATTERN31)
2403 FIXME("Unhandled stipple pattern render state (%#x).\n",
2408 hr = wined3d_device_get_render_state(This->wined3d_device, RenderStateType, Value);
2410 LeaveCriticalSection(&ddraw_cs);
2414 static HRESULT WINAPI
2415 IDirect3DDeviceImpl_7_GetRenderState_FPUSetup(IDirect3DDevice7 *iface,
2416 D3DRENDERSTATETYPE RenderStateType,
2419 return IDirect3DDeviceImpl_7_GetRenderState(iface, RenderStateType, Value);
2422 static HRESULT WINAPI
2423 IDirect3DDeviceImpl_7_GetRenderState_FPUPreserve(IDirect3DDevice7 *iface,
2424 D3DRENDERSTATETYPE RenderStateType,
2430 old_fpucw = d3d_fpu_setup();
2431 hr = IDirect3DDeviceImpl_7_GetRenderState(iface, RenderStateType, Value);
2432 set_fpu_control_word(old_fpucw);
2437 static HRESULT WINAPI
2438 IDirect3DDeviceImpl_3_GetRenderState(IDirect3DDevice3 *iface,
2439 D3DRENDERSTATETYPE dwRenderStateType,
2440 DWORD *lpdwRenderState)
2442 IDirect3DDeviceImpl *This = device_from_device3(iface);
2445 TRACE("iface %p, state %#x, value %p.\n", iface, dwRenderStateType, lpdwRenderState);
2447 switch(dwRenderStateType)
2449 case D3DRENDERSTATE_TEXTUREHANDLE:
2451 /* This state is wrapped to SetTexture in SetRenderState, so
2452 * it has to be wrapped to GetTexture here. */
2453 struct wined3d_texture *tex = NULL;
2454 *lpdwRenderState = 0;
2456 EnterCriticalSection(&ddraw_cs);
2458 hr = wined3d_device_get_texture(This->wined3d_device, 0, &tex);
2459 if (SUCCEEDED(hr) && tex)
2461 /* The parent of the texture is the IDirectDrawSurface7
2462 * interface of the ddraw surface. */
2463 IDirectDrawSurfaceImpl *parent = wined3d_texture_get_parent(tex);
2464 if (parent) *lpdwRenderState = parent->Handle;
2465 wined3d_texture_decref(tex);
2468 LeaveCriticalSection(&ddraw_cs);
2473 case D3DRENDERSTATE_TEXTUREMAPBLEND:
2475 /* D3DRENDERSTATE_TEXTUREMAPBLEND is mapped to texture state stages in SetRenderState; reverse
2476 the mapping to get the value. */
2477 DWORD colorop, colorarg1, colorarg2;
2478 DWORD alphaop, alphaarg1, alphaarg2;
2480 EnterCriticalSection(&ddraw_cs);
2482 This->legacyTextureBlending = TRUE;
2484 wined3d_device_get_texture_stage_state(This->wined3d_device, 0, WINED3DTSS_COLOROP, &colorop);
2485 wined3d_device_get_texture_stage_state(This->wined3d_device, 0, WINED3DTSS_COLORARG1, &colorarg1);
2486 wined3d_device_get_texture_stage_state(This->wined3d_device, 0, WINED3DTSS_COLORARG2, &colorarg2);
2487 wined3d_device_get_texture_stage_state(This->wined3d_device, 0, WINED3DTSS_ALPHAOP, &alphaop);
2488 wined3d_device_get_texture_stage_state(This->wined3d_device, 0, WINED3DTSS_ALPHAARG1, &alphaarg1);
2489 wined3d_device_get_texture_stage_state(This->wined3d_device, 0, WINED3DTSS_ALPHAARG2, &alphaarg2);
2491 if (colorop == WINED3DTOP_SELECTARG1 && colorarg1 == WINED3DTA_TEXTURE &&
2492 alphaop == WINED3DTOP_SELECTARG1 && alphaarg1 == WINED3DTA_TEXTURE)
2494 *lpdwRenderState = D3DTBLEND_DECAL;
2496 else if (colorop == WINED3DTOP_SELECTARG1 && colorarg1 == WINED3DTA_TEXTURE &&
2497 alphaop == WINED3DTOP_MODULATE && alphaarg1 == WINED3DTA_TEXTURE && alphaarg2 == WINED3DTA_CURRENT)
2499 *lpdwRenderState = D3DTBLEND_DECALALPHA;
2501 else if (colorop == WINED3DTOP_MODULATE && colorarg1 == WINED3DTA_TEXTURE && colorarg2 == WINED3DTA_CURRENT &&
2502 alphaop == WINED3DTOP_MODULATE && alphaarg1 == WINED3DTA_TEXTURE && alphaarg2 == WINED3DTA_CURRENT)
2504 *lpdwRenderState = D3DTBLEND_MODULATEALPHA;
2508 struct wined3d_texture *tex = NULL;
2510 BOOL tex_alpha = FALSE;
2511 DDPIXELFORMAT ddfmt;
2513 hr = wined3d_device_get_texture(This->wined3d_device, 0, &tex);
2515 if(hr == WINED3D_OK && tex)
2517 struct wined3d_resource *sub_resource;
2519 if ((sub_resource = wined3d_texture_get_sub_resource(tex, 0)))
2521 struct wined3d_resource_desc desc;
2523 wined3d_resource_get_desc(sub_resource, &desc);
2524 ddfmt.dwSize = sizeof(ddfmt);
2525 PixelFormat_WineD3DtoDD(&ddfmt, desc.format);
2526 if (ddfmt.u5.dwRGBAlphaBitMask) tex_alpha = TRUE;
2529 wined3d_texture_decref(tex);
2532 if (!(colorop == WINED3DTOP_MODULATE && colorarg1 == WINED3DTA_TEXTURE && colorarg2 == WINED3DTA_CURRENT &&
2533 alphaop == (tex_alpha ? WINED3DTOP_SELECTARG1 : WINED3DTOP_SELECTARG2) &&
2534 alphaarg1 == WINED3DTA_TEXTURE && alphaarg2 == WINED3DTA_CURRENT))
2536 ERR("Unexpected texture stage state setup, returning D3DTBLEND_MODULATE - likely erroneous\n");
2539 *lpdwRenderState = D3DTBLEND_MODULATE;
2542 LeaveCriticalSection(&ddraw_cs);
2548 return IDirect3DDevice7_GetRenderState((IDirect3DDevice7 *)This, dwRenderStateType, lpdwRenderState);
2552 static HRESULT WINAPI IDirect3DDeviceImpl_2_GetRenderState(IDirect3DDevice2 *iface,
2553 D3DRENDERSTATETYPE dwRenderStateType, DWORD *lpdwRenderState)
2555 IDirect3DDeviceImpl *This = device_from_device2(iface);
2557 TRACE("iface %p, state %#x, value %p.\n", iface, dwRenderStateType, lpdwRenderState);
2559 return IDirect3DDevice3_GetRenderState((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl,
2560 dwRenderStateType, lpdwRenderState);
2563 /*****************************************************************************
2564 * IDirect3DDevice7::SetRenderState
2566 * Sets a render state. The possible render states are defined in
2567 * include/d3dtypes.h
2569 * Version 2, 3 and 7
2572 * RenderStateType: State to set
2573 * Value: Value to assign to that state
2576 * D3D_OK on success,
2577 * for details see IWineD3DDevice::SetRenderState
2579 *****************************************************************************/
2581 IDirect3DDeviceImpl_7_SetRenderState(IDirect3DDevice7 *iface,
2582 D3DRENDERSTATETYPE RenderStateType,
2585 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
2588 TRACE("iface %p, state %#x, value %#x.\n", iface, RenderStateType, Value);
2590 EnterCriticalSection(&ddraw_cs);
2591 /* Some render states need special care */
2592 switch(RenderStateType)
2595 * The ddraw texture filter mapping works like this:
2596 * D3DFILTER_NEAREST Point min/mag, no mip
2597 * D3DFILTER_MIPNEAREST Point min/mag, point mip
2598 * D3DFILTER_LINEARMIPNEAREST: Point min/mag, linear mip
2600 * D3DFILTER_LINEAR Linear min/mag, no mip
2601 * D3DFILTER_MIPLINEAR Linear min/mag, point mip
2602 * D3DFILTER_LINEARMIPLINEAR Linear min/mag, linear mip
2604 * This is the opposite of the GL naming convention,
2605 * D3DFILTER_LINEARMIPNEAREST corresponds to GL_NEAREST_MIPMAP_LINEAR.
2607 case D3DRENDERSTATE_TEXTUREMAG:
2609 WINED3DTEXTUREFILTERTYPE tex_mag;
2613 case D3DFILTER_NEAREST:
2614 case D3DFILTER_MIPNEAREST:
2615 case D3DFILTER_LINEARMIPNEAREST:
2616 tex_mag = WINED3DTEXF_POINT;
2618 case D3DFILTER_LINEAR:
2619 case D3DFILTER_MIPLINEAR:
2620 case D3DFILTER_LINEARMIPLINEAR:
2621 tex_mag = WINED3DTEXF_LINEAR;
2624 tex_mag = WINED3DTEXF_POINT;
2625 ERR("Unhandled texture mag %d !\n",Value);
2629 hr = wined3d_device_set_sampler_state(This->wined3d_device, 0, WINED3DSAMP_MAGFILTER, tex_mag);
2633 case D3DRENDERSTATE_TEXTUREMIN:
2635 WINED3DTEXTUREFILTERTYPE tex_min;
2636 WINED3DTEXTUREFILTERTYPE tex_mip;
2638 switch ((D3DTEXTUREFILTER) Value)
2640 case D3DFILTER_NEAREST:
2641 tex_min = WINED3DTEXF_POINT;
2642 tex_mip = WINED3DTEXF_NONE;
2644 case D3DFILTER_LINEAR:
2645 tex_min = WINED3DTEXF_LINEAR;
2646 tex_mip = WINED3DTEXF_NONE;
2648 case D3DFILTER_MIPNEAREST:
2649 tex_min = WINED3DTEXF_POINT;
2650 tex_mip = WINED3DTEXF_POINT;
2652 case D3DFILTER_MIPLINEAR:
2653 tex_min = WINED3DTEXF_LINEAR;
2654 tex_mip = WINED3DTEXF_POINT;
2656 case D3DFILTER_LINEARMIPNEAREST:
2657 tex_min = WINED3DTEXF_POINT;
2658 tex_mip = WINED3DTEXF_LINEAR;
2660 case D3DFILTER_LINEARMIPLINEAR:
2661 tex_min = WINED3DTEXF_LINEAR;
2662 tex_mip = WINED3DTEXF_LINEAR;
2666 ERR("Unhandled texture min %d !\n",Value);
2667 tex_min = WINED3DTEXF_POINT;
2668 tex_mip = WINED3DTEXF_NONE;
2672 wined3d_device_set_sampler_state(This->wined3d_device,
2673 0, WINED3DSAMP_MIPFILTER, tex_mip);
2674 hr = wined3d_device_set_sampler_state(This->wined3d_device,
2675 0, WINED3DSAMP_MINFILTER, tex_min);
2679 case D3DRENDERSTATE_TEXTUREADDRESS:
2680 wined3d_device_set_sampler_state(This->wined3d_device,
2681 0, WINED3DSAMP_ADDRESSV, Value);
2683 case D3DRENDERSTATE_TEXTUREADDRESSU:
2684 hr = wined3d_device_set_sampler_state(This->wined3d_device,
2685 0, WINED3DSAMP_ADDRESSU, Value);
2687 case D3DRENDERSTATE_TEXTUREADDRESSV:
2688 hr = wined3d_device_set_sampler_state(This->wined3d_device,
2689 0, WINED3DSAMP_ADDRESSV, Value);
2692 case D3DRENDERSTATE_BORDERCOLOR:
2693 /* This should probably just forward to the corresponding sampler
2694 * state. Needs tests. */
2695 FIXME("Unhandled render state D3DRENDERSTATE_BORDERCOLOR.\n");
2699 case D3DRENDERSTATE_TEXTUREHANDLE:
2700 case D3DRENDERSTATE_TEXTUREMAPBLEND:
2701 WARN("Render state %#x is invalid in d3d7.\n", RenderStateType);
2702 hr = DDERR_INVALIDPARAMS;
2705 case D3DRENDERSTATE_ZBIAS:
2712 wined3d_value.f = Value * zbias_factor;
2713 hr = wined3d_device_set_render_state(This->wined3d_device, WINED3DRS_DEPTHBIAS, wined3d_value.d);
2718 if (RenderStateType >= D3DRENDERSTATE_STIPPLEPATTERN00
2719 && RenderStateType <= D3DRENDERSTATE_STIPPLEPATTERN31)
2721 FIXME("Unhandled stipple pattern render state (%#x).\n",
2727 hr = wined3d_device_set_render_state(This->wined3d_device, RenderStateType, Value);
2730 LeaveCriticalSection(&ddraw_cs);
2734 static HRESULT WINAPI
2735 IDirect3DDeviceImpl_7_SetRenderState_FPUSetup(IDirect3DDevice7 *iface,
2736 D3DRENDERSTATETYPE RenderStateType,
2739 return IDirect3DDeviceImpl_7_SetRenderState(iface, RenderStateType, Value);
2742 static HRESULT WINAPI
2743 IDirect3DDeviceImpl_7_SetRenderState_FPUPreserve(IDirect3DDevice7 *iface,
2744 D3DRENDERSTATETYPE RenderStateType,
2750 old_fpucw = d3d_fpu_setup();
2751 hr = IDirect3DDeviceImpl_7_SetRenderState(iface, RenderStateType, Value);
2752 set_fpu_control_word(old_fpucw);
2757 static HRESULT WINAPI
2758 IDirect3DDeviceImpl_3_SetRenderState(IDirect3DDevice3 *iface,
2759 D3DRENDERSTATETYPE RenderStateType,
2762 /* Note about D3DRENDERSTATE_TEXTUREMAPBLEND implementation: most of values
2763 for this state can be directly mapped to texture stage colorop and alphaop, but
2764 D3DTBLEND_MODULATE is tricky: it uses alpha from texture when available and alpha
2765 from diffuse otherwise. So changing the texture must be monitored in SetTexture to modify
2766 alphaarg when needed.
2768 Aliens vs Predator 1 depends on accurate D3DTBLEND_MODULATE emulation
2770 Legacy texture blending (TEXTUREMAPBLEND) and texture stage states: directx6 docs state that
2771 TEXTUREMAPBLEND is deprecated, yet can still be used. Games must not use both or results
2772 are undefined. D3DTBLEND_MODULATE mode in particular is dependent on texture pixel format and
2773 requires fixup of stage 0 texture states when texture changes, but this fixup can interfere
2774 with games not using this deprecated state. So a flag 'legacyTextureBlending' has to be kept
2775 in device - TRUE if the app is using TEXTUREMAPBLEND.
2777 Tests show that setting TEXTUREMAPBLEND on native doesn't seem to change values returned by
2778 GetTextureStageState and vice versa. Not so on Wine, but it is 'undefined' anyway so, probably, ok,
2779 unless some broken game will be found that cares. */
2782 IDirect3DDeviceImpl *This = device_from_device3(iface);
2784 TRACE("iface %p, state %#x, value %#x.\n", iface, RenderStateType, Value);
2786 EnterCriticalSection(&ddraw_cs);
2788 switch(RenderStateType)
2790 case D3DRENDERSTATE_TEXTUREHANDLE:
2792 IDirectDrawSurfaceImpl *surf;
2796 hr = wined3d_device_set_texture(This->wined3d_device, 0, NULL);
2800 surf = ddraw_get_object(&This->handle_table, Value - 1, DDRAW_HANDLE_SURFACE);
2803 WARN("Invalid texture handle.\n");
2804 hr = DDERR_INVALIDPARAMS;
2808 hr = IDirect3DDevice3_SetTexture(iface, 0, (IDirect3DTexture2 *)&surf->IDirect3DTexture2_vtbl);
2812 case D3DRENDERSTATE_TEXTUREMAPBLEND:
2814 This->legacyTextureBlending = TRUE;
2816 switch ( (D3DTEXTUREBLEND) Value)
2818 case D3DTBLEND_MODULATE:
2820 struct wined3d_texture *tex = NULL;
2821 BOOL tex_alpha = FALSE;
2822 DDPIXELFORMAT ddfmt;
2824 hr = wined3d_device_get_texture(This->wined3d_device, 0, &tex);
2826 if(hr == WINED3D_OK && tex)
2828 struct wined3d_resource *sub_resource;
2830 if ((sub_resource = wined3d_texture_get_sub_resource(tex, 0)))
2832 struct wined3d_resource_desc desc;
2834 wined3d_resource_get_desc(sub_resource, &desc);
2835 ddfmt.dwSize = sizeof(ddfmt);
2836 PixelFormat_WineD3DtoDD(&ddfmt, desc.format);
2837 if (ddfmt.u5.dwRGBAlphaBitMask) tex_alpha = TRUE;
2840 wined3d_texture_decref(tex);
2844 wined3d_device_set_texture_stage_state(This->wined3d_device,
2845 0, WINED3DTSS_ALPHAOP, WINED3DTOP_SELECTARG1);
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_ALPHAARG1, WINED3DTA_TEXTURE);
2851 wined3d_device_set_texture_stage_state(This->wined3d_device,
2852 0, WINED3DTSS_ALPHAARG2, WINED3DTA_CURRENT);
2853 wined3d_device_set_texture_stage_state(This->wined3d_device,
2854 0, WINED3DTSS_COLORARG1, WINED3DTA_TEXTURE);
2855 wined3d_device_set_texture_stage_state(This->wined3d_device,
2856 0, WINED3DTSS_COLORARG2, WINED3DTA_CURRENT);
2857 wined3d_device_set_texture_stage_state(This->wined3d_device,
2858 0, WINED3DTSS_COLOROP, WINED3DTOP_MODULATE);
2863 wined3d_device_set_texture_stage_state(This->wined3d_device,
2864 0, WINED3DTSS_COLOROP, WINED3DTOP_ADD);
2865 wined3d_device_set_texture_stage_state(This->wined3d_device,
2866 0, WINED3DTSS_COLORARG1, WINED3DTA_TEXTURE);
2867 wined3d_device_set_texture_stage_state(This->wined3d_device,
2868 0, WINED3DTSS_COLORARG2, WINED3DTA_CURRENT);
2869 wined3d_device_set_texture_stage_state(This->wined3d_device,
2870 0, WINED3DTSS_ALPHAOP, WINED3DTOP_SELECTARG2);
2871 wined3d_device_set_texture_stage_state(This->wined3d_device,
2872 0, WINED3DTSS_ALPHAARG2, WINED3DTA_CURRENT);
2875 case D3DTBLEND_MODULATEALPHA:
2876 wined3d_device_set_texture_stage_state(This->wined3d_device,
2877 0, WINED3DTSS_COLORARG1, WINED3DTA_TEXTURE);
2878 wined3d_device_set_texture_stage_state(This->wined3d_device,
2879 0, WINED3DTSS_ALPHAARG1, WINED3DTA_TEXTURE);
2880 wined3d_device_set_texture_stage_state(This->wined3d_device,
2881 0, WINED3DTSS_COLORARG2, WINED3DTA_CURRENT);
2882 wined3d_device_set_texture_stage_state(This->wined3d_device,
2883 0, WINED3DTSS_ALPHAARG2, WINED3DTA_CURRENT);
2884 wined3d_device_set_texture_stage_state(This->wined3d_device,
2885 0, WINED3DTSS_COLOROP, WINED3DTOP_MODULATE);
2886 wined3d_device_set_texture_stage_state(This->wined3d_device,
2887 0, WINED3DTSS_ALPHAOP, WINED3DTOP_MODULATE);
2890 case D3DTBLEND_COPY:
2891 case D3DTBLEND_DECAL:
2892 wined3d_device_set_texture_stage_state(This->wined3d_device,
2893 0, WINED3DTSS_COLORARG1, WINED3DTA_TEXTURE);
2894 wined3d_device_set_texture_stage_state(This->wined3d_device,
2895 0, WINED3DTSS_ALPHAARG1, WINED3DTA_TEXTURE);
2896 wined3d_device_set_texture_stage_state(This->wined3d_device,
2897 0, WINED3DTSS_COLOROP, WINED3DTOP_SELECTARG1);
2898 wined3d_device_set_texture_stage_state(This->wined3d_device,
2899 0, WINED3DTSS_ALPHAOP, WINED3DTOP_SELECTARG1);
2902 case D3DTBLEND_DECALALPHA:
2903 wined3d_device_set_texture_stage_state(This->wined3d_device,
2904 0, WINED3DTSS_COLOROP, WINED3DTOP_BLENDTEXTUREALPHA);
2905 wined3d_device_set_texture_stage_state(This->wined3d_device,
2906 0, WINED3DTSS_COLORARG1, WINED3DTA_TEXTURE);
2907 wined3d_device_set_texture_stage_state(This->wined3d_device,
2908 0, WINED3DTSS_COLORARG2, WINED3DTA_CURRENT);
2909 wined3d_device_set_texture_stage_state(This->wined3d_device,
2910 0, WINED3DTSS_ALPHAOP, WINED3DTOP_SELECTARG2);
2911 wined3d_device_set_texture_stage_state(This->wined3d_device,
2912 0, WINED3DTSS_ALPHAARG2, WINED3DTA_CURRENT);
2916 ERR("Unhandled texture environment %d !\n",Value);
2924 hr = IDirect3DDevice7_SetRenderState((IDirect3DDevice7 *)This, RenderStateType, Value);
2928 LeaveCriticalSection(&ddraw_cs);
2933 static HRESULT WINAPI IDirect3DDeviceImpl_2_SetRenderState(IDirect3DDevice2 *iface,
2934 D3DRENDERSTATETYPE RenderStateType, DWORD Value)
2936 IDirect3DDeviceImpl *This = device_from_device2(iface);
2938 TRACE("iface %p, state %#x, value %#x.\n", iface, RenderStateType, Value);
2940 return IDirect3DDevice3_SetRenderState((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl, RenderStateType, Value);
2943 /*****************************************************************************
2944 * Direct3DDevice3::SetLightState
2946 * Sets a light state for Direct3DDevice3 and Direct3DDevice2. The
2947 * light states are forwarded to Direct3DDevice7 render states
2952 * LightStateType: The light state to change
2953 * Value: The value to assign to that light state
2957 * DDERR_INVALIDPARAMS if the parameters were incorrect
2958 * Also check IDirect3DDevice7::SetRenderState
2960 *****************************************************************************/
2961 static HRESULT WINAPI
2962 IDirect3DDeviceImpl_3_SetLightState(IDirect3DDevice3 *iface,
2963 D3DLIGHTSTATETYPE LightStateType,
2966 IDirect3DDeviceImpl *This = device_from_device3(iface);
2969 TRACE("iface %p, state %#x, value %#x.\n", iface, LightStateType, Value);
2971 if (!LightStateType || (LightStateType > D3DLIGHTSTATE_COLORVERTEX))
2973 TRACE("Unexpected Light State Type\n");
2974 return DDERR_INVALIDPARAMS;
2977 EnterCriticalSection(&ddraw_cs);
2978 if (LightStateType == D3DLIGHTSTATE_MATERIAL /* 1 */)
2980 IDirect3DMaterialImpl *m = ddraw_get_object(&This->handle_table, Value - 1, DDRAW_HANDLE_MATERIAL);
2983 WARN("Invalid material handle.\n");
2984 LeaveCriticalSection(&ddraw_cs);
2985 return DDERR_INVALIDPARAMS;
2988 TRACE(" activating material %p.\n", m);
2989 material_activate(m);
2991 This->material = Value;
2993 else if (LightStateType == D3DLIGHTSTATE_COLORMODEL /* 3 */)
2998 ERR("DDCOLOR_MONO should not happen!\n");
3001 /* We are already in this mode */
3002 TRACE("Setting color model to RGB (no-op).\n");
3005 ERR("Unknown color model!\n");
3006 LeaveCriticalSection(&ddraw_cs);
3007 return DDERR_INVALIDPARAMS;
3012 D3DRENDERSTATETYPE rs;
3013 switch (LightStateType)
3015 case D3DLIGHTSTATE_AMBIENT: /* 2 */
3016 rs = D3DRENDERSTATE_AMBIENT;
3018 case D3DLIGHTSTATE_FOGMODE: /* 4 */
3019 rs = D3DRENDERSTATE_FOGVERTEXMODE;
3021 case D3DLIGHTSTATE_FOGSTART: /* 5 */
3022 rs = D3DRENDERSTATE_FOGSTART;
3024 case D3DLIGHTSTATE_FOGEND: /* 6 */
3025 rs = D3DRENDERSTATE_FOGEND;
3027 case D3DLIGHTSTATE_FOGDENSITY: /* 7 */
3028 rs = D3DRENDERSTATE_FOGDENSITY;
3030 case D3DLIGHTSTATE_COLORVERTEX: /* 8 */
3031 rs = D3DRENDERSTATE_COLORVERTEX;
3034 ERR("Unknown D3DLIGHTSTATETYPE %d.\n", LightStateType);
3035 LeaveCriticalSection(&ddraw_cs);
3036 return DDERR_INVALIDPARAMS;
3039 hr = IDirect3DDevice7_SetRenderState((IDirect3DDevice7 *)This, rs, Value);
3040 LeaveCriticalSection(&ddraw_cs);
3044 LeaveCriticalSection(&ddraw_cs);
3048 static HRESULT WINAPI IDirect3DDeviceImpl_2_SetLightState(IDirect3DDevice2 *iface,
3049 D3DLIGHTSTATETYPE LightStateType, DWORD Value)
3051 IDirect3DDeviceImpl *This = device_from_device2(iface);
3053 TRACE("iface %p, state %#x, value %#x.\n", iface, LightStateType, Value);
3055 return IDirect3DDevice3_SetLightState((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl, LightStateType, Value);
3058 /*****************************************************************************
3059 * IDirect3DDevice3::GetLightState
3061 * Returns the current setting of a light state. The state is read from
3062 * the Direct3DDevice7 render state.
3067 * LightStateType: The light state to return
3068 * Value: The address to store the light state setting at
3072 * DDDERR_INVALIDPARAMS if the parameters were incorrect
3073 * Also see IDirect3DDevice7::GetRenderState
3075 *****************************************************************************/
3076 static HRESULT WINAPI
3077 IDirect3DDeviceImpl_3_GetLightState(IDirect3DDevice3 *iface,
3078 D3DLIGHTSTATETYPE LightStateType,
3081 IDirect3DDeviceImpl *This = device_from_device3(iface);
3084 TRACE("iface %p, state %#x, value %p.\n", iface, LightStateType, Value);
3086 if (!LightStateType || (LightStateType > D3DLIGHTSTATE_COLORVERTEX))
3088 TRACE("Unexpected Light State Type\n");
3089 return DDERR_INVALIDPARAMS;
3093 return DDERR_INVALIDPARAMS;
3095 EnterCriticalSection(&ddraw_cs);
3096 if (LightStateType == D3DLIGHTSTATE_MATERIAL /* 1 */)
3098 *Value = This->material;
3100 else if (LightStateType == D3DLIGHTSTATE_COLORMODEL /* 3 */)
3102 *Value = D3DCOLOR_RGB;
3106 D3DRENDERSTATETYPE rs;
3107 switch (LightStateType)
3109 case D3DLIGHTSTATE_AMBIENT: /* 2 */
3110 rs = D3DRENDERSTATE_AMBIENT;
3112 case D3DLIGHTSTATE_FOGMODE: /* 4 */
3113 rs = D3DRENDERSTATE_FOGVERTEXMODE;
3115 case D3DLIGHTSTATE_FOGSTART: /* 5 */
3116 rs = D3DRENDERSTATE_FOGSTART;
3118 case D3DLIGHTSTATE_FOGEND: /* 6 */
3119 rs = D3DRENDERSTATE_FOGEND;
3121 case D3DLIGHTSTATE_FOGDENSITY: /* 7 */
3122 rs = D3DRENDERSTATE_FOGDENSITY;
3124 case D3DLIGHTSTATE_COLORVERTEX: /* 8 */
3125 rs = D3DRENDERSTATE_COLORVERTEX;
3128 ERR("Unknown D3DLIGHTSTATETYPE %d.\n", LightStateType);
3129 LeaveCriticalSection(&ddraw_cs);
3130 return DDERR_INVALIDPARAMS;
3133 hr = IDirect3DDevice7_GetRenderState((IDirect3DDevice7 *)This, rs, Value);
3134 LeaveCriticalSection(&ddraw_cs);
3138 LeaveCriticalSection(&ddraw_cs);
3142 static HRESULT WINAPI IDirect3DDeviceImpl_2_GetLightState(IDirect3DDevice2 *iface,
3143 D3DLIGHTSTATETYPE LightStateType, DWORD *Value)
3145 IDirect3DDeviceImpl *This = device_from_device2(iface);
3147 TRACE("iface %p, state %#x, value %p.\n", iface, LightStateType, Value);
3149 return IDirect3DDevice3_GetLightState((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl, LightStateType, Value);
3152 /*****************************************************************************
3153 * IDirect3DDevice7::SetTransform
3155 * Assigns a D3DMATRIX to a transform type. The transform types are defined
3156 * in include/d3dtypes.h.
3157 * The D3DTRANSFORMSTATE_WORLD (=1) is translated to D3DTS_WORLDMATRIX(0)
3158 * (=255) for wined3d, because the 1 transform state was removed in d3d8
3159 * and WineD3D already understands the replacement D3DTS_WORLDMATRIX(0)
3161 * Version 2, 3 and 7
3164 * TransformStateType: transform state to set
3165 * Matrix: Matrix to assign to the state
3169 * DDERR_INVALIDPARAMS if Matrix == NULL
3170 * For details see IWineD3DDevice::SetTransform
3172 *****************************************************************************/
3174 IDirect3DDeviceImpl_7_SetTransform(IDirect3DDevice7 *iface,
3175 D3DTRANSFORMSTATETYPE TransformStateType,
3178 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
3179 D3DTRANSFORMSTATETYPE type;
3182 TRACE("iface %p, state %#x, matrix %p.\n", iface, TransformStateType, Matrix);
3184 switch(TransformStateType)
3186 case D3DTRANSFORMSTATE_WORLD : type = WINED3DTS_WORLDMATRIX(0); break;
3187 case D3DTRANSFORMSTATE_WORLD1: type = WINED3DTS_WORLDMATRIX(1); break;
3188 case D3DTRANSFORMSTATE_WORLD2: type = WINED3DTS_WORLDMATRIX(2); break;
3189 case D3DTRANSFORMSTATE_WORLD3: type = WINED3DTS_WORLDMATRIX(3); break;
3190 default: type = TransformStateType;
3194 return DDERR_INVALIDPARAMS;
3196 /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
3197 EnterCriticalSection(&ddraw_cs);
3198 hr = wined3d_device_set_transform(This->wined3d_device, type, (WINED3DMATRIX *)Matrix);
3199 LeaveCriticalSection(&ddraw_cs);
3203 static HRESULT WINAPI
3204 IDirect3DDeviceImpl_7_SetTransform_FPUSetup(IDirect3DDevice7 *iface,
3205 D3DTRANSFORMSTATETYPE TransformStateType,
3208 return IDirect3DDeviceImpl_7_SetTransform(iface, TransformStateType, Matrix);
3211 static HRESULT WINAPI
3212 IDirect3DDeviceImpl_7_SetTransform_FPUPreserve(IDirect3DDevice7 *iface,
3213 D3DTRANSFORMSTATETYPE TransformStateType,
3219 old_fpucw = d3d_fpu_setup();
3220 hr = IDirect3DDeviceImpl_7_SetTransform(iface, TransformStateType, Matrix);
3221 set_fpu_control_word(old_fpucw);
3226 static HRESULT WINAPI IDirect3DDeviceImpl_3_SetTransform(IDirect3DDevice3 *iface,
3227 D3DTRANSFORMSTATETYPE TransformStateType, D3DMATRIX *D3DMatrix)
3229 IDirect3DDeviceImpl *This = device_from_device3(iface);
3231 TRACE("iface %p, state %#x, matrix %p.\n", iface, TransformStateType, D3DMatrix);
3233 return IDirect3DDevice7_SetTransform((IDirect3DDevice7 *)This, TransformStateType, D3DMatrix);
3236 static HRESULT WINAPI IDirect3DDeviceImpl_2_SetTransform(IDirect3DDevice2 *iface,
3237 D3DTRANSFORMSTATETYPE TransformStateType, D3DMATRIX *D3DMatrix)
3239 IDirect3DDeviceImpl *This = device_from_device2(iface);
3241 TRACE("iface %p, state %#x, matrix %p.\n", iface, TransformStateType, D3DMatrix);
3243 return IDirect3DDevice7_SetTransform((IDirect3DDevice7 *)This, TransformStateType, D3DMatrix);
3246 /*****************************************************************************
3247 * IDirect3DDevice7::GetTransform
3249 * Returns the matrix assigned to a transform state
3250 * D3DTRANSFORMSTATE_WORLD is translated to D3DTS_WORLDMATRIX(0), see
3254 * TransformStateType: State to read the matrix from
3255 * Matrix: Address to store the matrix at
3259 * DDERR_INVALIDPARAMS if Matrix == NULL
3260 * For details, see IWineD3DDevice::GetTransform
3262 *****************************************************************************/
3264 IDirect3DDeviceImpl_7_GetTransform(IDirect3DDevice7 *iface,
3265 D3DTRANSFORMSTATETYPE TransformStateType,
3268 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
3269 D3DTRANSFORMSTATETYPE type;
3272 TRACE("iface %p, state %#x, matrix %p.\n", iface, TransformStateType, Matrix);
3274 switch(TransformStateType)
3276 case D3DTRANSFORMSTATE_WORLD : type = WINED3DTS_WORLDMATRIX(0); break;
3277 case D3DTRANSFORMSTATE_WORLD1: type = WINED3DTS_WORLDMATRIX(1); break;
3278 case D3DTRANSFORMSTATE_WORLD2: type = WINED3DTS_WORLDMATRIX(2); break;
3279 case D3DTRANSFORMSTATE_WORLD3: type = WINED3DTS_WORLDMATRIX(3); break;
3280 default: type = TransformStateType;
3284 return DDERR_INVALIDPARAMS;
3286 /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
3287 EnterCriticalSection(&ddraw_cs);
3288 hr = wined3d_device_get_transform(This->wined3d_device, type, (WINED3DMATRIX *)Matrix);
3289 LeaveCriticalSection(&ddraw_cs);
3293 static HRESULT WINAPI
3294 IDirect3DDeviceImpl_7_GetTransform_FPUSetup(IDirect3DDevice7 *iface,
3295 D3DTRANSFORMSTATETYPE TransformStateType,
3298 return IDirect3DDeviceImpl_7_GetTransform(iface, TransformStateType, Matrix);
3301 static HRESULT WINAPI
3302 IDirect3DDeviceImpl_7_GetTransform_FPUPreserve(IDirect3DDevice7 *iface,
3303 D3DTRANSFORMSTATETYPE TransformStateType,
3309 old_fpucw = d3d_fpu_setup();
3310 hr = IDirect3DDeviceImpl_7_GetTransform(iface, TransformStateType, Matrix);
3311 set_fpu_control_word(old_fpucw);
3316 static HRESULT WINAPI IDirect3DDeviceImpl_3_GetTransform(IDirect3DDevice3 *iface,
3317 D3DTRANSFORMSTATETYPE TransformStateType, D3DMATRIX *D3DMatrix)
3319 IDirect3DDeviceImpl *This = device_from_device3(iface);
3321 TRACE("iface %p, state %#x, matrix %p.\n", iface, TransformStateType, D3DMatrix);
3323 return IDirect3DDevice7_GetTransform((IDirect3DDevice7 *)This, TransformStateType, D3DMatrix);
3326 static HRESULT WINAPI IDirect3DDeviceImpl_2_GetTransform(IDirect3DDevice2 *iface,
3327 D3DTRANSFORMSTATETYPE TransformStateType, D3DMATRIX *D3DMatrix)
3329 IDirect3DDeviceImpl *This = device_from_device2(iface);
3331 TRACE("iface %p, state %#x, matrix %p.\n", iface, TransformStateType, D3DMatrix);
3333 return IDirect3DDevice7_GetTransform((IDirect3DDevice7 *)This, TransformStateType, D3DMatrix);
3336 /*****************************************************************************
3337 * IDirect3DDevice7::MultiplyTransform
3339 * Multiplies the already-set transform matrix of a transform state
3340 * with another matrix. For the world matrix, see SetTransform
3342 * Version 2, 3 and 7
3345 * TransformStateType: Transform state to multiply
3346 * D3DMatrix Matrix to multiply with.
3350 * DDERR_INVALIDPARAMS if D3DMatrix is NULL
3351 * For details, see IWineD3DDevice::MultiplyTransform
3353 *****************************************************************************/
3355 IDirect3DDeviceImpl_7_MultiplyTransform(IDirect3DDevice7 *iface,
3356 D3DTRANSFORMSTATETYPE TransformStateType,
3357 D3DMATRIX *D3DMatrix)
3359 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
3361 D3DTRANSFORMSTATETYPE type;
3363 TRACE("iface %p, state %#x, matrix %p.\n", iface, TransformStateType, D3DMatrix);
3365 switch(TransformStateType)
3367 case D3DTRANSFORMSTATE_WORLD : type = WINED3DTS_WORLDMATRIX(0); break;
3368 case D3DTRANSFORMSTATE_WORLD1: type = WINED3DTS_WORLDMATRIX(1); break;
3369 case D3DTRANSFORMSTATE_WORLD2: type = WINED3DTS_WORLDMATRIX(2); break;
3370 case D3DTRANSFORMSTATE_WORLD3: type = WINED3DTS_WORLDMATRIX(3); break;
3371 default: type = TransformStateType;
3374 /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
3375 EnterCriticalSection(&ddraw_cs);
3376 hr = wined3d_device_multiply_transform(This->wined3d_device,
3377 type, (WINED3DMATRIX *)D3DMatrix);
3378 LeaveCriticalSection(&ddraw_cs);
3382 static HRESULT WINAPI
3383 IDirect3DDeviceImpl_7_MultiplyTransform_FPUSetup(IDirect3DDevice7 *iface,
3384 D3DTRANSFORMSTATETYPE TransformStateType,
3385 D3DMATRIX *D3DMatrix)
3387 return IDirect3DDeviceImpl_7_MultiplyTransform(iface, TransformStateType, D3DMatrix);
3390 static HRESULT WINAPI
3391 IDirect3DDeviceImpl_7_MultiplyTransform_FPUPreserve(IDirect3DDevice7 *iface,
3392 D3DTRANSFORMSTATETYPE TransformStateType,
3393 D3DMATRIX *D3DMatrix)
3398 old_fpucw = d3d_fpu_setup();
3399 hr = IDirect3DDeviceImpl_7_MultiplyTransform(iface, TransformStateType, D3DMatrix);
3400 set_fpu_control_word(old_fpucw);
3405 static HRESULT WINAPI IDirect3DDeviceImpl_3_MultiplyTransform(IDirect3DDevice3 *iface,
3406 D3DTRANSFORMSTATETYPE TransformStateType, D3DMATRIX *D3DMatrix)
3408 IDirect3DDeviceImpl *This = device_from_device3(iface);
3410 TRACE("iface %p, state %#x, matrix %p.\n", iface, TransformStateType, D3DMatrix);
3412 return IDirect3DDevice7_MultiplyTransform((IDirect3DDevice7 *)This, TransformStateType, D3DMatrix);
3415 static HRESULT WINAPI IDirect3DDeviceImpl_2_MultiplyTransform(IDirect3DDevice2 *iface,
3416 D3DTRANSFORMSTATETYPE TransformStateType, D3DMATRIX *D3DMatrix)
3418 IDirect3DDeviceImpl *This = device_from_device2(iface);
3420 TRACE("iface %p, state %#x, matrix %p.\n", iface, TransformStateType, D3DMatrix);
3422 return IDirect3DDevice7_MultiplyTransform((IDirect3DDevice7 *)This, TransformStateType, D3DMatrix);
3425 /*****************************************************************************
3426 * IDirect3DDevice7::DrawPrimitive
3428 * Draws primitives based on vertices in an application-provided pointer
3430 * Version 2, 3 and 7. The IDirect3DDevice2 thunk converts the fixed vertex type into
3431 * an FVF format for D3D7
3434 * PrimitiveType: The type of the primitives to draw
3435 * Vertex type: Flexible vertex format vertex description
3436 * Vertices: Pointer to the vertex array
3437 * VertexCount: The number of vertices to draw
3438 * Flags: As usual a few flags
3442 * DDERR_INVALIDPARAMS if Vertices is NULL
3443 * For details, see IWineD3DDevice::DrawPrimitiveUP
3445 *****************************************************************************/
3447 IDirect3DDeviceImpl_7_DrawPrimitive(IDirect3DDevice7 *iface,
3448 D3DPRIMITIVETYPE PrimitiveType,
3454 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
3458 TRACE("iface %p, primitive_type %#x, FVF %#x, vertices %p, vertex_count %u, flags %#x.\n",
3459 iface, PrimitiveType, VertexType, Vertices, VertexCount, Flags);
3462 return DDERR_INVALIDPARAMS;
3464 /* Get the stride */
3465 stride = get_flexible_vertex_size(VertexType);
3468 EnterCriticalSection(&ddraw_cs);
3469 hr = wined3d_device_set_vertex_declaration(This->wined3d_device, ddraw_find_decl(This->ddraw, VertexType));
3472 LeaveCriticalSection(&ddraw_cs);
3476 /* This method translates to the user pointer draw of WineD3D */
3477 wined3d_device_set_primitive_type(This->wined3d_device, PrimitiveType);
3478 hr = wined3d_device_draw_primitive_up(This->wined3d_device, VertexCount, Vertices, stride);
3479 LeaveCriticalSection(&ddraw_cs);
3483 static HRESULT WINAPI
3484 IDirect3DDeviceImpl_7_DrawPrimitive_FPUSetup(IDirect3DDevice7 *iface,
3485 D3DPRIMITIVETYPE PrimitiveType,
3491 return IDirect3DDeviceImpl_7_DrawPrimitive(iface, PrimitiveType, VertexType, Vertices, VertexCount, Flags);
3494 static HRESULT WINAPI
3495 IDirect3DDeviceImpl_7_DrawPrimitive_FPUPreserve(IDirect3DDevice7 *iface,
3496 D3DPRIMITIVETYPE PrimitiveType,
3505 old_fpucw = d3d_fpu_setup();
3506 hr = IDirect3DDeviceImpl_7_DrawPrimitive(iface, PrimitiveType, VertexType, Vertices, VertexCount, Flags);
3507 set_fpu_control_word(old_fpucw);
3512 static HRESULT WINAPI IDirect3DDeviceImpl_3_DrawPrimitive(IDirect3DDevice3 *iface,
3513 D3DPRIMITIVETYPE PrimitiveType, DWORD VertexType, void *Vertices, DWORD VertexCount,
3516 TRACE("iface %p, primitive_type %#x, FVF %#x, vertices %p, vertex_count %u, flags %#x.\n",
3517 iface, PrimitiveType, VertexType, Vertices, VertexCount, Flags);
3519 return IDirect3DDevice7_DrawPrimitive((IDirect3DDevice7 *)device_from_device3(iface),
3520 PrimitiveType, VertexType, Vertices, VertexCount, Flags);
3523 static HRESULT WINAPI IDirect3DDeviceImpl_2_DrawPrimitive(IDirect3DDevice2 *iface,
3524 D3DPRIMITIVETYPE PrimitiveType, D3DVERTEXTYPE VertexType, void *Vertices,
3525 DWORD VertexCount, DWORD Flags)
3529 TRACE("iface %p, primitive_type %#x, vertex_type %#x, vertices %p, vertex_count %u, flags %#x.\n",
3530 iface, PrimitiveType, VertexType, Vertices, VertexCount, Flags);
3534 case D3DVT_VERTEX: FVF = D3DFVF_VERTEX; break;
3535 case D3DVT_LVERTEX: FVF = D3DFVF_LVERTEX; break;
3536 case D3DVT_TLVERTEX: FVF = D3DFVF_TLVERTEX; break;
3538 ERR("Unexpected vertex type %d\n", VertexType);
3539 return DDERR_INVALIDPARAMS; /* Should never happen */
3542 return IDirect3DDevice7_DrawPrimitive((IDirect3DDevice7 *)device_from_device2(iface),
3543 PrimitiveType, FVF, Vertices, VertexCount, Flags);
3546 /*****************************************************************************
3547 * IDirect3DDevice7::DrawIndexedPrimitive
3549 * Draws vertices from an application-provided pointer, based on the index
3550 * numbers in a WORD array.
3552 * Version 2, 3 and 7. The version 7 thunk translates the vertex type into
3553 * an FVF format for D3D7
3556 * PrimitiveType: The primitive type to draw
3557 * VertexType: The FVF vertex description
3558 * Vertices: Pointer to the vertex array
3560 * Indices: Pointer to the index array
3561 * IndexCount: Number of indices = Number of vertices to draw
3562 * Flags: As usual, some flags
3566 * DDERR_INVALIDPARAMS if Vertices or Indices is NULL
3567 * For details, see IWineD3DDevice::DrawIndexedPrimitiveUP
3569 *****************************************************************************/
3571 IDirect3DDeviceImpl_7_DrawIndexedPrimitive(IDirect3DDevice7 *iface,
3572 D3DPRIMITIVETYPE PrimitiveType,
3580 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
3583 TRACE("iface %p, primitive_type %#x, FVF %#x, vertices %p, vertex_count %u, indices %p, index_count %u, flags %#x.\n",
3584 iface, PrimitiveType, VertexType, Vertices, VertexCount, Indices, IndexCount, Flags);
3586 /* Set the D3DDevice's FVF */
3587 EnterCriticalSection(&ddraw_cs);
3588 hr = wined3d_device_set_vertex_declaration(This->wined3d_device, ddraw_find_decl(This->ddraw, VertexType));
3591 ERR(" (%p) Setting the FVF failed, hr = %x!\n", This, hr);
3592 LeaveCriticalSection(&ddraw_cs);
3596 wined3d_device_set_primitive_type(This->wined3d_device, PrimitiveType);
3597 hr = wined3d_device_draw_indexed_primitive_up(This->wined3d_device, IndexCount, Indices,
3598 WINED3DFMT_R16_UINT, Vertices, get_flexible_vertex_size(VertexType));
3599 LeaveCriticalSection(&ddraw_cs);
3603 static HRESULT WINAPI
3604 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUSetup(IDirect3DDevice7 *iface,
3605 D3DPRIMITIVETYPE PrimitiveType,
3613 return IDirect3DDeviceImpl_7_DrawIndexedPrimitive(iface, PrimitiveType, VertexType, Vertices, VertexCount, Indices, IndexCount, Flags);
3616 static HRESULT WINAPI
3617 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUPreserve(IDirect3DDevice7 *iface,
3618 D3DPRIMITIVETYPE PrimitiveType,
3629 old_fpucw = d3d_fpu_setup();
3630 hr = IDirect3DDeviceImpl_7_DrawIndexedPrimitive(iface, PrimitiveType, VertexType, Vertices, VertexCount, Indices, IndexCount, Flags);
3631 set_fpu_control_word(old_fpucw);
3636 static HRESULT WINAPI IDirect3DDeviceImpl_3_DrawIndexedPrimitive(IDirect3DDevice3 *iface,
3637 D3DPRIMITIVETYPE PrimitiveType, DWORD VertexType, void *Vertices, DWORD VertexCount,
3638 WORD *Indices, DWORD IndexCount, DWORD Flags)
3640 TRACE("iface %p, primitive_type %#x, FVF %#x, vertices %p, vertex_count %u, indices %p, index_count %u, flags %#x.\n",
3641 iface, PrimitiveType, VertexType, Vertices, VertexCount, Indices, IndexCount, Flags);
3643 return IDirect3DDevice7_DrawIndexedPrimitive((IDirect3DDevice7 *)device_from_device3(iface),
3644 PrimitiveType, VertexType, Vertices, VertexCount, Indices, IndexCount, Flags);
3647 static HRESULT WINAPI IDirect3DDeviceImpl_2_DrawIndexedPrimitive(IDirect3DDevice2 *iface,
3648 D3DPRIMITIVETYPE PrimitiveType, D3DVERTEXTYPE VertexType, void *Vertices,
3649 DWORD VertexCount, WORD *Indices, DWORD IndexCount, DWORD Flags)
3653 TRACE("iface %p, primitive_type %#x, vertex_type %#x, vertices %p, vertex_count %u, indices %p, index_count %u, flags %#x.\n",
3654 iface, PrimitiveType, VertexType, Vertices, VertexCount, Indices, IndexCount, Flags);
3658 case D3DVT_VERTEX: FVF = D3DFVF_VERTEX; break;
3659 case D3DVT_LVERTEX: FVF = D3DFVF_LVERTEX; break;
3660 case D3DVT_TLVERTEX: FVF = D3DFVF_TLVERTEX; break;
3662 ERR("Unexpected vertex type %d\n", VertexType);
3663 return DDERR_INVALIDPARAMS; /* Should never happen */
3666 return IDirect3DDevice7_DrawIndexedPrimitive((IDirect3DDevice7 *)device_from_device2(iface),
3667 PrimitiveType, FVF, Vertices, VertexCount, Indices, IndexCount, Flags);
3670 /*****************************************************************************
3671 * IDirect3DDevice7::SetClipStatus
3673 * Sets the clip status. This defines things as clipping conditions and
3674 * the extents of the clipping region.
3676 * Version 2, 3 and 7
3682 * D3D_OK because it's a stub
3683 * (DDERR_INVALIDPARAMS if ClipStatus == NULL)
3685 *****************************************************************************/
3686 static HRESULT WINAPI
3687 IDirect3DDeviceImpl_7_SetClipStatus(IDirect3DDevice7 *iface,
3688 D3DCLIPSTATUS *ClipStatus)
3690 FIXME("iface %p, clip_status %p stub!\n", iface, ClipStatus);
3692 /* D3DCLIPSTATUS and WINED3DCLIPSTATUS are different. I don't know how to convert them
3693 * Perhaps this needs a new data type and an additional IWineD3DDevice method
3695 /* return IWineD3DDevice_SetClipStatus(This->wineD3DDevice, ClipStatus);*/
3699 static HRESULT WINAPI IDirect3DDeviceImpl_3_SetClipStatus(IDirect3DDevice3 *iface,
3700 D3DCLIPSTATUS *ClipStatus)
3702 TRACE("iface %p, clip_status %p.\n", iface, ClipStatus);
3704 return IDirect3DDevice7_SetClipStatus((IDirect3DDevice7 *)device_from_device3(iface), ClipStatus);
3707 static HRESULT WINAPI IDirect3DDeviceImpl_2_SetClipStatus(IDirect3DDevice2 *iface,
3708 D3DCLIPSTATUS *ClipStatus)
3710 TRACE("iface %p, clip_status %p.\n", iface, ClipStatus);
3712 return IDirect3DDevice7_SetClipStatus((IDirect3DDevice7 *)device_from_device2(iface), ClipStatus);
3715 /*****************************************************************************
3716 * IDirect3DDevice7::GetClipStatus
3718 * Returns the clip status
3721 * ClipStatus: Address to write the clip status to
3724 * D3D_OK because it's a stub
3726 *****************************************************************************/
3727 static HRESULT WINAPI
3728 IDirect3DDeviceImpl_7_GetClipStatus(IDirect3DDevice7 *iface,
3729 D3DCLIPSTATUS *ClipStatus)
3731 FIXME("iface %p, clip_status %p stub!\n", iface, ClipStatus);
3733 /* D3DCLIPSTATUS and WINED3DCLIPSTATUS are different. I don't know how to convert them */
3734 /* return IWineD3DDevice_GetClipStatus(This->wineD3DDevice, ClipStatus);*/
3738 static HRESULT WINAPI IDirect3DDeviceImpl_3_GetClipStatus(IDirect3DDevice3 *iface,
3739 D3DCLIPSTATUS *ClipStatus)
3741 TRACE("iface %p, clip_status %p.\n", iface, ClipStatus);
3743 return IDirect3DDevice7_GetClipStatus((IDirect3DDevice7 *)device_from_device3(iface), ClipStatus);
3746 static HRESULT WINAPI IDirect3DDeviceImpl_2_GetClipStatus(IDirect3DDevice2 *iface,
3747 D3DCLIPSTATUS *ClipStatus)
3749 TRACE("iface %p, clip_status %p.\n", iface, ClipStatus);
3751 return IDirect3DDevice7_GetClipStatus((IDirect3DDevice7 *)device_from_device2(iface), ClipStatus);
3754 /*****************************************************************************
3755 * IDirect3DDevice::DrawPrimitiveStrided
3757 * Draws vertices described by a D3DDRAWPRIMITIVESTRIDEDDATA structure.
3762 * PrimitiveType: The primitive type to draw
3763 * VertexType: The FVF description of the vertices to draw (for the stride??)
3764 * D3DDrawPrimStrideData: A D3DDRAWPRIMITIVESTRIDEDDATA structure describing
3765 * the vertex data locations
3766 * VertexCount: The number of vertices to draw
3770 * D3D_OK, because it's a stub
3771 * (DDERR_INVALIDPARAMS if D3DDrawPrimStrideData is NULL)
3772 * (For details, see IWineD3DDevice::DrawPrimitiveStrided)
3774 *****************************************************************************/
3776 IDirect3DDeviceImpl_7_DrawPrimitiveStrided(IDirect3DDevice7 *iface,
3777 D3DPRIMITIVETYPE PrimitiveType,
3779 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
3783 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
3784 WineDirect3DVertexStridedData WineD3DStrided;
3788 TRACE("iface %p, primitive_type %#x, FVF %#x, strided_data %p, vertex_count %u, flags %#x.\n",
3789 iface, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Flags);
3791 memset(&WineD3DStrided, 0, sizeof(WineD3DStrided));
3792 /* Get the strided data right. the wined3d structure is a bit bigger
3793 * Watch out: The contents of the strided data are determined by the fvf,
3794 * not by the members set in D3DDrawPrimStrideData. So it's valid
3795 * to have diffuse.lpvData set to 0xdeadbeef if the diffuse flag is
3796 * not set in the fvf.
3798 if(VertexType & D3DFVF_POSITION_MASK)
3800 WineD3DStrided.position.format = WINED3DFMT_R32G32B32_FLOAT;
3801 WineD3DStrided.position.lpData = D3DDrawPrimStrideData->position.lpvData;
3802 WineD3DStrided.position.dwStride = D3DDrawPrimStrideData->position.dwStride;
3803 if (VertexType & D3DFVF_XYZRHW)
3805 WineD3DStrided.position.format = WINED3DFMT_R32G32B32A32_FLOAT;
3806 WineD3DStrided.position_transformed = TRUE;
3808 WineD3DStrided.position_transformed = FALSE;
3811 if(VertexType & D3DFVF_NORMAL)
3813 WineD3DStrided.normal.format = WINED3DFMT_R32G32B32_FLOAT;
3814 WineD3DStrided.normal.lpData = D3DDrawPrimStrideData->normal.lpvData;
3815 WineD3DStrided.normal.dwStride = D3DDrawPrimStrideData->normal.dwStride;
3818 if(VertexType & D3DFVF_DIFFUSE)
3820 WineD3DStrided.diffuse.format = WINED3DFMT_B8G8R8A8_UNORM;
3821 WineD3DStrided.diffuse.lpData = D3DDrawPrimStrideData->diffuse.lpvData;
3822 WineD3DStrided.diffuse.dwStride = D3DDrawPrimStrideData->diffuse.dwStride;
3825 if(VertexType & D3DFVF_SPECULAR)
3827 WineD3DStrided.specular.format = WINED3DFMT_B8G8R8A8_UNORM;
3828 WineD3DStrided.specular.lpData = D3DDrawPrimStrideData->specular.lpvData;
3829 WineD3DStrided.specular.dwStride = D3DDrawPrimStrideData->specular.dwStride;
3832 for( i = 0; i < GET_TEXCOUNT_FROM_FVF(VertexType); i++)
3834 switch(GET_TEXCOORD_SIZE_FROM_FVF(VertexType, i))
3836 case 1: WineD3DStrided.texCoords[i].format = WINED3DFMT_R32_FLOAT; break;
3837 case 2: WineD3DStrided.texCoords[i].format = WINED3DFMT_R32G32_FLOAT; break;
3838 case 3: WineD3DStrided.texCoords[i].format = WINED3DFMT_R32G32B32_FLOAT; break;
3839 case 4: WineD3DStrided.texCoords[i].format = WINED3DFMT_R32G32B32A32_FLOAT; break;
3840 default: ERR("Unexpected texture coordinate size %d\n",
3841 GET_TEXCOORD_SIZE_FROM_FVF(VertexType, i));
3843 WineD3DStrided.texCoords[i].lpData = D3DDrawPrimStrideData->textureCoords[i].lpvData;
3844 WineD3DStrided.texCoords[i].dwStride = D3DDrawPrimStrideData->textureCoords[i].dwStride;
3847 /* WineD3D doesn't need the FVF here */
3848 EnterCriticalSection(&ddraw_cs);
3849 wined3d_device_set_primitive_type(This->wined3d_device, PrimitiveType);
3850 hr = wined3d_device_draw_primitive_strided(This->wined3d_device, VertexCount, &WineD3DStrided);
3851 LeaveCriticalSection(&ddraw_cs);
3855 static HRESULT WINAPI
3856 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUSetup(IDirect3DDevice7 *iface,
3857 D3DPRIMITIVETYPE PrimitiveType,
3859 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
3863 return IDirect3DDeviceImpl_7_DrawPrimitiveStrided(iface, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Flags);
3866 static HRESULT WINAPI
3867 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUPreserve(IDirect3DDevice7 *iface,
3868 D3DPRIMITIVETYPE PrimitiveType,
3870 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
3877 old_fpucw = d3d_fpu_setup();
3878 hr = IDirect3DDeviceImpl_7_DrawPrimitiveStrided(iface, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Flags);
3879 set_fpu_control_word(old_fpucw);
3884 static HRESULT WINAPI IDirect3DDeviceImpl_3_DrawPrimitiveStrided(IDirect3DDevice3 *iface,
3885 D3DPRIMITIVETYPE PrimitiveType, DWORD VertexType,
3886 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData, DWORD VertexCount, DWORD Flags)
3888 TRACE("iface %p, primitive_type %#x, FVF %#x, strided_data %p, vertex_count %u, flags %#x.\n",
3889 iface, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Flags);
3891 return IDirect3DDevice7_DrawPrimitiveStrided((IDirect3DDevice7 *)device_from_device3(iface),
3892 PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Flags);
3895 /*****************************************************************************
3896 * IDirect3DDevice7::DrawIndexedPrimitiveStrided
3898 * Draws primitives specified by strided data locations based on indices
3906 * D3D_OK, because it's a stub
3907 * (DDERR_INVALIDPARAMS if D3DDrawPrimStrideData is NULL)
3908 * (DDERR_INVALIDPARAMS if Indices is NULL)
3909 * (For more details, see IWineD3DDevice::DrawIndexedPrimitiveStrided)
3911 *****************************************************************************/
3913 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided(IDirect3DDevice7 *iface,
3914 D3DPRIMITIVETYPE PrimitiveType,
3916 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
3922 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
3923 WineDirect3DVertexStridedData WineD3DStrided;
3927 TRACE("iface %p, primitive_type %#x, FVF %#x, strided_data %p, vertex_count %u, indices %p, index_count %u, flags %#x.\n",
3928 iface, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Indices, IndexCount, Flags);
3930 memset(&WineD3DStrided, 0, sizeof(WineD3DStrided));
3931 /* Get the strided data right. the wined3d structure is a bit bigger
3932 * Watch out: The contents of the strided data are determined by the fvf,
3933 * not by the members set in D3DDrawPrimStrideData. So it's valid
3934 * to have diffuse.lpvData set to 0xdeadbeef if the diffuse flag is
3935 * not set in the fvf.
3937 if(VertexType & D3DFVF_POSITION_MASK)
3939 WineD3DStrided.position.format = WINED3DFMT_R32G32B32_FLOAT;
3940 WineD3DStrided.position.lpData = D3DDrawPrimStrideData->position.lpvData;
3941 WineD3DStrided.position.dwStride = D3DDrawPrimStrideData->position.dwStride;
3942 if (VertexType & D3DFVF_XYZRHW)
3944 WineD3DStrided.position.format = WINED3DFMT_R32G32B32A32_FLOAT;
3945 WineD3DStrided.position_transformed = TRUE;
3947 WineD3DStrided.position_transformed = FALSE;
3950 if(VertexType & D3DFVF_NORMAL)
3952 WineD3DStrided.normal.format = WINED3DFMT_R32G32B32_FLOAT;
3953 WineD3DStrided.normal.lpData = D3DDrawPrimStrideData->normal.lpvData;
3954 WineD3DStrided.normal.dwStride = D3DDrawPrimStrideData->normal.dwStride;
3957 if(VertexType & D3DFVF_DIFFUSE)
3959 WineD3DStrided.diffuse.format = WINED3DFMT_B8G8R8A8_UNORM;
3960 WineD3DStrided.diffuse.lpData = D3DDrawPrimStrideData->diffuse.lpvData;
3961 WineD3DStrided.diffuse.dwStride = D3DDrawPrimStrideData->diffuse.dwStride;
3964 if(VertexType & D3DFVF_SPECULAR)
3966 WineD3DStrided.specular.format = WINED3DFMT_B8G8R8A8_UNORM;
3967 WineD3DStrided.specular.lpData = D3DDrawPrimStrideData->specular.lpvData;
3968 WineD3DStrided.specular.dwStride = D3DDrawPrimStrideData->specular.dwStride;
3971 for( i = 0; i < GET_TEXCOUNT_FROM_FVF(VertexType); i++)
3973 switch(GET_TEXCOORD_SIZE_FROM_FVF(VertexType, i))
3975 case 1: WineD3DStrided.texCoords[i].format = WINED3DFMT_R32_FLOAT; break;
3976 case 2: WineD3DStrided.texCoords[i].format = WINED3DFMT_R32G32_FLOAT; break;
3977 case 3: WineD3DStrided.texCoords[i].format = WINED3DFMT_R32G32B32_FLOAT; break;
3978 case 4: WineD3DStrided.texCoords[i].format = WINED3DFMT_R32G32B32A32_FLOAT; break;
3979 default: ERR("Unexpected texture coordinate size %d\n",
3980 GET_TEXCOORD_SIZE_FROM_FVF(VertexType, i));
3982 WineD3DStrided.texCoords[i].lpData = D3DDrawPrimStrideData->textureCoords[i].lpvData;
3983 WineD3DStrided.texCoords[i].dwStride = D3DDrawPrimStrideData->textureCoords[i].dwStride;
3986 /* WineD3D doesn't need the FVF here */
3987 EnterCriticalSection(&ddraw_cs);
3988 wined3d_device_set_primitive_type(This->wined3d_device, PrimitiveType);
3989 hr = wined3d_device_draw_indexed_primitive_strided(This->wined3d_device,
3990 IndexCount, &WineD3DStrided, VertexCount, Indices, WINED3DFMT_R16_UINT);
3991 LeaveCriticalSection(&ddraw_cs);
3995 static HRESULT WINAPI
3996 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUSetup(IDirect3DDevice7 *iface,
3997 D3DPRIMITIVETYPE PrimitiveType,
3999 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
4005 return IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided(iface, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Indices, IndexCount, Flags);
4008 static HRESULT WINAPI
4009 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUPreserve(IDirect3DDevice7 *iface,
4010 D3DPRIMITIVETYPE PrimitiveType,
4012 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
4021 old_fpucw = d3d_fpu_setup();
4022 hr = IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided(iface, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Indices, IndexCount, Flags);
4023 set_fpu_control_word(old_fpucw);
4028 static HRESULT WINAPI IDirect3DDeviceImpl_3_DrawIndexedPrimitiveStrided(IDirect3DDevice3 *iface,
4029 D3DPRIMITIVETYPE PrimitiveType, DWORD VertexType,
4030 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData, DWORD VertexCount, WORD *Indices,
4031 DWORD IndexCount, DWORD Flags)
4033 TRACE("iface %p, primitive_type %#x, FVF %#x, strided_data %p, vertex_count %u, indices %p, index_count %u, flags %#x.\n",
4034 iface, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Indices, IndexCount, Flags);
4036 return IDirect3DDevice7_DrawIndexedPrimitiveStrided((IDirect3DDevice7 *)device_from_device3(iface),
4037 PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Indices, IndexCount, Flags);
4040 /*****************************************************************************
4041 * IDirect3DDevice7::DrawPrimitiveVB
4043 * Draws primitives from a vertex buffer to the screen.
4048 * PrimitiveType: Type of primitive to be rendered.
4049 * D3DVertexBuf: Source Vertex Buffer
4050 * StartVertex: Index of the first vertex from the buffer to be rendered
4051 * NumVertices: Number of vertices to be rendered
4052 * Flags: Can be D3DDP_WAIT to wait until rendering has finished
4056 * DDERR_INVALIDPARAMS if D3DVertexBuf is NULL
4058 *****************************************************************************/
4060 IDirect3DDeviceImpl_7_DrawPrimitiveVB(IDirect3DDevice7 *iface,
4061 D3DPRIMITIVETYPE PrimitiveType,
4062 IDirect3DVertexBuffer7 *D3DVertexBuf,
4067 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
4068 IDirect3DVertexBufferImpl *vb = unsafe_impl_from_IDirect3DVertexBuffer7(D3DVertexBuf);
4072 TRACE("iface %p, primitive_type %#x, vb %p, start_vertex %u, vertex_count %u, flags %#x.\n",
4073 iface, PrimitiveType, D3DVertexBuf, StartVertex, NumVertices, Flags);
4078 ERR("(%p) No Vertex buffer specified\n", This);
4079 return DDERR_INVALIDPARAMS;
4081 stride = get_flexible_vertex_size(vb->fvf);
4083 EnterCriticalSection(&ddraw_cs);
4084 hr = wined3d_device_set_vertex_declaration(This->wined3d_device, vb->wineD3DVertexDeclaration);
4087 ERR(" (%p) Setting the FVF failed, hr = %x!\n", This, hr);
4088 LeaveCriticalSection(&ddraw_cs);
4092 /* Set the vertex stream source */
4093 hr = wined3d_device_set_stream_source(This->wined3d_device, 0, vb->wineD3DVertexBuffer, 0, stride);
4096 ERR("(%p) IDirect3DDevice::SetStreamSource failed with hr = %08x\n", This, hr);
4097 LeaveCriticalSection(&ddraw_cs);
4101 /* Now draw the primitives */
4102 wined3d_device_set_primitive_type(This->wined3d_device, PrimitiveType);
4103 hr = wined3d_device_draw_primitive(This->wined3d_device, StartVertex, NumVertices);
4104 LeaveCriticalSection(&ddraw_cs);
4108 static HRESULT WINAPI
4109 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUSetup(IDirect3DDevice7 *iface,
4110 D3DPRIMITIVETYPE PrimitiveType,
4111 IDirect3DVertexBuffer7 *D3DVertexBuf,
4116 return IDirect3DDeviceImpl_7_DrawPrimitiveVB(iface, PrimitiveType, D3DVertexBuf, StartVertex, NumVertices, Flags);
4119 static HRESULT WINAPI
4120 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUPreserve(IDirect3DDevice7 *iface,
4121 D3DPRIMITIVETYPE PrimitiveType,
4122 IDirect3DVertexBuffer7 *D3DVertexBuf,
4130 old_fpucw = d3d_fpu_setup();
4131 hr = IDirect3DDeviceImpl_7_DrawPrimitiveVB(iface, PrimitiveType, D3DVertexBuf, StartVertex, NumVertices, Flags);
4132 set_fpu_control_word(old_fpucw);
4137 static HRESULT WINAPI IDirect3DDeviceImpl_3_DrawPrimitiveVB(IDirect3DDevice3 *iface,
4138 D3DPRIMITIVETYPE PrimitiveType, IDirect3DVertexBuffer *D3DVertexBuf, DWORD StartVertex,
4139 DWORD NumVertices, DWORD Flags)
4141 IDirect3DVertexBufferImpl *vb = unsafe_impl_from_IDirect3DVertexBuffer(D3DVertexBuf);
4143 TRACE("iface %p, primitive_type %#x, vb %p, start_vertex %u, vertex_count %u, flags %#x.\n",
4144 iface, PrimitiveType, D3DVertexBuf, StartVertex, NumVertices, Flags);
4146 return IDirect3DDevice7_DrawPrimitiveVB((IDirect3DDevice7 *)device_from_device3(iface),
4147 PrimitiveType, &vb->IDirect3DVertexBuffer7_iface, StartVertex, NumVertices, Flags);
4151 /*****************************************************************************
4152 * IDirect3DDevice7::DrawIndexedPrimitiveVB
4154 * Draws primitives from a vertex buffer to the screen
4157 * PrimitiveType: Type of primitive to be rendered.
4158 * D3DVertexBuf: Source Vertex Buffer
4159 * StartVertex: Index of the first vertex from the buffer to be rendered
4160 * NumVertices: Number of vertices to be rendered
4161 * Indices: Array of DWORDs used to index into the Vertices
4162 * IndexCount: Number of indices in Indices
4163 * Flags: Can be D3DDP_WAIT to wait until rendering has finished
4167 *****************************************************************************/
4169 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB(IDirect3DDevice7 *iface,
4170 D3DPRIMITIVETYPE PrimitiveType,
4171 IDirect3DVertexBuffer7 *D3DVertexBuf,
4178 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
4179 IDirect3DVertexBufferImpl *vb = unsafe_impl_from_IDirect3DVertexBuffer7(D3DVertexBuf);
4180 DWORD stride = get_flexible_vertex_size(vb->fvf);
4181 struct wined3d_resource *wined3d_resource;
4182 struct wined3d_resource_desc desc;
4183 WORD *LockedIndices;
4186 TRACE("iface %p, primitive_type %#x, vb %p, start_vertex %u, vertex_count %u, indices %p, index_count %u, flags %#x.\n",
4187 iface, PrimitiveType, D3DVertexBuf, StartVertex, NumVertices, Indices, IndexCount, Flags);
4190 * 1) Upload the Indices to the index buffer
4191 * 2) Set the index source
4192 * 3) Set the Vertex Buffer as the Stream source
4193 * 4) Call IWineD3DDevice::DrawIndexedPrimitive
4196 EnterCriticalSection(&ddraw_cs);
4198 hr = wined3d_device_set_vertex_declaration(This->wined3d_device, vb->wineD3DVertexDeclaration);
4201 ERR(" (%p) Setting the FVF failed, hr = %x!\n", This, hr);
4202 LeaveCriticalSection(&ddraw_cs);
4206 /* check that the buffer is large enough to hold the indices,
4207 * reallocate if necessary. */
4208 wined3d_resource = wined3d_buffer_get_resource(This->indexbuffer);
4209 wined3d_resource_get_desc(wined3d_resource, &desc);
4210 if (desc.size < IndexCount * sizeof(WORD))
4212 UINT size = max(desc.size * 2, IndexCount * sizeof(WORD));
4213 struct wined3d_buffer *buffer;
4215 TRACE("Growing index buffer to %u bytes\n", size);
4217 hr = wined3d_buffer_create_ib(This->wined3d_device, size, WINED3DUSAGE_DYNAMIC /* Usage */,
4218 WINED3DPOOL_DEFAULT, NULL, &ddraw_null_wined3d_parent_ops, &buffer);
4221 ERR("(%p) IWineD3DDevice::CreateIndexBuffer failed with hr = %08x\n", This, hr);
4222 LeaveCriticalSection(&ddraw_cs);
4226 wined3d_buffer_decref(This->indexbuffer);
4227 This->indexbuffer = buffer;
4230 /* Copy the index stream into the index buffer. A new IWineD3DDevice
4231 * method could be created which takes an user pointer containing the
4232 * indices or a SetData-Method for the index buffer, which overrides the
4233 * index buffer data with our pointer. */
4234 hr = wined3d_buffer_map(This->indexbuffer, 0, IndexCount * sizeof(WORD),
4235 (BYTE **)&LockedIndices, 0);
4238 ERR("Failed to map buffer, hr %#x.\n", hr);
4239 LeaveCriticalSection(&ddraw_cs);
4242 memcpy(LockedIndices, Indices, IndexCount * sizeof(WORD));
4243 wined3d_buffer_unmap(This->indexbuffer);
4245 /* Set the index stream */
4246 wined3d_device_set_base_vertex_index(This->wined3d_device, StartVertex);
4247 hr = wined3d_device_set_index_buffer(This->wined3d_device, This->indexbuffer, WINED3DFMT_R16_UINT);
4249 /* Set the vertex stream source */
4250 hr = wined3d_device_set_stream_source(This->wined3d_device, 0, vb->wineD3DVertexBuffer, 0, stride);
4253 ERR("(%p) IDirect3DDevice::SetStreamSource failed with hr = %08x\n", This, hr);
4254 LeaveCriticalSection(&ddraw_cs);
4259 wined3d_device_set_primitive_type(This->wined3d_device, PrimitiveType);
4260 hr = wined3d_device_draw_indexed_primitive(This->wined3d_device, 0, IndexCount);
4262 LeaveCriticalSection(&ddraw_cs);
4266 static HRESULT WINAPI
4267 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUSetup(IDirect3DDevice7 *iface,
4268 D3DPRIMITIVETYPE PrimitiveType,
4269 IDirect3DVertexBuffer7 *D3DVertexBuf,
4276 return IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB(iface, PrimitiveType, D3DVertexBuf, StartVertex, NumVertices, Indices, IndexCount, Flags);
4279 static HRESULT WINAPI
4280 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUPreserve(IDirect3DDevice7 *iface,
4281 D3DPRIMITIVETYPE PrimitiveType,
4282 IDirect3DVertexBuffer7 *D3DVertexBuf,
4292 old_fpucw = d3d_fpu_setup();
4293 hr = IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB(iface, PrimitiveType, D3DVertexBuf, StartVertex, NumVertices, Indices, IndexCount, Flags);
4294 set_fpu_control_word(old_fpucw);
4299 static HRESULT WINAPI IDirect3DDeviceImpl_3_DrawIndexedPrimitiveVB(IDirect3DDevice3 *iface,
4300 D3DPRIMITIVETYPE PrimitiveType, IDirect3DVertexBuffer *D3DVertexBuf, WORD *Indices,
4301 DWORD IndexCount, DWORD Flags)
4303 IDirect3DVertexBufferImpl *vb = unsafe_impl_from_IDirect3DVertexBuffer(D3DVertexBuf);
4305 TRACE("iface %p, primitive_type %#x, vb %p, indices %p, index_count %u, flags %#x.\n",
4306 iface, PrimitiveType, D3DVertexBuf, Indices, IndexCount, Flags);
4308 return IDirect3DDevice7_DrawIndexedPrimitiveVB((IDirect3DDevice7 *)device_from_device3(iface),
4309 PrimitiveType, &vb->IDirect3DVertexBuffer7_iface, 0, IndexCount, Indices, IndexCount,
4313 /*****************************************************************************
4314 * IDirect3DDevice7::ComputeSphereVisibility
4316 * Calculates the visibility of spheres in the current viewport. The spheres
4317 * are passed in the Centers and Radii arrays, the results are passed back
4318 * in the ReturnValues array. Return values are either completely visible,
4319 * partially visible or completely invisible.
4320 * The return value consist of a combination of D3DCLIP_* flags, or it's
4321 * 0 if the sphere is completely visible(according to the SDK, not checked)
4326 * Centers: Array containing the sphere centers
4327 * Radii: Array containing the sphere radii
4328 * NumSpheres: The number of centers and radii in the arrays
4330 * ReturnValues: Array to write the results to
4334 * (DDERR_INVALIDPARAMS if Centers, Radii or ReturnValues are NULL)
4335 * (D3DERR_INVALIDMATRIX if the combined world, view and proj matrix
4338 *****************************************************************************/
4340 static DWORD in_plane(UINT plane, D3DVECTOR normal, D3DVALUE origin_plane, D3DVECTOR center, D3DVALUE radius)
4342 float distance, norm;
4344 norm = sqrt( normal.u1.x * normal.u1.x + normal.u2.y * normal.u2.y + normal.u3.z * normal.u3.z );
4345 distance = ( origin_plane + normal.u1.x * center.u1.x + normal.u2.y * center.u2.y + normal.u3.z * center.u3.z ) / norm;
4347 if ( fabs( distance ) < radius ) return D3DSTATUS_CLIPUNIONLEFT << plane;
4348 if ( distance < -radius ) return (D3DSTATUS_CLIPUNIONLEFT | D3DSTATUS_CLIPINTERSECTIONLEFT) << plane;
4352 static HRESULT WINAPI
4353 IDirect3DDeviceImpl_7_ComputeSphereVisibility(IDirect3DDevice7 *iface,
4358 DWORD *ReturnValues)
4361 D3DVALUE origin_plane[6];
4366 TRACE("iface %p, centers %p, radii %p, sphere_count %u, flags %#x, return_values %p.\n",
4367 iface, Centers, Radii, NumSpheres, Flags, ReturnValues);
4369 hr = IDirect3DDeviceImpl_7_GetTransform(iface, D3DTRANSFORMSTATE_WORLD, &m);
4370 if ( hr != DD_OK ) return DDERR_INVALIDPARAMS;
4371 hr = IDirect3DDeviceImpl_7_GetTransform(iface, D3DTRANSFORMSTATE_VIEW, &temp);
4372 if ( hr != DD_OK ) return DDERR_INVALIDPARAMS;
4373 multiply_matrix(&m, &temp, &m);
4375 hr = IDirect3DDeviceImpl_7_GetTransform(iface, D3DTRANSFORMSTATE_PROJECTION, &temp);
4376 if ( hr != DD_OK ) return DDERR_INVALIDPARAMS;
4377 multiply_matrix(&m, &temp, &m);
4380 vec[0].u1.x = m._14 + m._11;
4381 vec[0].u2.y = m._24 + m._21;
4382 vec[0].u3.z = m._34 + m._31;
4383 origin_plane[0] = m._44 + m._41;
4386 vec[1].u1.x = m._14 - m._11;
4387 vec[1].u2.y = m._24 - m._21;
4388 vec[1].u3.z = m._34 - m._31;
4389 origin_plane[1] = m._44 - m._41;
4392 vec[2].u1.x = m._14 - m._12;
4393 vec[2].u2.y = m._24 - m._22;
4394 vec[2].u3.z = m._34 - m._32;
4395 origin_plane[2] = m._44 - m._42;
4398 vec[3].u1.x = m._14 + m._12;
4399 vec[3].u2.y = m._24 + m._22;
4400 vec[3].u3.z = m._34 + m._32;
4401 origin_plane[3] = m._44 + m._42;
4404 vec[4].u1.x = m._13;
4405 vec[4].u2.y = m._23;
4406 vec[4].u3.z = m._33;
4407 origin_plane[4] = m._43;
4410 vec[5].u1.x = m._14 - m._13;
4411 vec[5].u2.y = m._24 - m._23;
4412 vec[5].u3.z = m._34 - m._33;
4413 origin_plane[5] = m._44 - m._43;
4415 for(i=0; i<NumSpheres; i++)
4417 ReturnValues[i] = 0;
4418 for(j=0; j<6; j++) ReturnValues[i] |= in_plane(j, vec[j], origin_plane[j], Centers[i], Radii[i]);
4424 static HRESULT WINAPI IDirect3DDeviceImpl_3_ComputeSphereVisibility(IDirect3DDevice3 *iface,
4425 D3DVECTOR *Centers, D3DVALUE *Radii, DWORD NumSpheres, DWORD Flags, DWORD *ReturnValues)
4427 TRACE("iface %p, centers %p, radii %p, sphere_count %u, flags %#x, return_values %p.\n",
4428 iface, Centers, Radii, NumSpheres, Flags, ReturnValues);
4430 return IDirect3DDevice7_ComputeSphereVisibility((IDirect3DDevice7 *)device_from_device3(iface),
4431 Centers, Radii, NumSpheres, Flags, ReturnValues);
4434 /*****************************************************************************
4435 * IDirect3DDevice7::GetTexture
4437 * Returns the texture interface handle assigned to a texture stage.
4438 * The returned texture is AddRefed. This is taken from old ddraw,
4439 * not checked in Windows.
4444 * Stage: Texture stage to read the texture from
4445 * Texture: Address to store the interface pointer at
4449 * DDERR_INVALIDPARAMS if Texture is NULL
4450 * For details, see IWineD3DDevice::GetTexture
4452 *****************************************************************************/
4454 IDirect3DDeviceImpl_7_GetTexture(IDirect3DDevice7 *iface,
4456 IDirectDrawSurface7 **Texture)
4458 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
4459 struct wined3d_texture *wined3d_texture;
4462 TRACE("iface %p, stage %u, texture %p.\n", iface, Stage, Texture);
4466 TRACE("Texture == NULL, failing with DDERR_INVALIDPARAMS\n");
4467 return DDERR_INVALIDPARAMS;
4470 EnterCriticalSection(&ddraw_cs);
4471 hr = wined3d_device_get_texture(This->wined3d_device, Stage, &wined3d_texture);
4472 if (FAILED(hr) || !wined3d_texture)
4475 LeaveCriticalSection(&ddraw_cs);
4479 *Texture = wined3d_texture_get_parent(wined3d_texture);
4480 IDirectDrawSurface7_AddRef(*Texture);
4481 LeaveCriticalSection(&ddraw_cs);
4485 static HRESULT WINAPI
4486 IDirect3DDeviceImpl_7_GetTexture_FPUSetup(IDirect3DDevice7 *iface,
4488 IDirectDrawSurface7 **Texture)
4490 return IDirect3DDeviceImpl_7_GetTexture(iface, Stage, Texture);
4493 static HRESULT WINAPI
4494 IDirect3DDeviceImpl_7_GetTexture_FPUPreserve(IDirect3DDevice7 *iface,
4496 IDirectDrawSurface7 **Texture)
4501 old_fpucw = d3d_fpu_setup();
4502 hr = IDirect3DDeviceImpl_7_GetTexture(iface, Stage, Texture);
4503 set_fpu_control_word(old_fpucw);
4508 static HRESULT WINAPI IDirect3DDeviceImpl_3_GetTexture(IDirect3DDevice3 *iface, DWORD Stage,
4509 IDirect3DTexture2 **Texture2)
4512 IDirectDrawSurface7 *ret_val;
4513 IDirectDrawSurfaceImpl *ret_val_impl;
4515 TRACE("iface %p, stage %u, texture %p.\n", iface, Stage, Texture2);
4517 ret = IDirect3DDevice7_GetTexture((IDirect3DDevice7 *)device_from_device3(iface), Stage, &ret_val);
4519 ret_val_impl = unsafe_impl_from_IDirectDrawSurface7(ret_val);
4520 *Texture2 = ret_val_impl ? (IDirect3DTexture2 *)&ret_val_impl->IDirect3DTexture2_vtbl : NULL;
4522 TRACE("Returning texture %p.\n", *Texture2);
4527 /*****************************************************************************
4528 * IDirect3DDevice7::SetTexture
4530 * Assigns a texture to a texture stage. Is the texture AddRef-ed?
4535 * Stage: The stage to assign the texture to
4536 * Texture: Interface pointer to the texture surface
4540 * For details, see IWineD3DDevice::SetTexture
4542 *****************************************************************************/
4544 IDirect3DDeviceImpl_7_SetTexture(IDirect3DDevice7 *iface,
4546 IDirectDrawSurface7 *Texture)
4548 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
4549 IDirectDrawSurfaceImpl *surf = unsafe_impl_from_IDirectDrawSurface7(Texture);
4552 TRACE("iface %p, stage %u, texture %p.\n", iface, Stage, Texture);
4554 /* Texture may be NULL here */
4555 EnterCriticalSection(&ddraw_cs);
4556 hr = wined3d_device_set_texture(This->wined3d_device,
4557 Stage, surf ? surf->wined3d_texture : NULL);
4558 LeaveCriticalSection(&ddraw_cs);
4562 static HRESULT WINAPI
4563 IDirect3DDeviceImpl_7_SetTexture_FPUSetup(IDirect3DDevice7 *iface,
4565 IDirectDrawSurface7 *Texture)
4567 return IDirect3DDeviceImpl_7_SetTexture(iface, Stage, Texture);
4570 static HRESULT WINAPI
4571 IDirect3DDeviceImpl_7_SetTexture_FPUPreserve(IDirect3DDevice7 *iface,
4573 IDirectDrawSurface7 *Texture)
4578 old_fpucw = d3d_fpu_setup();
4579 hr = IDirect3DDeviceImpl_7_SetTexture(iface, Stage, Texture);
4580 set_fpu_control_word(old_fpucw);
4585 static HRESULT WINAPI
4586 IDirect3DDeviceImpl_3_SetTexture(IDirect3DDevice3 *iface,
4588 IDirect3DTexture2 *Texture2)
4590 IDirect3DDeviceImpl *This = device_from_device3(iface);
4591 IDirectDrawSurfaceImpl *tex = Texture2 ? surface_from_texture2(Texture2) : NULL;
4595 TRACE("iface %p, stage %u, texture %p.\n", iface, Stage, Texture2);
4597 EnterCriticalSection(&ddraw_cs);
4599 if (This->legacyTextureBlending)
4600 IDirect3DDevice3_GetRenderState(iface, D3DRENDERSTATE_TEXTUREMAPBLEND, &texmapblend);
4602 hr = IDirect3DDevice7_SetTexture((IDirect3DDevice7 *)This, Stage, &tex->IDirectDrawSurface7_iface);
4604 if (This->legacyTextureBlending && texmapblend == D3DTBLEND_MODULATE)
4606 /* This fixup is required by the way D3DTBLEND_MODULATE maps to texture stage states.
4607 See IDirect3DDeviceImpl_3_SetRenderState for details. */
4608 struct wined3d_texture *tex = NULL;
4609 BOOL tex_alpha = FALSE;
4610 DDPIXELFORMAT ddfmt;
4613 result = wined3d_device_get_texture(This->wined3d_device, 0, &tex);
4614 if (result == WINED3D_OK && tex)
4616 struct wined3d_resource *sub_resource;
4618 if ((sub_resource = wined3d_texture_get_sub_resource(tex, 0)))
4620 struct wined3d_resource_desc desc;
4622 wined3d_resource_get_desc(sub_resource, &desc);
4623 ddfmt.dwSize = sizeof(ddfmt);
4624 PixelFormat_WineD3DtoDD(&ddfmt, desc.format);
4625 if (ddfmt.u5.dwRGBAlphaBitMask) tex_alpha = TRUE;
4628 wined3d_texture_decref(tex);
4631 /* Arg 1/2 are already set to WINED3DTA_TEXTURE/WINED3DTA_CURRENT in case of D3DTBLEND_MODULATE */
4633 wined3d_device_set_texture_stage_state(This->wined3d_device, 0, WINED3DTSS_ALPHAOP, WINED3DTOP_SELECTARG1);
4635 wined3d_device_set_texture_stage_state(This->wined3d_device, 0, WINED3DTSS_ALPHAOP, WINED3DTOP_SELECTARG2);
4638 LeaveCriticalSection(&ddraw_cs);
4643 static const struct tss_lookup
4650 {FALSE, WINED3DTSS_FORCE_DWORD}, /* 0, unused */
4651 {FALSE, WINED3DTSS_COLOROP}, /* 1, D3DTSS_COLOROP */
4652 {FALSE, WINED3DTSS_COLORARG1}, /* 2, D3DTSS_COLORARG1 */
4653 {FALSE, WINED3DTSS_COLORARG2}, /* 3, D3DTSS_COLORARG2 */
4654 {FALSE, WINED3DTSS_ALPHAOP}, /* 4, D3DTSS_ALPHAOP */
4655 {FALSE, WINED3DTSS_ALPHAARG1}, /* 5, D3DTSS_ALPHAARG1 */
4656 {FALSE, WINED3DTSS_ALPHAARG2}, /* 6, D3DTSS_ALPHAARG2 */
4657 {FALSE, WINED3DTSS_BUMPENVMAT00}, /* 7, D3DTSS_BUMPENVMAT00 */
4658 {FALSE, WINED3DTSS_BUMPENVMAT01}, /* 8, D3DTSS_BUMPENVMAT01 */
4659 {FALSE, WINED3DTSS_BUMPENVMAT10}, /* 9, D3DTSS_BUMPENVMAT10 */
4660 {FALSE, WINED3DTSS_BUMPENVMAT11}, /* 10, D3DTSS_BUMPENVMAT11 */
4661 {FALSE, WINED3DTSS_TEXCOORDINDEX}, /* 11, D3DTSS_TEXCOORDINDEX */
4662 {TRUE, WINED3DSAMP_ADDRESSU}, /* 12, D3DTSS_ADDRESS */
4663 {TRUE, WINED3DSAMP_ADDRESSU}, /* 13, D3DTSS_ADDRESSU */
4664 {TRUE, WINED3DSAMP_ADDRESSV}, /* 14, D3DTSS_ADDRESSV */
4665 {TRUE, WINED3DSAMP_BORDERCOLOR}, /* 15, D3DTSS_BORDERCOLOR */
4666 {TRUE, WINED3DSAMP_MAGFILTER}, /* 16, D3DTSS_MAGFILTER */
4667 {TRUE, WINED3DSAMP_MINFILTER}, /* 17, D3DTSS_MINFILTER */
4668 {TRUE, WINED3DSAMP_MIPFILTER}, /* 18, D3DTSS_MIPFILTER */
4669 {TRUE, WINED3DSAMP_MIPMAPLODBIAS}, /* 19, D3DTSS_MIPMAPLODBIAS */
4670 {TRUE, WINED3DSAMP_MAXMIPLEVEL}, /* 20, D3DTSS_MAXMIPLEVEL */
4671 {TRUE, WINED3DSAMP_MAXANISOTROPY}, /* 21, D3DTSS_MAXANISOTROPY */
4672 {FALSE, WINED3DTSS_BUMPENVLSCALE}, /* 22, D3DTSS_BUMPENVLSCALE */
4673 {FALSE, WINED3DTSS_BUMPENVLOFFSET}, /* 23, D3DTSS_BUMPENVLOFFSET */
4674 {FALSE, WINED3DTSS_TEXTURETRANSFORMFLAGS}, /* 24, D3DTSS_TEXTURETRANSFORMFLAGS */
4677 /*****************************************************************************
4678 * IDirect3DDevice7::GetTextureStageState
4680 * Retrieves a state from a texture stage.
4685 * Stage: The stage to retrieve the state from
4686 * TexStageStateType: The state type to retrieve
4687 * State: Address to store the state's value at
4691 * DDERR_INVALIDPARAMS if State is NULL
4692 * For details, see IWineD3DDevice::GetTextureStageState
4694 *****************************************************************************/
4696 IDirect3DDeviceImpl_7_GetTextureStageState(IDirect3DDevice7 *iface,
4698 D3DTEXTURESTAGESTATETYPE TexStageStateType,
4701 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
4703 const struct tss_lookup *l;
4705 TRACE("iface %p, stage %u, state %#x, value %p.\n",
4706 iface, Stage, TexStageStateType, State);
4709 return DDERR_INVALIDPARAMS;
4711 if (TexStageStateType > D3DTSS_TEXTURETRANSFORMFLAGS)
4713 WARN("Invalid TexStageStateType %#x passed.\n", TexStageStateType);
4717 l = &tss_lookup[TexStageStateType];
4719 EnterCriticalSection(&ddraw_cs);
4721 if (l->sampler_state)
4723 hr = wined3d_device_get_sampler_state(This->wined3d_device, Stage, l->state, State);
4725 switch(TexStageStateType)
4727 /* Mipfilter is a sampler state with different values */
4728 case D3DTSS_MIPFILTER:
4732 case WINED3DTEXF_NONE: *State = D3DTFP_NONE; break;
4733 case WINED3DTEXF_POINT: *State = D3DTFP_POINT; break;
4734 case WINED3DTEXF_LINEAR: *State = D3DTFP_LINEAR; break;
4736 ERR("Unexpected mipfilter value %#x\n", *State);
4737 *State = D3DTFP_NONE;
4743 /* Magfilter has slightly different values */
4744 case D3DTSS_MAGFILTER:
4748 case WINED3DTEXF_POINT: *State = D3DTFG_POINT; break;
4749 case WINED3DTEXF_LINEAR: *State = D3DTFG_LINEAR; break;
4750 case WINED3DTEXF_ANISOTROPIC: *State = D3DTFG_ANISOTROPIC; break;
4751 case WINED3DTEXF_FLATCUBIC: *State = D3DTFG_FLATCUBIC; break;
4752 case WINED3DTEXF_GAUSSIANCUBIC: *State = D3DTFG_GAUSSIANCUBIC; break;
4754 ERR("Unexpected wined3d mag filter value %#x\n", *State);
4755 *State = D3DTFG_POINT;
4767 hr = wined3d_device_get_texture_stage_state(This->wined3d_device, Stage, l->state, State);
4770 LeaveCriticalSection(&ddraw_cs);
4774 static HRESULT WINAPI
4775 IDirect3DDeviceImpl_7_GetTextureStageState_FPUSetup(IDirect3DDevice7 *iface,
4777 D3DTEXTURESTAGESTATETYPE TexStageStateType,
4780 return IDirect3DDeviceImpl_7_GetTextureStageState(iface, Stage, TexStageStateType, State);
4783 static HRESULT WINAPI
4784 IDirect3DDeviceImpl_7_GetTextureStageState_FPUPreserve(IDirect3DDevice7 *iface,
4786 D3DTEXTURESTAGESTATETYPE TexStageStateType,
4792 old_fpucw = d3d_fpu_setup();
4793 hr = IDirect3DDeviceImpl_7_GetTextureStageState(iface, Stage, TexStageStateType, State);
4794 set_fpu_control_word(old_fpucw);
4799 static HRESULT WINAPI IDirect3DDeviceImpl_3_GetTextureStageState(IDirect3DDevice3 *iface,
4800 DWORD Stage, D3DTEXTURESTAGESTATETYPE TexStageStateType, DWORD *State)
4802 TRACE("iface %p, stage %u, state %#x, value %p.\n",
4803 iface, Stage, TexStageStateType, State);
4805 return IDirect3DDevice7_GetTextureStageState((IDirect3DDevice7 *)device_from_device3(iface),
4806 Stage, TexStageStateType, State);
4809 /*****************************************************************************
4810 * IDirect3DDevice7::SetTextureStageState
4812 * Sets a texture stage state. Some stage types need to be handled specially,
4813 * because they do not exist in WineD3D and were moved to another place
4818 * Stage: The stage to modify
4819 * TexStageStateType: The state to change
4820 * State: The new value for the state
4824 * For details, see IWineD3DDevice::SetTextureStageState
4826 *****************************************************************************/
4828 IDirect3DDeviceImpl_7_SetTextureStageState(IDirect3DDevice7 *iface,
4830 D3DTEXTURESTAGESTATETYPE TexStageStateType,
4833 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
4834 const struct tss_lookup *l;
4837 TRACE("iface %p, stage %u, state %#x, value %#x.\n",
4838 iface, Stage, TexStageStateType, State);
4840 if (TexStageStateType > D3DTSS_TEXTURETRANSFORMFLAGS)
4842 WARN("Invalid TexStageStateType %#x passed.\n", TexStageStateType);
4846 l = &tss_lookup[TexStageStateType];
4848 EnterCriticalSection(&ddraw_cs);
4850 if (l->sampler_state)
4852 switch(TexStageStateType)
4854 /* Mipfilter is a sampler state with different values */
4855 case D3DTSS_MIPFILTER:
4859 case D3DTFP_NONE: State = WINED3DTEXF_NONE; break;
4860 case D3DTFP_POINT: State = WINED3DTEXF_POINT; break;
4861 case 0: /* Unchecked */
4862 case D3DTFP_LINEAR: State = WINED3DTEXF_LINEAR; break;
4864 ERR("Unexpected mipfilter value %d\n", State);
4865 State = WINED3DTEXF_NONE;
4871 /* Magfilter has slightly different values */
4872 case D3DTSS_MAGFILTER:
4876 case D3DTFG_POINT: State = WINED3DTEXF_POINT; break;
4877 case D3DTFG_LINEAR: State = WINED3DTEXF_LINEAR; break;
4878 case D3DTFG_FLATCUBIC: State = WINED3DTEXF_FLATCUBIC; break;
4879 case D3DTFG_GAUSSIANCUBIC: State = WINED3DTEXF_GAUSSIANCUBIC; break;
4880 case D3DTFG_ANISOTROPIC: State = WINED3DTEXF_ANISOTROPIC; break;
4882 ERR("Unexpected d3d7 mag filter type %d\n", State);
4883 State = WINED3DTEXF_POINT;
4889 case D3DTSS_ADDRESS:
4890 wined3d_device_set_sampler_state(This->wined3d_device, Stage, WINED3DSAMP_ADDRESSV, State);
4897 hr = wined3d_device_set_sampler_state(This->wined3d_device, Stage, l->state, State);
4901 hr = wined3d_device_set_texture_stage_state(This->wined3d_device, Stage, l->state, State);
4904 LeaveCriticalSection(&ddraw_cs);
4908 static HRESULT WINAPI
4909 IDirect3DDeviceImpl_7_SetTextureStageState_FPUSetup(IDirect3DDevice7 *iface,
4911 D3DTEXTURESTAGESTATETYPE TexStageStateType,
4914 return IDirect3DDeviceImpl_7_SetTextureStageState(iface, Stage, TexStageStateType, State);
4917 static HRESULT WINAPI
4918 IDirect3DDeviceImpl_7_SetTextureStageState_FPUPreserve(IDirect3DDevice7 *iface,
4920 D3DTEXTURESTAGESTATETYPE TexStageStateType,
4926 old_fpucw = d3d_fpu_setup();
4927 hr = IDirect3DDeviceImpl_7_SetTextureStageState(iface, Stage, TexStageStateType, State);
4928 set_fpu_control_word(old_fpucw);
4933 static HRESULT WINAPI IDirect3DDeviceImpl_3_SetTextureStageState(IDirect3DDevice3 *iface,
4934 DWORD Stage, D3DTEXTURESTAGESTATETYPE TexStageStateType, DWORD State)
4936 TRACE("iface %p, stage %u, state %#x, value %#x.\n",
4937 iface, Stage, TexStageStateType, State);
4939 return IDirect3DDevice7_SetTextureStageState((IDirect3DDevice7 *)device_from_device3(iface),
4940 Stage, TexStageStateType, State);
4943 /*****************************************************************************
4944 * IDirect3DDevice7::ValidateDevice
4946 * SDK: "Reports the device's ability to render the currently set
4947 * texture-blending operations in a single pass". Whatever that means
4953 * NumPasses: Address to write the number of necessary passes for the
4954 * desired effect to.
4958 * See IWineD3DDevice::ValidateDevice for more details
4960 *****************************************************************************/
4962 IDirect3DDeviceImpl_7_ValidateDevice(IDirect3DDevice7 *iface,
4965 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
4968 TRACE("iface %p, pass_count %p.\n", iface, NumPasses);
4970 EnterCriticalSection(&ddraw_cs);
4971 hr = wined3d_device_validate_device(This->wined3d_device, NumPasses);
4972 LeaveCriticalSection(&ddraw_cs);
4976 static HRESULT WINAPI
4977 IDirect3DDeviceImpl_7_ValidateDevice_FPUSetup(IDirect3DDevice7 *iface,
4980 return IDirect3DDeviceImpl_7_ValidateDevice(iface, NumPasses);
4983 static HRESULT WINAPI
4984 IDirect3DDeviceImpl_7_ValidateDevice_FPUPreserve(IDirect3DDevice7 *iface,
4990 old_fpucw = d3d_fpu_setup();
4991 hr = IDirect3DDeviceImpl_7_ValidateDevice(iface, NumPasses);
4992 set_fpu_control_word(old_fpucw);
4997 static HRESULT WINAPI IDirect3DDeviceImpl_3_ValidateDevice(IDirect3DDevice3 *iface, DWORD *Passes)
4999 TRACE("iface %p, pass_count %p.\n", iface, Passes);
5001 return IDirect3DDevice7_ValidateDevice((IDirect3DDevice7 *)device_from_device3(iface), Passes);
5004 /*****************************************************************************
5005 * IDirect3DDevice7::Clear
5007 * Fills the render target, the z buffer and the stencil buffer with a
5008 * clear color / value
5013 * Count: Number of rectangles in Rects must be 0 if Rects is NULL
5014 * Rects: Rectangles to clear. If NULL, the whole surface is cleared
5015 * Flags: Some flags, as usual
5016 * Color: Clear color for the render target
5017 * Z: Clear value for the Z buffer
5018 * Stencil: Clear value to store in each stencil buffer entry
5022 * For details, see IWineD3DDevice::Clear
5024 *****************************************************************************/
5026 IDirect3DDeviceImpl_7_Clear(IDirect3DDevice7 *iface,
5034 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5037 TRACE("iface %p, count %u, rects %p, flags %#x, color 0x%08x, z %.8e, stencil %#x.\n",
5038 iface, Count, Rects, Flags, Color, Z, Stencil);
5040 EnterCriticalSection(&ddraw_cs);
5041 hr = wined3d_device_clear(This->wined3d_device, Count, (RECT *)Rects, Flags, Color, Z, Stencil);
5042 LeaveCriticalSection(&ddraw_cs);
5046 static HRESULT WINAPI
5047 IDirect3DDeviceImpl_7_Clear_FPUSetup(IDirect3DDevice7 *iface,
5055 return IDirect3DDeviceImpl_7_Clear(iface, Count, Rects, Flags, Color, Z, Stencil);
5058 static HRESULT WINAPI
5059 IDirect3DDeviceImpl_7_Clear_FPUPreserve(IDirect3DDevice7 *iface,
5070 old_fpucw = d3d_fpu_setup();
5071 hr = IDirect3DDeviceImpl_7_Clear(iface, Count, Rects, Flags, Color, Z, Stencil);
5072 set_fpu_control_word(old_fpucw);
5077 /*****************************************************************************
5078 * IDirect3DDevice7::SetViewport
5080 * Sets the current viewport.
5082 * Version 7 only, but IDirect3DViewport uses this call for older
5086 * Data: The new viewport to set
5090 * DDERR_INVALIDPARAMS if Data is NULL
5091 * For more details, see IWineDDDevice::SetViewport
5093 *****************************************************************************/
5095 IDirect3DDeviceImpl_7_SetViewport(IDirect3DDevice7 *iface,
5098 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5101 TRACE("iface %p, viewport %p.\n", iface, Data);
5104 return DDERR_INVALIDPARAMS;
5106 /* Note: D3DVIEWPORT7 is compatible with WINED3DVIEWPORT */
5107 EnterCriticalSection(&ddraw_cs);
5108 hr = wined3d_device_set_viewport(This->wined3d_device, (WINED3DVIEWPORT *)Data);
5109 LeaveCriticalSection(&ddraw_cs);
5113 static HRESULT WINAPI
5114 IDirect3DDeviceImpl_7_SetViewport_FPUSetup(IDirect3DDevice7 *iface,
5117 return IDirect3DDeviceImpl_7_SetViewport(iface, Data);
5120 static HRESULT WINAPI
5121 IDirect3DDeviceImpl_7_SetViewport_FPUPreserve(IDirect3DDevice7 *iface,
5127 old_fpucw = d3d_fpu_setup();
5128 hr = IDirect3DDeviceImpl_7_SetViewport(iface, Data);
5129 set_fpu_control_word(old_fpucw);
5134 /*****************************************************************************
5135 * IDirect3DDevice::GetViewport
5137 * Returns the current viewport
5142 * Data: D3D7Viewport structure to write the viewport information to
5146 * DDERR_INVALIDPARAMS if Data is NULL
5147 * For more details, see IWineD3DDevice::GetViewport
5149 *****************************************************************************/
5151 IDirect3DDeviceImpl_7_GetViewport(IDirect3DDevice7 *iface,
5154 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5157 TRACE("iface %p, viewport %p.\n", iface, Data);
5160 return DDERR_INVALIDPARAMS;
5162 /* Note: D3DVIEWPORT7 is compatible with WINED3DVIEWPORT */
5163 EnterCriticalSection(&ddraw_cs);
5164 hr = wined3d_device_get_viewport(This->wined3d_device, (WINED3DVIEWPORT *)Data);
5166 LeaveCriticalSection(&ddraw_cs);
5167 return hr_ddraw_from_wined3d(hr);
5170 static HRESULT WINAPI
5171 IDirect3DDeviceImpl_7_GetViewport_FPUSetup(IDirect3DDevice7 *iface,
5174 return IDirect3DDeviceImpl_7_GetViewport(iface, Data);
5177 static HRESULT WINAPI
5178 IDirect3DDeviceImpl_7_GetViewport_FPUPreserve(IDirect3DDevice7 *iface,
5184 old_fpucw = d3d_fpu_setup();
5185 hr = IDirect3DDeviceImpl_7_GetViewport(iface, Data);
5186 set_fpu_control_word(old_fpucw);
5191 /*****************************************************************************
5192 * IDirect3DDevice7::SetMaterial
5199 * Mat: The material to set
5203 * DDERR_INVALIDPARAMS if Mat is NULL.
5204 * For more details, see IWineD3DDevice::SetMaterial
5206 *****************************************************************************/
5208 IDirect3DDeviceImpl_7_SetMaterial(IDirect3DDevice7 *iface,
5211 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5214 TRACE("iface %p, material %p.\n", iface, Mat);
5216 if (!Mat) return DDERR_INVALIDPARAMS;
5217 /* Note: D3DMATERIAL7 is compatible with WINED3DMATERIAL */
5218 EnterCriticalSection(&ddraw_cs);
5219 hr = wined3d_device_set_material(This->wined3d_device, (WINED3DMATERIAL *)Mat);
5220 LeaveCriticalSection(&ddraw_cs);
5221 return hr_ddraw_from_wined3d(hr);
5224 static HRESULT WINAPI
5225 IDirect3DDeviceImpl_7_SetMaterial_FPUSetup(IDirect3DDevice7 *iface,
5228 return IDirect3DDeviceImpl_7_SetMaterial(iface, Mat);
5231 static HRESULT WINAPI
5232 IDirect3DDeviceImpl_7_SetMaterial_FPUPreserve(IDirect3DDevice7 *iface,
5238 old_fpucw = d3d_fpu_setup();
5239 hr = IDirect3DDeviceImpl_7_SetMaterial(iface, Mat);
5240 set_fpu_control_word(old_fpucw);
5245 /*****************************************************************************
5246 * IDirect3DDevice7::GetMaterial
5248 * Returns the current material
5253 * Mat: D3DMATERIAL7 structure to write the material parameters to
5257 * DDERR_INVALIDPARAMS if Mat is NULL
5258 * For more details, see IWineD3DDevice::GetMaterial
5260 *****************************************************************************/
5262 IDirect3DDeviceImpl_7_GetMaterial(IDirect3DDevice7 *iface,
5265 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5268 TRACE("iface %p, material %p.\n", iface, Mat);
5270 EnterCriticalSection(&ddraw_cs);
5271 /* Note: D3DMATERIAL7 is compatible with WINED3DMATERIAL */
5272 hr = wined3d_device_get_material(This->wined3d_device, (WINED3DMATERIAL *)Mat);
5273 LeaveCriticalSection(&ddraw_cs);
5274 return hr_ddraw_from_wined3d(hr);
5277 static HRESULT WINAPI
5278 IDirect3DDeviceImpl_7_GetMaterial_FPUSetup(IDirect3DDevice7 *iface,
5281 return IDirect3DDeviceImpl_7_GetMaterial(iface, Mat);
5284 static HRESULT WINAPI
5285 IDirect3DDeviceImpl_7_GetMaterial_FPUPreserve(IDirect3DDevice7 *iface,
5291 old_fpucw = d3d_fpu_setup();
5292 hr = IDirect3DDeviceImpl_7_GetMaterial(iface, Mat);
5293 set_fpu_control_word(old_fpucw);
5298 /*****************************************************************************
5299 * IDirect3DDevice7::SetLight
5301 * Assigns a light to a light index, but doesn't activate it yet.
5303 * Version 7, IDirect3DLight uses this method for older versions
5306 * LightIndex: The index of the new light
5307 * Light: A D3DLIGHT7 structure describing the light
5311 * For more details, see IWineD3DDevice::SetLight
5313 *****************************************************************************/
5315 IDirect3DDeviceImpl_7_SetLight(IDirect3DDevice7 *iface,
5319 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5322 TRACE("iface %p, light_idx %u, light %p.\n", iface, LightIndex, Light);
5324 EnterCriticalSection(&ddraw_cs);
5325 /* Note: D3DLIGHT7 is compatible with WINED3DLIGHT */
5326 hr = wined3d_device_set_light(This->wined3d_device, LightIndex, (WINED3DLIGHT *)Light);
5327 LeaveCriticalSection(&ddraw_cs);
5328 return hr_ddraw_from_wined3d(hr);
5331 static HRESULT WINAPI
5332 IDirect3DDeviceImpl_7_SetLight_FPUSetup(IDirect3DDevice7 *iface,
5336 return IDirect3DDeviceImpl_7_SetLight(iface, LightIndex, Light);
5339 static HRESULT WINAPI
5340 IDirect3DDeviceImpl_7_SetLight_FPUPreserve(IDirect3DDevice7 *iface,
5347 old_fpucw = d3d_fpu_setup();
5348 hr = IDirect3DDeviceImpl_7_SetLight(iface, LightIndex, Light);
5349 set_fpu_control_word(old_fpucw);
5354 /*****************************************************************************
5355 * IDirect3DDevice7::GetLight
5357 * Returns the light assigned to a light index
5360 * Light: Structure to write the light information to
5364 * DDERR_INVALIDPARAMS if Light is NULL
5365 * For details, see IWineD3DDevice::GetLight
5367 *****************************************************************************/
5369 IDirect3DDeviceImpl_7_GetLight(IDirect3DDevice7 *iface,
5373 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5376 TRACE("iface %p, light_idx %u, light %p.\n", iface, LightIndex, Light);
5378 EnterCriticalSection(&ddraw_cs);
5379 /* Note: D3DLIGHT7 is compatible with WINED3DLIGHT */
5380 rc = wined3d_device_get_light(This->wined3d_device, LightIndex, (WINED3DLIGHT *)Light);
5382 /* Translate the result. WineD3D returns other values than D3D7 */
5383 LeaveCriticalSection(&ddraw_cs);
5384 return hr_ddraw_from_wined3d(rc);
5387 static HRESULT WINAPI
5388 IDirect3DDeviceImpl_7_GetLight_FPUSetup(IDirect3DDevice7 *iface,
5392 return IDirect3DDeviceImpl_7_GetLight(iface, LightIndex, Light);
5395 static HRESULT WINAPI
5396 IDirect3DDeviceImpl_7_GetLight_FPUPreserve(IDirect3DDevice7 *iface,
5403 old_fpucw = d3d_fpu_setup();
5404 hr = IDirect3DDeviceImpl_7_GetLight(iface, LightIndex, Light);
5405 set_fpu_control_word(old_fpucw);
5410 /*****************************************************************************
5411 * IDirect3DDevice7::BeginStateBlock
5413 * Begins recording to a stateblock
5419 * For details see IWineD3DDevice::BeginStateBlock
5421 *****************************************************************************/
5423 IDirect3DDeviceImpl_7_BeginStateBlock(IDirect3DDevice7 *iface)
5425 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5428 TRACE("iface %p.\n", iface);
5430 EnterCriticalSection(&ddraw_cs);
5431 hr = wined3d_device_begin_stateblock(This->wined3d_device);
5432 LeaveCriticalSection(&ddraw_cs);
5433 return hr_ddraw_from_wined3d(hr);
5436 static HRESULT WINAPI
5437 IDirect3DDeviceImpl_7_BeginStateBlock_FPUSetup(IDirect3DDevice7 *iface)
5439 return IDirect3DDeviceImpl_7_BeginStateBlock(iface);
5442 static HRESULT WINAPI
5443 IDirect3DDeviceImpl_7_BeginStateBlock_FPUPreserve(IDirect3DDevice7 *iface)
5448 old_fpucw = d3d_fpu_setup();
5449 hr = IDirect3DDeviceImpl_7_BeginStateBlock(iface);
5450 set_fpu_control_word(old_fpucw);
5455 /*****************************************************************************
5456 * IDirect3DDevice7::EndStateBlock
5458 * Stops recording to a state block and returns the created stateblock
5464 * BlockHandle: Address to store the stateblock's handle to
5468 * DDERR_INVALIDPARAMS if BlockHandle is NULL
5469 * See IWineD3DDevice::EndStateBlock for more details
5471 *****************************************************************************/
5473 IDirect3DDeviceImpl_7_EndStateBlock(IDirect3DDevice7 *iface,
5476 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5477 struct wined3d_stateblock *wined3d_sb;
5481 TRACE("iface %p, stateblock %p.\n", iface, BlockHandle);
5485 WARN("BlockHandle == NULL, returning DDERR_INVALIDPARAMS\n");
5486 return DDERR_INVALIDPARAMS;
5489 EnterCriticalSection(&ddraw_cs);
5491 hr = wined3d_device_end_stateblock(This->wined3d_device, &wined3d_sb);
5494 WARN("Failed to end stateblock, hr %#x.\n", hr);
5495 LeaveCriticalSection(&ddraw_cs);
5497 return hr_ddraw_from_wined3d(hr);
5500 h = ddraw_allocate_handle(&This->handle_table, wined3d_sb, DDRAW_HANDLE_STATEBLOCK);
5501 if (h == DDRAW_INVALID_HANDLE)
5503 ERR("Failed to allocate a stateblock handle.\n");
5504 wined3d_stateblock_decref(wined3d_sb);
5505 LeaveCriticalSection(&ddraw_cs);
5507 return DDERR_OUTOFMEMORY;
5510 LeaveCriticalSection(&ddraw_cs);
5511 *BlockHandle = h + 1;
5513 return hr_ddraw_from_wined3d(hr);
5516 static HRESULT WINAPI
5517 IDirect3DDeviceImpl_7_EndStateBlock_FPUSetup(IDirect3DDevice7 *iface,
5520 return IDirect3DDeviceImpl_7_EndStateBlock(iface, BlockHandle);
5523 static HRESULT WINAPI
5524 IDirect3DDeviceImpl_7_EndStateBlock_FPUPreserve(IDirect3DDevice7 *iface,
5530 old_fpucw = d3d_fpu_setup();
5531 hr = IDirect3DDeviceImpl_7_EndStateBlock(iface, BlockHandle);
5532 set_fpu_control_word(old_fpucw);
5537 /*****************************************************************************
5538 * IDirect3DDevice7::PreLoad
5540 * Allows the app to signal that a texture will be used soon, to allow
5541 * the Direct3DDevice to load it to the video card in the meantime.
5546 * Texture: The texture to preload
5550 * DDERR_INVALIDPARAMS if Texture is NULL
5551 * See IWineD3DSurface::PreLoad for details
5553 *****************************************************************************/
5555 IDirect3DDeviceImpl_7_PreLoad(IDirect3DDevice7 *iface,
5556 IDirectDrawSurface7 *Texture)
5558 IDirectDrawSurfaceImpl *surf = unsafe_impl_from_IDirectDrawSurface7(Texture);
5560 TRACE("iface %p, texture %p.\n", iface, Texture);
5563 return DDERR_INVALIDPARAMS;
5565 EnterCriticalSection(&ddraw_cs);
5566 wined3d_surface_preload(surf->wined3d_surface);
5567 LeaveCriticalSection(&ddraw_cs);
5571 static HRESULT WINAPI
5572 IDirect3DDeviceImpl_7_PreLoad_FPUSetup(IDirect3DDevice7 *iface,
5573 IDirectDrawSurface7 *Texture)
5575 return IDirect3DDeviceImpl_7_PreLoad(iface, Texture);
5578 static HRESULT WINAPI
5579 IDirect3DDeviceImpl_7_PreLoad_FPUPreserve(IDirect3DDevice7 *iface,
5580 IDirectDrawSurface7 *Texture)
5585 old_fpucw = d3d_fpu_setup();
5586 hr = IDirect3DDeviceImpl_7_PreLoad(iface, Texture);
5587 set_fpu_control_word(old_fpucw);
5592 /*****************************************************************************
5593 * IDirect3DDevice7::ApplyStateBlock
5595 * Activates the state stored in a state block handle.
5598 * BlockHandle: The stateblock handle to activate
5602 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is NULL
5604 *****************************************************************************/
5606 IDirect3DDeviceImpl_7_ApplyStateBlock(IDirect3DDevice7 *iface,
5609 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5610 struct wined3d_stateblock *wined3d_sb;
5613 TRACE("iface %p, stateblock %#x.\n", iface, BlockHandle);
5615 EnterCriticalSection(&ddraw_cs);
5617 wined3d_sb = ddraw_get_object(&This->handle_table, BlockHandle - 1, DDRAW_HANDLE_STATEBLOCK);
5620 WARN("Invalid stateblock handle.\n");
5621 LeaveCriticalSection(&ddraw_cs);
5622 return D3DERR_INVALIDSTATEBLOCK;
5625 hr = wined3d_stateblock_apply(wined3d_sb);
5626 LeaveCriticalSection(&ddraw_cs);
5628 return hr_ddraw_from_wined3d(hr);
5631 static HRESULT WINAPI
5632 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUSetup(IDirect3DDevice7 *iface,
5635 return IDirect3DDeviceImpl_7_ApplyStateBlock(iface, BlockHandle);
5638 static HRESULT WINAPI
5639 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUPreserve(IDirect3DDevice7 *iface,
5645 old_fpucw = d3d_fpu_setup();
5646 hr = IDirect3DDeviceImpl_7_ApplyStateBlock(iface, BlockHandle);
5647 set_fpu_control_word(old_fpucw);
5652 /*****************************************************************************
5653 * IDirect3DDevice7::CaptureStateBlock
5655 * Updates a stateblock's values to the values currently set for the device
5660 * BlockHandle: Stateblock to update
5664 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is NULL
5665 * See IWineD3DDevice::CaptureStateBlock for more details
5667 *****************************************************************************/
5669 IDirect3DDeviceImpl_7_CaptureStateBlock(IDirect3DDevice7 *iface,
5672 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5673 struct wined3d_stateblock *wined3d_sb;
5676 TRACE("iface %p, stateblock %#x.\n", iface, BlockHandle);
5678 EnterCriticalSection(&ddraw_cs);
5680 wined3d_sb = ddraw_get_object(&This->handle_table, BlockHandle - 1, DDRAW_HANDLE_STATEBLOCK);
5683 WARN("Invalid stateblock handle.\n");
5684 LeaveCriticalSection(&ddraw_cs);
5685 return D3DERR_INVALIDSTATEBLOCK;
5688 hr = wined3d_stateblock_capture(wined3d_sb);
5689 LeaveCriticalSection(&ddraw_cs);
5690 return hr_ddraw_from_wined3d(hr);
5693 static HRESULT WINAPI
5694 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUSetup(IDirect3DDevice7 *iface,
5697 return IDirect3DDeviceImpl_7_CaptureStateBlock(iface, BlockHandle);
5700 static HRESULT WINAPI
5701 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUPreserve(IDirect3DDevice7 *iface,
5707 old_fpucw = d3d_fpu_setup();
5708 hr = IDirect3DDeviceImpl_7_CaptureStateBlock(iface, BlockHandle);
5709 set_fpu_control_word(old_fpucw);
5714 /*****************************************************************************
5715 * IDirect3DDevice7::DeleteStateBlock
5717 * Deletes a stateblock handle. This means releasing the WineD3DStateBlock
5722 * BlockHandle: Stateblock handle to delete
5726 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is 0
5728 *****************************************************************************/
5730 IDirect3DDeviceImpl_7_DeleteStateBlock(IDirect3DDevice7 *iface,
5733 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5734 struct wined3d_stateblock *wined3d_sb;
5737 TRACE("iface %p, stateblock %#x.\n", iface, BlockHandle);
5739 EnterCriticalSection(&ddraw_cs);
5741 wined3d_sb = ddraw_free_handle(&This->handle_table, BlockHandle - 1, DDRAW_HANDLE_STATEBLOCK);
5744 WARN("Invalid stateblock handle.\n");
5745 LeaveCriticalSection(&ddraw_cs);
5746 return D3DERR_INVALIDSTATEBLOCK;
5749 if ((ref = wined3d_stateblock_decref(wined3d_sb)))
5751 ERR("Something is still holding stateblock %p (refcount %u).\n", wined3d_sb, ref);
5754 LeaveCriticalSection(&ddraw_cs);
5758 static HRESULT WINAPI
5759 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUSetup(IDirect3DDevice7 *iface,
5762 return IDirect3DDeviceImpl_7_DeleteStateBlock(iface, BlockHandle);
5765 static HRESULT WINAPI
5766 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUPreserve(IDirect3DDevice7 *iface,
5772 old_fpucw = d3d_fpu_setup();
5773 hr = IDirect3DDeviceImpl_7_DeleteStateBlock(iface, BlockHandle);
5774 set_fpu_control_word(old_fpucw);
5779 /*****************************************************************************
5780 * IDirect3DDevice7::CreateStateBlock
5782 * Creates a new state block handle.
5787 * Type: The state block type
5788 * BlockHandle: Address to write the created handle to
5792 * DDERR_INVALIDPARAMS if BlockHandle is NULL
5794 *****************************************************************************/
5796 IDirect3DDeviceImpl_7_CreateStateBlock(IDirect3DDevice7 *iface,
5797 D3DSTATEBLOCKTYPE Type,
5800 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5801 struct wined3d_stateblock *wined3d_sb;
5805 TRACE("iface %p, type %#x, stateblock %p.\n", iface, Type, BlockHandle);
5809 WARN("BlockHandle == NULL, returning DDERR_INVALIDPARAMS\n");
5810 return DDERR_INVALIDPARAMS;
5812 if(Type != D3DSBT_ALL && Type != D3DSBT_PIXELSTATE &&
5813 Type != D3DSBT_VERTEXSTATE ) {
5814 WARN("Unexpected stateblock type, returning DDERR_INVALIDPARAMS\n");
5815 return DDERR_INVALIDPARAMS;
5818 EnterCriticalSection(&ddraw_cs);
5820 /* The D3DSTATEBLOCKTYPE enum is fine here. */
5821 hr = wined3d_stateblock_create(This->wined3d_device, Type, &wined3d_sb);
5824 WARN("Failed to create stateblock, hr %#x.\n", hr);
5825 LeaveCriticalSection(&ddraw_cs);
5826 return hr_ddraw_from_wined3d(hr);
5829 h = ddraw_allocate_handle(&This->handle_table, wined3d_sb, DDRAW_HANDLE_STATEBLOCK);
5830 if (h == DDRAW_INVALID_HANDLE)
5832 ERR("Failed to allocate stateblock handle.\n");
5833 wined3d_stateblock_decref(wined3d_sb);
5834 LeaveCriticalSection(&ddraw_cs);
5835 return DDERR_OUTOFMEMORY;
5838 *BlockHandle = h + 1;
5839 LeaveCriticalSection(&ddraw_cs);
5841 return hr_ddraw_from_wined3d(hr);
5844 static HRESULT WINAPI
5845 IDirect3DDeviceImpl_7_CreateStateBlock_FPUSetup(IDirect3DDevice7 *iface,
5846 D3DSTATEBLOCKTYPE Type,
5849 return IDirect3DDeviceImpl_7_CreateStateBlock(iface, Type, BlockHandle);
5852 static HRESULT WINAPI
5853 IDirect3DDeviceImpl_7_CreateStateBlock_FPUPreserve(IDirect3DDevice7 *iface,
5854 D3DSTATEBLOCKTYPE Type,
5860 old_fpucw = d3d_fpu_setup();
5861 hr =IDirect3DDeviceImpl_7_CreateStateBlock(iface, Type, BlockHandle);
5862 set_fpu_control_word(old_fpucw);
5867 /* Helper function for IDirect3DDeviceImpl_7_Load. */
5868 static BOOL is_mip_level_subset(IDirectDrawSurfaceImpl *dest,
5869 IDirectDrawSurfaceImpl *src)
5871 IDirectDrawSurfaceImpl *src_level, *dest_level;
5872 IDirectDrawSurface7 *temp;
5873 DDSURFACEDESC2 ddsd;
5874 BOOL levelFound; /* at least one suitable sublevel in dest found */
5876 /* To satisfy "destination is mip level subset of source" criteria (regular texture counts as 1 level),
5877 * 1) there must be at least one mip level in destination that matched dimensions of some mip level in source and
5878 * 2) there must be no destination levels that don't match any levels in source. Otherwise it's INVALIDPARAMS.
5885 for (;src_level && dest_level;)
5887 if (src_level->surface_desc.dwWidth == dest_level->surface_desc.dwWidth &&
5888 src_level->surface_desc.dwHeight == dest_level->surface_desc.dwHeight)
5892 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
5893 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_MIPMAPSUBLEVEL;
5894 IDirectDrawSurface7_GetAttachedSurface(&dest_level->IDirectDrawSurface7_iface, &ddsd.ddsCaps, &temp);
5896 if (dest_level != dest) IDirectDrawSurface7_Release(&dest_level->IDirectDrawSurface7_iface);
5898 dest_level = unsafe_impl_from_IDirectDrawSurface7(temp);
5901 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
5902 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_MIPMAPSUBLEVEL;
5903 IDirectDrawSurface7_GetAttachedSurface(&src_level->IDirectDrawSurface7_iface, &ddsd.ddsCaps, &temp);
5905 if (src_level != src) IDirectDrawSurface7_Release(&src_level->IDirectDrawSurface7_iface);
5907 src_level = unsafe_impl_from_IDirectDrawSurface7(temp);
5910 if (src_level && src_level != src) IDirectDrawSurface7_Release(&src_level->IDirectDrawSurface7_iface);
5911 if (dest_level && dest_level != dest) IDirectDrawSurface7_Release(&dest_level->IDirectDrawSurface7_iface);
5913 return !dest_level && levelFound;
5916 /* Helper function for IDirect3DDeviceImpl_7_Load. */
5917 static void copy_mipmap_chain(IDirect3DDeviceImpl *device,
5918 IDirectDrawSurfaceImpl *dest,
5919 IDirectDrawSurfaceImpl *src,
5920 const POINT *DestPoint,
5921 const RECT *SrcRect)
5923 IDirectDrawSurfaceImpl *src_level, *dest_level;
5924 IDirectDrawSurface7 *temp;
5925 DDSURFACEDESC2 ddsd;
5929 IDirectDrawPalette *pal = NULL, *pal_src = NULL;
5932 BOOL palette_missing = FALSE;
5934 /* Copy palette, if possible. */
5935 IDirectDrawSurface7_GetPalette(&src->IDirectDrawSurface7_iface, &pal_src);
5936 IDirectDrawSurface7_GetPalette(&dest->IDirectDrawSurface7_iface, &pal);
5938 if (pal_src != NULL && pal != NULL)
5940 PALETTEENTRY palent[256];
5942 IDirectDrawPalette_GetEntries(pal_src, 0, 0, 256, palent);
5943 IDirectDrawPalette_SetEntries(pal, 0, 0, 256, palent);
5946 if (dest->surface_desc.u4.ddpfPixelFormat.dwFlags & (DDPF_PALETTEINDEXED1 | DDPF_PALETTEINDEXED2 |
5947 DDPF_PALETTEINDEXED4 | DDPF_PALETTEINDEXED8 | DDPF_PALETTEINDEXEDTO8) && !pal)
5949 palette_missing = TRUE;
5952 if (pal) IDirectDrawPalette_Release(pal);
5953 if (pal_src) IDirectDrawPalette_Release(pal_src);
5955 /* Copy colorkeys, if present. */
5956 for (ckeyflag = DDCKEY_DESTBLT; ckeyflag <= DDCKEY_SRCOVERLAY; ckeyflag <<= 1)
5958 hr = IDirectDrawSurface7_GetColorKey(&src->IDirectDrawSurface7_iface, ckeyflag, &ddckey);
5962 IDirectDrawSurface7_SetColorKey(&dest->IDirectDrawSurface7_iface, ckeyflag, &ddckey);
5972 for (;src_level && dest_level;)
5974 if (src_level->surface_desc.dwWidth == dest_level->surface_desc.dwWidth &&
5975 src_level->surface_desc.dwHeight == dest_level->surface_desc.dwHeight)
5977 /* Try UpdateSurface that may perform a more direct OpenGL
5978 * loading. But skip this if destination is paletted texture and
5979 * has no palette. Some games like Sacrifice set palette after
5980 * Load, and it is a waste of effort to try to load texture
5981 * without palette and generates warnings in wined3d. */
5982 if (!palette_missing)
5983 hr = wined3d_device_update_surface(device->wined3d_device, src_level->wined3d_surface,
5984 &rect, dest_level->wined3d_surface, &point);
5986 if (palette_missing || FAILED(hr))
5988 /* UpdateSurface may fail e.g. if dest is in system memory. Fall back to BltFast that is less strict. */
5989 wined3d_surface_bltfast(dest_level->wined3d_surface, point.x, point.y,
5990 src_level->wined3d_surface, &rect, 0);
5993 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
5994 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_MIPMAPSUBLEVEL;
5995 IDirectDrawSurface7_GetAttachedSurface(&dest_level->IDirectDrawSurface7_iface, &ddsd.ddsCaps, &temp);
5997 if (dest_level != dest) IDirectDrawSurface7_Release(&dest_level->IDirectDrawSurface7_iface);
5999 dest_level = unsafe_impl_from_IDirectDrawSurface7(temp);
6002 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
6003 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_MIPMAPSUBLEVEL;
6004 IDirectDrawSurface7_GetAttachedSurface(&src_level->IDirectDrawSurface7_iface, &ddsd.ddsCaps, &temp);
6006 if (src_level != src) IDirectDrawSurface7_Release(&src_level->IDirectDrawSurface7_iface);
6008 src_level = unsafe_impl_from_IDirectDrawSurface7(temp);
6015 rect.right = (rect.right + 1) / 2;
6016 rect.bottom = (rect.bottom + 1) / 2;
6019 if (src_level && src_level != src) IDirectDrawSurface7_Release(&src_level->IDirectDrawSurface7_iface);
6020 if (dest_level && dest_level != dest) IDirectDrawSurface7_Release(&dest_level->IDirectDrawSurface7_iface);
6023 /*****************************************************************************
6024 * IDirect3DDevice7::Load
6026 * Loads a rectangular area from the source into the destination texture.
6027 * It can also copy the source to the faces of a cubic environment map
6032 * DestTex: Destination texture
6033 * DestPoint: Point in the destination where the source image should be
6035 * SrcTex: Source texture
6036 * SrcRect: Source rectangle
6037 * Flags: Cubemap faces to load (DDSCAPS2_CUBEMAP_ALLFACES, DDSCAPS2_CUBEMAP_POSITIVEX,
6038 * DDSCAPS2_CUBEMAP_NEGATIVEX, DDSCAPS2_CUBEMAP_POSITIVEY, DDSCAPS2_CUBEMAP_NEGATIVEY,
6039 * DDSCAPS2_CUBEMAP_POSITIVEZ, DDSCAPS2_CUBEMAP_NEGATIVEZ)
6043 * DDERR_INVALIDPARAMS if DestTex or SrcTex are NULL, broken coordinates or anything unexpected.
6046 *****************************************************************************/
6049 IDirect3DDeviceImpl_7_Load(IDirect3DDevice7 *iface,
6050 IDirectDrawSurface7 *DestTex,
6052 IDirectDrawSurface7 *SrcTex,
6056 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
6057 IDirectDrawSurfaceImpl *dest = unsafe_impl_from_IDirectDrawSurface7(DestTex);
6058 IDirectDrawSurfaceImpl *src = unsafe_impl_from_IDirectDrawSurface7(SrcTex);
6062 TRACE("iface %p, dst_texture %p, dst_pos %s, src_texture %p, src_rect %s, flags %#x.\n",
6063 iface, DestTex, wine_dbgstr_point(DestPoint), SrcTex, wine_dbgstr_rect(SrcRect), Flags);
6065 if( (!src) || (!dest) )
6066 return DDERR_INVALIDPARAMS;
6068 EnterCriticalSection(&ddraw_cs);
6070 if (SrcRect) srcrect = *SrcRect;
6073 srcrect.left = srcrect.top = 0;
6074 srcrect.right = src->surface_desc.dwWidth;
6075 srcrect.bottom = src->surface_desc.dwHeight;
6078 if (DestPoint) destpoint = *DestPoint;
6081 destpoint.x = destpoint.y = 0;
6083 /* Check bad dimensions. DestPoint is validated against src, not dest, because
6084 * destination can be a subset of mip levels, in which case actual coordinates used
6085 * for it may be divided. If any dimension of dest is larger than source, it can't be
6086 * mip level subset, so an error can be returned early.
6088 if (srcrect.left >= srcrect.right || srcrect.top >= srcrect.bottom ||
6089 srcrect.right > src->surface_desc.dwWidth ||
6090 srcrect.bottom > src->surface_desc.dwHeight ||
6091 destpoint.x + srcrect.right - srcrect.left > src->surface_desc.dwWidth ||
6092 destpoint.y + srcrect.bottom - srcrect.top > src->surface_desc.dwHeight ||
6093 dest->surface_desc.dwWidth > src->surface_desc.dwWidth ||
6094 dest->surface_desc.dwHeight > src->surface_desc.dwHeight)
6096 LeaveCriticalSection(&ddraw_cs);
6097 return DDERR_INVALIDPARAMS;
6100 /* Must be top level surfaces. */
6101 if (src->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_MIPMAPSUBLEVEL ||
6102 dest->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_MIPMAPSUBLEVEL)
6104 LeaveCriticalSection(&ddraw_cs);
6105 return DDERR_INVALIDPARAMS;
6108 if (src->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP)
6110 DWORD src_face_flag, dest_face_flag;
6111 IDirectDrawSurfaceImpl *src_face, *dest_face;
6112 IDirectDrawSurface7 *temp;
6113 DDSURFACEDESC2 ddsd;
6116 if (!(dest->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP))
6118 LeaveCriticalSection(&ddraw_cs);
6119 return DDERR_INVALIDPARAMS;
6122 /* Iterate through cube faces 2 times. First time is just to check INVALIDPARAMS conditions, second
6123 * time it's actual surface loading. */
6124 for (i = 0; i < 2; i++)
6129 for (;dest_face && src_face;)
6131 src_face_flag = src_face->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP_ALLFACES;
6132 dest_face_flag = dest_face->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP_ALLFACES;
6134 if (src_face_flag == dest_face_flag)
6138 /* Destination mip levels must be subset of source mip levels. */
6139 if (!is_mip_level_subset(dest_face, src_face))
6141 LeaveCriticalSection(&ddraw_cs);
6142 return DDERR_INVALIDPARAMS;
6145 else if (Flags & dest_face_flag)
6147 copy_mipmap_chain(This, dest_face, src_face, &destpoint, &srcrect);
6150 if (src_face_flag < DDSCAPS2_CUBEMAP_NEGATIVEZ)
6152 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
6153 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | (src_face_flag << 1);
6154 IDirectDrawSurface7_GetAttachedSurface(&src->IDirectDrawSurface7_iface, &ddsd.ddsCaps, &temp);
6156 if (src_face != src) IDirectDrawSurface7_Release(&src_face->IDirectDrawSurface7_iface);
6158 src_face = unsafe_impl_from_IDirectDrawSurface7(temp);
6162 if (src_face != src) IDirectDrawSurface7_Release(&src_face->IDirectDrawSurface7_iface);
6168 if (dest_face_flag < DDSCAPS2_CUBEMAP_NEGATIVEZ)
6170 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
6171 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | (dest_face_flag << 1);
6172 IDirectDrawSurface7_GetAttachedSurface(&dest->IDirectDrawSurface7_iface, &ddsd.ddsCaps, &temp);
6174 if (dest_face != dest) IDirectDrawSurface7_Release(&dest_face->IDirectDrawSurface7_iface);
6176 dest_face = unsafe_impl_from_IDirectDrawSurface7(temp);
6180 if (dest_face != dest) IDirectDrawSurface7_Release(&dest_face->IDirectDrawSurface7_iface);
6188 /* Native returns error if src faces are not subset of dest faces. */
6191 LeaveCriticalSection(&ddraw_cs);
6192 return DDERR_INVALIDPARAMS;
6197 LeaveCriticalSection(&ddraw_cs);
6200 else if (dest->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP)
6202 LeaveCriticalSection(&ddraw_cs);
6203 return DDERR_INVALIDPARAMS;
6206 /* Handle non cube map textures. */
6208 /* Destination mip levels must be subset of source mip levels. */
6209 if (!is_mip_level_subset(dest, src))
6211 LeaveCriticalSection(&ddraw_cs);
6212 return DDERR_INVALIDPARAMS;
6215 copy_mipmap_chain(This, dest, src, &destpoint, &srcrect);
6217 LeaveCriticalSection(&ddraw_cs);
6221 static HRESULT WINAPI
6222 IDirect3DDeviceImpl_7_Load_FPUSetup(IDirect3DDevice7 *iface,
6223 IDirectDrawSurface7 *DestTex,
6225 IDirectDrawSurface7 *SrcTex,
6229 return IDirect3DDeviceImpl_7_Load(iface, DestTex, DestPoint, SrcTex, SrcRect, Flags);
6232 static HRESULT WINAPI
6233 IDirect3DDeviceImpl_7_Load_FPUPreserve(IDirect3DDevice7 *iface,
6234 IDirectDrawSurface7 *DestTex,
6236 IDirectDrawSurface7 *SrcTex,
6243 old_fpucw = d3d_fpu_setup();
6244 hr = IDirect3DDeviceImpl_7_Load(iface, DestTex, DestPoint, SrcTex, SrcRect, Flags);
6245 set_fpu_control_word(old_fpucw);
6250 /*****************************************************************************
6251 * IDirect3DDevice7::LightEnable
6253 * Enables or disables a light
6255 * Version 7, IDirect3DLight uses this method too.
6258 * LightIndex: The index of the light to enable / disable
6259 * Enable: Enable or disable the light
6263 * For more details, see IWineD3DDevice::SetLightEnable
6265 *****************************************************************************/
6267 IDirect3DDeviceImpl_7_LightEnable(IDirect3DDevice7 *iface,
6271 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
6274 TRACE("iface %p, light_idx %u, enabled %#x.\n", iface, LightIndex, Enable);
6276 EnterCriticalSection(&ddraw_cs);
6277 hr = wined3d_device_set_light_enable(This->wined3d_device, LightIndex, Enable);
6278 LeaveCriticalSection(&ddraw_cs);
6279 return hr_ddraw_from_wined3d(hr);
6282 static HRESULT WINAPI
6283 IDirect3DDeviceImpl_7_LightEnable_FPUSetup(IDirect3DDevice7 *iface,
6287 return IDirect3DDeviceImpl_7_LightEnable(iface, LightIndex, Enable);
6290 static HRESULT WINAPI
6291 IDirect3DDeviceImpl_7_LightEnable_FPUPreserve(IDirect3DDevice7 *iface,
6298 old_fpucw = d3d_fpu_setup();
6299 hr = IDirect3DDeviceImpl_7_LightEnable(iface, LightIndex, Enable);
6300 set_fpu_control_word(old_fpucw);
6305 /*****************************************************************************
6306 * IDirect3DDevice7::GetLightEnable
6308 * Retrieves if the light with the given index is enabled or not
6313 * LightIndex: Index of desired light
6314 * Enable: Pointer to a BOOL which contains the result
6318 * DDERR_INVALIDPARAMS if Enable is NULL
6319 * See IWineD3DDevice::GetLightEnable for more details
6321 *****************************************************************************/
6323 IDirect3DDeviceImpl_7_GetLightEnable(IDirect3DDevice7 *iface,
6327 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
6330 TRACE("iface %p, light_idx %u, enabled %p.\n", iface, LightIndex, Enable);
6333 return DDERR_INVALIDPARAMS;
6335 EnterCriticalSection(&ddraw_cs);
6336 hr = wined3d_device_get_light_enable(This->wined3d_device, LightIndex, Enable);
6337 LeaveCriticalSection(&ddraw_cs);
6338 return hr_ddraw_from_wined3d(hr);
6341 static HRESULT WINAPI
6342 IDirect3DDeviceImpl_7_GetLightEnable_FPUSetup(IDirect3DDevice7 *iface,
6346 return IDirect3DDeviceImpl_7_GetLightEnable(iface, LightIndex, Enable);
6349 static HRESULT WINAPI
6350 IDirect3DDeviceImpl_7_GetLightEnable_FPUPreserve(IDirect3DDevice7 *iface,
6357 old_fpucw = d3d_fpu_setup();
6358 hr = IDirect3DDeviceImpl_7_GetLightEnable(iface, LightIndex, Enable);
6359 set_fpu_control_word(old_fpucw);
6364 /*****************************************************************************
6365 * IDirect3DDevice7::SetClipPlane
6367 * Sets custom clipping plane
6372 * Index: The index of the clipping plane
6373 * PlaneEquation: An equation defining the clipping plane
6377 * DDERR_INVALIDPARAMS if PlaneEquation is NULL
6378 * See IWineD3DDevice::SetClipPlane for more details
6380 *****************************************************************************/
6382 IDirect3DDeviceImpl_7_SetClipPlane(IDirect3DDevice7 *iface,
6384 D3DVALUE* PlaneEquation)
6386 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
6389 TRACE("iface %p, idx %u, plane %p.\n", iface, Index, PlaneEquation);
6392 return DDERR_INVALIDPARAMS;
6394 EnterCriticalSection(&ddraw_cs);
6395 hr = wined3d_device_set_clip_plane(This->wined3d_device, Index, PlaneEquation);
6396 LeaveCriticalSection(&ddraw_cs);
6400 static HRESULT WINAPI
6401 IDirect3DDeviceImpl_7_SetClipPlane_FPUSetup(IDirect3DDevice7 *iface,
6403 D3DVALUE* PlaneEquation)
6405 return IDirect3DDeviceImpl_7_SetClipPlane(iface, Index, PlaneEquation);
6408 static HRESULT WINAPI
6409 IDirect3DDeviceImpl_7_SetClipPlane_FPUPreserve(IDirect3DDevice7 *iface,
6411 D3DVALUE* PlaneEquation)
6416 old_fpucw = d3d_fpu_setup();
6417 hr = IDirect3DDeviceImpl_7_SetClipPlane(iface, Index, PlaneEquation);
6418 set_fpu_control_word(old_fpucw);
6423 /*****************************************************************************
6424 * IDirect3DDevice7::GetClipPlane
6426 * Returns the clipping plane with a specific index
6429 * Index: The index of the desired plane
6430 * PlaneEquation: Address to store the plane equation to
6434 * DDERR_INVALIDPARAMS if PlaneEquation is NULL
6435 * See IWineD3DDevice::GetClipPlane for more details
6437 *****************************************************************************/
6439 IDirect3DDeviceImpl_7_GetClipPlane(IDirect3DDevice7 *iface,
6441 D3DVALUE* PlaneEquation)
6443 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
6446 TRACE("iface %p, idx %u, plane %p.\n", iface, Index, PlaneEquation);
6449 return DDERR_INVALIDPARAMS;
6451 EnterCriticalSection(&ddraw_cs);
6452 hr = wined3d_device_get_clip_plane(This->wined3d_device, Index, PlaneEquation);
6453 LeaveCriticalSection(&ddraw_cs);
6457 static HRESULT WINAPI
6458 IDirect3DDeviceImpl_7_GetClipPlane_FPUSetup(IDirect3DDevice7 *iface,
6460 D3DVALUE* PlaneEquation)
6462 return IDirect3DDeviceImpl_7_GetClipPlane(iface, Index, PlaneEquation);
6465 static HRESULT WINAPI
6466 IDirect3DDeviceImpl_7_GetClipPlane_FPUPreserve(IDirect3DDevice7 *iface,
6468 D3DVALUE* PlaneEquation)
6473 old_fpucw = d3d_fpu_setup();
6474 hr = IDirect3DDeviceImpl_7_GetClipPlane(iface, Index, PlaneEquation);
6475 set_fpu_control_word(old_fpucw);
6480 /*****************************************************************************
6481 * IDirect3DDevice7::GetInfo
6483 * Retrieves some information about the device. The DirectX sdk says that
6484 * this version returns S_FALSE for all retail builds of DirectX, that's what
6485 * this implementation does.
6488 * DevInfoID: Information type requested
6489 * DevInfoStruct: Pointer to a structure to store the info to
6490 * Size: Size of the structure
6493 * S_FALSE, because it's a non-debug driver
6495 *****************************************************************************/
6496 static HRESULT WINAPI
6497 IDirect3DDeviceImpl_7_GetInfo(IDirect3DDevice7 *iface,
6499 void *DevInfoStruct,
6502 TRACE("iface %p, info_id %#x, info %p, info_size %u.\n",
6503 iface, DevInfoID, DevInfoStruct, Size);
6505 if (TRACE_ON(ddraw))
6507 TRACE(" info requested : ");
6510 case D3DDEVINFOID_TEXTUREMANAGER: TRACE("D3DDEVINFOID_TEXTUREMANAGER\n"); break;
6511 case D3DDEVINFOID_D3DTEXTUREMANAGER: TRACE("D3DDEVINFOID_D3DTEXTUREMANAGER\n"); break;
6512 case D3DDEVINFOID_TEXTURING: TRACE("D3DDEVINFOID_TEXTURING\n"); break;
6513 default: ERR(" invalid flag !!!\n"); return DDERR_INVALIDPARAMS;
6517 return S_FALSE; /* According to MSDN, this is valid for a non-debug driver */
6520 /* For performance optimization, devices created in FPUSETUP and FPUPRESERVE modes
6521 * have separate vtables. Simple functions where this doesn't matter like GetDirect3D
6522 * are not duplicated.
6524 * Device created with DDSCL_FPUSETUP (d3d7 default) - device methods assume that FPU
6525 * has already been setup for optimal d3d operation.
6527 * Device created with DDSCL_FPUPRESERVE - resets and restores FPU mode when necessary in
6528 * d3d calls (FPU may be in a mode non-suitable for d3d when the app calls d3d). Required
6529 * by Sacrifice (game). */
6530 static const struct IDirect3DDevice7Vtbl d3d_device7_fpu_setup_vtbl =
6532 /*** IUnknown Methods ***/
6533 IDirect3DDeviceImpl_7_QueryInterface,
6534 IDirect3DDeviceImpl_7_AddRef,
6535 IDirect3DDeviceImpl_7_Release,
6536 /*** IDirect3DDevice7 ***/
6537 IDirect3DDeviceImpl_7_GetCaps_FPUSetup,
6538 IDirect3DDeviceImpl_7_EnumTextureFormats_FPUSetup,
6539 IDirect3DDeviceImpl_7_BeginScene_FPUSetup,
6540 IDirect3DDeviceImpl_7_EndScene_FPUSetup,
6541 IDirect3DDeviceImpl_7_GetDirect3D,
6542 IDirect3DDeviceImpl_7_SetRenderTarget_FPUSetup,
6543 IDirect3DDeviceImpl_7_GetRenderTarget,
6544 IDirect3DDeviceImpl_7_Clear_FPUSetup,
6545 IDirect3DDeviceImpl_7_SetTransform_FPUSetup,
6546 IDirect3DDeviceImpl_7_GetTransform_FPUSetup,
6547 IDirect3DDeviceImpl_7_SetViewport_FPUSetup,
6548 IDirect3DDeviceImpl_7_MultiplyTransform_FPUSetup,
6549 IDirect3DDeviceImpl_7_GetViewport_FPUSetup,
6550 IDirect3DDeviceImpl_7_SetMaterial_FPUSetup,
6551 IDirect3DDeviceImpl_7_GetMaterial_FPUSetup,
6552 IDirect3DDeviceImpl_7_SetLight_FPUSetup,
6553 IDirect3DDeviceImpl_7_GetLight_FPUSetup,
6554 IDirect3DDeviceImpl_7_SetRenderState_FPUSetup,
6555 IDirect3DDeviceImpl_7_GetRenderState_FPUSetup,
6556 IDirect3DDeviceImpl_7_BeginStateBlock_FPUSetup,
6557 IDirect3DDeviceImpl_7_EndStateBlock_FPUSetup,
6558 IDirect3DDeviceImpl_7_PreLoad_FPUSetup,
6559 IDirect3DDeviceImpl_7_DrawPrimitive_FPUSetup,
6560 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUSetup,
6561 IDirect3DDeviceImpl_7_SetClipStatus,
6562 IDirect3DDeviceImpl_7_GetClipStatus,
6563 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUSetup,
6564 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUSetup,
6565 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUSetup,
6566 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUSetup,
6567 IDirect3DDeviceImpl_7_ComputeSphereVisibility,
6568 IDirect3DDeviceImpl_7_GetTexture_FPUSetup,
6569 IDirect3DDeviceImpl_7_SetTexture_FPUSetup,
6570 IDirect3DDeviceImpl_7_GetTextureStageState_FPUSetup,
6571 IDirect3DDeviceImpl_7_SetTextureStageState_FPUSetup,
6572 IDirect3DDeviceImpl_7_ValidateDevice_FPUSetup,
6573 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUSetup,
6574 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUSetup,
6575 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUSetup,
6576 IDirect3DDeviceImpl_7_CreateStateBlock_FPUSetup,
6577 IDirect3DDeviceImpl_7_Load_FPUSetup,
6578 IDirect3DDeviceImpl_7_LightEnable_FPUSetup,
6579 IDirect3DDeviceImpl_7_GetLightEnable_FPUSetup,
6580 IDirect3DDeviceImpl_7_SetClipPlane_FPUSetup,
6581 IDirect3DDeviceImpl_7_GetClipPlane_FPUSetup,
6582 IDirect3DDeviceImpl_7_GetInfo
6585 static const struct IDirect3DDevice7Vtbl d3d_device7_fpu_preserve_vtbl =
6587 /*** IUnknown Methods ***/
6588 IDirect3DDeviceImpl_7_QueryInterface,
6589 IDirect3DDeviceImpl_7_AddRef,
6590 IDirect3DDeviceImpl_7_Release,
6591 /*** IDirect3DDevice7 ***/
6592 IDirect3DDeviceImpl_7_GetCaps_FPUPreserve,
6593 IDirect3DDeviceImpl_7_EnumTextureFormats_FPUPreserve,
6594 IDirect3DDeviceImpl_7_BeginScene_FPUPreserve,
6595 IDirect3DDeviceImpl_7_EndScene_FPUPreserve,
6596 IDirect3DDeviceImpl_7_GetDirect3D,
6597 IDirect3DDeviceImpl_7_SetRenderTarget_FPUPreserve,
6598 IDirect3DDeviceImpl_7_GetRenderTarget,
6599 IDirect3DDeviceImpl_7_Clear_FPUPreserve,
6600 IDirect3DDeviceImpl_7_SetTransform_FPUPreserve,
6601 IDirect3DDeviceImpl_7_GetTransform_FPUPreserve,
6602 IDirect3DDeviceImpl_7_SetViewport_FPUPreserve,
6603 IDirect3DDeviceImpl_7_MultiplyTransform_FPUPreserve,
6604 IDirect3DDeviceImpl_7_GetViewport_FPUPreserve,
6605 IDirect3DDeviceImpl_7_SetMaterial_FPUPreserve,
6606 IDirect3DDeviceImpl_7_GetMaterial_FPUPreserve,
6607 IDirect3DDeviceImpl_7_SetLight_FPUPreserve,
6608 IDirect3DDeviceImpl_7_GetLight_FPUPreserve,
6609 IDirect3DDeviceImpl_7_SetRenderState_FPUPreserve,
6610 IDirect3DDeviceImpl_7_GetRenderState_FPUPreserve,
6611 IDirect3DDeviceImpl_7_BeginStateBlock_FPUPreserve,
6612 IDirect3DDeviceImpl_7_EndStateBlock_FPUPreserve,
6613 IDirect3DDeviceImpl_7_PreLoad_FPUPreserve,
6614 IDirect3DDeviceImpl_7_DrawPrimitive_FPUPreserve,
6615 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUPreserve,
6616 IDirect3DDeviceImpl_7_SetClipStatus,
6617 IDirect3DDeviceImpl_7_GetClipStatus,
6618 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUPreserve,
6619 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUPreserve,
6620 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUPreserve,
6621 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUPreserve,
6622 IDirect3DDeviceImpl_7_ComputeSphereVisibility,
6623 IDirect3DDeviceImpl_7_GetTexture_FPUPreserve,
6624 IDirect3DDeviceImpl_7_SetTexture_FPUPreserve,
6625 IDirect3DDeviceImpl_7_GetTextureStageState_FPUPreserve,
6626 IDirect3DDeviceImpl_7_SetTextureStageState_FPUPreserve,
6627 IDirect3DDeviceImpl_7_ValidateDevice_FPUPreserve,
6628 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUPreserve,
6629 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUPreserve,
6630 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUPreserve,
6631 IDirect3DDeviceImpl_7_CreateStateBlock_FPUPreserve,
6632 IDirect3DDeviceImpl_7_Load_FPUPreserve,
6633 IDirect3DDeviceImpl_7_LightEnable_FPUPreserve,
6634 IDirect3DDeviceImpl_7_GetLightEnable_FPUPreserve,
6635 IDirect3DDeviceImpl_7_SetClipPlane_FPUPreserve,
6636 IDirect3DDeviceImpl_7_GetClipPlane_FPUPreserve,
6637 IDirect3DDeviceImpl_7_GetInfo
6640 static const struct IDirect3DDevice3Vtbl d3d_device3_vtbl =
6642 /*** IUnknown Methods ***/
6643 IDirect3DDeviceImpl_3_QueryInterface,
6644 IDirect3DDeviceImpl_3_AddRef,
6645 IDirect3DDeviceImpl_3_Release,
6646 /*** IDirect3DDevice3 ***/
6647 IDirect3DDeviceImpl_3_GetCaps,
6648 IDirect3DDeviceImpl_3_GetStats,
6649 IDirect3DDeviceImpl_3_AddViewport,
6650 IDirect3DDeviceImpl_3_DeleteViewport,
6651 IDirect3DDeviceImpl_3_NextViewport,
6652 IDirect3DDeviceImpl_3_EnumTextureFormats,
6653 IDirect3DDeviceImpl_3_BeginScene,
6654 IDirect3DDeviceImpl_3_EndScene,
6655 IDirect3DDeviceImpl_3_GetDirect3D,
6656 IDirect3DDeviceImpl_3_SetCurrentViewport,
6657 IDirect3DDeviceImpl_3_GetCurrentViewport,
6658 IDirect3DDeviceImpl_3_SetRenderTarget,
6659 IDirect3DDeviceImpl_3_GetRenderTarget,
6660 IDirect3DDeviceImpl_3_Begin,
6661 IDirect3DDeviceImpl_3_BeginIndexed,
6662 IDirect3DDeviceImpl_3_Vertex,
6663 IDirect3DDeviceImpl_3_Index,
6664 IDirect3DDeviceImpl_3_End,
6665 IDirect3DDeviceImpl_3_GetRenderState,
6666 IDirect3DDeviceImpl_3_SetRenderState,
6667 IDirect3DDeviceImpl_3_GetLightState,
6668 IDirect3DDeviceImpl_3_SetLightState,
6669 IDirect3DDeviceImpl_3_SetTransform,
6670 IDirect3DDeviceImpl_3_GetTransform,
6671 IDirect3DDeviceImpl_3_MultiplyTransform,
6672 IDirect3DDeviceImpl_3_DrawPrimitive,
6673 IDirect3DDeviceImpl_3_DrawIndexedPrimitive,
6674 IDirect3DDeviceImpl_3_SetClipStatus,
6675 IDirect3DDeviceImpl_3_GetClipStatus,
6676 IDirect3DDeviceImpl_3_DrawPrimitiveStrided,
6677 IDirect3DDeviceImpl_3_DrawIndexedPrimitiveStrided,
6678 IDirect3DDeviceImpl_3_DrawPrimitiveVB,
6679 IDirect3DDeviceImpl_3_DrawIndexedPrimitiveVB,
6680 IDirect3DDeviceImpl_3_ComputeSphereVisibility,
6681 IDirect3DDeviceImpl_3_GetTexture,
6682 IDirect3DDeviceImpl_3_SetTexture,
6683 IDirect3DDeviceImpl_3_GetTextureStageState,
6684 IDirect3DDeviceImpl_3_SetTextureStageState,
6685 IDirect3DDeviceImpl_3_ValidateDevice
6688 static const struct IDirect3DDevice2Vtbl d3d_device2_vtbl =
6690 /*** IUnknown Methods ***/
6691 IDirect3DDeviceImpl_2_QueryInterface,
6692 IDirect3DDeviceImpl_2_AddRef,
6693 IDirect3DDeviceImpl_2_Release,
6694 /*** IDirect3DDevice2 ***/
6695 IDirect3DDeviceImpl_2_GetCaps,
6696 IDirect3DDeviceImpl_2_SwapTextureHandles,
6697 IDirect3DDeviceImpl_2_GetStats,
6698 IDirect3DDeviceImpl_2_AddViewport,
6699 IDirect3DDeviceImpl_2_DeleteViewport,
6700 IDirect3DDeviceImpl_2_NextViewport,
6701 IDirect3DDeviceImpl_2_EnumTextureFormats,
6702 IDirect3DDeviceImpl_2_BeginScene,
6703 IDirect3DDeviceImpl_2_EndScene,
6704 IDirect3DDeviceImpl_2_GetDirect3D,
6705 IDirect3DDeviceImpl_2_SetCurrentViewport,
6706 IDirect3DDeviceImpl_2_GetCurrentViewport,
6707 IDirect3DDeviceImpl_2_SetRenderTarget,
6708 IDirect3DDeviceImpl_2_GetRenderTarget,
6709 IDirect3DDeviceImpl_2_Begin,
6710 IDirect3DDeviceImpl_2_BeginIndexed,
6711 IDirect3DDeviceImpl_2_Vertex,
6712 IDirect3DDeviceImpl_2_Index,
6713 IDirect3DDeviceImpl_2_End,
6714 IDirect3DDeviceImpl_2_GetRenderState,
6715 IDirect3DDeviceImpl_2_SetRenderState,
6716 IDirect3DDeviceImpl_2_GetLightState,
6717 IDirect3DDeviceImpl_2_SetLightState,
6718 IDirect3DDeviceImpl_2_SetTransform,
6719 IDirect3DDeviceImpl_2_GetTransform,
6720 IDirect3DDeviceImpl_2_MultiplyTransform,
6721 IDirect3DDeviceImpl_2_DrawPrimitive,
6722 IDirect3DDeviceImpl_2_DrawIndexedPrimitive,
6723 IDirect3DDeviceImpl_2_SetClipStatus,
6724 IDirect3DDeviceImpl_2_GetClipStatus
6727 static const struct IDirect3DDeviceVtbl d3d_device1_vtbl =
6729 /*** IUnknown Methods ***/
6730 IDirect3DDeviceImpl_1_QueryInterface,
6731 IDirect3DDeviceImpl_1_AddRef,
6732 IDirect3DDeviceImpl_1_Release,
6733 /*** IDirect3DDevice1 ***/
6734 IDirect3DDeviceImpl_1_Initialize,
6735 IDirect3DDeviceImpl_1_GetCaps,
6736 IDirect3DDeviceImpl_1_SwapTextureHandles,
6737 IDirect3DDeviceImpl_1_CreateExecuteBuffer,
6738 IDirect3DDeviceImpl_1_GetStats,
6739 IDirect3DDeviceImpl_1_Execute,
6740 IDirect3DDeviceImpl_1_AddViewport,
6741 IDirect3DDeviceImpl_1_DeleteViewport,
6742 IDirect3DDeviceImpl_1_NextViewport,
6743 IDirect3DDeviceImpl_1_Pick,
6744 IDirect3DDeviceImpl_1_GetPickRecords,
6745 IDirect3DDeviceImpl_1_EnumTextureFormats,
6746 IDirect3DDeviceImpl_1_CreateMatrix,
6747 IDirect3DDeviceImpl_1_SetMatrix,
6748 IDirect3DDeviceImpl_1_GetMatrix,
6749 IDirect3DDeviceImpl_1_DeleteMatrix,
6750 IDirect3DDeviceImpl_1_BeginScene,
6751 IDirect3DDeviceImpl_1_EndScene,
6752 IDirect3DDeviceImpl_1_GetDirect3D
6755 /*****************************************************************************
6756 * IDirect3DDeviceImpl_UpdateDepthStencil
6758 * Checks the current render target for attached depth stencils and sets the
6759 * WineD3D depth stencil accordingly.
6762 * The depth stencil state to set if creating the device
6764 *****************************************************************************/
6766 IDirect3DDeviceImpl_UpdateDepthStencil(IDirect3DDeviceImpl *This)
6768 IDirectDrawSurface7 *depthStencil = NULL;
6769 IDirectDrawSurfaceImpl *dsi;
6770 static DDSCAPS2 depthcaps = { DDSCAPS_ZBUFFER, 0, 0, 0 };
6772 IDirectDrawSurface7_GetAttachedSurface(&This->target->IDirectDrawSurface7_iface, &depthcaps, &depthStencil);
6775 TRACE("Setting wined3d depth stencil to NULL\n");
6776 wined3d_device_set_depth_stencil(This->wined3d_device, NULL);
6777 return WINED3DZB_FALSE;
6780 dsi = impl_from_IDirectDrawSurface7(depthStencil);
6781 TRACE("Setting wined3d depth stencil to %p (wined3d %p)\n", dsi, dsi->wined3d_surface);
6782 wined3d_device_set_depth_stencil(This->wined3d_device, dsi->wined3d_surface);
6784 IDirectDrawSurface7_Release(depthStencil);
6785 return WINED3DZB_TRUE;
6788 HRESULT d3d_device_init(IDirect3DDeviceImpl *device, IDirectDrawImpl *ddraw, IDirectDrawSurfaceImpl *target)
6792 if (ddraw->cooperative_level & DDSCL_FPUPRESERVE)
6793 device->lpVtbl = &d3d_device7_fpu_preserve_vtbl;
6795 device->lpVtbl = &d3d_device7_fpu_setup_vtbl;
6797 device->IDirect3DDevice3_vtbl = &d3d_device3_vtbl;
6798 device->IDirect3DDevice2_vtbl = &d3d_device2_vtbl;
6799 device->IDirect3DDevice_vtbl = &d3d_device1_vtbl;
6801 device->ddraw = ddraw;
6802 device->target = target;
6803 list_init(&device->viewport_list);
6805 if (!ddraw_handle_table_init(&device->handle_table, 64))
6807 ERR("Failed to initialize handle table.\n");
6808 return DDERR_OUTOFMEMORY;
6811 device->legacyTextureBlending = FALSE;
6813 /* Create an index buffer, it's needed for indexed drawing */
6814 hr = wined3d_buffer_create_ib(ddraw->wined3d_device, 0x40000 /* Length. Don't know how long it should be */,
6815 WINED3DUSAGE_DYNAMIC /* Usage */, WINED3DPOOL_DEFAULT, NULL,
6816 &ddraw_null_wined3d_parent_ops, &device->indexbuffer);
6819 ERR("Failed to create an index buffer, hr %#x.\n", hr);
6820 ddraw_handle_table_destroy(&device->handle_table);
6824 /* This is for convenience. */
6825 device->wined3d_device = ddraw->wined3d_device;
6826 wined3d_device_incref(ddraw->wined3d_device);
6828 /* Render to the back buffer */
6829 hr = wined3d_device_set_render_target(ddraw->wined3d_device, 0, target->wined3d_surface, TRUE);
6832 ERR("Failed to set render target, hr %#x.\n", hr);
6833 wined3d_buffer_decref(device->indexbuffer);
6834 ddraw_handle_table_destroy(&device->handle_table);
6838 /* FIXME: This is broken. The target AddRef() makes some sense, because
6839 * we store a pointer during initialization, but then that's also where
6840 * the AddRef() should be. We don't store ddraw->d3d_target anywhere. */
6841 /* AddRef the render target. Also AddRef the render target from ddraw,
6842 * because if it is released before the app releases the D3D device, the
6843 * D3D capabilities of wined3d will be uninitialized, which has bad effects.
6845 * In most cases, those surfaces are the same anyway, but this will simply
6846 * add another ref which is released when the device is destroyed. */
6847 IDirectDrawSurface7_AddRef(&target->IDirectDrawSurface7_iface);
6848 IDirectDrawSurface7_AddRef(&ddraw->d3d_target->IDirectDrawSurface7_iface);
6850 ddraw->d3ddevice = device;
6852 wined3d_device_set_render_state(ddraw->wined3d_device, WINED3DRS_ZENABLE,
6853 IDirect3DDeviceImpl_UpdateDepthStencil(device));