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 = impl_from_IDirect3DDevice7(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_iface;
167 TRACE("(%p) Returning IDirect3DDevice interface at %p\n", This, *obj);
169 else if ( IsEqualGUID( &IID_IDirect3DDevice2 , refiid ) ) {
170 *obj = &This->IDirect3DDevice2_iface;
171 TRACE("(%p) Returning IDirect3DDevice2 interface at %p\n", This, *obj);
173 else if ( IsEqualGUID( &IID_IDirect3DDevice3 , refiid ) ) {
174 *obj = &This->IDirect3DDevice3_iface;
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 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice3(iface);
198 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), obj);
200 return IDirect3DDevice7_QueryInterface(&This->IDirect3DDevice7_iface, riid, obj);
203 static HRESULT WINAPI IDirect3DDeviceImpl_2_QueryInterface(IDirect3DDevice2 *iface, REFIID riid,
206 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice2(iface);
207 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), obj);
209 return IDirect3DDevice7_QueryInterface(&This->IDirect3DDevice7_iface, riid, obj);
212 static HRESULT WINAPI IDirect3DDeviceImpl_1_QueryInterface(IDirect3DDevice *iface, REFIID riid,
215 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice(iface);
216 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), obp);
218 return IDirect3DDevice7_QueryInterface(&This->IDirect3DDevice7_iface, riid, obp);
221 /*****************************************************************************
222 * IDirect3DDevice7::AddRef
224 * Increases the refcount....
225 * The most exciting Method, definitely
227 * Exists in Version 1, 2, 3 and 7
232 *****************************************************************************/
234 IDirect3DDeviceImpl_7_AddRef(IDirect3DDevice7 *iface)
236 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice7(iface);
237 ULONG ref = InterlockedIncrement(&This->ref);
239 TRACE("%p increasing refcount to %u.\n", This, ref);
244 static ULONG WINAPI IDirect3DDeviceImpl_3_AddRef(IDirect3DDevice3 *iface)
246 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice3(iface);
247 TRACE("iface %p.\n", iface);
249 return IDirect3DDevice7_AddRef(&This->IDirect3DDevice7_iface);
252 static ULONG WINAPI IDirect3DDeviceImpl_2_AddRef(IDirect3DDevice2 *iface)
254 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice2(iface);
255 TRACE("iface %p.\n", iface);
257 return IDirect3DDevice7_AddRef(&This->IDirect3DDevice7_iface);
260 static ULONG WINAPI IDirect3DDeviceImpl_1_AddRef(IDirect3DDevice *iface)
262 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice(iface);
263 TRACE("iface %p.\n", iface);
265 return IDirect3DDevice7_AddRef(&This->IDirect3DDevice7_iface);
268 /*****************************************************************************
269 * IDirect3DDevice7::Release
271 * Decreases the refcount of the interface
272 * When the refcount is reduced to 0, the object is destroyed.
274 * Exists in Version 1, 2, 3 and 7
279 *****************************************************************************/
281 IDirect3DDeviceImpl_7_Release(IDirect3DDevice7 *iface)
283 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice7(iface);
284 ULONG ref = InterlockedDecrement(&This->ref);
286 TRACE("%p decreasing refcount to %u.\n", This, ref);
288 /* This method doesn't destroy the WineD3DDevice, because it's still in use for
289 * 2D rendering. IDirectDrawSurface7::Release will destroy the WineD3DDevice
290 * when the render target is released
296 wined3d_mutex_lock();
298 /* There is no need to unset any resources here, wined3d will take
299 * care of that on Uninit3D(). */
301 /* Free the index buffer. */
302 wined3d_buffer_decref(This->indexbuffer);
304 /* Set the device up to render to the front buffer since the back
305 * buffer will vanish soon. */
306 wined3d_device_set_render_target(This->wined3d_device, 0,
307 This->ddraw->d3d_target->wined3d_surface, TRUE);
309 /* Release the WineD3DDevice. This won't destroy it. */
310 if (!wined3d_device_decref(This->wined3d_device))
311 ERR("The wined3d device (%p) was destroyed unexpectedly.\n", This->wined3d_device);
313 /* The texture handles should be unset by now, but there might be some bits
314 * missing in our reference counting(needs test). Do a sanity check. */
315 for (i = 0; i < This->handle_table.entry_count; ++i)
317 struct ddraw_handle_entry *entry = &This->handle_table.entries[i];
321 case DDRAW_HANDLE_FREE:
324 case DDRAW_HANDLE_MATERIAL:
326 IDirect3DMaterialImpl *m = entry->object;
327 FIXME("Material handle %#x (%p) not unset properly.\n", i + 1, m);
332 case DDRAW_HANDLE_MATRIX:
334 /* No FIXME here because this might happen because of sloppy applications. */
335 WARN("Leftover matrix handle %#x (%p), deleting.\n", i + 1, entry->object);
336 IDirect3DDevice_DeleteMatrix(&This->IDirect3DDevice_iface, i + 1);
340 case DDRAW_HANDLE_STATEBLOCK:
342 /* No FIXME here because this might happen because of sloppy applications. */
343 WARN("Leftover stateblock handle %#x (%p), deleting.\n", i + 1, entry->object);
344 IDirect3DDevice7_DeleteStateBlock(iface, i + 1);
348 case DDRAW_HANDLE_SURFACE:
350 IDirectDrawSurfaceImpl *surf = entry->object;
351 FIXME("Texture handle %#x (%p) not unset properly.\n", i + 1, surf);
357 FIXME("Handle %#x (%p) has unknown type %#x.\n", i + 1, entry->object, entry->type);
362 ddraw_handle_table_destroy(&This->handle_table);
364 TRACE("Releasing target %p %p\n", This->target, This->ddraw->d3d_target);
365 /* Release the render target and the WineD3D render target
366 * (See IDirect3D7::CreateDevice for more comments on this)
368 IDirectDrawSurface7_Release(&This->target->IDirectDrawSurface7_iface);
369 IDirectDrawSurface7_Release(&This->ddraw->d3d_target->IDirectDrawSurface7_iface);
370 TRACE("Target release done\n");
372 This->ddraw->d3ddevice = NULL;
374 /* Now free the structure */
375 HeapFree(GetProcessHeap(), 0, This);
376 wined3d_mutex_unlock();
383 static ULONG WINAPI IDirect3DDeviceImpl_3_Release(IDirect3DDevice3 *iface)
385 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice3(iface);
386 TRACE("iface %p.\n", iface);
388 return IDirect3DDevice7_Release(&This->IDirect3DDevice7_iface);
391 static ULONG WINAPI IDirect3DDeviceImpl_2_Release(IDirect3DDevice2 *iface)
393 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice2(iface);
394 TRACE("iface %p.\n", iface);
396 return IDirect3DDevice7_Release(&This->IDirect3DDevice7_iface);
399 static ULONG WINAPI IDirect3DDeviceImpl_1_Release(IDirect3DDevice *iface)
401 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice(iface);
402 TRACE("iface %p.\n", iface);
404 return IDirect3DDevice7_Release(&This->IDirect3DDevice7_iface);
407 /*****************************************************************************
408 * IDirect3DDevice Methods
409 *****************************************************************************/
411 /*****************************************************************************
412 * IDirect3DDevice::Initialize
414 * Initializes a Direct3DDevice. This implementation is a no-op, as all
415 * initialization is done at create time.
417 * Exists in Version 1
420 * No idea what they mean, as the MSDN page is gone
424 *****************************************************************************/
425 static HRESULT WINAPI
426 IDirect3DDeviceImpl_1_Initialize(IDirect3DDevice *iface,
427 IDirect3D *Direct3D, GUID *guid,
430 /* It shouldn't be crucial, but print a FIXME, I'm interested if
431 * any game calls it and when. */
432 FIXME("iface %p, d3d %p, guid %s, device_desc %p nop!\n",
433 iface, Direct3D, debugstr_guid(guid), Desc);
438 /*****************************************************************************
439 * IDirect3DDevice7::GetCaps
441 * Retrieves the device's capabilities
443 * This implementation is used for Version 7 only, the older versions have
444 * their own implementation.
447 * Desc: Pointer to a D3DDEVICEDESC7 structure to fill
451 * D3DERR_* if a problem occurs. See WineD3D
453 *****************************************************************************/
455 IDirect3DDeviceImpl_7_GetCaps(IDirect3DDevice7 *iface,
456 D3DDEVICEDESC7 *Desc)
458 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice7(iface);
459 D3DDEVICEDESC OldDesc;
461 TRACE("iface %p, device_desc %p.\n", iface, Desc);
463 /* Call the same function used by IDirect3D, this saves code */
464 return IDirect3DImpl_GetCaps(This->ddraw->wineD3D, &OldDesc, Desc);
467 static HRESULT WINAPI
468 IDirect3DDeviceImpl_7_GetCaps_FPUSetup(IDirect3DDevice7 *iface,
469 D3DDEVICEDESC7 *Desc)
471 return IDirect3DDeviceImpl_7_GetCaps(iface, Desc);
474 static HRESULT WINAPI
475 IDirect3DDeviceImpl_7_GetCaps_FPUPreserve(IDirect3DDevice7 *iface,
476 D3DDEVICEDESC7 *Desc)
481 old_fpucw = d3d_fpu_setup();
482 hr = IDirect3DDeviceImpl_7_GetCaps(iface, Desc);
483 set_fpu_control_word(old_fpucw);
487 /*****************************************************************************
488 * IDirect3DDevice3::GetCaps
490 * Retrieves the capabilities of the hardware device and the emulation
491 * device. For Wine, hardware and emulation are the same (it's all HW).
493 * This implementation is used for Version 1, 2, and 3. Version 7 has its own
496 * HWDesc: Structure to fill with the HW caps
497 * HelDesc: Structure to fill with the hardware emulation caps
501 * D3DERR_* if a problem occurs. See WineD3D
503 *****************************************************************************/
504 static HRESULT WINAPI
505 IDirect3DDeviceImpl_3_GetCaps(IDirect3DDevice3 *iface,
506 D3DDEVICEDESC *HWDesc,
507 D3DDEVICEDESC *HelDesc)
509 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice3(iface);
510 D3DDEVICEDESC7 newDesc;
513 TRACE("iface %p, hw_desc %p, hel_desc %p.\n", iface, HWDesc, HelDesc);
515 hr = IDirect3DImpl_GetCaps(This->ddraw->wineD3D, HWDesc, &newDesc);
516 if(hr != D3D_OK) return hr;
522 static HRESULT WINAPI IDirect3DDeviceImpl_2_GetCaps(IDirect3DDevice2 *iface,
523 D3DDEVICEDESC *D3DHWDevDesc, D3DDEVICEDESC *D3DHELDevDesc)
525 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice2(iface);
526 TRACE("iface %p, hw_desc %p, hel_desc %p.\n", iface, D3DHWDevDesc, D3DHELDevDesc);
527 return IDirect3DDevice3_GetCaps(&This->IDirect3DDevice3_iface, D3DHWDevDesc, D3DHELDevDesc);
530 static HRESULT WINAPI IDirect3DDeviceImpl_1_GetCaps(IDirect3DDevice *iface,
531 D3DDEVICEDESC *D3DHWDevDesc, D3DDEVICEDESC *D3DHELDevDesc)
533 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice(iface);
534 TRACE("iface %p, hw_desc %p, hel_desc %p.\n", iface, D3DHWDevDesc, D3DHELDevDesc);
535 return IDirect3DDevice3_GetCaps(&This->IDirect3DDevice3_iface, D3DHWDevDesc, D3DHELDevDesc);
538 /*****************************************************************************
539 * IDirect3DDevice2::SwapTextureHandles
541 * Swaps the texture handles of 2 Texture interfaces. Version 1 and 2
544 * Tex1, Tex2: The 2 Textures to swap
549 *****************************************************************************/
550 static HRESULT WINAPI
551 IDirect3DDeviceImpl_2_SwapTextureHandles(IDirect3DDevice2 *iface,
552 IDirect3DTexture2 *Tex1,
553 IDirect3DTexture2 *Tex2)
555 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice2(iface);
556 IDirectDrawSurfaceImpl *surf1 = unsafe_impl_from_IDirect3DTexture2(Tex1);
557 IDirectDrawSurfaceImpl *surf2 = unsafe_impl_from_IDirect3DTexture2(Tex2);
560 TRACE("iface %p, tex1 %p, tex2 %p.\n", iface, Tex1, Tex2);
562 wined3d_mutex_lock();
564 h1 = surf1->Handle - 1;
565 h2 = surf2->Handle - 1;
566 This->handle_table.entries[h1].object = surf2;
567 This->handle_table.entries[h2].object = surf1;
568 surf2->Handle = h1 + 1;
569 surf1->Handle = h2 + 1;
571 wined3d_mutex_unlock();
576 static HRESULT WINAPI IDirect3DDeviceImpl_1_SwapTextureHandles(IDirect3DDevice *iface,
577 IDirect3DTexture *D3DTex1, IDirect3DTexture *D3DTex2)
579 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice(iface);
580 IDirectDrawSurfaceImpl *surf1 = unsafe_impl_from_IDirect3DTexture(D3DTex1);
581 IDirectDrawSurfaceImpl *surf2 = unsafe_impl_from_IDirect3DTexture(D3DTex2);
582 IDirect3DTexture2 *t1 = surf1 ? &surf1->IDirect3DTexture2_iface : NULL;
583 IDirect3DTexture2 *t2 = surf2 ? &surf2->IDirect3DTexture2_iface : NULL;
585 TRACE("iface %p, tex1 %p, tex2 %p.\n", iface, D3DTex1, D3DTex2);
587 return IDirect3DDevice2_SwapTextureHandles(&This->IDirect3DDevice2_iface, t1, t2);
590 /*****************************************************************************
591 * IDirect3DDevice3::GetStats
593 * This method seems to retrieve some stats from the device.
594 * The MSDN documentation doesn't exist any more, but the D3DSTATS
595 * structure suggests that the amount of drawn primitives and processed
596 * vertices is returned.
598 * Exists in Version 1, 2 and 3
601 * Stats: Pointer to a D3DSTATS structure to be filled
605 * DDERR_INVALIDPARAMS if Stats == NULL
607 *****************************************************************************/
608 static HRESULT WINAPI
609 IDirect3DDeviceImpl_3_GetStats(IDirect3DDevice3 *iface,
612 FIXME("iface %p, stats %p stub!\n", iface, Stats);
615 return DDERR_INVALIDPARAMS;
617 /* Fill the Stats with 0 */
618 Stats->dwTrianglesDrawn = 0;
619 Stats->dwLinesDrawn = 0;
620 Stats->dwPointsDrawn = 0;
621 Stats->dwSpansDrawn = 0;
622 Stats->dwVerticesProcessed = 0;
627 static HRESULT WINAPI IDirect3DDeviceImpl_2_GetStats(IDirect3DDevice2 *iface, D3DSTATS *Stats)
629 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice2(iface);
631 TRACE("iface %p, stats %p.\n", iface, Stats);
633 return IDirect3DDevice3_GetStats(&This->IDirect3DDevice3_iface, Stats);
636 static HRESULT WINAPI IDirect3DDeviceImpl_1_GetStats(IDirect3DDevice *iface, D3DSTATS *Stats)
638 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice(iface);
640 TRACE("iface %p, stats %p.\n", iface, Stats);
642 return IDirect3DDevice3_GetStats(&This->IDirect3DDevice3_iface, Stats);
645 /*****************************************************************************
646 * IDirect3DDevice::CreateExecuteBuffer
648 * Creates an IDirect3DExecuteBuffer, used for rendering with a
654 * Desc: Buffer description
655 * ExecuteBuffer: Address to return the Interface pointer at
656 * UnkOuter: Must be NULL. Basically for aggregation, which ddraw doesn't
660 * CLASS_E_NOAGGREGATION if UnkOuter != NULL
661 * DDERR_OUTOFMEMORY if we ran out of memory
664 *****************************************************************************/
665 static HRESULT WINAPI
666 IDirect3DDeviceImpl_1_CreateExecuteBuffer(IDirect3DDevice *iface,
667 D3DEXECUTEBUFFERDESC *Desc,
668 IDirect3DExecuteBuffer **ExecuteBuffer,
671 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice(iface);
672 IDirect3DExecuteBufferImpl* object;
675 TRACE("iface %p, buffer_desc %p, buffer %p, outer_unknown %p.\n",
676 iface, Desc, ExecuteBuffer, UnkOuter);
679 return CLASS_E_NOAGGREGATION;
681 /* Allocate the new Execute Buffer */
682 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DExecuteBufferImpl));
685 ERR("Out of memory when allocating a IDirect3DExecuteBufferImpl structure\n");
686 return DDERR_OUTOFMEMORY;
689 hr = d3d_execute_buffer_init(object, This, Desc);
692 WARN("Failed to initialize execute buffer, hr %#x.\n", hr);
693 HeapFree(GetProcessHeap(), 0, object);
697 *ExecuteBuffer = &object->IDirect3DExecuteBuffer_iface;
699 TRACE(" Returning IDirect3DExecuteBuffer at %p, implementation is at %p\n", *ExecuteBuffer, object);
704 /*****************************************************************************
705 * IDirect3DDevice::Execute
707 * Executes all the stuff in an execute buffer.
710 * ExecuteBuffer: The buffer to execute
711 * Viewport: The viewport used for rendering
715 * DDERR_INVALIDPARAMS if ExecuteBuffer == NULL
718 *****************************************************************************/
719 static HRESULT WINAPI IDirect3DDeviceImpl_1_Execute(IDirect3DDevice *iface,
720 IDirect3DExecuteBuffer *ExecuteBuffer, IDirect3DViewport *Viewport, DWORD Flags)
722 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice(iface);
723 IDirect3DExecuteBufferImpl *buffer = unsafe_impl_from_IDirect3DExecuteBuffer(ExecuteBuffer);
724 IDirect3DViewportImpl *Direct3DViewportImpl = unsafe_impl_from_IDirect3DViewport(Viewport);
727 TRACE("iface %p, buffer %p, viewport %p, flags %#x.\n", iface, ExecuteBuffer, Viewport, Flags);
730 return DDERR_INVALIDPARAMS;
733 wined3d_mutex_lock();
734 hr = d3d_execute_buffer_execute(buffer, This, Direct3DViewportImpl);
735 wined3d_mutex_unlock();
740 /*****************************************************************************
741 * IDirect3DDevice3::AddViewport
743 * Add a Direct3DViewport to the device's viewport list. These viewports
744 * are wrapped to IDirect3DDevice7 viewports in viewport.c
746 * Exists in Version 1, 2 and 3. Note that IDirect3DViewport 1, 2 and 3
747 * are the same interfaces.
750 * Viewport: The viewport to add
753 * DDERR_INVALIDPARAMS if Viewport == NULL
756 *****************************************************************************/
757 static HRESULT WINAPI
758 IDirect3DDeviceImpl_3_AddViewport(IDirect3DDevice3 *iface,
759 IDirect3DViewport3 *Viewport)
761 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice3(iface);
762 IDirect3DViewportImpl *vp = unsafe_impl_from_IDirect3DViewport3(Viewport);
764 TRACE("iface %p, viewport %p.\n", iface, Viewport);
768 return DDERR_INVALIDPARAMS;
770 wined3d_mutex_lock();
771 list_add_head(&This->viewport_list, &vp->entry);
772 vp->active_device = This; /* Viewport must be usable for Clear() after AddViewport,
773 so set active_device here. */
774 wined3d_mutex_unlock();
779 static HRESULT WINAPI IDirect3DDeviceImpl_2_AddViewport(IDirect3DDevice2 *iface,
780 IDirect3DViewport2 *Direct3DViewport2)
782 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice2(iface);
783 IDirect3DViewportImpl *vp = unsafe_impl_from_IDirect3DViewport2(Direct3DViewport2);
785 TRACE("iface %p, viewport %p.\n", iface, Direct3DViewport2);
787 return IDirect3DDevice3_AddViewport(&This->IDirect3DDevice3_iface, &vp->IDirect3DViewport3_iface);
790 static HRESULT WINAPI IDirect3DDeviceImpl_1_AddViewport(IDirect3DDevice *iface,
791 IDirect3DViewport *Direct3DViewport)
793 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice(iface);
794 IDirect3DViewportImpl *vp = unsafe_impl_from_IDirect3DViewport(Direct3DViewport);
796 TRACE("iface %p, viewport %p.\n", iface, Direct3DViewport);
798 return IDirect3DDevice3_AddViewport(&This->IDirect3DDevice3_iface, &vp->IDirect3DViewport3_iface);
801 /*****************************************************************************
802 * IDirect3DDevice3::DeleteViewport
804 * Deletes a Direct3DViewport from the device's viewport list.
806 * Exists in Version 1, 2 and 3. Note that all Viewport interface versions
810 * Viewport: The viewport to delete
814 * DDERR_INVALIDPARAMS if the viewport wasn't found in the list
816 *****************************************************************************/
817 static HRESULT WINAPI IDirect3DDeviceImpl_3_DeleteViewport(IDirect3DDevice3 *iface, IDirect3DViewport3 *viewport)
819 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice3(iface);
820 IDirect3DViewportImpl *vp = unsafe_impl_from_IDirect3DViewport3(viewport);
822 TRACE("iface %p, viewport %p.\n", iface, viewport);
824 wined3d_mutex_lock();
826 if (vp->active_device != This)
828 WARN("Viewport %p active device is %p.\n", vp, vp->active_device);
829 wined3d_mutex_unlock();
830 return DDERR_INVALIDPARAMS;
833 vp->active_device = NULL;
834 list_remove(&vp->entry);
836 wined3d_mutex_unlock();
841 static HRESULT WINAPI IDirect3DDeviceImpl_2_DeleteViewport(IDirect3DDevice2 *iface,
842 IDirect3DViewport2 *Direct3DViewport2)
844 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice2(iface);
845 IDirect3DViewportImpl *vp = unsafe_impl_from_IDirect3DViewport2(Direct3DViewport2);
847 TRACE("iface %p, viewport %p.\n", iface, Direct3DViewport2);
849 return IDirect3DDevice3_DeleteViewport(&This->IDirect3DDevice3_iface, &vp->IDirect3DViewport3_iface);
852 static HRESULT WINAPI IDirect3DDeviceImpl_1_DeleteViewport(IDirect3DDevice *iface,
853 IDirect3DViewport *Direct3DViewport)
855 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice(iface);
856 IDirect3DViewportImpl *vp = unsafe_impl_from_IDirect3DViewport(Direct3DViewport);
858 TRACE("iface %p, viewport %p.\n", iface, Direct3DViewport);
860 return IDirect3DDevice3_DeleteViewport(&This->IDirect3DDevice3_iface, &vp->IDirect3DViewport3_iface);
863 /*****************************************************************************
864 * IDirect3DDevice3::NextViewport
866 * Returns a viewport from the viewport list, depending on the
867 * passed viewport and the flags.
869 * Exists in Version 1, 2 and 3. Note that all Viewport interface versions
873 * Viewport: Viewport to use for beginning the search
874 * Flags: D3DNEXT_NEXT, D3DNEXT_HEAD or D3DNEXT_TAIL
878 * DDERR_INVALIDPARAMS if the flags were wrong, or Viewport was NULL
880 *****************************************************************************/
881 static HRESULT WINAPI
882 IDirect3DDeviceImpl_3_NextViewport(IDirect3DDevice3 *iface,
883 IDirect3DViewport3 *Viewport3,
884 IDirect3DViewport3 **lplpDirect3DViewport3,
887 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice3(iface);
888 IDirect3DViewportImpl *vp = unsafe_impl_from_IDirect3DViewport3(Viewport3);
889 IDirect3DViewportImpl *next;
892 TRACE("iface %p, viewport %p, next %p, flags %#x.\n",
893 iface, Viewport3, lplpDirect3DViewport3, Flags);
897 *lplpDirect3DViewport3 = NULL;
898 return DDERR_INVALIDPARAMS;
902 wined3d_mutex_lock();
906 entry = list_next(&This->viewport_list, &vp->entry);
910 entry = list_head(&This->viewport_list);
914 entry = list_tail(&This->viewport_list);
918 WARN("Invalid flags %#x.\n", Flags);
919 *lplpDirect3DViewport3 = NULL;
920 wined3d_mutex_unlock();
921 return DDERR_INVALIDPARAMS;
926 next = LIST_ENTRY(entry, IDirect3DViewportImpl, entry);
927 *lplpDirect3DViewport3 = &next->IDirect3DViewport3_iface;
930 *lplpDirect3DViewport3 = NULL;
932 wined3d_mutex_unlock();
937 static HRESULT WINAPI IDirect3DDeviceImpl_2_NextViewport(IDirect3DDevice2 *iface,
938 IDirect3DViewport2 *Viewport2, IDirect3DViewport2 **lplpDirect3DViewport2, DWORD Flags)
940 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice2(iface);
941 IDirect3DViewportImpl *vp = unsafe_impl_from_IDirect3DViewport2(Viewport2);
942 IDirect3DViewport3 *res;
945 TRACE("iface %p, viewport %p, next %p, flags %#x.\n",
946 iface, Viewport2, lplpDirect3DViewport2, Flags);
948 hr = IDirect3DDevice3_NextViewport(&This->IDirect3DDevice3_iface,
949 &vp->IDirect3DViewport3_iface, &res, Flags);
950 *lplpDirect3DViewport2 = (IDirect3DViewport2 *)res;
954 static HRESULT WINAPI IDirect3DDeviceImpl_1_NextViewport(IDirect3DDevice *iface,
955 IDirect3DViewport *Viewport, IDirect3DViewport **lplpDirect3DViewport, DWORD Flags)
957 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice(iface);
958 IDirect3DViewportImpl *vp = unsafe_impl_from_IDirect3DViewport(Viewport);
959 IDirect3DViewport3 *res;
962 TRACE("iface %p, viewport %p, next %p, flags %#x.\n",
963 iface, Viewport, lplpDirect3DViewport, Flags);
965 hr = IDirect3DDevice3_NextViewport(&This->IDirect3DDevice3_iface,
966 &vp->IDirect3DViewport3_iface, &res, Flags);
967 *lplpDirect3DViewport = (IDirect3DViewport *)res;
971 /*****************************************************************************
972 * IDirect3DDevice::Pick
974 * Executes an execute buffer without performing rendering. Instead, a
975 * list of primitives that intersect with (x1,y1) of the passed rectangle
976 * is created. IDirect3DDevice::GetPickRecords can be used to retrieve
982 * ExecuteBuffer: Buffer to execute
983 * Viewport: Viewport to use for execution
984 * Flags: None are defined, according to the SDK
985 * Rect: Specifies the coordinates to be picked. Only x1 and y2 are used,
986 * x2 and y2 are ignored.
989 * D3D_OK because it's a stub
991 *****************************************************************************/
992 static HRESULT WINAPI
993 IDirect3DDeviceImpl_1_Pick(IDirect3DDevice *iface,
994 IDirect3DExecuteBuffer *ExecuteBuffer,
995 IDirect3DViewport *Viewport,
999 FIXME("iface %p, buffer %p, viewport %p, flags %#x, rect %s stub!\n",
1000 iface, ExecuteBuffer, Viewport, Flags, wine_dbgstr_rect((RECT *)Rect));
1005 /*****************************************************************************
1006 * IDirect3DDevice::GetPickRecords
1008 * Retrieves the pick records generated by IDirect3DDevice::GetPickRecords
1013 * Count: Pointer to a DWORD containing the numbers of pick records to
1015 * D3DPickRec: Address to store the resulting D3DPICKRECORD array.
1018 * D3D_OK, because it's a stub
1020 *****************************************************************************/
1021 static HRESULT WINAPI
1022 IDirect3DDeviceImpl_1_GetPickRecords(IDirect3DDevice *iface,
1024 D3DPICKRECORD *D3DPickRec)
1026 FIXME("iface %p, count %p, records %p stub!\n", iface, Count, D3DPickRec);
1031 /*****************************************************************************
1032 * IDirect3DDevice7::EnumTextureformats
1034 * Enumerates the supported texture formats. It has a list of all possible
1035 * formats and calls IWineD3D::CheckDeviceFormat for each format to see if
1036 * WineD3D supports it. If so, then it is passed to the app.
1038 * This is for Version 7 and 3, older versions have a different
1039 * callback function and their own implementation
1042 * Callback: Callback to call for each enumerated format
1043 * Arg: Argument to pass to the callback
1047 * DDERR_INVALIDPARAMS if Callback == NULL
1049 *****************************************************************************/
1051 IDirect3DDeviceImpl_7_EnumTextureFormats(IDirect3DDevice7 *iface,
1052 LPD3DENUMPIXELFORMATSCALLBACK Callback,
1055 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice7(iface);
1056 struct wined3d_display_mode mode;
1060 static const enum wined3d_format_id FormatList[] =
1063 WINED3DFMT_B8G8R8A8_UNORM,
1064 WINED3DFMT_B8G8R8X8_UNORM,
1066 WINED3DFMT_B8G8R8_UNORM,
1068 WINED3DFMT_B5G5R5A1_UNORM,
1069 WINED3DFMT_B4G4R4A4_UNORM,
1070 WINED3DFMT_B5G6R5_UNORM,
1071 WINED3DFMT_B5G5R5X1_UNORM,
1073 WINED3DFMT_B2G3R3_UNORM,
1081 static const enum wined3d_format_id BumpFormatList[] =
1083 WINED3DFMT_R8G8_SNORM,
1084 WINED3DFMT_R5G5_SNORM_L6_UNORM,
1085 WINED3DFMT_R8G8_SNORM_L8X8_UNORM,
1086 WINED3DFMT_R16G16_SNORM,
1087 WINED3DFMT_R10G11B11_SNORM,
1088 WINED3DFMT_R10G10B10_SNORM_A2_UNORM
1091 TRACE("iface %p, callback %p, context %p.\n", iface, Callback, Arg);
1094 return DDERR_INVALIDPARAMS;
1096 wined3d_mutex_lock();
1098 memset(&mode, 0, sizeof(mode));
1099 hr = wined3d_device_get_display_mode(This->ddraw->wined3d_device, 0, &mode);
1102 wined3d_mutex_unlock();
1103 WARN("Cannot get the current adapter format\n");
1107 for (i = 0; i < sizeof(FormatList) / sizeof(*FormatList); ++i)
1109 hr = wined3d_check_device_format(This->ddraw->wineD3D, WINED3DADAPTER_DEFAULT, WINED3DDEVTYPE_HAL,
1110 mode.format_id, 0, WINED3DRTYPE_TEXTURE, FormatList[i], SURFACE_OPENGL);
1113 DDPIXELFORMAT pformat;
1115 memset(&pformat, 0, sizeof(pformat));
1116 pformat.dwSize = sizeof(pformat);
1117 PixelFormat_WineD3DtoDD(&pformat, FormatList[i]);
1119 TRACE("Enumerating WineD3DFormat %d\n", FormatList[i]);
1120 hr = Callback(&pformat, Arg);
1121 if(hr != DDENUMRET_OK)
1123 TRACE("Format enumeration cancelled by application\n");
1124 wined3d_mutex_unlock();
1130 for (i = 0; i < sizeof(BumpFormatList) / sizeof(*BumpFormatList); ++i)
1132 hr = wined3d_check_device_format(This->ddraw->wineD3D, WINED3DADAPTER_DEFAULT,
1133 WINED3DDEVTYPE_HAL, mode.format_id, WINED3DUSAGE_QUERY_LEGACYBUMPMAP,
1134 WINED3DRTYPE_TEXTURE, BumpFormatList[i], SURFACE_OPENGL);
1137 DDPIXELFORMAT pformat;
1139 memset(&pformat, 0, sizeof(pformat));
1140 pformat.dwSize = sizeof(pformat);
1141 PixelFormat_WineD3DtoDD(&pformat, BumpFormatList[i]);
1143 TRACE("Enumerating WineD3DFormat %d\n", BumpFormatList[i]);
1144 hr = Callback(&pformat, Arg);
1145 if(hr != DDENUMRET_OK)
1147 TRACE("Format enumeration cancelled by application\n");
1148 wined3d_mutex_unlock();
1153 TRACE("End of enumeration\n");
1154 wined3d_mutex_unlock();
1159 static HRESULT WINAPI
1160 IDirect3DDeviceImpl_7_EnumTextureFormats_FPUSetup(IDirect3DDevice7 *iface,
1161 LPD3DENUMPIXELFORMATSCALLBACK Callback,
1164 return IDirect3DDeviceImpl_7_EnumTextureFormats(iface, Callback, Arg);
1167 static HRESULT WINAPI
1168 IDirect3DDeviceImpl_7_EnumTextureFormats_FPUPreserve(IDirect3DDevice7 *iface,
1169 LPD3DENUMPIXELFORMATSCALLBACK Callback,
1175 old_fpucw = d3d_fpu_setup();
1176 hr = IDirect3DDeviceImpl_7_EnumTextureFormats(iface, Callback, Arg);
1177 set_fpu_control_word(old_fpucw);
1182 static HRESULT WINAPI IDirect3DDeviceImpl_3_EnumTextureFormats(IDirect3DDevice3 *iface,
1183 LPD3DENUMPIXELFORMATSCALLBACK Callback, void *Arg)
1185 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice3(iface);
1187 TRACE("iface %p, callback %p, context %p.\n", iface, Callback, Arg);
1189 return IDirect3DDevice7_EnumTextureFormats(&This->IDirect3DDevice7_iface, Callback, Arg);
1192 /*****************************************************************************
1193 * IDirect3DDevice2::EnumTextureformats
1195 * EnumTextureFormats for Version 1 and 2, see
1196 * IDirect3DDevice7::EnumTexureFormats for a more detailed description.
1198 * This version has a different callback and does not enumerate FourCC
1201 *****************************************************************************/
1202 static HRESULT WINAPI
1203 IDirect3DDeviceImpl_2_EnumTextureFormats(IDirect3DDevice2 *iface,
1204 LPD3DENUMTEXTUREFORMATSCALLBACK Callback,
1207 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice2(iface);
1208 struct wined3d_display_mode mode;
1212 static const enum wined3d_format_id FormatList[] =
1215 WINED3DFMT_B8G8R8A8_UNORM,
1216 WINED3DFMT_B8G8R8X8_UNORM,
1218 WINED3DFMT_B8G8R8_UNORM,
1220 WINED3DFMT_B5G5R5A1_UNORM,
1221 WINED3DFMT_B4G4R4A4_UNORM,
1222 WINED3DFMT_B5G6R5_UNORM,
1223 WINED3DFMT_B5G5R5X1_UNORM,
1225 WINED3DFMT_B2G3R3_UNORM,
1227 /* FOURCC codes - Not in this version*/
1230 TRACE("iface %p, callback %p, context %p.\n", iface, Callback, Arg);
1233 return DDERR_INVALIDPARAMS;
1235 wined3d_mutex_lock();
1237 memset(&mode, 0, sizeof(mode));
1238 hr = wined3d_device_get_display_mode(This->ddraw->wined3d_device, 0, &mode);
1241 wined3d_mutex_unlock();
1242 WARN("Cannot get the current adapter format\n");
1246 for (i = 0; i < sizeof(FormatList) / sizeof(*FormatList); ++i)
1248 hr = wined3d_check_device_format(This->ddraw->wineD3D, 0, WINED3DDEVTYPE_HAL,
1249 mode.format_id, 0, WINED3DRTYPE_TEXTURE, FormatList[i], SURFACE_OPENGL);
1252 DDSURFACEDESC sdesc;
1254 memset(&sdesc, 0, sizeof(sdesc));
1255 sdesc.dwSize = sizeof(sdesc);
1256 sdesc.dwFlags = DDSD_PIXELFORMAT | DDSD_CAPS;
1257 sdesc.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1258 sdesc.ddpfPixelFormat.dwSize = sizeof(sdesc.ddpfPixelFormat);
1259 PixelFormat_WineD3DtoDD(&sdesc.ddpfPixelFormat, FormatList[i]);
1261 TRACE("Enumerating WineD3DFormat %d\n", FormatList[i]);
1262 hr = Callback(&sdesc, Arg);
1263 if(hr != DDENUMRET_OK)
1265 TRACE("Format enumeration cancelled by application\n");
1266 wined3d_mutex_unlock();
1271 TRACE("End of enumeration\n");
1272 wined3d_mutex_unlock();
1277 static HRESULT WINAPI IDirect3DDeviceImpl_1_EnumTextureFormats(IDirect3DDevice *iface,
1278 LPD3DENUMTEXTUREFORMATSCALLBACK Callback, void *Arg)
1280 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice(iface);
1282 TRACE("iface %p, callback %p, context %p.\n", iface, Callback, Arg);
1284 return IDirect3DDevice2_EnumTextureFormats(&This->IDirect3DDevice2_iface, Callback, Arg);
1287 /*****************************************************************************
1288 * IDirect3DDevice::CreateMatrix
1290 * Creates a matrix handle. A handle is created and memory for a D3DMATRIX is
1291 * allocated for the handle.
1296 * D3DMatHandle: Address to return the handle at
1300 * DDERR_INVALIDPARAMS if D3DMatHandle = NULL
1302 *****************************************************************************/
1303 static HRESULT WINAPI
1304 IDirect3DDeviceImpl_1_CreateMatrix(IDirect3DDevice *iface, D3DMATRIXHANDLE *D3DMatHandle)
1306 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice(iface);
1310 TRACE("iface %p, matrix_handle %p.\n", iface, D3DMatHandle);
1313 return DDERR_INVALIDPARAMS;
1315 Matrix = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(D3DMATRIX));
1318 ERR("Out of memory when allocating a D3DMATRIX\n");
1319 return DDERR_OUTOFMEMORY;
1322 wined3d_mutex_lock();
1324 h = ddraw_allocate_handle(&This->handle_table, Matrix, DDRAW_HANDLE_MATRIX);
1325 if (h == DDRAW_INVALID_HANDLE)
1327 ERR("Failed to allocate a matrix handle.\n");
1328 HeapFree(GetProcessHeap(), 0, Matrix);
1329 wined3d_mutex_unlock();
1330 return DDERR_OUTOFMEMORY;
1333 *D3DMatHandle = h + 1;
1335 TRACE(" returning matrix handle %d\n", *D3DMatHandle);
1337 wined3d_mutex_unlock();
1342 /*****************************************************************************
1343 * IDirect3DDevice::SetMatrix
1345 * Sets a matrix for a matrix handle. The matrix is copied into the memory
1346 * allocated for the handle
1351 * D3DMatHandle: Handle to set the matrix to
1352 * D3DMatrix: Matrix to set
1356 * DDERR_INVALIDPARAMS if the handle of the matrix is invalid or the matrix
1359 *****************************************************************************/
1360 static HRESULT WINAPI
1361 IDirect3DDeviceImpl_1_SetMatrix(IDirect3DDevice *iface,
1362 D3DMATRIXHANDLE D3DMatHandle,
1363 D3DMATRIX *D3DMatrix)
1365 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice(iface);
1368 TRACE("iface %p, matrix_handle %#x, matrix %p.\n", iface, D3DMatHandle, D3DMatrix);
1370 if (!D3DMatrix) return DDERR_INVALIDPARAMS;
1372 wined3d_mutex_lock();
1374 m = ddraw_get_object(&This->handle_table, D3DMatHandle - 1, DDRAW_HANDLE_MATRIX);
1377 WARN("Invalid matrix handle.\n");
1378 wined3d_mutex_unlock();
1379 return DDERR_INVALIDPARAMS;
1382 if (TRACE_ON(ddraw))
1383 dump_D3DMATRIX(D3DMatrix);
1387 if (D3DMatHandle == This->world)
1388 wined3d_device_set_transform(This->wined3d_device,
1389 WINED3DTS_WORLDMATRIX(0), (struct wined3d_matrix *)D3DMatrix);
1391 if (D3DMatHandle == This->view)
1392 wined3d_device_set_transform(This->wined3d_device,
1393 WINED3DTS_VIEW, (struct wined3d_matrix *)D3DMatrix);
1395 if (D3DMatHandle == This->proj)
1396 wined3d_device_set_transform(This->wined3d_device,
1397 WINED3DTS_PROJECTION, (struct wined3d_matrix *)D3DMatrix);
1399 wined3d_mutex_unlock();
1404 /*****************************************************************************
1405 * IDirect3DDevice::GetMatrix
1407 * Returns the content of a D3DMATRIX handle
1412 * D3DMatHandle: Matrix handle to read the content from
1413 * D3DMatrix: Address to store the content at
1417 * DDERR_INVALIDPARAMS if D3DMatHandle is invalid or D3DMatrix is NULL
1419 *****************************************************************************/
1420 static HRESULT WINAPI
1421 IDirect3DDeviceImpl_1_GetMatrix(IDirect3DDevice *iface,
1422 D3DMATRIXHANDLE D3DMatHandle,
1423 D3DMATRIX *D3DMatrix)
1425 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice(iface);
1428 TRACE("iface %p, matrix_handle %#x, matrix %p.\n", iface, D3DMatHandle, D3DMatrix);
1430 if (!D3DMatrix) return DDERR_INVALIDPARAMS;
1432 wined3d_mutex_lock();
1434 m = ddraw_get_object(&This->handle_table, D3DMatHandle - 1, DDRAW_HANDLE_MATRIX);
1437 WARN("Invalid matrix handle.\n");
1438 wined3d_mutex_unlock();
1439 return DDERR_INVALIDPARAMS;
1444 wined3d_mutex_unlock();
1449 /*****************************************************************************
1450 * IDirect3DDevice::DeleteMatrix
1452 * Destroys a Matrix handle. Frees the memory and unsets the handle data
1457 * D3DMatHandle: Handle to destroy
1461 * DDERR_INVALIDPARAMS if D3DMatHandle is invalid
1463 *****************************************************************************/
1464 static HRESULT WINAPI
1465 IDirect3DDeviceImpl_1_DeleteMatrix(IDirect3DDevice *iface,
1466 D3DMATRIXHANDLE D3DMatHandle)
1468 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice(iface);
1471 TRACE("iface %p, matrix_handle %#x.\n", iface, D3DMatHandle);
1473 wined3d_mutex_lock();
1475 m = ddraw_free_handle(&This->handle_table, D3DMatHandle - 1, DDRAW_HANDLE_MATRIX);
1478 WARN("Invalid matrix handle.\n");
1479 wined3d_mutex_unlock();
1480 return DDERR_INVALIDPARAMS;
1483 wined3d_mutex_unlock();
1485 HeapFree(GetProcessHeap(), 0, m);
1490 /*****************************************************************************
1491 * IDirect3DDevice7::BeginScene
1493 * This method must be called before any rendering is performed.
1494 * IDirect3DDevice::EndScene has to be called after the scene is complete
1496 * Version 1, 2, 3 and 7
1499 * D3D_OK on success, for details see IWineD3DDevice::BeginScene
1500 * D3DERR_SCENE_IN_SCENE if WineD3D returns an error(Only in case of an already
1503 *****************************************************************************/
1505 IDirect3DDeviceImpl_7_BeginScene(IDirect3DDevice7 *iface)
1507 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice7(iface);
1510 TRACE("iface %p.\n", iface);
1512 wined3d_mutex_lock();
1513 hr = wined3d_device_begin_scene(This->wined3d_device);
1514 wined3d_mutex_unlock();
1516 if(hr == WINED3D_OK) return D3D_OK;
1517 else return D3DERR_SCENE_IN_SCENE; /* TODO: Other possible causes of failure */
1520 static HRESULT WINAPI
1521 IDirect3DDeviceImpl_7_BeginScene_FPUSetup(IDirect3DDevice7 *iface)
1523 return IDirect3DDeviceImpl_7_BeginScene(iface);
1526 static HRESULT WINAPI
1527 IDirect3DDeviceImpl_7_BeginScene_FPUPreserve(IDirect3DDevice7 *iface)
1532 old_fpucw = d3d_fpu_setup();
1533 hr = IDirect3DDeviceImpl_7_BeginScene(iface);
1534 set_fpu_control_word(old_fpucw);
1539 static HRESULT WINAPI IDirect3DDeviceImpl_3_BeginScene(IDirect3DDevice3 *iface)
1541 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice3(iface);
1542 TRACE("iface %p.\n", iface);
1544 return IDirect3DDevice7_BeginScene(&This->IDirect3DDevice7_iface);
1547 static HRESULT WINAPI IDirect3DDeviceImpl_2_BeginScene(IDirect3DDevice2 *iface)
1549 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice2(iface);
1550 TRACE("iface %p.\n", iface);
1552 return IDirect3DDevice7_BeginScene(&This->IDirect3DDevice7_iface);
1555 static HRESULT WINAPI IDirect3DDeviceImpl_1_BeginScene(IDirect3DDevice *iface)
1557 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice(iface);
1558 TRACE("iface %p.\n", iface);
1560 return IDirect3DDevice7_BeginScene(&This->IDirect3DDevice7_iface);
1563 /*****************************************************************************
1564 * IDirect3DDevice7::EndScene
1566 * Ends a scene that has been begun with IDirect3DDevice7::BeginScene.
1567 * This method must be called after rendering is finished.
1569 * Version 1, 2, 3 and 7
1572 * D3D_OK on success, for details see IWineD3DDevice::EndScene
1573 * D3DERR_SCENE_NOT_IN_SCENE is returned if WineD3D returns an error. It does
1574 * that only if the scene was already ended.
1576 *****************************************************************************/
1578 IDirect3DDeviceImpl_7_EndScene(IDirect3DDevice7 *iface)
1580 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice7(iface);
1583 TRACE("iface %p.\n", iface);
1585 wined3d_mutex_lock();
1586 hr = wined3d_device_end_scene(This->wined3d_device);
1587 wined3d_mutex_unlock();
1589 if(hr == WINED3D_OK) return D3D_OK;
1590 else return D3DERR_SCENE_NOT_IN_SCENE;
1593 static HRESULT WINAPI DECLSPEC_HOTPATCH
1594 IDirect3DDeviceImpl_7_EndScene_FPUSetup(IDirect3DDevice7 *iface)
1596 return IDirect3DDeviceImpl_7_EndScene(iface);
1599 static HRESULT WINAPI DECLSPEC_HOTPATCH
1600 IDirect3DDeviceImpl_7_EndScene_FPUPreserve(IDirect3DDevice7 *iface)
1605 old_fpucw = d3d_fpu_setup();
1606 hr = IDirect3DDeviceImpl_7_EndScene(iface);
1607 set_fpu_control_word(old_fpucw);
1612 static HRESULT WINAPI DECLSPEC_HOTPATCH IDirect3DDeviceImpl_3_EndScene(IDirect3DDevice3 *iface)
1614 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice3(iface);
1615 TRACE("iface %p.\n", iface);
1617 return IDirect3DDevice7_EndScene(&This->IDirect3DDevice7_iface);
1620 static HRESULT WINAPI DECLSPEC_HOTPATCH IDirect3DDeviceImpl_2_EndScene(IDirect3DDevice2 *iface)
1622 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice2(iface);
1623 TRACE("iface %p.\n", iface);
1625 return IDirect3DDevice7_EndScene(&This->IDirect3DDevice7_iface);
1628 static HRESULT WINAPI DECLSPEC_HOTPATCH IDirect3DDeviceImpl_1_EndScene(IDirect3DDevice *iface)
1630 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice(iface);
1631 TRACE("iface %p.\n", iface);
1633 return IDirect3DDevice7_EndScene(&This->IDirect3DDevice7_iface);
1636 /*****************************************************************************
1637 * IDirect3DDevice7::GetDirect3D
1639 * Returns the IDirect3D(= interface to the DirectDraw object) used to create
1643 * Direct3D7: Address to store the interface pointer at
1647 * DDERR_INVALIDPARAMS if Direct3D7 == NULL
1649 *****************************************************************************/
1650 static HRESULT WINAPI
1651 IDirect3DDeviceImpl_7_GetDirect3D(IDirect3DDevice7 *iface,
1652 IDirect3D7 **Direct3D7)
1654 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice7(iface);
1656 TRACE("iface %p, d3d %p.\n", iface, Direct3D7);
1659 return DDERR_INVALIDPARAMS;
1661 *Direct3D7 = &This->ddraw->IDirect3D7_iface;
1662 IDirect3D7_AddRef(*Direct3D7);
1664 TRACE(" returning interface %p\n", *Direct3D7);
1668 static HRESULT WINAPI IDirect3DDeviceImpl_3_GetDirect3D(IDirect3DDevice3 *iface,
1669 IDirect3D3 **Direct3D3)
1671 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice3(iface);
1673 TRACE("iface %p, d3d %p.\n", iface, Direct3D3);
1676 return DDERR_INVALIDPARAMS;
1678 IDirect3D3_AddRef(&This->ddraw->IDirect3D3_iface);
1679 *Direct3D3 = &This->ddraw->IDirect3D3_iface;
1680 TRACE(" returning interface %p\n", *Direct3D3);
1684 static HRESULT WINAPI IDirect3DDeviceImpl_2_GetDirect3D(IDirect3DDevice2 *iface,
1685 IDirect3D2 **Direct3D2)
1687 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice2(iface);
1689 TRACE("iface %p, d3d %p.\n", iface, Direct3D2);
1692 return DDERR_INVALIDPARAMS;
1694 IDirect3D2_AddRef(&This->ddraw->IDirect3D2_iface);
1695 *Direct3D2 = &This->ddraw->IDirect3D2_iface;
1696 TRACE(" returning interface %p\n", *Direct3D2);
1700 static HRESULT WINAPI IDirect3DDeviceImpl_1_GetDirect3D(IDirect3DDevice *iface,
1701 IDirect3D **Direct3D)
1703 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice(iface);
1705 TRACE("iface %p, d3d %p.\n", iface, Direct3D);
1708 return DDERR_INVALIDPARAMS;
1710 IDirect3D_AddRef(&This->ddraw->IDirect3D_iface);
1711 *Direct3D = &This->ddraw->IDirect3D_iface;
1712 TRACE(" returning interface %p\n", *Direct3D);
1716 /*****************************************************************************
1717 * IDirect3DDevice3::SetCurrentViewport
1719 * Sets a Direct3DViewport as the current viewport.
1720 * For the thunks note that all viewport interface versions are equal
1723 * Direct3DViewport3: The viewport to set
1729 * (Is a NULL viewport valid?)
1731 *****************************************************************************/
1732 static HRESULT WINAPI
1733 IDirect3DDeviceImpl_3_SetCurrentViewport(IDirect3DDevice3 *iface,
1734 IDirect3DViewport3 *Direct3DViewport3)
1736 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice3(iface);
1737 IDirect3DViewportImpl *vp = unsafe_impl_from_IDirect3DViewport3(Direct3DViewport3);
1739 TRACE("iface %p, viewport %p.\n", iface, Direct3DViewport3);
1741 wined3d_mutex_lock();
1742 /* Do nothing if the specified viewport is the same as the current one */
1743 if (This->current_viewport == vp )
1745 wined3d_mutex_unlock();
1749 if (vp->active_device != This)
1751 WARN("Viewport %p active device is %p.\n", vp, vp->active_device);
1752 wined3d_mutex_unlock();
1753 return DDERR_INVALIDPARAMS;
1756 /* Release previous viewport and AddRef the new one */
1757 if (This->current_viewport)
1759 TRACE("ViewportImpl is at %p, interface is at %p\n", This->current_viewport,
1760 &This->current_viewport->IDirect3DViewport3_iface);
1761 IDirect3DViewport3_Release(&This->current_viewport->IDirect3DViewport3_iface);
1763 IDirect3DViewport3_AddRef(Direct3DViewport3);
1765 /* Set this viewport as the current viewport */
1766 This->current_viewport = vp;
1768 /* Activate this viewport */
1769 viewport_activate(This->current_viewport, FALSE);
1771 wined3d_mutex_unlock();
1776 static HRESULT WINAPI IDirect3DDeviceImpl_2_SetCurrentViewport(IDirect3DDevice2 *iface,
1777 IDirect3DViewport2 *Direct3DViewport2)
1779 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice2(iface);
1780 IDirect3DViewportImpl *vp = unsafe_impl_from_IDirect3DViewport2(Direct3DViewport2);
1782 TRACE("iface %p, viewport %p.\n", iface, Direct3DViewport2);
1784 return IDirect3DDevice3_SetCurrentViewport(&This->IDirect3DDevice3_iface,
1785 &vp->IDirect3DViewport3_iface);
1788 /*****************************************************************************
1789 * IDirect3DDevice3::GetCurrentViewport
1791 * Returns the currently active viewport.
1796 * Direct3DViewport3: Address to return the interface pointer at
1800 * DDERR_INVALIDPARAMS if Direct3DViewport == NULL
1802 *****************************************************************************/
1803 static HRESULT WINAPI
1804 IDirect3DDeviceImpl_3_GetCurrentViewport(IDirect3DDevice3 *iface,
1805 IDirect3DViewport3 **Direct3DViewport3)
1807 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice3(iface);
1809 TRACE("iface %p, viewport %p.\n", iface, Direct3DViewport3);
1811 if(!Direct3DViewport3)
1812 return DDERR_INVALIDPARAMS;
1814 wined3d_mutex_lock();
1815 *Direct3DViewport3 = &This->current_viewport->IDirect3DViewport3_iface;
1817 /* AddRef the returned viewport */
1818 if(*Direct3DViewport3) IDirect3DViewport3_AddRef(*Direct3DViewport3);
1820 TRACE(" returning interface %p\n", *Direct3DViewport3);
1822 wined3d_mutex_unlock();
1827 static HRESULT WINAPI IDirect3DDeviceImpl_2_GetCurrentViewport(IDirect3DDevice2 *iface,
1828 IDirect3DViewport2 **Direct3DViewport2)
1830 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice2(iface);
1833 TRACE("iface %p, viewport %p.\n", iface, Direct3DViewport2);
1835 hr = IDirect3DDevice3_GetCurrentViewport(&This->IDirect3DDevice3_iface,
1836 (IDirect3DViewport3 **)Direct3DViewport2);
1837 if(hr != D3D_OK) return hr;
1841 /*****************************************************************************
1842 * IDirect3DDevice7::SetRenderTarget
1844 * Sets the render target for the Direct3DDevice.
1845 * For the thunks note that IDirectDrawSurface7 == IDirectDrawSurface4 and
1846 * IDirectDrawSurface3 == IDirectDrawSurface
1848 * Version 2, 3 and 7
1851 * NewTarget: Pointer to an IDirectDrawSurface7 interface to set as the new
1856 * D3D_OK on success, for details see IWineD3DDevice::SetRenderTarget
1858 *****************************************************************************/
1859 static HRESULT d3d_device_set_render_target(IDirect3DDeviceImpl *This, IDirectDrawSurfaceImpl *Target)
1863 wined3d_mutex_lock();
1865 if(This->target == Target)
1867 TRACE("No-op SetRenderTarget operation, not doing anything\n");
1868 wined3d_mutex_unlock();
1871 This->target = Target;
1872 hr = wined3d_device_set_render_target(This->wined3d_device, 0,
1873 Target ? Target->wined3d_surface : NULL, FALSE);
1876 wined3d_mutex_unlock();
1879 IDirect3DDeviceImpl_UpdateDepthStencil(This);
1881 wined3d_mutex_unlock();
1887 IDirect3DDeviceImpl_7_SetRenderTarget(IDirect3DDevice7 *iface,
1888 IDirectDrawSurface7 *NewTarget,
1891 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice7(iface);
1892 IDirectDrawSurfaceImpl *Target = unsafe_impl_from_IDirectDrawSurface7(NewTarget);
1894 TRACE("iface %p, target %p, flags %#x.\n", iface, NewTarget, Flags);
1895 /* Flags: Not used */
1897 IDirectDrawSurface7_AddRef(NewTarget);
1898 IDirectDrawSurface7_Release(&This->target->IDirectDrawSurface7_iface);
1899 return d3d_device_set_render_target(This, Target);
1902 static HRESULT WINAPI
1903 IDirect3DDeviceImpl_7_SetRenderTarget_FPUSetup(IDirect3DDevice7 *iface,
1904 IDirectDrawSurface7 *NewTarget,
1907 return IDirect3DDeviceImpl_7_SetRenderTarget(iface, NewTarget, Flags);
1910 static HRESULT WINAPI
1911 IDirect3DDeviceImpl_7_SetRenderTarget_FPUPreserve(IDirect3DDevice7 *iface,
1912 IDirectDrawSurface7 *NewTarget,
1918 old_fpucw = d3d_fpu_setup();
1919 hr = IDirect3DDeviceImpl_7_SetRenderTarget(iface, NewTarget, Flags);
1920 set_fpu_control_word(old_fpucw);
1925 static HRESULT WINAPI IDirect3DDeviceImpl_3_SetRenderTarget(IDirect3DDevice3 *iface,
1926 IDirectDrawSurface4 *NewRenderTarget, DWORD Flags)
1928 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice3(iface);
1929 IDirectDrawSurfaceImpl *Target = unsafe_impl_from_IDirectDrawSurface4(NewRenderTarget);
1931 TRACE("iface %p, target %p, flags %#x.\n", iface, NewRenderTarget, Flags);
1933 IDirectDrawSurface4_AddRef(NewRenderTarget);
1934 IDirectDrawSurface4_Release(&This->target->IDirectDrawSurface4_iface);
1935 return d3d_device_set_render_target(This, Target);
1938 static HRESULT WINAPI IDirect3DDeviceImpl_2_SetRenderTarget(IDirect3DDevice2 *iface,
1939 IDirectDrawSurface *NewRenderTarget, DWORD Flags)
1941 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice2(iface);
1942 IDirectDrawSurfaceImpl *Target = unsafe_impl_from_IDirectDrawSurface(NewRenderTarget);
1944 TRACE("iface %p, target %p, flags %#x.\n", iface, NewRenderTarget, Flags);
1946 IDirectDrawSurface_AddRef(NewRenderTarget);
1947 IDirectDrawSurface_Release(&This->target->IDirectDrawSurface_iface);
1948 return d3d_device_set_render_target(This, Target);
1951 /*****************************************************************************
1952 * IDirect3DDevice7::GetRenderTarget
1954 * Returns the current render target.
1955 * This is handled locally, because the WineD3D render target's parent
1958 * Version 2, 3 and 7
1961 * RenderTarget: Address to store the surface interface pointer
1965 * DDERR_INVALIDPARAMS if RenderTarget == NULL
1967 *****************************************************************************/
1968 static HRESULT WINAPI
1969 IDirect3DDeviceImpl_7_GetRenderTarget(IDirect3DDevice7 *iface,
1970 IDirectDrawSurface7 **RenderTarget)
1972 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice7(iface);
1974 TRACE("iface %p, target %p.\n", iface, RenderTarget);
1977 return DDERR_INVALIDPARAMS;
1979 wined3d_mutex_lock();
1980 *RenderTarget = &This->target->IDirectDrawSurface7_iface;
1981 IDirectDrawSurface7_AddRef(*RenderTarget);
1982 wined3d_mutex_unlock();
1987 static HRESULT WINAPI IDirect3DDeviceImpl_3_GetRenderTarget(IDirect3DDevice3 *iface,
1988 IDirectDrawSurface4 **RenderTarget)
1990 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice3(iface);
1991 IDirectDrawSurface7 *RenderTarget7;
1992 IDirectDrawSurfaceImpl *RenderTargetImpl;
1995 TRACE("iface %p, target %p.\n", iface, RenderTarget);
1998 return DDERR_INVALIDPARAMS;
2000 hr = IDirect3DDevice7_GetRenderTarget(&This->IDirect3DDevice7_iface, &RenderTarget7);
2001 if(hr != D3D_OK) return hr;
2002 RenderTargetImpl = impl_from_IDirectDrawSurface7(RenderTarget7);
2003 *RenderTarget = &RenderTargetImpl->IDirectDrawSurface4_iface;
2004 IDirectDrawSurface4_AddRef(*RenderTarget);
2005 IDirectDrawSurface7_Release(RenderTarget7);
2009 static HRESULT WINAPI IDirect3DDeviceImpl_2_GetRenderTarget(IDirect3DDevice2 *iface,
2010 IDirectDrawSurface **RenderTarget)
2012 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice2(iface);
2013 IDirectDrawSurface7 *RenderTarget7;
2014 IDirectDrawSurfaceImpl *RenderTargetImpl;
2017 TRACE("iface %p, target %p.\n", iface, RenderTarget);
2020 return DDERR_INVALIDPARAMS;
2022 hr = IDirect3DDevice7_GetRenderTarget(&This->IDirect3DDevice7_iface, &RenderTarget7);
2023 if(hr != D3D_OK) return hr;
2024 RenderTargetImpl = impl_from_IDirectDrawSurface7(RenderTarget7);
2025 *RenderTarget = &RenderTargetImpl->IDirectDrawSurface_iface;
2026 IDirectDrawSurface_AddRef(*RenderTarget);
2027 IDirectDrawSurface7_Release(RenderTarget7);
2031 /*****************************************************************************
2032 * IDirect3DDevice3::Begin
2034 * Begins a description block of vertices. This is similar to glBegin()
2035 * and glEnd(). After a call to IDirect3DDevice3::End, the vertices
2036 * described with IDirect3DDevice::Vertex are drawn.
2041 * PrimitiveType: The type of primitives to draw
2042 * VertexTypeDesc: A flexible vertex format description of the vertices
2043 * Flags: Some flags..
2048 *****************************************************************************/
2049 static HRESULT WINAPI
2050 IDirect3DDeviceImpl_3_Begin(IDirect3DDevice3 *iface,
2051 D3DPRIMITIVETYPE PrimitiveType,
2052 DWORD VertexTypeDesc,
2055 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice3(iface);
2057 TRACE("iface %p, primitive_type %#x, FVF %#x, flags %#x.\n",
2058 iface, PrimitiveType, VertexTypeDesc, Flags);
2060 wined3d_mutex_lock();
2061 This->primitive_type = PrimitiveType;
2062 This->vertex_type = VertexTypeDesc;
2063 This->render_flags = Flags;
2064 This->vertex_size = get_flexible_vertex_size(This->vertex_type);
2065 This->nb_vertices = 0;
2066 wined3d_mutex_unlock();
2071 static HRESULT WINAPI IDirect3DDeviceImpl_2_Begin(IDirect3DDevice2 *iface, D3DPRIMITIVETYPE d3dpt,
2072 D3DVERTEXTYPE dwVertexTypeDesc, DWORD dwFlags)
2075 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice2(iface);
2077 TRACE("iface %p, primitive_type %#x, vertex_type %#x, flags %#x.\n",
2078 iface, d3dpt, dwVertexTypeDesc, dwFlags);
2080 switch(dwVertexTypeDesc)
2082 case D3DVT_VERTEX: FVF = D3DFVF_VERTEX; break;
2083 case D3DVT_LVERTEX: FVF = D3DFVF_LVERTEX; break;
2084 case D3DVT_TLVERTEX: FVF = D3DFVF_TLVERTEX; break;
2086 ERR("Unexpected vertex type %d\n", dwVertexTypeDesc);
2087 return DDERR_INVALIDPARAMS; /* Should never happen */
2090 return IDirect3DDevice3_Begin(&This->IDirect3DDevice3_iface, d3dpt, FVF, dwFlags);
2093 /*****************************************************************************
2094 * IDirect3DDevice3::BeginIndexed
2096 * Draws primitives based on vertices in a vertex array which are specified
2102 * PrimitiveType: Primitive type to draw
2103 * VertexType: A FVF description of the vertex format
2104 * Vertices: pointer to an array containing the vertices
2105 * NumVertices: The number of vertices in the vertex array
2106 * Flags: Some flags ...
2109 * D3D_OK, because it's a stub
2111 *****************************************************************************/
2112 static HRESULT WINAPI
2113 IDirect3DDeviceImpl_3_BeginIndexed(IDirect3DDevice3 *iface,
2114 D3DPRIMITIVETYPE PrimitiveType,
2120 FIXME("iface %p, primitive_type %#x, FVF %#x, vertices %p, vertex_count %u, flags %#x stub!\n",
2121 iface, PrimitiveType, VertexType, Vertices, NumVertices, Flags);
2127 static HRESULT WINAPI IDirect3DDeviceImpl_2_BeginIndexed(IDirect3DDevice2 *iface,
2128 D3DPRIMITIVETYPE d3dptPrimitiveType, D3DVERTEXTYPE d3dvtVertexType,
2129 void *lpvVertices, DWORD dwNumVertices, DWORD dwFlags)
2132 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice2(iface);
2134 TRACE("iface %p, primitive_type %#x, vertex_type %#x, vertices %p, vertex_count %u, flags %#x stub!\n",
2135 iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwNumVertices, dwFlags);
2137 switch(d3dvtVertexType)
2139 case D3DVT_VERTEX: FVF = D3DFVF_VERTEX; break;
2140 case D3DVT_LVERTEX: FVF = D3DFVF_LVERTEX; break;
2141 case D3DVT_TLVERTEX: FVF = D3DFVF_TLVERTEX; break;
2143 ERR("Unexpected vertex type %d\n", d3dvtVertexType);
2144 return DDERR_INVALIDPARAMS; /* Should never happen */
2147 return IDirect3DDevice3_BeginIndexed(&This->IDirect3DDevice3_iface,
2148 d3dptPrimitiveType, FVF, lpvVertices, dwNumVertices, dwFlags);
2151 /*****************************************************************************
2152 * IDirect3DDevice3::Vertex
2154 * Draws a vertex as described by IDirect3DDevice3::Begin. It places all
2155 * drawn vertices in a vertex buffer. If the buffer is too small, its
2156 * size is increased.
2161 * Vertex: Pointer to the vertex
2164 * D3D_OK, on success
2165 * DDERR_INVALIDPARAMS if Vertex is NULL
2167 *****************************************************************************/
2168 static HRESULT WINAPI
2169 IDirect3DDeviceImpl_3_Vertex(IDirect3DDevice3 *iface,
2172 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice3(iface);
2174 TRACE("iface %p, vertex %p.\n", iface, Vertex);
2177 return DDERR_INVALIDPARAMS;
2179 wined3d_mutex_lock();
2180 if ((This->nb_vertices+1)*This->vertex_size > This->buffer_size)
2183 This->buffer_size = This->buffer_size ? This->buffer_size * 2 : This->vertex_size * 3;
2184 old_buffer = This->vertex_buffer;
2185 This->vertex_buffer = HeapAlloc(GetProcessHeap(), 0, This->buffer_size);
2188 CopyMemory(This->vertex_buffer, old_buffer, This->nb_vertices * This->vertex_size);
2189 HeapFree(GetProcessHeap(), 0, old_buffer);
2193 CopyMemory(This->vertex_buffer + This->nb_vertices++ * This->vertex_size, Vertex, This->vertex_size);
2194 wined3d_mutex_unlock();
2199 static HRESULT WINAPI IDirect3DDeviceImpl_2_Vertex(IDirect3DDevice2 *iface, void *lpVertexType)
2201 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice2(iface);
2203 TRACE("iface %p, vertex %p.\n", iface, lpVertexType);
2205 return IDirect3DDevice3_Vertex(&This->IDirect3DDevice3_iface, lpVertexType);
2208 /*****************************************************************************
2209 * IDirect3DDevice3::Index
2211 * Specifies an index to a vertex to be drawn. The vertex array has to
2212 * be specified with BeginIndexed first.
2215 * VertexIndex: The index of the vertex to draw
2218 * D3D_OK because it's a stub
2220 *****************************************************************************/
2221 static HRESULT WINAPI
2222 IDirect3DDeviceImpl_3_Index(IDirect3DDevice3 *iface,
2225 FIXME("iface %p, index %#x stub!\n", iface, VertexIndex);
2230 static HRESULT WINAPI IDirect3DDeviceImpl_2_Index(IDirect3DDevice2 *iface, WORD wVertexIndex)
2232 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice2(iface);
2234 TRACE("iface %p, index %#x.\n", iface, wVertexIndex);
2236 return IDirect3DDevice3_Index(&This->IDirect3DDevice3_iface, wVertexIndex);
2239 /*****************************************************************************
2240 * IDirect3DDevice3::End
2242 * Ends a draw begun with IDirect3DDevice3::Begin or
2243 * IDirect3DDevice::BeginIndexed. The vertices specified with
2244 * IDirect3DDevice::Vertex or IDirect3DDevice::Index are drawn using
2245 * the IDirect3DDevice7::DrawPrimitive method. So far only
2246 * non-indexed mode is supported
2251 * Flags: Some flags, as usual. Don't know which are defined
2254 * The return value of IDirect3DDevice7::DrawPrimitive
2256 *****************************************************************************/
2257 static HRESULT WINAPI
2258 IDirect3DDeviceImpl_3_End(IDirect3DDevice3 *iface,
2261 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice3(iface);
2263 TRACE("iface %p, flags %#x.\n", iface, Flags);
2265 return IDirect3DDevice7_DrawPrimitive(&This->IDirect3DDevice7_iface, This->primitive_type,
2266 This->vertex_type, This->vertex_buffer, This->nb_vertices, This->render_flags);
2269 static HRESULT WINAPI IDirect3DDeviceImpl_2_End(IDirect3DDevice2 *iface, DWORD dwFlags)
2271 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice2(iface);
2273 TRACE("iface %p, flags %#x.\n", iface, dwFlags);
2275 return IDirect3DDevice3_End(&This->IDirect3DDevice3_iface, dwFlags);
2278 /*****************************************************************************
2279 * IDirect3DDevice7::GetRenderState
2281 * Returns the value of a render state. The possible render states are
2282 * defined in include/d3dtypes.h
2284 * Version 2, 3 and 7
2287 * RenderStateType: Render state to return the current setting of
2288 * Value: Address to store the value at
2291 * D3D_OK on success, for details see IWineD3DDevice::GetRenderState
2292 * DDERR_INVALIDPARAMS if Value == NULL
2294 *****************************************************************************/
2295 static HRESULT IDirect3DDeviceImpl_7_GetRenderState(IDirect3DDevice7 *iface,
2296 D3DRENDERSTATETYPE RenderStateType, DWORD *Value)
2298 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice7(iface);
2301 TRACE("iface %p, state %#x, value %p.\n", iface, RenderStateType, Value);
2304 return DDERR_INVALIDPARAMS;
2306 wined3d_mutex_lock();
2307 switch(RenderStateType)
2309 case D3DRENDERSTATE_TEXTUREMAG:
2311 WINED3DTEXTUREFILTERTYPE tex_mag;
2313 hr = wined3d_device_get_sampler_state(This->wined3d_device, 0, WINED3DSAMP_MAGFILTER, &tex_mag);
2317 case WINED3DTEXF_POINT:
2318 *Value = D3DFILTER_NEAREST;
2320 case WINED3DTEXF_LINEAR:
2321 *Value = D3DFILTER_LINEAR;
2324 ERR("Unhandled texture mag %d !\n",tex_mag);
2330 case D3DRENDERSTATE_TEXTUREMIN:
2332 WINED3DTEXTUREFILTERTYPE tex_min;
2333 WINED3DTEXTUREFILTERTYPE tex_mip;
2335 hr = wined3d_device_get_sampler_state(This->wined3d_device,
2336 0, WINED3DSAMP_MINFILTER, &tex_min);
2339 wined3d_mutex_unlock();
2342 hr = wined3d_device_get_sampler_state(This->wined3d_device,
2343 0, WINED3DSAMP_MIPFILTER, &tex_mip);
2347 case WINED3DTEXF_POINT:
2350 case WINED3DTEXF_NONE:
2351 *Value = D3DFILTER_NEAREST;
2353 case WINED3DTEXF_POINT:
2354 *Value = D3DFILTER_MIPNEAREST;
2356 case WINED3DTEXF_LINEAR:
2357 *Value = D3DFILTER_LINEARMIPNEAREST;
2360 ERR("Unhandled mip filter %#x.\n", tex_mip);
2361 *Value = D3DFILTER_NEAREST;
2365 case WINED3DTEXF_LINEAR:
2368 case WINED3DTEXF_NONE:
2369 *Value = D3DFILTER_LINEAR;
2371 case WINED3DTEXF_POINT:
2372 *Value = D3DFILTER_MIPLINEAR;
2374 case WINED3DTEXF_LINEAR:
2375 *Value = D3DFILTER_LINEARMIPLINEAR;
2378 ERR("Unhandled mip filter %#x.\n", tex_mip);
2379 *Value = D3DFILTER_LINEAR;
2384 ERR("Unhandled texture min filter %#x.\n",tex_min);
2385 *Value = D3DFILTER_NEAREST;
2391 case D3DRENDERSTATE_TEXTUREADDRESS:
2392 case D3DRENDERSTATE_TEXTUREADDRESSU:
2393 hr = wined3d_device_get_sampler_state(This->wined3d_device,
2394 0, WINED3DSAMP_ADDRESSU, Value);
2396 case D3DRENDERSTATE_TEXTUREADDRESSV:
2397 hr = wined3d_device_get_sampler_state(This->wined3d_device,
2398 0, WINED3DSAMP_ADDRESSV, Value);
2401 case D3DRENDERSTATE_BORDERCOLOR:
2402 FIXME("Unhandled render state D3DRENDERSTATE_BORDERCOLOR.\n");
2406 case D3DRENDERSTATE_TEXTUREHANDLE:
2407 case D3DRENDERSTATE_TEXTUREMAPBLEND:
2408 WARN("Render state %#x is invalid in d3d7.\n", RenderStateType);
2409 hr = DDERR_INVALIDPARAMS;
2412 case D3DRENDERSTATE_ZBIAS:
2413 hr = wined3d_device_get_render_state(This->wined3d_device, WINED3DRS_DEPTHBIAS, Value);
2417 if (RenderStateType >= D3DRENDERSTATE_STIPPLEPATTERN00
2418 && RenderStateType <= D3DRENDERSTATE_STIPPLEPATTERN31)
2420 FIXME("Unhandled stipple pattern render state (%#x).\n",
2425 hr = wined3d_device_get_render_state(This->wined3d_device, RenderStateType, Value);
2427 wined3d_mutex_unlock();
2432 static HRESULT WINAPI
2433 IDirect3DDeviceImpl_7_GetRenderState_FPUSetup(IDirect3DDevice7 *iface,
2434 D3DRENDERSTATETYPE RenderStateType,
2437 return IDirect3DDeviceImpl_7_GetRenderState(iface, RenderStateType, Value);
2440 static HRESULT WINAPI
2441 IDirect3DDeviceImpl_7_GetRenderState_FPUPreserve(IDirect3DDevice7 *iface,
2442 D3DRENDERSTATETYPE RenderStateType,
2448 old_fpucw = d3d_fpu_setup();
2449 hr = IDirect3DDeviceImpl_7_GetRenderState(iface, RenderStateType, Value);
2450 set_fpu_control_word(old_fpucw);
2455 static HRESULT WINAPI
2456 IDirect3DDeviceImpl_3_GetRenderState(IDirect3DDevice3 *iface,
2457 D3DRENDERSTATETYPE dwRenderStateType,
2458 DWORD *lpdwRenderState)
2460 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice3(iface);
2463 TRACE("iface %p, state %#x, value %p.\n", iface, dwRenderStateType, lpdwRenderState);
2465 switch(dwRenderStateType)
2467 case D3DRENDERSTATE_TEXTUREHANDLE:
2469 /* This state is wrapped to SetTexture in SetRenderState, so
2470 * it has to be wrapped to GetTexture here. */
2471 struct wined3d_texture *tex = NULL;
2472 *lpdwRenderState = 0;
2474 wined3d_mutex_lock();
2475 hr = wined3d_device_get_texture(This->wined3d_device, 0, &tex);
2476 if (SUCCEEDED(hr) && tex)
2478 /* The parent of the texture is the IDirectDrawSurface7
2479 * interface of the ddraw surface. */
2480 IDirectDrawSurfaceImpl *parent = wined3d_texture_get_parent(tex);
2481 if (parent) *lpdwRenderState = parent->Handle;
2482 wined3d_texture_decref(tex);
2484 wined3d_mutex_unlock();
2489 case D3DRENDERSTATE_TEXTUREMAPBLEND:
2491 /* D3DRENDERSTATE_TEXTUREMAPBLEND is mapped to texture state stages in SetRenderState; reverse
2492 the mapping to get the value. */
2493 DWORD colorop, colorarg1, colorarg2;
2494 DWORD alphaop, alphaarg1, alphaarg2;
2496 wined3d_mutex_lock();
2498 This->legacyTextureBlending = TRUE;
2500 wined3d_device_get_texture_stage_state(This->wined3d_device, 0, WINED3DTSS_COLOROP, &colorop);
2501 wined3d_device_get_texture_stage_state(This->wined3d_device, 0, WINED3DTSS_COLORARG1, &colorarg1);
2502 wined3d_device_get_texture_stage_state(This->wined3d_device, 0, WINED3DTSS_COLORARG2, &colorarg2);
2503 wined3d_device_get_texture_stage_state(This->wined3d_device, 0, WINED3DTSS_ALPHAOP, &alphaop);
2504 wined3d_device_get_texture_stage_state(This->wined3d_device, 0, WINED3DTSS_ALPHAARG1, &alphaarg1);
2505 wined3d_device_get_texture_stage_state(This->wined3d_device, 0, WINED3DTSS_ALPHAARG2, &alphaarg2);
2507 if (colorop == WINED3DTOP_SELECTARG1 && colorarg1 == WINED3DTA_TEXTURE &&
2508 alphaop == WINED3DTOP_SELECTARG1 && alphaarg1 == WINED3DTA_TEXTURE)
2510 *lpdwRenderState = D3DTBLEND_DECAL;
2512 else if (colorop == WINED3DTOP_SELECTARG1 && colorarg1 == WINED3DTA_TEXTURE &&
2513 alphaop == WINED3DTOP_MODULATE && alphaarg1 == WINED3DTA_TEXTURE && alphaarg2 == WINED3DTA_CURRENT)
2515 *lpdwRenderState = D3DTBLEND_DECALALPHA;
2517 else if (colorop == WINED3DTOP_MODULATE && colorarg1 == WINED3DTA_TEXTURE && colorarg2 == WINED3DTA_CURRENT &&
2518 alphaop == WINED3DTOP_MODULATE && alphaarg1 == WINED3DTA_TEXTURE && alphaarg2 == WINED3DTA_CURRENT)
2520 *lpdwRenderState = D3DTBLEND_MODULATEALPHA;
2524 struct wined3d_texture *tex = NULL;
2526 BOOL tex_alpha = FALSE;
2527 DDPIXELFORMAT ddfmt;
2529 hr = wined3d_device_get_texture(This->wined3d_device, 0, &tex);
2531 if(hr == WINED3D_OK && tex)
2533 struct wined3d_resource *sub_resource;
2535 if ((sub_resource = wined3d_texture_get_sub_resource(tex, 0)))
2537 struct wined3d_resource_desc desc;
2539 wined3d_resource_get_desc(sub_resource, &desc);
2540 ddfmt.dwSize = sizeof(ddfmt);
2541 PixelFormat_WineD3DtoDD(&ddfmt, desc.format);
2542 if (ddfmt.u5.dwRGBAlphaBitMask) tex_alpha = TRUE;
2545 wined3d_texture_decref(tex);
2548 if (!(colorop == WINED3DTOP_MODULATE && colorarg1 == WINED3DTA_TEXTURE && colorarg2 == WINED3DTA_CURRENT &&
2549 alphaop == (tex_alpha ? WINED3DTOP_SELECTARG1 : WINED3DTOP_SELECTARG2) &&
2550 alphaarg1 == WINED3DTA_TEXTURE && alphaarg2 == WINED3DTA_CURRENT))
2552 ERR("Unexpected texture stage state setup, returning D3DTBLEND_MODULATE - likely erroneous\n");
2555 *lpdwRenderState = D3DTBLEND_MODULATE;
2558 wined3d_mutex_unlock();
2564 return IDirect3DDevice7_GetRenderState(&This->IDirect3DDevice7_iface, dwRenderStateType, lpdwRenderState);
2568 static HRESULT WINAPI IDirect3DDeviceImpl_2_GetRenderState(IDirect3DDevice2 *iface,
2569 D3DRENDERSTATETYPE dwRenderStateType, DWORD *lpdwRenderState)
2571 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice2(iface);
2573 TRACE("iface %p, state %#x, value %p.\n", iface, dwRenderStateType, lpdwRenderState);
2575 return IDirect3DDevice3_GetRenderState(&This->IDirect3DDevice3_iface,
2576 dwRenderStateType, lpdwRenderState);
2579 /*****************************************************************************
2580 * IDirect3DDevice7::SetRenderState
2582 * Sets a render state. The possible render states are defined in
2583 * include/d3dtypes.h
2585 * Version 2, 3 and 7
2588 * RenderStateType: State to set
2589 * Value: Value to assign to that state
2592 * D3D_OK on success,
2593 * for details see IWineD3DDevice::SetRenderState
2595 *****************************************************************************/
2597 IDirect3DDeviceImpl_7_SetRenderState(IDirect3DDevice7 *iface,
2598 D3DRENDERSTATETYPE RenderStateType,
2601 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice7(iface);
2604 TRACE("iface %p, state %#x, value %#x.\n", iface, RenderStateType, Value);
2606 wined3d_mutex_lock();
2607 /* Some render states need special care */
2608 switch(RenderStateType)
2611 * The ddraw texture filter mapping works like this:
2612 * D3DFILTER_NEAREST Point min/mag, no mip
2613 * D3DFILTER_MIPNEAREST Point min/mag, point mip
2614 * D3DFILTER_LINEARMIPNEAREST: Point min/mag, linear mip
2616 * D3DFILTER_LINEAR Linear min/mag, no mip
2617 * D3DFILTER_MIPLINEAR Linear min/mag, point mip
2618 * D3DFILTER_LINEARMIPLINEAR Linear min/mag, linear mip
2620 * This is the opposite of the GL naming convention,
2621 * D3DFILTER_LINEARMIPNEAREST corresponds to GL_NEAREST_MIPMAP_LINEAR.
2623 case D3DRENDERSTATE_TEXTUREMAG:
2625 WINED3DTEXTUREFILTERTYPE tex_mag;
2629 case D3DFILTER_NEAREST:
2630 case D3DFILTER_MIPNEAREST:
2631 case D3DFILTER_LINEARMIPNEAREST:
2632 tex_mag = WINED3DTEXF_POINT;
2634 case D3DFILTER_LINEAR:
2635 case D3DFILTER_MIPLINEAR:
2636 case D3DFILTER_LINEARMIPLINEAR:
2637 tex_mag = WINED3DTEXF_LINEAR;
2640 tex_mag = WINED3DTEXF_POINT;
2641 ERR("Unhandled texture mag %d !\n",Value);
2645 hr = wined3d_device_set_sampler_state(This->wined3d_device, 0, WINED3DSAMP_MAGFILTER, tex_mag);
2649 case D3DRENDERSTATE_TEXTUREMIN:
2651 WINED3DTEXTUREFILTERTYPE tex_min;
2652 WINED3DTEXTUREFILTERTYPE tex_mip;
2654 switch ((D3DTEXTUREFILTER) Value)
2656 case D3DFILTER_NEAREST:
2657 tex_min = WINED3DTEXF_POINT;
2658 tex_mip = WINED3DTEXF_NONE;
2660 case D3DFILTER_LINEAR:
2661 tex_min = WINED3DTEXF_LINEAR;
2662 tex_mip = WINED3DTEXF_NONE;
2664 case D3DFILTER_MIPNEAREST:
2665 tex_min = WINED3DTEXF_POINT;
2666 tex_mip = WINED3DTEXF_POINT;
2668 case D3DFILTER_MIPLINEAR:
2669 tex_min = WINED3DTEXF_LINEAR;
2670 tex_mip = WINED3DTEXF_POINT;
2672 case D3DFILTER_LINEARMIPNEAREST:
2673 tex_min = WINED3DTEXF_POINT;
2674 tex_mip = WINED3DTEXF_LINEAR;
2676 case D3DFILTER_LINEARMIPLINEAR:
2677 tex_min = WINED3DTEXF_LINEAR;
2678 tex_mip = WINED3DTEXF_LINEAR;
2682 ERR("Unhandled texture min %d !\n",Value);
2683 tex_min = WINED3DTEXF_POINT;
2684 tex_mip = WINED3DTEXF_NONE;
2688 wined3d_device_set_sampler_state(This->wined3d_device,
2689 0, WINED3DSAMP_MIPFILTER, tex_mip);
2690 hr = wined3d_device_set_sampler_state(This->wined3d_device,
2691 0, WINED3DSAMP_MINFILTER, tex_min);
2695 case D3DRENDERSTATE_TEXTUREADDRESS:
2696 wined3d_device_set_sampler_state(This->wined3d_device,
2697 0, WINED3DSAMP_ADDRESSV, Value);
2699 case D3DRENDERSTATE_TEXTUREADDRESSU:
2700 hr = wined3d_device_set_sampler_state(This->wined3d_device,
2701 0, WINED3DSAMP_ADDRESSU, Value);
2703 case D3DRENDERSTATE_TEXTUREADDRESSV:
2704 hr = wined3d_device_set_sampler_state(This->wined3d_device,
2705 0, WINED3DSAMP_ADDRESSV, Value);
2708 case D3DRENDERSTATE_BORDERCOLOR:
2709 /* This should probably just forward to the corresponding sampler
2710 * state. Needs tests. */
2711 FIXME("Unhandled render state D3DRENDERSTATE_BORDERCOLOR.\n");
2715 case D3DRENDERSTATE_TEXTUREHANDLE:
2716 case D3DRENDERSTATE_TEXTUREMAPBLEND:
2717 WARN("Render state %#x is invalid in d3d7.\n", RenderStateType);
2718 hr = DDERR_INVALIDPARAMS;
2721 case D3DRENDERSTATE_ZBIAS:
2722 hr = wined3d_device_set_render_state(This->wined3d_device, WINED3DRS_DEPTHBIAS, Value);
2726 if (RenderStateType >= D3DRENDERSTATE_STIPPLEPATTERN00
2727 && RenderStateType <= D3DRENDERSTATE_STIPPLEPATTERN31)
2729 FIXME("Unhandled stipple pattern render state (%#x).\n",
2735 hr = wined3d_device_set_render_state(This->wined3d_device, RenderStateType, Value);
2738 wined3d_mutex_unlock();
2743 static HRESULT WINAPI
2744 IDirect3DDeviceImpl_7_SetRenderState_FPUSetup(IDirect3DDevice7 *iface,
2745 D3DRENDERSTATETYPE RenderStateType,
2748 return IDirect3DDeviceImpl_7_SetRenderState(iface, RenderStateType, Value);
2751 static HRESULT WINAPI
2752 IDirect3DDeviceImpl_7_SetRenderState_FPUPreserve(IDirect3DDevice7 *iface,
2753 D3DRENDERSTATETYPE RenderStateType,
2759 old_fpucw = d3d_fpu_setup();
2760 hr = IDirect3DDeviceImpl_7_SetRenderState(iface, RenderStateType, Value);
2761 set_fpu_control_word(old_fpucw);
2766 static HRESULT WINAPI
2767 IDirect3DDeviceImpl_3_SetRenderState(IDirect3DDevice3 *iface,
2768 D3DRENDERSTATETYPE RenderStateType,
2771 /* Note about D3DRENDERSTATE_TEXTUREMAPBLEND implementation: most of values
2772 for this state can be directly mapped to texture stage colorop and alphaop, but
2773 D3DTBLEND_MODULATE is tricky: it uses alpha from texture when available and alpha
2774 from diffuse otherwise. So changing the texture must be monitored in SetTexture to modify
2775 alphaarg when needed.
2777 Aliens vs Predator 1 depends on accurate D3DTBLEND_MODULATE emulation
2779 Legacy texture blending (TEXTUREMAPBLEND) and texture stage states: directx6 docs state that
2780 TEXTUREMAPBLEND is deprecated, yet can still be used. Games must not use both or results
2781 are undefined. D3DTBLEND_MODULATE mode in particular is dependent on texture pixel format and
2782 requires fixup of stage 0 texture states when texture changes, but this fixup can interfere
2783 with games not using this deprecated state. So a flag 'legacyTextureBlending' has to be kept
2784 in device - TRUE if the app is using TEXTUREMAPBLEND.
2786 Tests show that setting TEXTUREMAPBLEND on native doesn't seem to change values returned by
2787 GetTextureStageState and vice versa. Not so on Wine, but it is 'undefined' anyway so, probably, ok,
2788 unless some broken game will be found that cares. */
2791 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice3(iface);
2793 TRACE("iface %p, state %#x, value %#x.\n", iface, RenderStateType, Value);
2795 wined3d_mutex_lock();
2797 switch(RenderStateType)
2799 case D3DRENDERSTATE_TEXTUREHANDLE:
2801 IDirectDrawSurfaceImpl *surf;
2805 hr = wined3d_device_set_texture(This->wined3d_device, 0, NULL);
2809 surf = ddraw_get_object(&This->handle_table, Value - 1, DDRAW_HANDLE_SURFACE);
2812 WARN("Invalid texture handle.\n");
2813 hr = DDERR_INVALIDPARAMS;
2817 hr = IDirect3DDevice3_SetTexture(iface, 0, &surf->IDirect3DTexture2_iface);
2821 case D3DRENDERSTATE_TEXTUREMAPBLEND:
2823 This->legacyTextureBlending = TRUE;
2825 switch ( (D3DTEXTUREBLEND) Value)
2827 case D3DTBLEND_MODULATE:
2829 struct wined3d_texture *tex = NULL;
2830 BOOL tex_alpha = FALSE;
2831 DDPIXELFORMAT ddfmt;
2833 hr = wined3d_device_get_texture(This->wined3d_device, 0, &tex);
2835 if(hr == WINED3D_OK && tex)
2837 struct wined3d_resource *sub_resource;
2839 if ((sub_resource = wined3d_texture_get_sub_resource(tex, 0)))
2841 struct wined3d_resource_desc desc;
2843 wined3d_resource_get_desc(sub_resource, &desc);
2844 ddfmt.dwSize = sizeof(ddfmt);
2845 PixelFormat_WineD3DtoDD(&ddfmt, desc.format);
2846 if (ddfmt.u5.dwRGBAlphaBitMask) tex_alpha = TRUE;
2849 wined3d_texture_decref(tex);
2853 wined3d_device_set_texture_stage_state(This->wined3d_device,
2854 0, WINED3DTSS_ALPHAOP, WINED3DTOP_SELECTARG1);
2856 wined3d_device_set_texture_stage_state(This->wined3d_device,
2857 0, WINED3DTSS_ALPHAOP, WINED3DTOP_SELECTARG2);
2858 wined3d_device_set_texture_stage_state(This->wined3d_device,
2859 0, WINED3DTSS_ALPHAARG1, WINED3DTA_TEXTURE);
2860 wined3d_device_set_texture_stage_state(This->wined3d_device,
2861 0, WINED3DTSS_ALPHAARG2, WINED3DTA_CURRENT);
2862 wined3d_device_set_texture_stage_state(This->wined3d_device,
2863 0, WINED3DTSS_COLORARG1, WINED3DTA_TEXTURE);
2864 wined3d_device_set_texture_stage_state(This->wined3d_device,
2865 0, WINED3DTSS_COLORARG2, WINED3DTA_CURRENT);
2866 wined3d_device_set_texture_stage_state(This->wined3d_device,
2867 0, WINED3DTSS_COLOROP, WINED3DTOP_MODULATE);
2872 wined3d_device_set_texture_stage_state(This->wined3d_device,
2873 0, WINED3DTSS_COLOROP, WINED3DTOP_ADD);
2874 wined3d_device_set_texture_stage_state(This->wined3d_device,
2875 0, WINED3DTSS_COLORARG1, WINED3DTA_TEXTURE);
2876 wined3d_device_set_texture_stage_state(This->wined3d_device,
2877 0, WINED3DTSS_COLORARG2, WINED3DTA_CURRENT);
2878 wined3d_device_set_texture_stage_state(This->wined3d_device,
2879 0, WINED3DTSS_ALPHAOP, WINED3DTOP_SELECTARG2);
2880 wined3d_device_set_texture_stage_state(This->wined3d_device,
2881 0, WINED3DTSS_ALPHAARG2, WINED3DTA_CURRENT);
2884 case D3DTBLEND_MODULATEALPHA:
2885 wined3d_device_set_texture_stage_state(This->wined3d_device,
2886 0, WINED3DTSS_COLORARG1, WINED3DTA_TEXTURE);
2887 wined3d_device_set_texture_stage_state(This->wined3d_device,
2888 0, WINED3DTSS_ALPHAARG1, WINED3DTA_TEXTURE);
2889 wined3d_device_set_texture_stage_state(This->wined3d_device,
2890 0, WINED3DTSS_COLORARG2, WINED3DTA_CURRENT);
2891 wined3d_device_set_texture_stage_state(This->wined3d_device,
2892 0, WINED3DTSS_ALPHAARG2, WINED3DTA_CURRENT);
2893 wined3d_device_set_texture_stage_state(This->wined3d_device,
2894 0, WINED3DTSS_COLOROP, WINED3DTOP_MODULATE);
2895 wined3d_device_set_texture_stage_state(This->wined3d_device,
2896 0, WINED3DTSS_ALPHAOP, WINED3DTOP_MODULATE);
2899 case D3DTBLEND_COPY:
2900 case D3DTBLEND_DECAL:
2901 wined3d_device_set_texture_stage_state(This->wined3d_device,
2902 0, WINED3DTSS_COLORARG1, WINED3DTA_TEXTURE);
2903 wined3d_device_set_texture_stage_state(This->wined3d_device,
2904 0, WINED3DTSS_ALPHAARG1, WINED3DTA_TEXTURE);
2905 wined3d_device_set_texture_stage_state(This->wined3d_device,
2906 0, WINED3DTSS_COLOROP, WINED3DTOP_SELECTARG1);
2907 wined3d_device_set_texture_stage_state(This->wined3d_device,
2908 0, WINED3DTSS_ALPHAOP, WINED3DTOP_SELECTARG1);
2911 case D3DTBLEND_DECALALPHA:
2912 wined3d_device_set_texture_stage_state(This->wined3d_device,
2913 0, WINED3DTSS_COLOROP, WINED3DTOP_BLENDTEXTUREALPHA);
2914 wined3d_device_set_texture_stage_state(This->wined3d_device,
2915 0, WINED3DTSS_COLORARG1, WINED3DTA_TEXTURE);
2916 wined3d_device_set_texture_stage_state(This->wined3d_device,
2917 0, WINED3DTSS_COLORARG2, WINED3DTA_CURRENT);
2918 wined3d_device_set_texture_stage_state(This->wined3d_device,
2919 0, WINED3DTSS_ALPHAOP, WINED3DTOP_SELECTARG2);
2920 wined3d_device_set_texture_stage_state(This->wined3d_device,
2921 0, WINED3DTSS_ALPHAARG2, WINED3DTA_CURRENT);
2925 ERR("Unhandled texture environment %d !\n",Value);
2933 hr = IDirect3DDevice7_SetRenderState(&This->IDirect3DDevice7_iface, RenderStateType, Value);
2936 wined3d_mutex_unlock();
2941 static HRESULT WINAPI IDirect3DDeviceImpl_2_SetRenderState(IDirect3DDevice2 *iface,
2942 D3DRENDERSTATETYPE RenderStateType, DWORD Value)
2944 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice2(iface);
2946 TRACE("iface %p, state %#x, value %#x.\n", iface, RenderStateType, Value);
2948 return IDirect3DDevice3_SetRenderState(&This->IDirect3DDevice3_iface, RenderStateType, Value);
2951 /*****************************************************************************
2952 * Direct3DDevice3::SetLightState
2954 * Sets a light state for Direct3DDevice3 and Direct3DDevice2. The
2955 * light states are forwarded to Direct3DDevice7 render states
2960 * LightStateType: The light state to change
2961 * Value: The value to assign to that light state
2965 * DDERR_INVALIDPARAMS if the parameters were incorrect
2966 * Also check IDirect3DDevice7::SetRenderState
2968 *****************************************************************************/
2969 static HRESULT WINAPI
2970 IDirect3DDeviceImpl_3_SetLightState(IDirect3DDevice3 *iface,
2971 D3DLIGHTSTATETYPE LightStateType,
2974 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice3(iface);
2977 TRACE("iface %p, state %#x, value %#x.\n", iface, LightStateType, Value);
2979 if (!LightStateType || (LightStateType > D3DLIGHTSTATE_COLORVERTEX))
2981 TRACE("Unexpected Light State Type\n");
2982 return DDERR_INVALIDPARAMS;
2985 wined3d_mutex_lock();
2986 if (LightStateType == D3DLIGHTSTATE_MATERIAL /* 1 */)
2988 IDirect3DMaterialImpl *m = ddraw_get_object(&This->handle_table, Value - 1, DDRAW_HANDLE_MATERIAL);
2991 WARN("Invalid material handle.\n");
2992 wined3d_mutex_unlock();
2993 return DDERR_INVALIDPARAMS;
2996 TRACE(" activating material %p.\n", m);
2997 material_activate(m);
2999 This->material = Value;
3001 else if (LightStateType == D3DLIGHTSTATE_COLORMODEL /* 3 */)
3006 ERR("DDCOLOR_MONO should not happen!\n");
3009 /* We are already in this mode */
3010 TRACE("Setting color model to RGB (no-op).\n");
3013 ERR("Unknown color model!\n");
3014 wined3d_mutex_unlock();
3015 return DDERR_INVALIDPARAMS;
3020 D3DRENDERSTATETYPE rs;
3021 switch (LightStateType)
3023 case D3DLIGHTSTATE_AMBIENT: /* 2 */
3024 rs = D3DRENDERSTATE_AMBIENT;
3026 case D3DLIGHTSTATE_FOGMODE: /* 4 */
3027 rs = D3DRENDERSTATE_FOGVERTEXMODE;
3029 case D3DLIGHTSTATE_FOGSTART: /* 5 */
3030 rs = D3DRENDERSTATE_FOGSTART;
3032 case D3DLIGHTSTATE_FOGEND: /* 6 */
3033 rs = D3DRENDERSTATE_FOGEND;
3035 case D3DLIGHTSTATE_FOGDENSITY: /* 7 */
3036 rs = D3DRENDERSTATE_FOGDENSITY;
3038 case D3DLIGHTSTATE_COLORVERTEX: /* 8 */
3039 rs = D3DRENDERSTATE_COLORVERTEX;
3042 ERR("Unknown D3DLIGHTSTATETYPE %d.\n", LightStateType);
3043 wined3d_mutex_unlock();
3044 return DDERR_INVALIDPARAMS;
3047 hr = IDirect3DDevice7_SetRenderState(&This->IDirect3DDevice7_iface, rs, Value);
3048 wined3d_mutex_unlock();
3051 wined3d_mutex_unlock();
3056 static HRESULT WINAPI IDirect3DDeviceImpl_2_SetLightState(IDirect3DDevice2 *iface,
3057 D3DLIGHTSTATETYPE LightStateType, DWORD Value)
3059 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice2(iface);
3061 TRACE("iface %p, state %#x, value %#x.\n", iface, LightStateType, Value);
3063 return IDirect3DDevice3_SetLightState(&This->IDirect3DDevice3_iface, LightStateType, Value);
3066 /*****************************************************************************
3067 * IDirect3DDevice3::GetLightState
3069 * Returns the current setting of a light state. The state is read from
3070 * the Direct3DDevice7 render state.
3075 * LightStateType: The light state to return
3076 * Value: The address to store the light state setting at
3080 * DDDERR_INVALIDPARAMS if the parameters were incorrect
3081 * Also see IDirect3DDevice7::GetRenderState
3083 *****************************************************************************/
3084 static HRESULT WINAPI
3085 IDirect3DDeviceImpl_3_GetLightState(IDirect3DDevice3 *iface,
3086 D3DLIGHTSTATETYPE LightStateType,
3089 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice3(iface);
3092 TRACE("iface %p, state %#x, value %p.\n", iface, LightStateType, Value);
3094 if (!LightStateType || (LightStateType > D3DLIGHTSTATE_COLORVERTEX))
3096 TRACE("Unexpected Light State Type\n");
3097 return DDERR_INVALIDPARAMS;
3101 return DDERR_INVALIDPARAMS;
3103 wined3d_mutex_lock();
3104 if (LightStateType == D3DLIGHTSTATE_MATERIAL /* 1 */)
3106 *Value = This->material;
3108 else if (LightStateType == D3DLIGHTSTATE_COLORMODEL /* 3 */)
3110 *Value = D3DCOLOR_RGB;
3114 D3DRENDERSTATETYPE rs;
3115 switch (LightStateType)
3117 case D3DLIGHTSTATE_AMBIENT: /* 2 */
3118 rs = D3DRENDERSTATE_AMBIENT;
3120 case D3DLIGHTSTATE_FOGMODE: /* 4 */
3121 rs = D3DRENDERSTATE_FOGVERTEXMODE;
3123 case D3DLIGHTSTATE_FOGSTART: /* 5 */
3124 rs = D3DRENDERSTATE_FOGSTART;
3126 case D3DLIGHTSTATE_FOGEND: /* 6 */
3127 rs = D3DRENDERSTATE_FOGEND;
3129 case D3DLIGHTSTATE_FOGDENSITY: /* 7 */
3130 rs = D3DRENDERSTATE_FOGDENSITY;
3132 case D3DLIGHTSTATE_COLORVERTEX: /* 8 */
3133 rs = D3DRENDERSTATE_COLORVERTEX;
3136 ERR("Unknown D3DLIGHTSTATETYPE %d.\n", LightStateType);
3137 wined3d_mutex_unlock();
3138 return DDERR_INVALIDPARAMS;
3141 hr = IDirect3DDevice7_GetRenderState(&This->IDirect3DDevice7_iface, rs, Value);
3142 wined3d_mutex_unlock();
3145 wined3d_mutex_unlock();
3150 static HRESULT WINAPI IDirect3DDeviceImpl_2_GetLightState(IDirect3DDevice2 *iface,
3151 D3DLIGHTSTATETYPE LightStateType, DWORD *Value)
3153 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice2(iface);
3155 TRACE("iface %p, state %#x, value %p.\n", iface, LightStateType, Value);
3157 return IDirect3DDevice3_GetLightState(&This->IDirect3DDevice3_iface, LightStateType, Value);
3160 /*****************************************************************************
3161 * IDirect3DDevice7::SetTransform
3163 * Assigns a D3DMATRIX to a transform type. The transform types are defined
3164 * in include/d3dtypes.h.
3165 * The D3DTRANSFORMSTATE_WORLD (=1) is translated to D3DTS_WORLDMATRIX(0)
3166 * (=255) for wined3d, because the 1 transform state was removed in d3d8
3167 * and WineD3D already understands the replacement D3DTS_WORLDMATRIX(0)
3169 * Version 2, 3 and 7
3172 * TransformStateType: transform state to set
3173 * Matrix: Matrix to assign to the state
3177 * DDERR_INVALIDPARAMS if Matrix == NULL
3178 * For details see IWineD3DDevice::SetTransform
3180 *****************************************************************************/
3182 IDirect3DDeviceImpl_7_SetTransform(IDirect3DDevice7 *iface,
3183 D3DTRANSFORMSTATETYPE TransformStateType,
3186 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice7(iface);
3187 D3DTRANSFORMSTATETYPE type;
3190 TRACE("iface %p, state %#x, matrix %p.\n", iface, TransformStateType, Matrix);
3192 switch(TransformStateType)
3194 case D3DTRANSFORMSTATE_WORLD : type = WINED3DTS_WORLDMATRIX(0); break;
3195 case D3DTRANSFORMSTATE_WORLD1: type = WINED3DTS_WORLDMATRIX(1); break;
3196 case D3DTRANSFORMSTATE_WORLD2: type = WINED3DTS_WORLDMATRIX(2); break;
3197 case D3DTRANSFORMSTATE_WORLD3: type = WINED3DTS_WORLDMATRIX(3); break;
3198 default: type = TransformStateType;
3202 return DDERR_INVALIDPARAMS;
3204 /* Note: D3DMATRIX is compatible with struct wined3d_matrix. */
3205 wined3d_mutex_lock();
3206 hr = wined3d_device_set_transform(This->wined3d_device, type, (struct wined3d_matrix *)Matrix);
3207 wined3d_mutex_unlock();
3212 static HRESULT WINAPI
3213 IDirect3DDeviceImpl_7_SetTransform_FPUSetup(IDirect3DDevice7 *iface,
3214 D3DTRANSFORMSTATETYPE TransformStateType,
3217 return IDirect3DDeviceImpl_7_SetTransform(iface, TransformStateType, Matrix);
3220 static HRESULT WINAPI
3221 IDirect3DDeviceImpl_7_SetTransform_FPUPreserve(IDirect3DDevice7 *iface,
3222 D3DTRANSFORMSTATETYPE TransformStateType,
3228 old_fpucw = d3d_fpu_setup();
3229 hr = IDirect3DDeviceImpl_7_SetTransform(iface, TransformStateType, Matrix);
3230 set_fpu_control_word(old_fpucw);
3235 static HRESULT WINAPI IDirect3DDeviceImpl_3_SetTransform(IDirect3DDevice3 *iface,
3236 D3DTRANSFORMSTATETYPE TransformStateType, D3DMATRIX *D3DMatrix)
3238 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice3(iface);
3240 TRACE("iface %p, state %#x, matrix %p.\n", iface, TransformStateType, D3DMatrix);
3242 return IDirect3DDevice7_SetTransform(&This->IDirect3DDevice7_iface, TransformStateType, D3DMatrix);
3245 static HRESULT WINAPI IDirect3DDeviceImpl_2_SetTransform(IDirect3DDevice2 *iface,
3246 D3DTRANSFORMSTATETYPE TransformStateType, D3DMATRIX *D3DMatrix)
3248 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice2(iface);
3250 TRACE("iface %p, state %#x, matrix %p.\n", iface, TransformStateType, D3DMatrix);
3252 return IDirect3DDevice7_SetTransform(&This->IDirect3DDevice7_iface, TransformStateType, D3DMatrix);
3255 /*****************************************************************************
3256 * IDirect3DDevice7::GetTransform
3258 * Returns the matrix assigned to a transform state
3259 * D3DTRANSFORMSTATE_WORLD is translated to D3DTS_WORLDMATRIX(0), see
3263 * TransformStateType: State to read the matrix from
3264 * Matrix: Address to store the matrix at
3268 * DDERR_INVALIDPARAMS if Matrix == NULL
3269 * For details, see IWineD3DDevice::GetTransform
3271 *****************************************************************************/
3273 IDirect3DDeviceImpl_7_GetTransform(IDirect3DDevice7 *iface,
3274 D3DTRANSFORMSTATETYPE TransformStateType,
3277 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice7(iface);
3278 D3DTRANSFORMSTATETYPE type;
3281 TRACE("iface %p, state %#x, matrix %p.\n", iface, TransformStateType, Matrix);
3283 switch(TransformStateType)
3285 case D3DTRANSFORMSTATE_WORLD : type = WINED3DTS_WORLDMATRIX(0); break;
3286 case D3DTRANSFORMSTATE_WORLD1: type = WINED3DTS_WORLDMATRIX(1); break;
3287 case D3DTRANSFORMSTATE_WORLD2: type = WINED3DTS_WORLDMATRIX(2); break;
3288 case D3DTRANSFORMSTATE_WORLD3: type = WINED3DTS_WORLDMATRIX(3); break;
3289 default: type = TransformStateType;
3293 return DDERR_INVALIDPARAMS;
3295 /* Note: D3DMATRIX is compatible with struct wined3d_matrix. */
3296 wined3d_mutex_lock();
3297 hr = wined3d_device_get_transform(This->wined3d_device, type, (struct wined3d_matrix *)Matrix);
3298 wined3d_mutex_unlock();
3303 static HRESULT WINAPI
3304 IDirect3DDeviceImpl_7_GetTransform_FPUSetup(IDirect3DDevice7 *iface,
3305 D3DTRANSFORMSTATETYPE TransformStateType,
3308 return IDirect3DDeviceImpl_7_GetTransform(iface, TransformStateType, Matrix);
3311 static HRESULT WINAPI
3312 IDirect3DDeviceImpl_7_GetTransform_FPUPreserve(IDirect3DDevice7 *iface,
3313 D3DTRANSFORMSTATETYPE TransformStateType,
3319 old_fpucw = d3d_fpu_setup();
3320 hr = IDirect3DDeviceImpl_7_GetTransform(iface, TransformStateType, Matrix);
3321 set_fpu_control_word(old_fpucw);
3326 static HRESULT WINAPI IDirect3DDeviceImpl_3_GetTransform(IDirect3DDevice3 *iface,
3327 D3DTRANSFORMSTATETYPE TransformStateType, D3DMATRIX *D3DMatrix)
3329 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice3(iface);
3331 TRACE("iface %p, state %#x, matrix %p.\n", iface, TransformStateType, D3DMatrix);
3333 return IDirect3DDevice7_GetTransform(&This->IDirect3DDevice7_iface, TransformStateType, D3DMatrix);
3336 static HRESULT WINAPI IDirect3DDeviceImpl_2_GetTransform(IDirect3DDevice2 *iface,
3337 D3DTRANSFORMSTATETYPE TransformStateType, D3DMATRIX *D3DMatrix)
3339 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice2(iface);
3341 TRACE("iface %p, state %#x, matrix %p.\n", iface, TransformStateType, D3DMatrix);
3343 return IDirect3DDevice7_GetTransform(&This->IDirect3DDevice7_iface, TransformStateType, D3DMatrix);
3346 /*****************************************************************************
3347 * IDirect3DDevice7::MultiplyTransform
3349 * Multiplies the already-set transform matrix of a transform state
3350 * with another matrix. For the world matrix, see SetTransform
3352 * Version 2, 3 and 7
3355 * TransformStateType: Transform state to multiply
3356 * D3DMatrix Matrix to multiply with.
3360 * DDERR_INVALIDPARAMS if D3DMatrix is NULL
3361 * For details, see IWineD3DDevice::MultiplyTransform
3363 *****************************************************************************/
3365 IDirect3DDeviceImpl_7_MultiplyTransform(IDirect3DDevice7 *iface,
3366 D3DTRANSFORMSTATETYPE TransformStateType,
3367 D3DMATRIX *D3DMatrix)
3369 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice7(iface);
3371 D3DTRANSFORMSTATETYPE type;
3373 TRACE("iface %p, state %#x, matrix %p.\n", iface, TransformStateType, D3DMatrix);
3375 switch(TransformStateType)
3377 case D3DTRANSFORMSTATE_WORLD : type = WINED3DTS_WORLDMATRIX(0); break;
3378 case D3DTRANSFORMSTATE_WORLD1: type = WINED3DTS_WORLDMATRIX(1); break;
3379 case D3DTRANSFORMSTATE_WORLD2: type = WINED3DTS_WORLDMATRIX(2); break;
3380 case D3DTRANSFORMSTATE_WORLD3: type = WINED3DTS_WORLDMATRIX(3); break;
3381 default: type = TransformStateType;
3384 /* Note: D3DMATRIX is compatible with struct wined3d_matrix. */
3385 wined3d_mutex_lock();
3386 hr = wined3d_device_multiply_transform(This->wined3d_device,
3387 type, (struct wined3d_matrix *)D3DMatrix);
3388 wined3d_mutex_unlock();
3393 static HRESULT WINAPI
3394 IDirect3DDeviceImpl_7_MultiplyTransform_FPUSetup(IDirect3DDevice7 *iface,
3395 D3DTRANSFORMSTATETYPE TransformStateType,
3396 D3DMATRIX *D3DMatrix)
3398 return IDirect3DDeviceImpl_7_MultiplyTransform(iface, TransformStateType, D3DMatrix);
3401 static HRESULT WINAPI
3402 IDirect3DDeviceImpl_7_MultiplyTransform_FPUPreserve(IDirect3DDevice7 *iface,
3403 D3DTRANSFORMSTATETYPE TransformStateType,
3404 D3DMATRIX *D3DMatrix)
3409 old_fpucw = d3d_fpu_setup();
3410 hr = IDirect3DDeviceImpl_7_MultiplyTransform(iface, TransformStateType, D3DMatrix);
3411 set_fpu_control_word(old_fpucw);
3416 static HRESULT WINAPI IDirect3DDeviceImpl_3_MultiplyTransform(IDirect3DDevice3 *iface,
3417 D3DTRANSFORMSTATETYPE TransformStateType, D3DMATRIX *D3DMatrix)
3419 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice3(iface);
3421 TRACE("iface %p, state %#x, matrix %p.\n", iface, TransformStateType, D3DMatrix);
3423 return IDirect3DDevice7_MultiplyTransform(&This->IDirect3DDevice7_iface, TransformStateType, D3DMatrix);
3426 static HRESULT WINAPI IDirect3DDeviceImpl_2_MultiplyTransform(IDirect3DDevice2 *iface,
3427 D3DTRANSFORMSTATETYPE TransformStateType, D3DMATRIX *D3DMatrix)
3429 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice2(iface);
3431 TRACE("iface %p, state %#x, matrix %p.\n", iface, TransformStateType, D3DMatrix);
3433 return IDirect3DDevice7_MultiplyTransform(&This->IDirect3DDevice7_iface, TransformStateType, D3DMatrix);
3436 /*****************************************************************************
3437 * IDirect3DDevice7::DrawPrimitive
3439 * Draws primitives based on vertices in an application-provided pointer
3441 * Version 2, 3 and 7. The IDirect3DDevice2 thunk converts the fixed vertex type into
3442 * an FVF format for D3D7
3445 * PrimitiveType: The type of the primitives to draw
3446 * Vertex type: Flexible vertex format vertex description
3447 * Vertices: Pointer to the vertex array
3448 * VertexCount: The number of vertices to draw
3449 * Flags: As usual a few flags
3453 * DDERR_INVALIDPARAMS if Vertices is NULL
3454 * For details, see IWineD3DDevice::DrawPrimitiveUP
3456 *****************************************************************************/
3458 IDirect3DDeviceImpl_7_DrawPrimitive(IDirect3DDevice7 *iface,
3459 D3DPRIMITIVETYPE PrimitiveType,
3465 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice7(iface);
3469 TRACE("iface %p, primitive_type %#x, FVF %#x, vertices %p, vertex_count %u, flags %#x.\n",
3470 iface, PrimitiveType, VertexType, Vertices, VertexCount, Flags);
3473 return DDERR_INVALIDPARAMS;
3475 /* Get the stride */
3476 stride = get_flexible_vertex_size(VertexType);
3479 wined3d_mutex_lock();
3480 hr = wined3d_device_set_vertex_declaration(This->wined3d_device, ddraw_find_decl(This->ddraw, VertexType));
3483 wined3d_mutex_unlock();
3487 /* This method translates to the user pointer draw of WineD3D */
3488 wined3d_device_set_primitive_type(This->wined3d_device, PrimitiveType);
3489 hr = wined3d_device_draw_primitive_up(This->wined3d_device, VertexCount, Vertices, stride);
3490 wined3d_mutex_unlock();
3495 static HRESULT WINAPI
3496 IDirect3DDeviceImpl_7_DrawPrimitive_FPUSetup(IDirect3DDevice7 *iface,
3497 D3DPRIMITIVETYPE PrimitiveType,
3503 return IDirect3DDeviceImpl_7_DrawPrimitive(iface, PrimitiveType, VertexType, Vertices, VertexCount, Flags);
3506 static HRESULT WINAPI
3507 IDirect3DDeviceImpl_7_DrawPrimitive_FPUPreserve(IDirect3DDevice7 *iface,
3508 D3DPRIMITIVETYPE PrimitiveType,
3517 old_fpucw = d3d_fpu_setup();
3518 hr = IDirect3DDeviceImpl_7_DrawPrimitive(iface, PrimitiveType, VertexType, Vertices, VertexCount, Flags);
3519 set_fpu_control_word(old_fpucw);
3524 static HRESULT WINAPI IDirect3DDeviceImpl_3_DrawPrimitive(IDirect3DDevice3 *iface,
3525 D3DPRIMITIVETYPE PrimitiveType, DWORD VertexType, void *Vertices, DWORD VertexCount,
3528 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice3(iface);
3529 TRACE("iface %p, primitive_type %#x, FVF %#x, vertices %p, vertex_count %u, flags %#x.\n",
3530 iface, PrimitiveType, VertexType, Vertices, VertexCount, Flags);
3532 return IDirect3DDevice7_DrawPrimitive(&This->IDirect3DDevice7_iface,
3533 PrimitiveType, VertexType, Vertices, VertexCount, Flags);
3536 static HRESULT WINAPI IDirect3DDeviceImpl_2_DrawPrimitive(IDirect3DDevice2 *iface,
3537 D3DPRIMITIVETYPE PrimitiveType, D3DVERTEXTYPE VertexType, void *Vertices,
3538 DWORD VertexCount, DWORD Flags)
3540 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice2(iface);
3543 TRACE("iface %p, primitive_type %#x, vertex_type %#x, vertices %p, vertex_count %u, flags %#x.\n",
3544 iface, PrimitiveType, VertexType, Vertices, VertexCount, Flags);
3548 case D3DVT_VERTEX: FVF = D3DFVF_VERTEX; break;
3549 case D3DVT_LVERTEX: FVF = D3DFVF_LVERTEX; break;
3550 case D3DVT_TLVERTEX: FVF = D3DFVF_TLVERTEX; break;
3552 ERR("Unexpected vertex type %d\n", VertexType);
3553 return DDERR_INVALIDPARAMS; /* Should never happen */
3556 return IDirect3DDevice7_DrawPrimitive(&This->IDirect3DDevice7_iface,
3557 PrimitiveType, FVF, Vertices, VertexCount, Flags);
3560 /*****************************************************************************
3561 * IDirect3DDevice7::DrawIndexedPrimitive
3563 * Draws vertices from an application-provided pointer, based on the index
3564 * numbers in a WORD array.
3566 * Version 2, 3 and 7. The version 7 thunk translates the vertex type into
3567 * an FVF format for D3D7
3570 * PrimitiveType: The primitive type to draw
3571 * VertexType: The FVF vertex description
3572 * Vertices: Pointer to the vertex array
3574 * Indices: Pointer to the index array
3575 * IndexCount: Number of indices = Number of vertices to draw
3576 * Flags: As usual, some flags
3580 * DDERR_INVALIDPARAMS if Vertices or Indices is NULL
3581 * For details, see IWineD3DDevice::DrawIndexedPrimitiveUP
3583 *****************************************************************************/
3585 IDirect3DDeviceImpl_7_DrawIndexedPrimitive(IDirect3DDevice7 *iface,
3586 D3DPRIMITIVETYPE PrimitiveType,
3594 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice7(iface);
3597 TRACE("iface %p, primitive_type %#x, FVF %#x, vertices %p, vertex_count %u, indices %p, index_count %u, flags %#x.\n",
3598 iface, PrimitiveType, VertexType, Vertices, VertexCount, Indices, IndexCount, Flags);
3600 /* Set the D3DDevice's FVF */
3601 wined3d_mutex_lock();
3602 hr = wined3d_device_set_vertex_declaration(This->wined3d_device, ddraw_find_decl(This->ddraw, VertexType));
3605 ERR(" (%p) Setting the FVF failed, hr = %x!\n", This, hr);
3606 wined3d_mutex_unlock();
3610 wined3d_device_set_primitive_type(This->wined3d_device, PrimitiveType);
3611 hr = wined3d_device_draw_indexed_primitive_up(This->wined3d_device, IndexCount, Indices,
3612 WINED3DFMT_R16_UINT, Vertices, get_flexible_vertex_size(VertexType));
3613 wined3d_mutex_unlock();
3618 static HRESULT WINAPI
3619 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUSetup(IDirect3DDevice7 *iface,
3620 D3DPRIMITIVETYPE PrimitiveType,
3628 return IDirect3DDeviceImpl_7_DrawIndexedPrimitive(iface, PrimitiveType, VertexType, Vertices, VertexCount, Indices, IndexCount, Flags);
3631 static HRESULT WINAPI
3632 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUPreserve(IDirect3DDevice7 *iface,
3633 D3DPRIMITIVETYPE PrimitiveType,
3644 old_fpucw = d3d_fpu_setup();
3645 hr = IDirect3DDeviceImpl_7_DrawIndexedPrimitive(iface, PrimitiveType, VertexType, Vertices, VertexCount, Indices, IndexCount, Flags);
3646 set_fpu_control_word(old_fpucw);
3651 static HRESULT WINAPI IDirect3DDeviceImpl_3_DrawIndexedPrimitive(IDirect3DDevice3 *iface,
3652 D3DPRIMITIVETYPE PrimitiveType, DWORD VertexType, void *Vertices, DWORD VertexCount,
3653 WORD *Indices, DWORD IndexCount, DWORD Flags)
3655 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice3(iface);
3656 TRACE("iface %p, primitive_type %#x, FVF %#x, vertices %p, vertex_count %u, indices %p, index_count %u, flags %#x.\n",
3657 iface, PrimitiveType, VertexType, Vertices, VertexCount, Indices, IndexCount, Flags);
3659 return IDirect3DDevice7_DrawIndexedPrimitive(&This->IDirect3DDevice7_iface,
3660 PrimitiveType, VertexType, Vertices, VertexCount, Indices, IndexCount, Flags);
3663 static HRESULT WINAPI IDirect3DDeviceImpl_2_DrawIndexedPrimitive(IDirect3DDevice2 *iface,
3664 D3DPRIMITIVETYPE PrimitiveType, D3DVERTEXTYPE VertexType, void *Vertices,
3665 DWORD VertexCount, WORD *Indices, DWORD IndexCount, DWORD Flags)
3667 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice2(iface);
3670 TRACE("iface %p, primitive_type %#x, vertex_type %#x, vertices %p, vertex_count %u, indices %p, index_count %u, flags %#x.\n",
3671 iface, PrimitiveType, VertexType, Vertices, VertexCount, Indices, IndexCount, Flags);
3675 case D3DVT_VERTEX: FVF = D3DFVF_VERTEX; break;
3676 case D3DVT_LVERTEX: FVF = D3DFVF_LVERTEX; break;
3677 case D3DVT_TLVERTEX: FVF = D3DFVF_TLVERTEX; break;
3679 ERR("Unexpected vertex type %d\n", VertexType);
3680 return DDERR_INVALIDPARAMS; /* Should never happen */
3683 return IDirect3DDevice7_DrawIndexedPrimitive(&This->IDirect3DDevice7_iface,
3684 PrimitiveType, FVF, Vertices, VertexCount, Indices, IndexCount, Flags);
3687 /*****************************************************************************
3688 * IDirect3DDevice7::SetClipStatus
3690 * Sets the clip status. This defines things as clipping conditions and
3691 * the extents of the clipping region.
3693 * Version 2, 3 and 7
3699 * D3D_OK because it's a stub
3700 * (DDERR_INVALIDPARAMS if ClipStatus == NULL)
3702 *****************************************************************************/
3703 static HRESULT WINAPI
3704 IDirect3DDeviceImpl_7_SetClipStatus(IDirect3DDevice7 *iface,
3705 D3DCLIPSTATUS *ClipStatus)
3707 FIXME("iface %p, clip_status %p stub!\n", iface, ClipStatus);
3709 /* D3DCLIPSTATUS and WINED3DCLIPSTATUS are different. I don't know how to convert them
3710 * Perhaps this needs a new data type and an additional IWineD3DDevice method
3712 /* return IWineD3DDevice_SetClipStatus(This->wineD3DDevice, ClipStatus);*/
3716 static HRESULT WINAPI IDirect3DDeviceImpl_3_SetClipStatus(IDirect3DDevice3 *iface,
3717 D3DCLIPSTATUS *ClipStatus)
3719 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice3(iface);
3720 TRACE("iface %p, clip_status %p.\n", iface, ClipStatus);
3722 return IDirect3DDevice7_SetClipStatus(&This->IDirect3DDevice7_iface, ClipStatus);
3725 static HRESULT WINAPI IDirect3DDeviceImpl_2_SetClipStatus(IDirect3DDevice2 *iface,
3726 D3DCLIPSTATUS *ClipStatus)
3728 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice2(iface);
3729 TRACE("iface %p, clip_status %p.\n", iface, ClipStatus);
3731 return IDirect3DDevice7_SetClipStatus(&This->IDirect3DDevice7_iface, ClipStatus);
3734 /*****************************************************************************
3735 * IDirect3DDevice7::GetClipStatus
3737 * Returns the clip status
3740 * ClipStatus: Address to write the clip status to
3743 * D3D_OK because it's a stub
3745 *****************************************************************************/
3746 static HRESULT WINAPI
3747 IDirect3DDeviceImpl_7_GetClipStatus(IDirect3DDevice7 *iface,
3748 D3DCLIPSTATUS *ClipStatus)
3750 FIXME("iface %p, clip_status %p stub!\n", iface, ClipStatus);
3752 /* D3DCLIPSTATUS and WINED3DCLIPSTATUS are different. I don't know how to convert them */
3753 /* return IWineD3DDevice_GetClipStatus(This->wineD3DDevice, ClipStatus);*/
3757 static HRESULT WINAPI IDirect3DDeviceImpl_3_GetClipStatus(IDirect3DDevice3 *iface,
3758 D3DCLIPSTATUS *ClipStatus)
3760 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice3(iface);
3761 TRACE("iface %p, clip_status %p.\n", iface, ClipStatus);
3763 return IDirect3DDevice7_GetClipStatus(&This->IDirect3DDevice7_iface, ClipStatus);
3766 static HRESULT WINAPI IDirect3DDeviceImpl_2_GetClipStatus(IDirect3DDevice2 *iface,
3767 D3DCLIPSTATUS *ClipStatus)
3769 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice2(iface);
3770 TRACE("iface %p, clip_status %p.\n", iface, ClipStatus);
3772 return IDirect3DDevice7_GetClipStatus(&This->IDirect3DDevice7_iface, ClipStatus);
3775 /*****************************************************************************
3776 * IDirect3DDevice::DrawPrimitiveStrided
3778 * Draws vertices described by a D3DDRAWPRIMITIVESTRIDEDDATA structure.
3783 * PrimitiveType: The primitive type to draw
3784 * VertexType: The FVF description of the vertices to draw (for the stride??)
3785 * D3DDrawPrimStrideData: A D3DDRAWPRIMITIVESTRIDEDDATA structure describing
3786 * the vertex data locations
3787 * VertexCount: The number of vertices to draw
3791 * D3D_OK, because it's a stub
3792 * (DDERR_INVALIDPARAMS if D3DDrawPrimStrideData is NULL)
3793 * (For details, see IWineD3DDevice::DrawPrimitiveStrided)
3795 *****************************************************************************/
3797 IDirect3DDeviceImpl_7_DrawPrimitiveStrided(IDirect3DDevice7 *iface,
3798 D3DPRIMITIVETYPE PrimitiveType,
3800 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
3804 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice7(iface);
3805 WineDirect3DVertexStridedData WineD3DStrided;
3809 TRACE("iface %p, primitive_type %#x, FVF %#x, strided_data %p, vertex_count %u, flags %#x.\n",
3810 iface, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Flags);
3812 memset(&WineD3DStrided, 0, sizeof(WineD3DStrided));
3813 /* Get the strided data right. the wined3d structure is a bit bigger
3814 * Watch out: The contents of the strided data are determined by the fvf,
3815 * not by the members set in D3DDrawPrimStrideData. So it's valid
3816 * to have diffuse.lpvData set to 0xdeadbeef if the diffuse flag is
3817 * not set in the fvf.
3819 if(VertexType & D3DFVF_POSITION_MASK)
3821 WineD3DStrided.position.format = WINED3DFMT_R32G32B32_FLOAT;
3822 WineD3DStrided.position.lpData = D3DDrawPrimStrideData->position.lpvData;
3823 WineD3DStrided.position.dwStride = D3DDrawPrimStrideData->position.dwStride;
3824 if (VertexType & D3DFVF_XYZRHW)
3826 WineD3DStrided.position.format = WINED3DFMT_R32G32B32A32_FLOAT;
3827 WineD3DStrided.position_transformed = TRUE;
3829 WineD3DStrided.position_transformed = FALSE;
3832 if(VertexType & D3DFVF_NORMAL)
3834 WineD3DStrided.normal.format = WINED3DFMT_R32G32B32_FLOAT;
3835 WineD3DStrided.normal.lpData = D3DDrawPrimStrideData->normal.lpvData;
3836 WineD3DStrided.normal.dwStride = D3DDrawPrimStrideData->normal.dwStride;
3839 if(VertexType & D3DFVF_DIFFUSE)
3841 WineD3DStrided.diffuse.format = WINED3DFMT_B8G8R8A8_UNORM;
3842 WineD3DStrided.diffuse.lpData = D3DDrawPrimStrideData->diffuse.lpvData;
3843 WineD3DStrided.diffuse.dwStride = D3DDrawPrimStrideData->diffuse.dwStride;
3846 if(VertexType & D3DFVF_SPECULAR)
3848 WineD3DStrided.specular.format = WINED3DFMT_B8G8R8A8_UNORM;
3849 WineD3DStrided.specular.lpData = D3DDrawPrimStrideData->specular.lpvData;
3850 WineD3DStrided.specular.dwStride = D3DDrawPrimStrideData->specular.dwStride;
3853 for( i = 0; i < GET_TEXCOUNT_FROM_FVF(VertexType); i++)
3855 switch(GET_TEXCOORD_SIZE_FROM_FVF(VertexType, i))
3857 case 1: WineD3DStrided.texCoords[i].format = WINED3DFMT_R32_FLOAT; break;
3858 case 2: WineD3DStrided.texCoords[i].format = WINED3DFMT_R32G32_FLOAT; break;
3859 case 3: WineD3DStrided.texCoords[i].format = WINED3DFMT_R32G32B32_FLOAT; break;
3860 case 4: WineD3DStrided.texCoords[i].format = WINED3DFMT_R32G32B32A32_FLOAT; break;
3861 default: ERR("Unexpected texture coordinate size %d\n",
3862 GET_TEXCOORD_SIZE_FROM_FVF(VertexType, i));
3864 WineD3DStrided.texCoords[i].lpData = D3DDrawPrimStrideData->textureCoords[i].lpvData;
3865 WineD3DStrided.texCoords[i].dwStride = D3DDrawPrimStrideData->textureCoords[i].dwStride;
3868 /* WineD3D doesn't need the FVF here */
3869 wined3d_mutex_lock();
3870 wined3d_device_set_primitive_type(This->wined3d_device, PrimitiveType);
3871 hr = wined3d_device_draw_primitive_strided(This->wined3d_device, VertexCount, &WineD3DStrided);
3872 wined3d_mutex_unlock();
3877 static HRESULT WINAPI
3878 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUSetup(IDirect3DDevice7 *iface,
3879 D3DPRIMITIVETYPE PrimitiveType,
3881 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
3885 return IDirect3DDeviceImpl_7_DrawPrimitiveStrided(iface, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Flags);
3888 static HRESULT WINAPI
3889 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUPreserve(IDirect3DDevice7 *iface,
3890 D3DPRIMITIVETYPE PrimitiveType,
3892 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
3899 old_fpucw = d3d_fpu_setup();
3900 hr = IDirect3DDeviceImpl_7_DrawPrimitiveStrided(iface, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Flags);
3901 set_fpu_control_word(old_fpucw);
3906 static HRESULT WINAPI IDirect3DDeviceImpl_3_DrawPrimitiveStrided(IDirect3DDevice3 *iface,
3907 D3DPRIMITIVETYPE PrimitiveType, DWORD VertexType,
3908 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData, DWORD VertexCount, DWORD Flags)
3910 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice3(iface);
3912 TRACE("iface %p, primitive_type %#x, FVF %#x, strided_data %p, vertex_count %u, flags %#x.\n",
3913 iface, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Flags);
3915 return IDirect3DDevice7_DrawPrimitiveStrided(&This->IDirect3DDevice7_iface,
3916 PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Flags);
3919 /*****************************************************************************
3920 * IDirect3DDevice7::DrawIndexedPrimitiveStrided
3922 * Draws primitives specified by strided data locations based on indices
3930 * D3D_OK, because it's a stub
3931 * (DDERR_INVALIDPARAMS if D3DDrawPrimStrideData is NULL)
3932 * (DDERR_INVALIDPARAMS if Indices is NULL)
3933 * (For more details, see IWineD3DDevice::DrawIndexedPrimitiveStrided)
3935 *****************************************************************************/
3937 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided(IDirect3DDevice7 *iface,
3938 D3DPRIMITIVETYPE PrimitiveType,
3940 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
3946 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice7(iface);
3947 WineDirect3DVertexStridedData WineD3DStrided;
3951 TRACE("iface %p, primitive_type %#x, FVF %#x, strided_data %p, vertex_count %u, indices %p, index_count %u, flags %#x.\n",
3952 iface, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Indices, IndexCount, Flags);
3954 memset(&WineD3DStrided, 0, sizeof(WineD3DStrided));
3955 /* Get the strided data right. the wined3d structure is a bit bigger
3956 * Watch out: The contents of the strided data are determined by the fvf,
3957 * not by the members set in D3DDrawPrimStrideData. So it's valid
3958 * to have diffuse.lpvData set to 0xdeadbeef if the diffuse flag is
3959 * not set in the fvf.
3961 if(VertexType & D3DFVF_POSITION_MASK)
3963 WineD3DStrided.position.format = WINED3DFMT_R32G32B32_FLOAT;
3964 WineD3DStrided.position.lpData = D3DDrawPrimStrideData->position.lpvData;
3965 WineD3DStrided.position.dwStride = D3DDrawPrimStrideData->position.dwStride;
3966 if (VertexType & D3DFVF_XYZRHW)
3968 WineD3DStrided.position.format = WINED3DFMT_R32G32B32A32_FLOAT;
3969 WineD3DStrided.position_transformed = TRUE;
3971 WineD3DStrided.position_transformed = FALSE;
3974 if(VertexType & D3DFVF_NORMAL)
3976 WineD3DStrided.normal.format = WINED3DFMT_R32G32B32_FLOAT;
3977 WineD3DStrided.normal.lpData = D3DDrawPrimStrideData->normal.lpvData;
3978 WineD3DStrided.normal.dwStride = D3DDrawPrimStrideData->normal.dwStride;
3981 if(VertexType & D3DFVF_DIFFUSE)
3983 WineD3DStrided.diffuse.format = WINED3DFMT_B8G8R8A8_UNORM;
3984 WineD3DStrided.diffuse.lpData = D3DDrawPrimStrideData->diffuse.lpvData;
3985 WineD3DStrided.diffuse.dwStride = D3DDrawPrimStrideData->diffuse.dwStride;
3988 if(VertexType & D3DFVF_SPECULAR)
3990 WineD3DStrided.specular.format = WINED3DFMT_B8G8R8A8_UNORM;
3991 WineD3DStrided.specular.lpData = D3DDrawPrimStrideData->specular.lpvData;
3992 WineD3DStrided.specular.dwStride = D3DDrawPrimStrideData->specular.dwStride;
3995 for( i = 0; i < GET_TEXCOUNT_FROM_FVF(VertexType); i++)
3997 switch(GET_TEXCOORD_SIZE_FROM_FVF(VertexType, i))
3999 case 1: WineD3DStrided.texCoords[i].format = WINED3DFMT_R32_FLOAT; break;
4000 case 2: WineD3DStrided.texCoords[i].format = WINED3DFMT_R32G32_FLOAT; break;
4001 case 3: WineD3DStrided.texCoords[i].format = WINED3DFMT_R32G32B32_FLOAT; break;
4002 case 4: WineD3DStrided.texCoords[i].format = WINED3DFMT_R32G32B32A32_FLOAT; break;
4003 default: ERR("Unexpected texture coordinate size %d\n",
4004 GET_TEXCOORD_SIZE_FROM_FVF(VertexType, i));
4006 WineD3DStrided.texCoords[i].lpData = D3DDrawPrimStrideData->textureCoords[i].lpvData;
4007 WineD3DStrided.texCoords[i].dwStride = D3DDrawPrimStrideData->textureCoords[i].dwStride;
4010 /* WineD3D doesn't need the FVF here */
4011 wined3d_mutex_lock();
4012 wined3d_device_set_primitive_type(This->wined3d_device, PrimitiveType);
4013 hr = wined3d_device_draw_indexed_primitive_strided(This->wined3d_device,
4014 IndexCount, &WineD3DStrided, VertexCount, Indices, WINED3DFMT_R16_UINT);
4015 wined3d_mutex_unlock();
4020 static HRESULT WINAPI
4021 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUSetup(IDirect3DDevice7 *iface,
4022 D3DPRIMITIVETYPE PrimitiveType,
4024 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
4030 return IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided(iface, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Indices, IndexCount, Flags);
4033 static HRESULT WINAPI
4034 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUPreserve(IDirect3DDevice7 *iface,
4035 D3DPRIMITIVETYPE PrimitiveType,
4037 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
4046 old_fpucw = d3d_fpu_setup();
4047 hr = IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided(iface, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Indices, IndexCount, Flags);
4048 set_fpu_control_word(old_fpucw);
4053 static HRESULT WINAPI IDirect3DDeviceImpl_3_DrawIndexedPrimitiveStrided(IDirect3DDevice3 *iface,
4054 D3DPRIMITIVETYPE PrimitiveType, DWORD VertexType,
4055 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData, DWORD VertexCount, WORD *Indices,
4056 DWORD IndexCount, DWORD Flags)
4058 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice3(iface);
4060 TRACE("iface %p, primitive_type %#x, FVF %#x, strided_data %p, vertex_count %u, indices %p, index_count %u, flags %#x.\n",
4061 iface, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Indices, IndexCount, Flags);
4063 return IDirect3DDevice7_DrawIndexedPrimitiveStrided(&This->IDirect3DDevice7_iface,
4064 PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Indices, IndexCount, Flags);
4067 /*****************************************************************************
4068 * IDirect3DDevice7::DrawPrimitiveVB
4070 * Draws primitives from a vertex buffer to the screen.
4075 * PrimitiveType: Type of primitive to be rendered.
4076 * D3DVertexBuf: Source Vertex Buffer
4077 * StartVertex: Index of the first vertex from the buffer to be rendered
4078 * NumVertices: Number of vertices to be rendered
4079 * Flags: Can be D3DDP_WAIT to wait until rendering has finished
4083 * DDERR_INVALIDPARAMS if D3DVertexBuf is NULL
4085 *****************************************************************************/
4087 IDirect3DDeviceImpl_7_DrawPrimitiveVB(IDirect3DDevice7 *iface,
4088 D3DPRIMITIVETYPE PrimitiveType,
4089 IDirect3DVertexBuffer7 *D3DVertexBuf,
4094 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice7(iface);
4095 IDirect3DVertexBufferImpl *vb = unsafe_impl_from_IDirect3DVertexBuffer7(D3DVertexBuf);
4099 TRACE("iface %p, primitive_type %#x, vb %p, start_vertex %u, vertex_count %u, flags %#x.\n",
4100 iface, PrimitiveType, D3DVertexBuf, StartVertex, NumVertices, Flags);
4105 ERR("(%p) No Vertex buffer specified\n", This);
4106 return DDERR_INVALIDPARAMS;
4108 stride = get_flexible_vertex_size(vb->fvf);
4110 wined3d_mutex_lock();
4111 hr = wined3d_device_set_vertex_declaration(This->wined3d_device, vb->wineD3DVertexDeclaration);
4114 ERR(" (%p) Setting the FVF failed, hr = %x!\n", This, hr);
4115 wined3d_mutex_unlock();
4119 /* Set the vertex stream source */
4120 hr = wined3d_device_set_stream_source(This->wined3d_device, 0, vb->wineD3DVertexBuffer, 0, stride);
4123 ERR("(%p) IDirect3DDevice::SetStreamSource failed with hr = %08x\n", This, hr);
4124 wined3d_mutex_unlock();
4128 /* Now draw the primitives */
4129 wined3d_device_set_primitive_type(This->wined3d_device, PrimitiveType);
4130 hr = wined3d_device_draw_primitive(This->wined3d_device, StartVertex, NumVertices);
4131 wined3d_mutex_unlock();
4136 static HRESULT WINAPI
4137 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUSetup(IDirect3DDevice7 *iface,
4138 D3DPRIMITIVETYPE PrimitiveType,
4139 IDirect3DVertexBuffer7 *D3DVertexBuf,
4144 return IDirect3DDeviceImpl_7_DrawPrimitiveVB(iface, PrimitiveType, D3DVertexBuf, StartVertex, NumVertices, Flags);
4147 static HRESULT WINAPI
4148 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUPreserve(IDirect3DDevice7 *iface,
4149 D3DPRIMITIVETYPE PrimitiveType,
4150 IDirect3DVertexBuffer7 *D3DVertexBuf,
4158 old_fpucw = d3d_fpu_setup();
4159 hr = IDirect3DDeviceImpl_7_DrawPrimitiveVB(iface, PrimitiveType, D3DVertexBuf, StartVertex, NumVertices, Flags);
4160 set_fpu_control_word(old_fpucw);
4165 static HRESULT WINAPI IDirect3DDeviceImpl_3_DrawPrimitiveVB(IDirect3DDevice3 *iface,
4166 D3DPRIMITIVETYPE PrimitiveType, IDirect3DVertexBuffer *D3DVertexBuf, DWORD StartVertex,
4167 DWORD NumVertices, DWORD Flags)
4169 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice3(iface);
4170 IDirect3DVertexBufferImpl *vb = unsafe_impl_from_IDirect3DVertexBuffer(D3DVertexBuf);
4172 TRACE("iface %p, primitive_type %#x, vb %p, start_vertex %u, vertex_count %u, flags %#x.\n",
4173 iface, PrimitiveType, D3DVertexBuf, StartVertex, NumVertices, Flags);
4175 return IDirect3DDevice7_DrawPrimitiveVB(&This->IDirect3DDevice7_iface,
4176 PrimitiveType, &vb->IDirect3DVertexBuffer7_iface, StartVertex, NumVertices, Flags);
4180 /*****************************************************************************
4181 * IDirect3DDevice7::DrawIndexedPrimitiveVB
4183 * Draws primitives from a vertex buffer to the screen
4186 * PrimitiveType: Type of primitive to be rendered.
4187 * D3DVertexBuf: Source Vertex Buffer
4188 * StartVertex: Index of the first vertex from the buffer to be rendered
4189 * NumVertices: Number of vertices to be rendered
4190 * Indices: Array of DWORDs used to index into the Vertices
4191 * IndexCount: Number of indices in Indices
4192 * Flags: Can be D3DDP_WAIT to wait until rendering has finished
4196 *****************************************************************************/
4198 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB(IDirect3DDevice7 *iface,
4199 D3DPRIMITIVETYPE PrimitiveType,
4200 IDirect3DVertexBuffer7 *D3DVertexBuf,
4207 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice7(iface);
4208 IDirect3DVertexBufferImpl *vb = unsafe_impl_from_IDirect3DVertexBuffer7(D3DVertexBuf);
4209 DWORD stride = get_flexible_vertex_size(vb->fvf);
4210 struct wined3d_resource *wined3d_resource;
4211 struct wined3d_resource_desc desc;
4212 WORD *LockedIndices;
4215 TRACE("iface %p, primitive_type %#x, vb %p, start_vertex %u, vertex_count %u, indices %p, index_count %u, flags %#x.\n",
4216 iface, PrimitiveType, D3DVertexBuf, StartVertex, NumVertices, Indices, IndexCount, Flags);
4219 * 1) Upload the Indices to the index buffer
4220 * 2) Set the index source
4221 * 3) Set the Vertex Buffer as the Stream source
4222 * 4) Call IWineD3DDevice::DrawIndexedPrimitive
4225 wined3d_mutex_lock();
4227 hr = wined3d_device_set_vertex_declaration(This->wined3d_device, vb->wineD3DVertexDeclaration);
4230 ERR(" (%p) Setting the FVF failed, hr = %x!\n", This, hr);
4231 wined3d_mutex_unlock();
4235 /* check that the buffer is large enough to hold the indices,
4236 * reallocate if necessary. */
4237 wined3d_resource = wined3d_buffer_get_resource(This->indexbuffer);
4238 wined3d_resource_get_desc(wined3d_resource, &desc);
4239 if (desc.size < IndexCount * sizeof(WORD))
4241 UINT size = max(desc.size * 2, IndexCount * sizeof(WORD));
4242 struct wined3d_buffer *buffer;
4244 TRACE("Growing index buffer to %u bytes\n", size);
4246 hr = wined3d_buffer_create_ib(This->wined3d_device, size, WINED3DUSAGE_DYNAMIC /* Usage */,
4247 WINED3DPOOL_DEFAULT, NULL, &ddraw_null_wined3d_parent_ops, &buffer);
4250 ERR("(%p) IWineD3DDevice::CreateIndexBuffer failed with hr = %08x\n", This, hr);
4251 wined3d_mutex_unlock();
4255 wined3d_buffer_decref(This->indexbuffer);
4256 This->indexbuffer = buffer;
4259 /* Copy the index stream into the index buffer. A new IWineD3DDevice
4260 * method could be created which takes an user pointer containing the
4261 * indices or a SetData-Method for the index buffer, which overrides the
4262 * index buffer data with our pointer. */
4263 hr = wined3d_buffer_map(This->indexbuffer, 0, IndexCount * sizeof(WORD),
4264 (BYTE **)&LockedIndices, 0);
4267 ERR("Failed to map buffer, hr %#x.\n", hr);
4268 wined3d_mutex_unlock();
4271 memcpy(LockedIndices, Indices, IndexCount * sizeof(WORD));
4272 wined3d_buffer_unmap(This->indexbuffer);
4274 /* Set the index stream */
4275 wined3d_device_set_base_vertex_index(This->wined3d_device, StartVertex);
4276 hr = wined3d_device_set_index_buffer(This->wined3d_device, This->indexbuffer, WINED3DFMT_R16_UINT);
4278 /* Set the vertex stream source */
4279 hr = wined3d_device_set_stream_source(This->wined3d_device, 0, vb->wineD3DVertexBuffer, 0, stride);
4282 ERR("(%p) IDirect3DDevice::SetStreamSource failed with hr = %08x\n", This, hr);
4283 wined3d_mutex_unlock();
4288 wined3d_device_set_primitive_type(This->wined3d_device, PrimitiveType);
4289 hr = wined3d_device_draw_indexed_primitive(This->wined3d_device, 0, IndexCount);
4291 wined3d_mutex_unlock();
4296 static HRESULT WINAPI
4297 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUSetup(IDirect3DDevice7 *iface,
4298 D3DPRIMITIVETYPE PrimitiveType,
4299 IDirect3DVertexBuffer7 *D3DVertexBuf,
4306 return IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB(iface, PrimitiveType, D3DVertexBuf, StartVertex, NumVertices, Indices, IndexCount, Flags);
4309 static HRESULT WINAPI
4310 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUPreserve(IDirect3DDevice7 *iface,
4311 D3DPRIMITIVETYPE PrimitiveType,
4312 IDirect3DVertexBuffer7 *D3DVertexBuf,
4322 old_fpucw = d3d_fpu_setup();
4323 hr = IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB(iface, PrimitiveType, D3DVertexBuf, StartVertex, NumVertices, Indices, IndexCount, Flags);
4324 set_fpu_control_word(old_fpucw);
4329 static HRESULT WINAPI IDirect3DDeviceImpl_3_DrawIndexedPrimitiveVB(IDirect3DDevice3 *iface,
4330 D3DPRIMITIVETYPE PrimitiveType, IDirect3DVertexBuffer *D3DVertexBuf, WORD *Indices,
4331 DWORD IndexCount, DWORD Flags)
4333 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice3(iface);
4334 IDirect3DVertexBufferImpl *vb = unsafe_impl_from_IDirect3DVertexBuffer(D3DVertexBuf);
4336 TRACE("iface %p, primitive_type %#x, vb %p, indices %p, index_count %u, flags %#x.\n",
4337 iface, PrimitiveType, D3DVertexBuf, Indices, IndexCount, Flags);
4339 return IDirect3DDevice7_DrawIndexedPrimitiveVB(&This->IDirect3DDevice7_iface,
4340 PrimitiveType, &vb->IDirect3DVertexBuffer7_iface, 0, IndexCount, Indices, IndexCount,
4344 /*****************************************************************************
4345 * IDirect3DDevice7::ComputeSphereVisibility
4347 * Calculates the visibility of spheres in the current viewport. The spheres
4348 * are passed in the Centers and Radii arrays, the results are passed back
4349 * in the ReturnValues array. Return values are either completely visible,
4350 * partially visible or completely invisible.
4351 * The return value consist of a combination of D3DCLIP_* flags, or it's
4352 * 0 if the sphere is completely visible(according to the SDK, not checked)
4357 * Centers: Array containing the sphere centers
4358 * Radii: Array containing the sphere radii
4359 * NumSpheres: The number of centers and radii in the arrays
4361 * ReturnValues: Array to write the results to
4365 * (DDERR_INVALIDPARAMS if Centers, Radii or ReturnValues are NULL)
4366 * (D3DERR_INVALIDMATRIX if the combined world, view and proj matrix
4369 *****************************************************************************/
4371 static DWORD in_plane(UINT plane, D3DVECTOR normal, D3DVALUE origin_plane, D3DVECTOR center, D3DVALUE radius)
4373 float distance, norm;
4375 norm = sqrt( normal.u1.x * normal.u1.x + normal.u2.y * normal.u2.y + normal.u3.z * normal.u3.z );
4376 distance = ( origin_plane + normal.u1.x * center.u1.x + normal.u2.y * center.u2.y + normal.u3.z * center.u3.z ) / norm;
4378 if ( fabs( distance ) < radius ) return D3DSTATUS_CLIPUNIONLEFT << plane;
4379 if ( distance < -radius ) return (D3DSTATUS_CLIPUNIONLEFT | D3DSTATUS_CLIPINTERSECTIONLEFT) << plane;
4383 static HRESULT WINAPI
4384 IDirect3DDeviceImpl_7_ComputeSphereVisibility(IDirect3DDevice7 *iface,
4389 DWORD *ReturnValues)
4392 D3DVALUE origin_plane[6];
4397 TRACE("iface %p, centers %p, radii %p, sphere_count %u, flags %#x, return_values %p.\n",
4398 iface, Centers, Radii, NumSpheres, Flags, ReturnValues);
4400 hr = IDirect3DDeviceImpl_7_GetTransform(iface, D3DTRANSFORMSTATE_WORLD, &m);
4401 if ( hr != DD_OK ) return DDERR_INVALIDPARAMS;
4402 hr = IDirect3DDeviceImpl_7_GetTransform(iface, D3DTRANSFORMSTATE_VIEW, &temp);
4403 if ( hr != DD_OK ) return DDERR_INVALIDPARAMS;
4404 multiply_matrix(&m, &temp, &m);
4406 hr = IDirect3DDeviceImpl_7_GetTransform(iface, D3DTRANSFORMSTATE_PROJECTION, &temp);
4407 if ( hr != DD_OK ) return DDERR_INVALIDPARAMS;
4408 multiply_matrix(&m, &temp, &m);
4411 vec[0].u1.x = m._14 + m._11;
4412 vec[0].u2.y = m._24 + m._21;
4413 vec[0].u3.z = m._34 + m._31;
4414 origin_plane[0] = m._44 + m._41;
4417 vec[1].u1.x = m._14 - m._11;
4418 vec[1].u2.y = m._24 - m._21;
4419 vec[1].u3.z = m._34 - m._31;
4420 origin_plane[1] = m._44 - m._41;
4423 vec[2].u1.x = m._14 - m._12;
4424 vec[2].u2.y = m._24 - m._22;
4425 vec[2].u3.z = m._34 - m._32;
4426 origin_plane[2] = m._44 - m._42;
4429 vec[3].u1.x = m._14 + m._12;
4430 vec[3].u2.y = m._24 + m._22;
4431 vec[3].u3.z = m._34 + m._32;
4432 origin_plane[3] = m._44 + m._42;
4435 vec[4].u1.x = m._13;
4436 vec[4].u2.y = m._23;
4437 vec[4].u3.z = m._33;
4438 origin_plane[4] = m._43;
4441 vec[5].u1.x = m._14 - m._13;
4442 vec[5].u2.y = m._24 - m._23;
4443 vec[5].u3.z = m._34 - m._33;
4444 origin_plane[5] = m._44 - m._43;
4446 for(i=0; i<NumSpheres; i++)
4448 ReturnValues[i] = 0;
4449 for(j=0; j<6; j++) ReturnValues[i] |= in_plane(j, vec[j], origin_plane[j], Centers[i], Radii[i]);
4455 static HRESULT WINAPI IDirect3DDeviceImpl_3_ComputeSphereVisibility(IDirect3DDevice3 *iface,
4456 D3DVECTOR *Centers, D3DVALUE *Radii, DWORD NumSpheres, DWORD Flags, DWORD *ReturnValues)
4458 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice3(iface);
4460 TRACE("iface %p, centers %p, radii %p, sphere_count %u, flags %#x, return_values %p.\n",
4461 iface, Centers, Radii, NumSpheres, Flags, ReturnValues);
4463 return IDirect3DDevice7_ComputeSphereVisibility(&This->IDirect3DDevice7_iface,
4464 Centers, Radii, NumSpheres, Flags, ReturnValues);
4467 /*****************************************************************************
4468 * IDirect3DDevice7::GetTexture
4470 * Returns the texture interface handle assigned to a texture stage.
4471 * The returned texture is AddRefed. This is taken from old ddraw,
4472 * not checked in Windows.
4477 * Stage: Texture stage to read the texture from
4478 * Texture: Address to store the interface pointer at
4482 * DDERR_INVALIDPARAMS if Texture is NULL
4483 * For details, see IWineD3DDevice::GetTexture
4485 *****************************************************************************/
4487 IDirect3DDeviceImpl_7_GetTexture(IDirect3DDevice7 *iface,
4489 IDirectDrawSurface7 **Texture)
4491 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice7(iface);
4492 struct wined3d_texture *wined3d_texture;
4495 TRACE("iface %p, stage %u, texture %p.\n", iface, Stage, Texture);
4499 TRACE("Texture == NULL, failing with DDERR_INVALIDPARAMS\n");
4500 return DDERR_INVALIDPARAMS;
4503 wined3d_mutex_lock();
4504 hr = wined3d_device_get_texture(This->wined3d_device, Stage, &wined3d_texture);
4505 if (FAILED(hr) || !wined3d_texture)
4508 wined3d_mutex_unlock();
4512 *Texture = wined3d_texture_get_parent(wined3d_texture);
4513 IDirectDrawSurface7_AddRef(*Texture);
4514 wined3d_texture_decref(wined3d_texture);
4515 wined3d_mutex_unlock();
4520 static HRESULT WINAPI
4521 IDirect3DDeviceImpl_7_GetTexture_FPUSetup(IDirect3DDevice7 *iface,
4523 IDirectDrawSurface7 **Texture)
4525 return IDirect3DDeviceImpl_7_GetTexture(iface, Stage, Texture);
4528 static HRESULT WINAPI
4529 IDirect3DDeviceImpl_7_GetTexture_FPUPreserve(IDirect3DDevice7 *iface,
4531 IDirectDrawSurface7 **Texture)
4536 old_fpucw = d3d_fpu_setup();
4537 hr = IDirect3DDeviceImpl_7_GetTexture(iface, Stage, Texture);
4538 set_fpu_control_word(old_fpucw);
4543 static HRESULT WINAPI IDirect3DDeviceImpl_3_GetTexture(IDirect3DDevice3 *iface, DWORD Stage,
4544 IDirect3DTexture2 **Texture2)
4546 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice3(iface);
4548 IDirectDrawSurface7 *ret_val;
4549 IDirectDrawSurfaceImpl *ret_val_impl;
4551 TRACE("iface %p, stage %u, texture %p.\n", iface, Stage, Texture2);
4553 ret = IDirect3DDevice7_GetTexture(&This->IDirect3DDevice7_iface, Stage, &ret_val);
4555 ret_val_impl = unsafe_impl_from_IDirectDrawSurface7(ret_val);
4556 *Texture2 = ret_val_impl ? &ret_val_impl->IDirect3DTexture2_iface : NULL;
4558 TRACE("Returning texture %p.\n", *Texture2);
4563 /*****************************************************************************
4564 * IDirect3DDevice7::SetTexture
4566 * Assigns a texture to a texture stage. Is the texture AddRef-ed?
4571 * Stage: The stage to assign the texture to
4572 * Texture: Interface pointer to the texture surface
4576 * For details, see IWineD3DDevice::SetTexture
4578 *****************************************************************************/
4580 IDirect3DDeviceImpl_7_SetTexture(IDirect3DDevice7 *iface,
4582 IDirectDrawSurface7 *Texture)
4584 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice7(iface);
4585 IDirectDrawSurfaceImpl *surf = unsafe_impl_from_IDirectDrawSurface7(Texture);
4588 TRACE("iface %p, stage %u, texture %p.\n", iface, Stage, Texture);
4590 /* Texture may be NULL here */
4591 wined3d_mutex_lock();
4592 hr = wined3d_device_set_texture(This->wined3d_device,
4593 Stage, surf ? surf->wined3d_texture : NULL);
4594 wined3d_mutex_unlock();
4599 static HRESULT WINAPI
4600 IDirect3DDeviceImpl_7_SetTexture_FPUSetup(IDirect3DDevice7 *iface,
4602 IDirectDrawSurface7 *Texture)
4604 return IDirect3DDeviceImpl_7_SetTexture(iface, Stage, Texture);
4607 static HRESULT WINAPI
4608 IDirect3DDeviceImpl_7_SetTexture_FPUPreserve(IDirect3DDevice7 *iface,
4610 IDirectDrawSurface7 *Texture)
4615 old_fpucw = d3d_fpu_setup();
4616 hr = IDirect3DDeviceImpl_7_SetTexture(iface, Stage, Texture);
4617 set_fpu_control_word(old_fpucw);
4622 static HRESULT WINAPI
4623 IDirect3DDeviceImpl_3_SetTexture(IDirect3DDevice3 *iface,
4625 IDirect3DTexture2 *Texture2)
4627 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice3(iface);
4628 IDirectDrawSurfaceImpl *tex = unsafe_impl_from_IDirect3DTexture2(Texture2);
4632 TRACE("iface %p, stage %u, texture %p.\n", iface, Stage, Texture2);
4634 wined3d_mutex_lock();
4636 if (This->legacyTextureBlending)
4637 IDirect3DDevice3_GetRenderState(iface, D3DRENDERSTATE_TEXTUREMAPBLEND, &texmapblend);
4639 hr = IDirect3DDevice7_SetTexture(&This->IDirect3DDevice7_iface, Stage, &tex->IDirectDrawSurface7_iface);
4641 if (This->legacyTextureBlending && texmapblend == D3DTBLEND_MODULATE)
4643 /* This fixup is required by the way D3DTBLEND_MODULATE maps to texture stage states.
4644 See IDirect3DDeviceImpl_3_SetRenderState for details. */
4645 struct wined3d_texture *tex = NULL;
4646 BOOL tex_alpha = FALSE;
4647 DDPIXELFORMAT ddfmt;
4650 result = wined3d_device_get_texture(This->wined3d_device, 0, &tex);
4651 if (result == WINED3D_OK && tex)
4653 struct wined3d_resource *sub_resource;
4655 if ((sub_resource = wined3d_texture_get_sub_resource(tex, 0)))
4657 struct wined3d_resource_desc desc;
4659 wined3d_resource_get_desc(sub_resource, &desc);
4660 ddfmt.dwSize = sizeof(ddfmt);
4661 PixelFormat_WineD3DtoDD(&ddfmt, desc.format);
4662 if (ddfmt.u5.dwRGBAlphaBitMask) tex_alpha = TRUE;
4665 wined3d_texture_decref(tex);
4668 /* Arg 1/2 are already set to WINED3DTA_TEXTURE/WINED3DTA_CURRENT in case of D3DTBLEND_MODULATE */
4670 wined3d_device_set_texture_stage_state(This->wined3d_device, 0, WINED3DTSS_ALPHAOP, WINED3DTOP_SELECTARG1);
4672 wined3d_device_set_texture_stage_state(This->wined3d_device, 0, WINED3DTSS_ALPHAOP, WINED3DTOP_SELECTARG2);
4675 wined3d_mutex_unlock();
4680 static const struct tss_lookup
4687 {FALSE, WINED3DTSS_FORCE_DWORD}, /* 0, unused */
4688 {FALSE, WINED3DTSS_COLOROP}, /* 1, D3DTSS_COLOROP */
4689 {FALSE, WINED3DTSS_COLORARG1}, /* 2, D3DTSS_COLORARG1 */
4690 {FALSE, WINED3DTSS_COLORARG2}, /* 3, D3DTSS_COLORARG2 */
4691 {FALSE, WINED3DTSS_ALPHAOP}, /* 4, D3DTSS_ALPHAOP */
4692 {FALSE, WINED3DTSS_ALPHAARG1}, /* 5, D3DTSS_ALPHAARG1 */
4693 {FALSE, WINED3DTSS_ALPHAARG2}, /* 6, D3DTSS_ALPHAARG2 */
4694 {FALSE, WINED3DTSS_BUMPENVMAT00}, /* 7, D3DTSS_BUMPENVMAT00 */
4695 {FALSE, WINED3DTSS_BUMPENVMAT01}, /* 8, D3DTSS_BUMPENVMAT01 */
4696 {FALSE, WINED3DTSS_BUMPENVMAT10}, /* 9, D3DTSS_BUMPENVMAT10 */
4697 {FALSE, WINED3DTSS_BUMPENVMAT11}, /* 10, D3DTSS_BUMPENVMAT11 */
4698 {FALSE, WINED3DTSS_TEXCOORDINDEX}, /* 11, D3DTSS_TEXCOORDINDEX */
4699 {TRUE, WINED3DSAMP_ADDRESSU}, /* 12, D3DTSS_ADDRESS */
4700 {TRUE, WINED3DSAMP_ADDRESSU}, /* 13, D3DTSS_ADDRESSU */
4701 {TRUE, WINED3DSAMP_ADDRESSV}, /* 14, D3DTSS_ADDRESSV */
4702 {TRUE, WINED3DSAMP_BORDERCOLOR}, /* 15, D3DTSS_BORDERCOLOR */
4703 {TRUE, WINED3DSAMP_MAGFILTER}, /* 16, D3DTSS_MAGFILTER */
4704 {TRUE, WINED3DSAMP_MINFILTER}, /* 17, D3DTSS_MINFILTER */
4705 {TRUE, WINED3DSAMP_MIPFILTER}, /* 18, D3DTSS_MIPFILTER */
4706 {TRUE, WINED3DSAMP_MIPMAPLODBIAS}, /* 19, D3DTSS_MIPMAPLODBIAS */
4707 {TRUE, WINED3DSAMP_MAXMIPLEVEL}, /* 20, D3DTSS_MAXMIPLEVEL */
4708 {TRUE, WINED3DSAMP_MAXANISOTROPY}, /* 21, D3DTSS_MAXANISOTROPY */
4709 {FALSE, WINED3DTSS_BUMPENVLSCALE}, /* 22, D3DTSS_BUMPENVLSCALE */
4710 {FALSE, WINED3DTSS_BUMPENVLOFFSET}, /* 23, D3DTSS_BUMPENVLOFFSET */
4711 {FALSE, WINED3DTSS_TEXTURETRANSFORMFLAGS}, /* 24, D3DTSS_TEXTURETRANSFORMFLAGS */
4714 /*****************************************************************************
4715 * IDirect3DDevice7::GetTextureStageState
4717 * Retrieves a state from a texture stage.
4722 * Stage: The stage to retrieve the state from
4723 * TexStageStateType: The state type to retrieve
4724 * State: Address to store the state's value at
4728 * DDERR_INVALIDPARAMS if State is NULL
4729 * For details, see IWineD3DDevice::GetTextureStageState
4731 *****************************************************************************/
4733 IDirect3DDeviceImpl_7_GetTextureStageState(IDirect3DDevice7 *iface,
4735 D3DTEXTURESTAGESTATETYPE TexStageStateType,
4738 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice7(iface);
4740 const struct tss_lookup *l;
4742 TRACE("iface %p, stage %u, state %#x, value %p.\n",
4743 iface, Stage, TexStageStateType, State);
4746 return DDERR_INVALIDPARAMS;
4748 if (TexStageStateType > D3DTSS_TEXTURETRANSFORMFLAGS)
4750 WARN("Invalid TexStageStateType %#x passed.\n", TexStageStateType);
4754 l = &tss_lookup[TexStageStateType];
4756 wined3d_mutex_lock();
4758 if (l->sampler_state)
4760 hr = wined3d_device_get_sampler_state(This->wined3d_device, Stage, l->state, State);
4762 switch(TexStageStateType)
4764 /* Mipfilter is a sampler state with different values */
4765 case D3DTSS_MIPFILTER:
4769 case WINED3DTEXF_NONE: *State = D3DTFP_NONE; break;
4770 case WINED3DTEXF_POINT: *State = D3DTFP_POINT; break;
4771 case WINED3DTEXF_LINEAR: *State = D3DTFP_LINEAR; break;
4773 ERR("Unexpected mipfilter value %#x\n", *State);
4774 *State = D3DTFP_NONE;
4780 /* Magfilter has slightly different values */
4781 case D3DTSS_MAGFILTER:
4785 case WINED3DTEXF_POINT: *State = D3DTFG_POINT; break;
4786 case WINED3DTEXF_LINEAR: *State = D3DTFG_LINEAR; break;
4787 case WINED3DTEXF_ANISOTROPIC: *State = D3DTFG_ANISOTROPIC; break;
4788 case WINED3DTEXF_FLATCUBIC: *State = D3DTFG_FLATCUBIC; break;
4789 case WINED3DTEXF_GAUSSIANCUBIC: *State = D3DTFG_GAUSSIANCUBIC; break;
4791 ERR("Unexpected wined3d mag filter value %#x\n", *State);
4792 *State = D3DTFG_POINT;
4804 hr = wined3d_device_get_texture_stage_state(This->wined3d_device, Stage, l->state, State);
4807 wined3d_mutex_unlock();
4812 static HRESULT WINAPI
4813 IDirect3DDeviceImpl_7_GetTextureStageState_FPUSetup(IDirect3DDevice7 *iface,
4815 D3DTEXTURESTAGESTATETYPE TexStageStateType,
4818 return IDirect3DDeviceImpl_7_GetTextureStageState(iface, Stage, TexStageStateType, State);
4821 static HRESULT WINAPI
4822 IDirect3DDeviceImpl_7_GetTextureStageState_FPUPreserve(IDirect3DDevice7 *iface,
4824 D3DTEXTURESTAGESTATETYPE TexStageStateType,
4830 old_fpucw = d3d_fpu_setup();
4831 hr = IDirect3DDeviceImpl_7_GetTextureStageState(iface, Stage, TexStageStateType, State);
4832 set_fpu_control_word(old_fpucw);
4837 static HRESULT WINAPI IDirect3DDeviceImpl_3_GetTextureStageState(IDirect3DDevice3 *iface,
4838 DWORD Stage, D3DTEXTURESTAGESTATETYPE TexStageStateType, DWORD *State)
4840 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice3(iface);
4842 TRACE("iface %p, stage %u, state %#x, value %p.\n",
4843 iface, Stage, TexStageStateType, State);
4845 return IDirect3DDevice7_GetTextureStageState(&This->IDirect3DDevice7_iface,
4846 Stage, TexStageStateType, State);
4849 /*****************************************************************************
4850 * IDirect3DDevice7::SetTextureStageState
4852 * Sets a texture stage state. Some stage types need to be handled specially,
4853 * because they do not exist in WineD3D and were moved to another place
4858 * Stage: The stage to modify
4859 * TexStageStateType: The state to change
4860 * State: The new value for the state
4864 * For details, see IWineD3DDevice::SetTextureStageState
4866 *****************************************************************************/
4868 IDirect3DDeviceImpl_7_SetTextureStageState(IDirect3DDevice7 *iface,
4870 D3DTEXTURESTAGESTATETYPE TexStageStateType,
4873 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice7(iface);
4874 const struct tss_lookup *l;
4877 TRACE("iface %p, stage %u, state %#x, value %#x.\n",
4878 iface, Stage, TexStageStateType, State);
4880 if (TexStageStateType > D3DTSS_TEXTURETRANSFORMFLAGS)
4882 WARN("Invalid TexStageStateType %#x passed.\n", TexStageStateType);
4886 l = &tss_lookup[TexStageStateType];
4888 wined3d_mutex_lock();
4890 if (l->sampler_state)
4892 switch(TexStageStateType)
4894 /* Mipfilter is a sampler state with different values */
4895 case D3DTSS_MIPFILTER:
4899 case D3DTFP_NONE: State = WINED3DTEXF_NONE; break;
4900 case D3DTFP_POINT: State = WINED3DTEXF_POINT; break;
4901 case 0: /* Unchecked */
4902 case D3DTFP_LINEAR: State = WINED3DTEXF_LINEAR; break;
4904 ERR("Unexpected mipfilter value %d\n", State);
4905 State = WINED3DTEXF_NONE;
4911 /* Magfilter has slightly different values */
4912 case D3DTSS_MAGFILTER:
4916 case D3DTFG_POINT: State = WINED3DTEXF_POINT; break;
4917 case D3DTFG_LINEAR: State = WINED3DTEXF_LINEAR; break;
4918 case D3DTFG_FLATCUBIC: State = WINED3DTEXF_FLATCUBIC; break;
4919 case D3DTFG_GAUSSIANCUBIC: State = WINED3DTEXF_GAUSSIANCUBIC; break;
4920 case D3DTFG_ANISOTROPIC: State = WINED3DTEXF_ANISOTROPIC; break;
4922 ERR("Unexpected d3d7 mag filter type %d\n", State);
4923 State = WINED3DTEXF_POINT;
4929 case D3DTSS_ADDRESS:
4930 wined3d_device_set_sampler_state(This->wined3d_device, Stage, WINED3DSAMP_ADDRESSV, State);
4937 hr = wined3d_device_set_sampler_state(This->wined3d_device, Stage, l->state, State);
4941 hr = wined3d_device_set_texture_stage_state(This->wined3d_device, Stage, l->state, State);
4944 wined3d_mutex_unlock();
4949 static HRESULT WINAPI
4950 IDirect3DDeviceImpl_7_SetTextureStageState_FPUSetup(IDirect3DDevice7 *iface,
4952 D3DTEXTURESTAGESTATETYPE TexStageStateType,
4955 return IDirect3DDeviceImpl_7_SetTextureStageState(iface, Stage, TexStageStateType, State);
4958 static HRESULT WINAPI
4959 IDirect3DDeviceImpl_7_SetTextureStageState_FPUPreserve(IDirect3DDevice7 *iface,
4961 D3DTEXTURESTAGESTATETYPE TexStageStateType,
4967 old_fpucw = d3d_fpu_setup();
4968 hr = IDirect3DDeviceImpl_7_SetTextureStageState(iface, Stage, TexStageStateType, State);
4969 set_fpu_control_word(old_fpucw);
4974 static HRESULT WINAPI IDirect3DDeviceImpl_3_SetTextureStageState(IDirect3DDevice3 *iface,
4975 DWORD Stage, D3DTEXTURESTAGESTATETYPE TexStageStateType, DWORD State)
4977 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice3(iface);
4979 TRACE("iface %p, stage %u, state %#x, value %#x.\n",
4980 iface, Stage, TexStageStateType, State);
4982 return IDirect3DDevice7_SetTextureStageState(&This->IDirect3DDevice7_iface,
4983 Stage, TexStageStateType, State);
4986 /*****************************************************************************
4987 * IDirect3DDevice7::ValidateDevice
4989 * SDK: "Reports the device's ability to render the currently set
4990 * texture-blending operations in a single pass". Whatever that means
4996 * NumPasses: Address to write the number of necessary passes for the
4997 * desired effect to.
5001 * See IWineD3DDevice::ValidateDevice for more details
5003 *****************************************************************************/
5005 IDirect3DDeviceImpl_7_ValidateDevice(IDirect3DDevice7 *iface,
5008 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice7(iface);
5011 TRACE("iface %p, pass_count %p.\n", iface, NumPasses);
5013 wined3d_mutex_lock();
5014 hr = wined3d_device_validate_device(This->wined3d_device, NumPasses);
5015 wined3d_mutex_unlock();
5020 static HRESULT WINAPI
5021 IDirect3DDeviceImpl_7_ValidateDevice_FPUSetup(IDirect3DDevice7 *iface,
5024 return IDirect3DDeviceImpl_7_ValidateDevice(iface, NumPasses);
5027 static HRESULT WINAPI
5028 IDirect3DDeviceImpl_7_ValidateDevice_FPUPreserve(IDirect3DDevice7 *iface,
5034 old_fpucw = d3d_fpu_setup();
5035 hr = IDirect3DDeviceImpl_7_ValidateDevice(iface, NumPasses);
5036 set_fpu_control_word(old_fpucw);
5041 static HRESULT WINAPI IDirect3DDeviceImpl_3_ValidateDevice(IDirect3DDevice3 *iface, DWORD *Passes)
5043 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice3(iface);
5045 TRACE("iface %p, pass_count %p.\n", iface, Passes);
5047 return IDirect3DDevice7_ValidateDevice(&This->IDirect3DDevice7_iface, Passes);
5050 /*****************************************************************************
5051 * IDirect3DDevice7::Clear
5053 * Fills the render target, the z buffer and the stencil buffer with a
5054 * clear color / value
5059 * Count: Number of rectangles in Rects must be 0 if Rects is NULL
5060 * Rects: Rectangles to clear. If NULL, the whole surface is cleared
5061 * Flags: Some flags, as usual
5062 * Color: Clear color for the render target
5063 * Z: Clear value for the Z buffer
5064 * Stencil: Clear value to store in each stencil buffer entry
5068 * For details, see IWineD3DDevice::Clear
5070 *****************************************************************************/
5071 static HRESULT IDirect3DDeviceImpl_7_Clear(IDirect3DDevice7 *iface, DWORD count,
5072 D3DRECT *rects, DWORD flags, D3DCOLOR color, D3DVALUE z, DWORD stencil)
5074 const struct wined3d_color c =
5076 ((color >> 16) & 0xff) / 255.0f,
5077 ((color >> 8) & 0xff) / 255.0f,
5078 (color & 0xff) / 255.0f,
5079 ((color >> 24) & 0xff) / 255.0f,
5081 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice7(iface);
5084 TRACE("iface %p, count %u, rects %p, flags %#x, color 0x%08x, z %.8e, stencil %#x.\n",
5085 iface, count, rects, flags, color, z, stencil);
5087 wined3d_mutex_lock();
5088 hr = wined3d_device_clear(This->wined3d_device, count, (RECT *)rects, flags, &c, z, stencil);
5089 wined3d_mutex_unlock();
5094 static HRESULT WINAPI
5095 IDirect3DDeviceImpl_7_Clear_FPUSetup(IDirect3DDevice7 *iface,
5103 return IDirect3DDeviceImpl_7_Clear(iface, Count, Rects, Flags, Color, Z, Stencil);
5106 static HRESULT WINAPI
5107 IDirect3DDeviceImpl_7_Clear_FPUPreserve(IDirect3DDevice7 *iface,
5118 old_fpucw = d3d_fpu_setup();
5119 hr = IDirect3DDeviceImpl_7_Clear(iface, Count, Rects, Flags, Color, Z, Stencil);
5120 set_fpu_control_word(old_fpucw);
5125 /*****************************************************************************
5126 * IDirect3DDevice7::SetViewport
5128 * Sets the current viewport.
5130 * Version 7 only, but IDirect3DViewport uses this call for older
5134 * Data: The new viewport to set
5138 * DDERR_INVALIDPARAMS if Data is NULL
5139 * For more details, see IWineDDDevice::SetViewport
5141 *****************************************************************************/
5143 IDirect3DDeviceImpl_7_SetViewport(IDirect3DDevice7 *iface,
5146 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice7(iface);
5149 TRACE("iface %p, viewport %p.\n", iface, Data);
5152 return DDERR_INVALIDPARAMS;
5154 /* Note: D3DVIEWPORT7 is compatible with struct wined3d_viewport. */
5155 wined3d_mutex_lock();
5156 hr = wined3d_device_set_viewport(This->wined3d_device, (struct wined3d_viewport *)Data);
5157 wined3d_mutex_unlock();
5162 static HRESULT WINAPI
5163 IDirect3DDeviceImpl_7_SetViewport_FPUSetup(IDirect3DDevice7 *iface,
5166 return IDirect3DDeviceImpl_7_SetViewport(iface, Data);
5169 static HRESULT WINAPI
5170 IDirect3DDeviceImpl_7_SetViewport_FPUPreserve(IDirect3DDevice7 *iface,
5176 old_fpucw = d3d_fpu_setup();
5177 hr = IDirect3DDeviceImpl_7_SetViewport(iface, Data);
5178 set_fpu_control_word(old_fpucw);
5183 /*****************************************************************************
5184 * IDirect3DDevice::GetViewport
5186 * Returns the current viewport
5191 * Data: D3D7Viewport structure to write the viewport information to
5195 * DDERR_INVALIDPARAMS if Data is NULL
5196 * For more details, see IWineD3DDevice::GetViewport
5198 *****************************************************************************/
5200 IDirect3DDeviceImpl_7_GetViewport(IDirect3DDevice7 *iface,
5203 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice7(iface);
5206 TRACE("iface %p, viewport %p.\n", iface, Data);
5209 return DDERR_INVALIDPARAMS;
5211 /* Note: D3DVIEWPORT7 is compatible with struct wined3d_viewport. */
5212 wined3d_mutex_lock();
5213 hr = wined3d_device_get_viewport(This->wined3d_device, (struct wined3d_viewport *)Data);
5214 wined3d_mutex_unlock();
5216 return hr_ddraw_from_wined3d(hr);
5219 static HRESULT WINAPI
5220 IDirect3DDeviceImpl_7_GetViewport_FPUSetup(IDirect3DDevice7 *iface,
5223 return IDirect3DDeviceImpl_7_GetViewport(iface, Data);
5226 static HRESULT WINAPI
5227 IDirect3DDeviceImpl_7_GetViewport_FPUPreserve(IDirect3DDevice7 *iface,
5233 old_fpucw = d3d_fpu_setup();
5234 hr = IDirect3DDeviceImpl_7_GetViewport(iface, Data);
5235 set_fpu_control_word(old_fpucw);
5240 /*****************************************************************************
5241 * IDirect3DDevice7::SetMaterial
5248 * Mat: The material to set
5252 * DDERR_INVALIDPARAMS if Mat is NULL.
5253 * For more details, see IWineD3DDevice::SetMaterial
5255 *****************************************************************************/
5257 IDirect3DDeviceImpl_7_SetMaterial(IDirect3DDevice7 *iface,
5260 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice7(iface);
5263 TRACE("iface %p, material %p.\n", iface, Mat);
5265 if (!Mat) return DDERR_INVALIDPARAMS;
5267 wined3d_mutex_lock();
5268 /* Note: D3DMATERIAL7 is compatible with struct wined3d_material. */
5269 hr = wined3d_device_set_material(This->wined3d_device, (struct wined3d_material *)Mat);
5270 wined3d_mutex_unlock();
5272 return hr_ddraw_from_wined3d(hr);
5275 static HRESULT WINAPI
5276 IDirect3DDeviceImpl_7_SetMaterial_FPUSetup(IDirect3DDevice7 *iface,
5279 return IDirect3DDeviceImpl_7_SetMaterial(iface, Mat);
5282 static HRESULT WINAPI
5283 IDirect3DDeviceImpl_7_SetMaterial_FPUPreserve(IDirect3DDevice7 *iface,
5289 old_fpucw = d3d_fpu_setup();
5290 hr = IDirect3DDeviceImpl_7_SetMaterial(iface, Mat);
5291 set_fpu_control_word(old_fpucw);
5296 /*****************************************************************************
5297 * IDirect3DDevice7::GetMaterial
5299 * Returns the current material
5304 * Mat: D3DMATERIAL7 structure to write the material parameters to
5308 * DDERR_INVALIDPARAMS if Mat is NULL
5309 * For more details, see IWineD3DDevice::GetMaterial
5311 *****************************************************************************/
5313 IDirect3DDeviceImpl_7_GetMaterial(IDirect3DDevice7 *iface,
5316 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice7(iface);
5319 TRACE("iface %p, material %p.\n", iface, Mat);
5321 wined3d_mutex_lock();
5322 /* Note: D3DMATERIAL7 is compatible with struct wined3d_material. */
5323 hr = wined3d_device_get_material(This->wined3d_device, (struct wined3d_material *)Mat);
5324 wined3d_mutex_unlock();
5326 return hr_ddraw_from_wined3d(hr);
5329 static HRESULT WINAPI
5330 IDirect3DDeviceImpl_7_GetMaterial_FPUSetup(IDirect3DDevice7 *iface,
5333 return IDirect3DDeviceImpl_7_GetMaterial(iface, Mat);
5336 static HRESULT WINAPI
5337 IDirect3DDeviceImpl_7_GetMaterial_FPUPreserve(IDirect3DDevice7 *iface,
5343 old_fpucw = d3d_fpu_setup();
5344 hr = IDirect3DDeviceImpl_7_GetMaterial(iface, Mat);
5345 set_fpu_control_word(old_fpucw);
5350 /*****************************************************************************
5351 * IDirect3DDevice7::SetLight
5353 * Assigns a light to a light index, but doesn't activate it yet.
5355 * Version 7, IDirect3DLight uses this method for older versions
5358 * LightIndex: The index of the new light
5359 * Light: A D3DLIGHT7 structure describing the light
5363 * For more details, see IWineD3DDevice::SetLight
5365 *****************************************************************************/
5367 IDirect3DDeviceImpl_7_SetLight(IDirect3DDevice7 *iface,
5371 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice7(iface);
5374 TRACE("iface %p, light_idx %u, light %p.\n", iface, LightIndex, Light);
5376 wined3d_mutex_lock();
5377 /* Note: D3DLIGHT7 is compatible with struct wined3d_light. */
5378 hr = wined3d_device_set_light(This->wined3d_device, LightIndex, (struct wined3d_light *)Light);
5379 wined3d_mutex_unlock();
5381 return hr_ddraw_from_wined3d(hr);
5384 static HRESULT WINAPI
5385 IDirect3DDeviceImpl_7_SetLight_FPUSetup(IDirect3DDevice7 *iface,
5389 return IDirect3DDeviceImpl_7_SetLight(iface, LightIndex, Light);
5392 static HRESULT WINAPI
5393 IDirect3DDeviceImpl_7_SetLight_FPUPreserve(IDirect3DDevice7 *iface,
5400 old_fpucw = d3d_fpu_setup();
5401 hr = IDirect3DDeviceImpl_7_SetLight(iface, LightIndex, Light);
5402 set_fpu_control_word(old_fpucw);
5407 /*****************************************************************************
5408 * IDirect3DDevice7::GetLight
5410 * Returns the light assigned to a light index
5413 * Light: Structure to write the light information to
5417 * DDERR_INVALIDPARAMS if Light is NULL
5418 * For details, see IWineD3DDevice::GetLight
5420 *****************************************************************************/
5422 IDirect3DDeviceImpl_7_GetLight(IDirect3DDevice7 *iface,
5426 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice7(iface);
5429 TRACE("iface %p, light_idx %u, light %p.\n", iface, LightIndex, Light);
5431 wined3d_mutex_lock();
5432 /* Note: D3DLIGHT7 is compatible with struct wined3d_light. */
5433 rc = wined3d_device_get_light(This->wined3d_device, LightIndex, (struct wined3d_light *)Light);
5434 wined3d_mutex_unlock();
5436 /* Translate the result. WineD3D returns other values than D3D7 */
5437 return hr_ddraw_from_wined3d(rc);
5440 static HRESULT WINAPI
5441 IDirect3DDeviceImpl_7_GetLight_FPUSetup(IDirect3DDevice7 *iface,
5445 return IDirect3DDeviceImpl_7_GetLight(iface, LightIndex, Light);
5448 static HRESULT WINAPI
5449 IDirect3DDeviceImpl_7_GetLight_FPUPreserve(IDirect3DDevice7 *iface,
5456 old_fpucw = d3d_fpu_setup();
5457 hr = IDirect3DDeviceImpl_7_GetLight(iface, LightIndex, Light);
5458 set_fpu_control_word(old_fpucw);
5463 /*****************************************************************************
5464 * IDirect3DDevice7::BeginStateBlock
5466 * Begins recording to a stateblock
5472 * For details see IWineD3DDevice::BeginStateBlock
5474 *****************************************************************************/
5476 IDirect3DDeviceImpl_7_BeginStateBlock(IDirect3DDevice7 *iface)
5478 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice7(iface);
5481 TRACE("iface %p.\n", iface);
5483 wined3d_mutex_lock();
5484 hr = wined3d_device_begin_stateblock(This->wined3d_device);
5485 wined3d_mutex_unlock();
5487 return hr_ddraw_from_wined3d(hr);
5490 static HRESULT WINAPI
5491 IDirect3DDeviceImpl_7_BeginStateBlock_FPUSetup(IDirect3DDevice7 *iface)
5493 return IDirect3DDeviceImpl_7_BeginStateBlock(iface);
5496 static HRESULT WINAPI
5497 IDirect3DDeviceImpl_7_BeginStateBlock_FPUPreserve(IDirect3DDevice7 *iface)
5502 old_fpucw = d3d_fpu_setup();
5503 hr = IDirect3DDeviceImpl_7_BeginStateBlock(iface);
5504 set_fpu_control_word(old_fpucw);
5509 /*****************************************************************************
5510 * IDirect3DDevice7::EndStateBlock
5512 * Stops recording to a state block and returns the created stateblock
5518 * BlockHandle: Address to store the stateblock's handle to
5522 * DDERR_INVALIDPARAMS if BlockHandle is NULL
5523 * See IWineD3DDevice::EndStateBlock for more details
5525 *****************************************************************************/
5527 IDirect3DDeviceImpl_7_EndStateBlock(IDirect3DDevice7 *iface,
5530 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice7(iface);
5531 struct wined3d_stateblock *wined3d_sb;
5535 TRACE("iface %p, stateblock %p.\n", iface, BlockHandle);
5539 WARN("BlockHandle == NULL, returning DDERR_INVALIDPARAMS\n");
5540 return DDERR_INVALIDPARAMS;
5543 wined3d_mutex_lock();
5545 hr = wined3d_device_end_stateblock(This->wined3d_device, &wined3d_sb);
5548 WARN("Failed to end stateblock, hr %#x.\n", hr);
5549 wined3d_mutex_unlock();
5551 return hr_ddraw_from_wined3d(hr);
5554 h = ddraw_allocate_handle(&This->handle_table, wined3d_sb, DDRAW_HANDLE_STATEBLOCK);
5555 if (h == DDRAW_INVALID_HANDLE)
5557 ERR("Failed to allocate a stateblock handle.\n");
5558 wined3d_stateblock_decref(wined3d_sb);
5559 wined3d_mutex_unlock();
5561 return DDERR_OUTOFMEMORY;
5564 wined3d_mutex_unlock();
5565 *BlockHandle = h + 1;
5567 return hr_ddraw_from_wined3d(hr);
5570 static HRESULT WINAPI
5571 IDirect3DDeviceImpl_7_EndStateBlock_FPUSetup(IDirect3DDevice7 *iface,
5574 return IDirect3DDeviceImpl_7_EndStateBlock(iface, BlockHandle);
5577 static HRESULT WINAPI
5578 IDirect3DDeviceImpl_7_EndStateBlock_FPUPreserve(IDirect3DDevice7 *iface,
5584 old_fpucw = d3d_fpu_setup();
5585 hr = IDirect3DDeviceImpl_7_EndStateBlock(iface, BlockHandle);
5586 set_fpu_control_word(old_fpucw);
5591 /*****************************************************************************
5592 * IDirect3DDevice7::PreLoad
5594 * Allows the app to signal that a texture will be used soon, to allow
5595 * the Direct3DDevice to load it to the video card in the meantime.
5600 * Texture: The texture to preload
5604 * DDERR_INVALIDPARAMS if Texture is NULL
5605 * See IWineD3DSurface::PreLoad for details
5607 *****************************************************************************/
5609 IDirect3DDeviceImpl_7_PreLoad(IDirect3DDevice7 *iface,
5610 IDirectDrawSurface7 *Texture)
5612 IDirectDrawSurfaceImpl *surf = unsafe_impl_from_IDirectDrawSurface7(Texture);
5614 TRACE("iface %p, texture %p.\n", iface, Texture);
5617 return DDERR_INVALIDPARAMS;
5619 wined3d_mutex_lock();
5620 wined3d_surface_preload(surf->wined3d_surface);
5621 wined3d_mutex_unlock();
5626 static HRESULT WINAPI
5627 IDirect3DDeviceImpl_7_PreLoad_FPUSetup(IDirect3DDevice7 *iface,
5628 IDirectDrawSurface7 *Texture)
5630 return IDirect3DDeviceImpl_7_PreLoad(iface, Texture);
5633 static HRESULT WINAPI
5634 IDirect3DDeviceImpl_7_PreLoad_FPUPreserve(IDirect3DDevice7 *iface,
5635 IDirectDrawSurface7 *Texture)
5640 old_fpucw = d3d_fpu_setup();
5641 hr = IDirect3DDeviceImpl_7_PreLoad(iface, Texture);
5642 set_fpu_control_word(old_fpucw);
5647 /*****************************************************************************
5648 * IDirect3DDevice7::ApplyStateBlock
5650 * Activates the state stored in a state block handle.
5653 * BlockHandle: The stateblock handle to activate
5657 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is NULL
5659 *****************************************************************************/
5661 IDirect3DDeviceImpl_7_ApplyStateBlock(IDirect3DDevice7 *iface,
5664 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice7(iface);
5665 struct wined3d_stateblock *wined3d_sb;
5668 TRACE("iface %p, stateblock %#x.\n", iface, BlockHandle);
5670 wined3d_mutex_lock();
5671 wined3d_sb = ddraw_get_object(&This->handle_table, BlockHandle - 1, DDRAW_HANDLE_STATEBLOCK);
5674 WARN("Invalid stateblock handle.\n");
5675 wined3d_mutex_unlock();
5676 return D3DERR_INVALIDSTATEBLOCK;
5679 hr = wined3d_stateblock_apply(wined3d_sb);
5680 wined3d_mutex_unlock();
5682 return hr_ddraw_from_wined3d(hr);
5685 static HRESULT WINAPI
5686 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUSetup(IDirect3DDevice7 *iface,
5689 return IDirect3DDeviceImpl_7_ApplyStateBlock(iface, BlockHandle);
5692 static HRESULT WINAPI
5693 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUPreserve(IDirect3DDevice7 *iface,
5699 old_fpucw = d3d_fpu_setup();
5700 hr = IDirect3DDeviceImpl_7_ApplyStateBlock(iface, BlockHandle);
5701 set_fpu_control_word(old_fpucw);
5706 /*****************************************************************************
5707 * IDirect3DDevice7::CaptureStateBlock
5709 * Updates a stateblock's values to the values currently set for the device
5714 * BlockHandle: Stateblock to update
5718 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is NULL
5719 * See IWineD3DDevice::CaptureStateBlock for more details
5721 *****************************************************************************/
5723 IDirect3DDeviceImpl_7_CaptureStateBlock(IDirect3DDevice7 *iface,
5726 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice7(iface);
5727 struct wined3d_stateblock *wined3d_sb;
5730 TRACE("iface %p, stateblock %#x.\n", iface, BlockHandle);
5732 wined3d_mutex_lock();
5733 wined3d_sb = ddraw_get_object(&This->handle_table, BlockHandle - 1, DDRAW_HANDLE_STATEBLOCK);
5736 WARN("Invalid stateblock handle.\n");
5737 wined3d_mutex_unlock();
5738 return D3DERR_INVALIDSTATEBLOCK;
5741 hr = wined3d_stateblock_capture(wined3d_sb);
5742 wined3d_mutex_unlock();
5744 return hr_ddraw_from_wined3d(hr);
5747 static HRESULT WINAPI
5748 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUSetup(IDirect3DDevice7 *iface,
5751 return IDirect3DDeviceImpl_7_CaptureStateBlock(iface, BlockHandle);
5754 static HRESULT WINAPI
5755 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUPreserve(IDirect3DDevice7 *iface,
5761 old_fpucw = d3d_fpu_setup();
5762 hr = IDirect3DDeviceImpl_7_CaptureStateBlock(iface, BlockHandle);
5763 set_fpu_control_word(old_fpucw);
5768 /*****************************************************************************
5769 * IDirect3DDevice7::DeleteStateBlock
5771 * Deletes a stateblock handle. This means releasing the WineD3DStateBlock
5776 * BlockHandle: Stateblock handle to delete
5780 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is 0
5782 *****************************************************************************/
5784 IDirect3DDeviceImpl_7_DeleteStateBlock(IDirect3DDevice7 *iface,
5787 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice7(iface);
5788 struct wined3d_stateblock *wined3d_sb;
5791 TRACE("iface %p, stateblock %#x.\n", iface, BlockHandle);
5793 wined3d_mutex_lock();
5795 wined3d_sb = ddraw_free_handle(&This->handle_table, BlockHandle - 1, DDRAW_HANDLE_STATEBLOCK);
5798 WARN("Invalid stateblock handle.\n");
5799 wined3d_mutex_unlock();
5800 return D3DERR_INVALIDSTATEBLOCK;
5803 if ((ref = wined3d_stateblock_decref(wined3d_sb)))
5805 ERR("Something is still holding stateblock %p (refcount %u).\n", wined3d_sb, ref);
5808 wined3d_mutex_unlock();
5813 static HRESULT WINAPI
5814 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUSetup(IDirect3DDevice7 *iface,
5817 return IDirect3DDeviceImpl_7_DeleteStateBlock(iface, BlockHandle);
5820 static HRESULT WINAPI
5821 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUPreserve(IDirect3DDevice7 *iface,
5827 old_fpucw = d3d_fpu_setup();
5828 hr = IDirect3DDeviceImpl_7_DeleteStateBlock(iface, BlockHandle);
5829 set_fpu_control_word(old_fpucw);
5834 /*****************************************************************************
5835 * IDirect3DDevice7::CreateStateBlock
5837 * Creates a new state block handle.
5842 * Type: The state block type
5843 * BlockHandle: Address to write the created handle to
5847 * DDERR_INVALIDPARAMS if BlockHandle is NULL
5849 *****************************************************************************/
5851 IDirect3DDeviceImpl_7_CreateStateBlock(IDirect3DDevice7 *iface,
5852 D3DSTATEBLOCKTYPE Type,
5855 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice7(iface);
5856 struct wined3d_stateblock *wined3d_sb;
5860 TRACE("iface %p, type %#x, stateblock %p.\n", iface, Type, BlockHandle);
5864 WARN("BlockHandle == NULL, returning DDERR_INVALIDPARAMS\n");
5865 return DDERR_INVALIDPARAMS;
5867 if(Type != D3DSBT_ALL && Type != D3DSBT_PIXELSTATE &&
5868 Type != D3DSBT_VERTEXSTATE ) {
5869 WARN("Unexpected stateblock type, returning DDERR_INVALIDPARAMS\n");
5870 return DDERR_INVALIDPARAMS;
5873 wined3d_mutex_lock();
5875 /* The D3DSTATEBLOCKTYPE enum is fine here. */
5876 hr = wined3d_stateblock_create(This->wined3d_device, Type, &wined3d_sb);
5879 WARN("Failed to create stateblock, hr %#x.\n", hr);
5880 wined3d_mutex_unlock();
5881 return hr_ddraw_from_wined3d(hr);
5884 h = ddraw_allocate_handle(&This->handle_table, wined3d_sb, DDRAW_HANDLE_STATEBLOCK);
5885 if (h == DDRAW_INVALID_HANDLE)
5887 ERR("Failed to allocate stateblock handle.\n");
5888 wined3d_stateblock_decref(wined3d_sb);
5889 wined3d_mutex_unlock();
5890 return DDERR_OUTOFMEMORY;
5893 *BlockHandle = h + 1;
5894 wined3d_mutex_unlock();
5896 return hr_ddraw_from_wined3d(hr);
5899 static HRESULT WINAPI
5900 IDirect3DDeviceImpl_7_CreateStateBlock_FPUSetup(IDirect3DDevice7 *iface,
5901 D3DSTATEBLOCKTYPE Type,
5904 return IDirect3DDeviceImpl_7_CreateStateBlock(iface, Type, BlockHandle);
5907 static HRESULT WINAPI
5908 IDirect3DDeviceImpl_7_CreateStateBlock_FPUPreserve(IDirect3DDevice7 *iface,
5909 D3DSTATEBLOCKTYPE Type,
5915 old_fpucw = d3d_fpu_setup();
5916 hr =IDirect3DDeviceImpl_7_CreateStateBlock(iface, Type, BlockHandle);
5917 set_fpu_control_word(old_fpucw);
5922 /* Helper function for IDirect3DDeviceImpl_7_Load. */
5923 static BOOL is_mip_level_subset(IDirectDrawSurfaceImpl *dest,
5924 IDirectDrawSurfaceImpl *src)
5926 IDirectDrawSurfaceImpl *src_level, *dest_level;
5927 IDirectDrawSurface7 *temp;
5928 DDSURFACEDESC2 ddsd;
5929 BOOL levelFound; /* at least one suitable sublevel in dest found */
5931 /* To satisfy "destination is mip level subset of source" criteria (regular texture counts as 1 level),
5932 * 1) there must be at least one mip level in destination that matched dimensions of some mip level in source and
5933 * 2) there must be no destination levels that don't match any levels in source. Otherwise it's INVALIDPARAMS.
5940 for (;src_level && dest_level;)
5942 if (src_level->surface_desc.dwWidth == dest_level->surface_desc.dwWidth &&
5943 src_level->surface_desc.dwHeight == dest_level->surface_desc.dwHeight)
5947 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
5948 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_MIPMAPSUBLEVEL;
5949 IDirectDrawSurface7_GetAttachedSurface(&dest_level->IDirectDrawSurface7_iface, &ddsd.ddsCaps, &temp);
5951 if (dest_level != dest) IDirectDrawSurface7_Release(&dest_level->IDirectDrawSurface7_iface);
5953 dest_level = unsafe_impl_from_IDirectDrawSurface7(temp);
5956 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
5957 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_MIPMAPSUBLEVEL;
5958 IDirectDrawSurface7_GetAttachedSurface(&src_level->IDirectDrawSurface7_iface, &ddsd.ddsCaps, &temp);
5960 if (src_level != src) IDirectDrawSurface7_Release(&src_level->IDirectDrawSurface7_iface);
5962 src_level = unsafe_impl_from_IDirectDrawSurface7(temp);
5965 if (src_level && src_level != src) IDirectDrawSurface7_Release(&src_level->IDirectDrawSurface7_iface);
5966 if (dest_level && dest_level != dest) IDirectDrawSurface7_Release(&dest_level->IDirectDrawSurface7_iface);
5968 return !dest_level && levelFound;
5971 /* Helper function for IDirect3DDeviceImpl_7_Load. */
5972 static void copy_mipmap_chain(IDirect3DDeviceImpl *device,
5973 IDirectDrawSurfaceImpl *dest,
5974 IDirectDrawSurfaceImpl *src,
5975 const POINT *DestPoint,
5976 const RECT *SrcRect)
5978 IDirectDrawSurfaceImpl *src_level, *dest_level;
5979 IDirectDrawSurface7 *temp;
5980 DDSURFACEDESC2 ddsd;
5984 IDirectDrawPalette *pal = NULL, *pal_src = NULL;
5988 /* Copy palette, if possible. */
5989 IDirectDrawSurface7_GetPalette(&src->IDirectDrawSurface7_iface, &pal_src);
5990 IDirectDrawSurface7_GetPalette(&dest->IDirectDrawSurface7_iface, &pal);
5992 if (pal_src != NULL && pal != NULL)
5994 PALETTEENTRY palent[256];
5996 IDirectDrawPalette_GetEntries(pal_src, 0, 0, 256, palent);
5997 IDirectDrawPalette_SetEntries(pal, 0, 0, 256, palent);
6000 if (pal) IDirectDrawPalette_Release(pal);
6001 if (pal_src) IDirectDrawPalette_Release(pal_src);
6003 /* Copy colorkeys, if present. */
6004 for (ckeyflag = DDCKEY_DESTBLT; ckeyflag <= DDCKEY_SRCOVERLAY; ckeyflag <<= 1)
6006 hr = IDirectDrawSurface7_GetColorKey(&src->IDirectDrawSurface7_iface, ckeyflag, &ddckey);
6010 IDirectDrawSurface7_SetColorKey(&dest->IDirectDrawSurface7_iface, ckeyflag, &ddckey);
6018 src_rect = *SrcRect;
6020 for (;src_level && dest_level;)
6022 if (src_level->surface_desc.dwWidth == dest_level->surface_desc.dwWidth &&
6023 src_level->surface_desc.dwHeight == dest_level->surface_desc.dwHeight)
6025 UINT src_w = src_rect.right - src_rect.left;
6026 UINT src_h = src_rect.bottom - src_rect.top;
6027 RECT dst_rect = {point.x, point.y, point.x + src_w, point.y + src_h};
6029 if (FAILED(hr = wined3d_surface_blt(dest_level->wined3d_surface, &dst_rect,
6030 src_level->wined3d_surface, &src_rect, 0, NULL, WINED3DTEXF_POINT)))
6031 ERR("Blit failed, hr %#x.\n", hr);
6033 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
6034 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_MIPMAPSUBLEVEL;
6035 IDirectDrawSurface7_GetAttachedSurface(&dest_level->IDirectDrawSurface7_iface, &ddsd.ddsCaps, &temp);
6037 if (dest_level != dest) IDirectDrawSurface7_Release(&dest_level->IDirectDrawSurface7_iface);
6039 dest_level = unsafe_impl_from_IDirectDrawSurface7(temp);
6042 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
6043 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_MIPMAPSUBLEVEL;
6044 IDirectDrawSurface7_GetAttachedSurface(&src_level->IDirectDrawSurface7_iface, &ddsd.ddsCaps, &temp);
6046 if (src_level != src) IDirectDrawSurface7_Release(&src_level->IDirectDrawSurface7_iface);
6048 src_level = unsafe_impl_from_IDirectDrawSurface7(temp);
6055 src_rect.right = (src_rect.right + 1) / 2;
6056 src_rect.bottom = (src_rect.bottom + 1) / 2;
6059 if (src_level && src_level != src) IDirectDrawSurface7_Release(&src_level->IDirectDrawSurface7_iface);
6060 if (dest_level && dest_level != dest) IDirectDrawSurface7_Release(&dest_level->IDirectDrawSurface7_iface);
6063 /*****************************************************************************
6064 * IDirect3DDevice7::Load
6066 * Loads a rectangular area from the source into the destination texture.
6067 * It can also copy the source to the faces of a cubic environment map
6072 * DestTex: Destination texture
6073 * DestPoint: Point in the destination where the source image should be
6075 * SrcTex: Source texture
6076 * SrcRect: Source rectangle
6077 * Flags: Cubemap faces to load (DDSCAPS2_CUBEMAP_ALLFACES, DDSCAPS2_CUBEMAP_POSITIVEX,
6078 * DDSCAPS2_CUBEMAP_NEGATIVEX, DDSCAPS2_CUBEMAP_POSITIVEY, DDSCAPS2_CUBEMAP_NEGATIVEY,
6079 * DDSCAPS2_CUBEMAP_POSITIVEZ, DDSCAPS2_CUBEMAP_NEGATIVEZ)
6083 * DDERR_INVALIDPARAMS if DestTex or SrcTex are NULL, broken coordinates or anything unexpected.
6086 *****************************************************************************/
6089 IDirect3DDeviceImpl_7_Load(IDirect3DDevice7 *iface,
6090 IDirectDrawSurface7 *DestTex,
6092 IDirectDrawSurface7 *SrcTex,
6096 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice7(iface);
6097 IDirectDrawSurfaceImpl *dest = unsafe_impl_from_IDirectDrawSurface7(DestTex);
6098 IDirectDrawSurfaceImpl *src = unsafe_impl_from_IDirectDrawSurface7(SrcTex);
6102 TRACE("iface %p, dst_texture %p, dst_pos %s, src_texture %p, src_rect %s, flags %#x.\n",
6103 iface, DestTex, wine_dbgstr_point(DestPoint), SrcTex, wine_dbgstr_rect(SrcRect), Flags);
6105 if( (!src) || (!dest) )
6106 return DDERR_INVALIDPARAMS;
6108 wined3d_mutex_lock();
6110 if (SrcRect) srcrect = *SrcRect;
6113 srcrect.left = srcrect.top = 0;
6114 srcrect.right = src->surface_desc.dwWidth;
6115 srcrect.bottom = src->surface_desc.dwHeight;
6118 if (DestPoint) destpoint = *DestPoint;
6121 destpoint.x = destpoint.y = 0;
6123 /* Check bad dimensions. DestPoint is validated against src, not dest, because
6124 * destination can be a subset of mip levels, in which case actual coordinates used
6125 * for it may be divided. If any dimension of dest is larger than source, it can't be
6126 * mip level subset, so an error can be returned early.
6128 if (srcrect.left >= srcrect.right || srcrect.top >= srcrect.bottom ||
6129 srcrect.right > src->surface_desc.dwWidth ||
6130 srcrect.bottom > src->surface_desc.dwHeight ||
6131 destpoint.x + srcrect.right - srcrect.left > src->surface_desc.dwWidth ||
6132 destpoint.y + srcrect.bottom - srcrect.top > src->surface_desc.dwHeight ||
6133 dest->surface_desc.dwWidth > src->surface_desc.dwWidth ||
6134 dest->surface_desc.dwHeight > src->surface_desc.dwHeight)
6136 wined3d_mutex_unlock();
6137 return DDERR_INVALIDPARAMS;
6140 /* Must be top level surfaces. */
6141 if (src->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_MIPMAPSUBLEVEL ||
6142 dest->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_MIPMAPSUBLEVEL)
6144 wined3d_mutex_unlock();
6145 return DDERR_INVALIDPARAMS;
6148 if (src->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP)
6150 DWORD src_face_flag, dest_face_flag;
6151 IDirectDrawSurfaceImpl *src_face, *dest_face;
6152 IDirectDrawSurface7 *temp;
6153 DDSURFACEDESC2 ddsd;
6156 if (!(dest->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP))
6158 wined3d_mutex_unlock();
6159 return DDERR_INVALIDPARAMS;
6162 /* Iterate through cube faces 2 times. First time is just to check INVALIDPARAMS conditions, second
6163 * time it's actual surface loading. */
6164 for (i = 0; i < 2; i++)
6169 for (;dest_face && src_face;)
6171 src_face_flag = src_face->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP_ALLFACES;
6172 dest_face_flag = dest_face->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP_ALLFACES;
6174 if (src_face_flag == dest_face_flag)
6178 /* Destination mip levels must be subset of source mip levels. */
6179 if (!is_mip_level_subset(dest_face, src_face))
6181 wined3d_mutex_unlock();
6182 return DDERR_INVALIDPARAMS;
6185 else if (Flags & dest_face_flag)
6187 copy_mipmap_chain(This, dest_face, src_face, &destpoint, &srcrect);
6190 if (src_face_flag < DDSCAPS2_CUBEMAP_NEGATIVEZ)
6192 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
6193 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | (src_face_flag << 1);
6194 IDirectDrawSurface7_GetAttachedSurface(&src->IDirectDrawSurface7_iface, &ddsd.ddsCaps, &temp);
6196 if (src_face != src) IDirectDrawSurface7_Release(&src_face->IDirectDrawSurface7_iface);
6198 src_face = unsafe_impl_from_IDirectDrawSurface7(temp);
6202 if (src_face != src) IDirectDrawSurface7_Release(&src_face->IDirectDrawSurface7_iface);
6208 if (dest_face_flag < DDSCAPS2_CUBEMAP_NEGATIVEZ)
6210 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
6211 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | (dest_face_flag << 1);
6212 IDirectDrawSurface7_GetAttachedSurface(&dest->IDirectDrawSurface7_iface, &ddsd.ddsCaps, &temp);
6214 if (dest_face != dest) IDirectDrawSurface7_Release(&dest_face->IDirectDrawSurface7_iface);
6216 dest_face = unsafe_impl_from_IDirectDrawSurface7(temp);
6220 if (dest_face != dest) IDirectDrawSurface7_Release(&dest_face->IDirectDrawSurface7_iface);
6228 /* Native returns error if src faces are not subset of dest faces. */
6231 wined3d_mutex_unlock();
6232 return DDERR_INVALIDPARAMS;
6237 wined3d_mutex_unlock();
6240 else if (dest->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP)
6242 wined3d_mutex_unlock();
6243 return DDERR_INVALIDPARAMS;
6246 /* Handle non cube map textures. */
6248 /* Destination mip levels must be subset of source mip levels. */
6249 if (!is_mip_level_subset(dest, src))
6251 wined3d_mutex_unlock();
6252 return DDERR_INVALIDPARAMS;
6255 copy_mipmap_chain(This, dest, src, &destpoint, &srcrect);
6257 wined3d_mutex_unlock();
6262 static HRESULT WINAPI
6263 IDirect3DDeviceImpl_7_Load_FPUSetup(IDirect3DDevice7 *iface,
6264 IDirectDrawSurface7 *DestTex,
6266 IDirectDrawSurface7 *SrcTex,
6270 return IDirect3DDeviceImpl_7_Load(iface, DestTex, DestPoint, SrcTex, SrcRect, Flags);
6273 static HRESULT WINAPI
6274 IDirect3DDeviceImpl_7_Load_FPUPreserve(IDirect3DDevice7 *iface,
6275 IDirectDrawSurface7 *DestTex,
6277 IDirectDrawSurface7 *SrcTex,
6284 old_fpucw = d3d_fpu_setup();
6285 hr = IDirect3DDeviceImpl_7_Load(iface, DestTex, DestPoint, SrcTex, SrcRect, Flags);
6286 set_fpu_control_word(old_fpucw);
6291 /*****************************************************************************
6292 * IDirect3DDevice7::LightEnable
6294 * Enables or disables a light
6296 * Version 7, IDirect3DLight uses this method too.
6299 * LightIndex: The index of the light to enable / disable
6300 * Enable: Enable or disable the light
6304 * For more details, see IWineD3DDevice::SetLightEnable
6306 *****************************************************************************/
6308 IDirect3DDeviceImpl_7_LightEnable(IDirect3DDevice7 *iface,
6312 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice7(iface);
6315 TRACE("iface %p, light_idx %u, enabled %#x.\n", iface, LightIndex, Enable);
6317 wined3d_mutex_lock();
6318 hr = wined3d_device_set_light_enable(This->wined3d_device, LightIndex, Enable);
6319 wined3d_mutex_unlock();
6321 return hr_ddraw_from_wined3d(hr);
6324 static HRESULT WINAPI
6325 IDirect3DDeviceImpl_7_LightEnable_FPUSetup(IDirect3DDevice7 *iface,
6329 return IDirect3DDeviceImpl_7_LightEnable(iface, LightIndex, Enable);
6332 static HRESULT WINAPI
6333 IDirect3DDeviceImpl_7_LightEnable_FPUPreserve(IDirect3DDevice7 *iface,
6340 old_fpucw = d3d_fpu_setup();
6341 hr = IDirect3DDeviceImpl_7_LightEnable(iface, LightIndex, Enable);
6342 set_fpu_control_word(old_fpucw);
6347 /*****************************************************************************
6348 * IDirect3DDevice7::GetLightEnable
6350 * Retrieves if the light with the given index is enabled or not
6355 * LightIndex: Index of desired light
6356 * Enable: Pointer to a BOOL which contains the result
6360 * DDERR_INVALIDPARAMS if Enable is NULL
6361 * See IWineD3DDevice::GetLightEnable for more details
6363 *****************************************************************************/
6365 IDirect3DDeviceImpl_7_GetLightEnable(IDirect3DDevice7 *iface,
6369 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice7(iface);
6372 TRACE("iface %p, light_idx %u, enabled %p.\n", iface, LightIndex, Enable);
6375 return DDERR_INVALIDPARAMS;
6377 wined3d_mutex_lock();
6378 hr = wined3d_device_get_light_enable(This->wined3d_device, LightIndex, Enable);
6379 wined3d_mutex_unlock();
6381 return hr_ddraw_from_wined3d(hr);
6384 static HRESULT WINAPI
6385 IDirect3DDeviceImpl_7_GetLightEnable_FPUSetup(IDirect3DDevice7 *iface,
6389 return IDirect3DDeviceImpl_7_GetLightEnable(iface, LightIndex, Enable);
6392 static HRESULT WINAPI
6393 IDirect3DDeviceImpl_7_GetLightEnable_FPUPreserve(IDirect3DDevice7 *iface,
6400 old_fpucw = d3d_fpu_setup();
6401 hr = IDirect3DDeviceImpl_7_GetLightEnable(iface, LightIndex, Enable);
6402 set_fpu_control_word(old_fpucw);
6407 /*****************************************************************************
6408 * IDirect3DDevice7::SetClipPlane
6410 * Sets custom clipping plane
6415 * Index: The index of the clipping plane
6416 * PlaneEquation: An equation defining the clipping plane
6420 * DDERR_INVALIDPARAMS if PlaneEquation is NULL
6421 * See IWineD3DDevice::SetClipPlane for more details
6423 *****************************************************************************/
6425 IDirect3DDeviceImpl_7_SetClipPlane(IDirect3DDevice7 *iface,
6427 D3DVALUE* PlaneEquation)
6429 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice7(iface);
6432 TRACE("iface %p, idx %u, plane %p.\n", iface, Index, PlaneEquation);
6435 return DDERR_INVALIDPARAMS;
6437 wined3d_mutex_lock();
6438 hr = wined3d_device_set_clip_plane(This->wined3d_device, Index, PlaneEquation);
6439 wined3d_mutex_unlock();
6444 static HRESULT WINAPI
6445 IDirect3DDeviceImpl_7_SetClipPlane_FPUSetup(IDirect3DDevice7 *iface,
6447 D3DVALUE* PlaneEquation)
6449 return IDirect3DDeviceImpl_7_SetClipPlane(iface, Index, PlaneEquation);
6452 static HRESULT WINAPI
6453 IDirect3DDeviceImpl_7_SetClipPlane_FPUPreserve(IDirect3DDevice7 *iface,
6455 D3DVALUE* PlaneEquation)
6460 old_fpucw = d3d_fpu_setup();
6461 hr = IDirect3DDeviceImpl_7_SetClipPlane(iface, Index, PlaneEquation);
6462 set_fpu_control_word(old_fpucw);
6467 /*****************************************************************************
6468 * IDirect3DDevice7::GetClipPlane
6470 * Returns the clipping plane with a specific index
6473 * Index: The index of the desired plane
6474 * PlaneEquation: Address to store the plane equation to
6478 * DDERR_INVALIDPARAMS if PlaneEquation is NULL
6479 * See IWineD3DDevice::GetClipPlane for more details
6481 *****************************************************************************/
6483 IDirect3DDeviceImpl_7_GetClipPlane(IDirect3DDevice7 *iface,
6485 D3DVALUE* PlaneEquation)
6487 IDirect3DDeviceImpl *This = impl_from_IDirect3DDevice7(iface);
6490 TRACE("iface %p, idx %u, plane %p.\n", iface, Index, PlaneEquation);
6493 return DDERR_INVALIDPARAMS;
6495 wined3d_mutex_lock();
6496 hr = wined3d_device_get_clip_plane(This->wined3d_device, Index, PlaneEquation);
6497 wined3d_mutex_unlock();
6502 static HRESULT WINAPI
6503 IDirect3DDeviceImpl_7_GetClipPlane_FPUSetup(IDirect3DDevice7 *iface,
6505 D3DVALUE* PlaneEquation)
6507 return IDirect3DDeviceImpl_7_GetClipPlane(iface, Index, PlaneEquation);
6510 static HRESULT WINAPI
6511 IDirect3DDeviceImpl_7_GetClipPlane_FPUPreserve(IDirect3DDevice7 *iface,
6513 D3DVALUE* PlaneEquation)
6518 old_fpucw = d3d_fpu_setup();
6519 hr = IDirect3DDeviceImpl_7_GetClipPlane(iface, Index, PlaneEquation);
6520 set_fpu_control_word(old_fpucw);
6525 /*****************************************************************************
6526 * IDirect3DDevice7::GetInfo
6528 * Retrieves some information about the device. The DirectX sdk says that
6529 * this version returns S_FALSE for all retail builds of DirectX, that's what
6530 * this implementation does.
6533 * DevInfoID: Information type requested
6534 * DevInfoStruct: Pointer to a structure to store the info to
6535 * Size: Size of the structure
6538 * S_FALSE, because it's a non-debug driver
6540 *****************************************************************************/
6541 static HRESULT WINAPI
6542 IDirect3DDeviceImpl_7_GetInfo(IDirect3DDevice7 *iface,
6544 void *DevInfoStruct,
6547 TRACE("iface %p, info_id %#x, info %p, info_size %u.\n",
6548 iface, DevInfoID, DevInfoStruct, Size);
6550 if (TRACE_ON(ddraw))
6552 TRACE(" info requested : ");
6555 case D3DDEVINFOID_TEXTUREMANAGER: TRACE("D3DDEVINFOID_TEXTUREMANAGER\n"); break;
6556 case D3DDEVINFOID_D3DTEXTUREMANAGER: TRACE("D3DDEVINFOID_D3DTEXTUREMANAGER\n"); break;
6557 case D3DDEVINFOID_TEXTURING: TRACE("D3DDEVINFOID_TEXTURING\n"); break;
6558 default: ERR(" invalid flag !!!\n"); return DDERR_INVALIDPARAMS;
6562 return S_FALSE; /* According to MSDN, this is valid for a non-debug driver */
6565 /* For performance optimization, devices created in FPUSETUP and FPUPRESERVE modes
6566 * have separate vtables. Simple functions where this doesn't matter like GetDirect3D
6567 * are not duplicated.
6569 * Device created with DDSCL_FPUSETUP (d3d7 default) - device methods assume that FPU
6570 * has already been setup for optimal d3d operation.
6572 * Device created with DDSCL_FPUPRESERVE - resets and restores FPU mode when necessary in
6573 * d3d calls (FPU may be in a mode non-suitable for d3d when the app calls d3d). Required
6574 * by Sacrifice (game). */
6575 static const struct IDirect3DDevice7Vtbl d3d_device7_fpu_setup_vtbl =
6577 /*** IUnknown Methods ***/
6578 IDirect3DDeviceImpl_7_QueryInterface,
6579 IDirect3DDeviceImpl_7_AddRef,
6580 IDirect3DDeviceImpl_7_Release,
6581 /*** IDirect3DDevice7 ***/
6582 IDirect3DDeviceImpl_7_GetCaps_FPUSetup,
6583 IDirect3DDeviceImpl_7_EnumTextureFormats_FPUSetup,
6584 IDirect3DDeviceImpl_7_BeginScene_FPUSetup,
6585 IDirect3DDeviceImpl_7_EndScene_FPUSetup,
6586 IDirect3DDeviceImpl_7_GetDirect3D,
6587 IDirect3DDeviceImpl_7_SetRenderTarget_FPUSetup,
6588 IDirect3DDeviceImpl_7_GetRenderTarget,
6589 IDirect3DDeviceImpl_7_Clear_FPUSetup,
6590 IDirect3DDeviceImpl_7_SetTransform_FPUSetup,
6591 IDirect3DDeviceImpl_7_GetTransform_FPUSetup,
6592 IDirect3DDeviceImpl_7_SetViewport_FPUSetup,
6593 IDirect3DDeviceImpl_7_MultiplyTransform_FPUSetup,
6594 IDirect3DDeviceImpl_7_GetViewport_FPUSetup,
6595 IDirect3DDeviceImpl_7_SetMaterial_FPUSetup,
6596 IDirect3DDeviceImpl_7_GetMaterial_FPUSetup,
6597 IDirect3DDeviceImpl_7_SetLight_FPUSetup,
6598 IDirect3DDeviceImpl_7_GetLight_FPUSetup,
6599 IDirect3DDeviceImpl_7_SetRenderState_FPUSetup,
6600 IDirect3DDeviceImpl_7_GetRenderState_FPUSetup,
6601 IDirect3DDeviceImpl_7_BeginStateBlock_FPUSetup,
6602 IDirect3DDeviceImpl_7_EndStateBlock_FPUSetup,
6603 IDirect3DDeviceImpl_7_PreLoad_FPUSetup,
6604 IDirect3DDeviceImpl_7_DrawPrimitive_FPUSetup,
6605 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUSetup,
6606 IDirect3DDeviceImpl_7_SetClipStatus,
6607 IDirect3DDeviceImpl_7_GetClipStatus,
6608 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUSetup,
6609 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUSetup,
6610 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUSetup,
6611 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUSetup,
6612 IDirect3DDeviceImpl_7_ComputeSphereVisibility,
6613 IDirect3DDeviceImpl_7_GetTexture_FPUSetup,
6614 IDirect3DDeviceImpl_7_SetTexture_FPUSetup,
6615 IDirect3DDeviceImpl_7_GetTextureStageState_FPUSetup,
6616 IDirect3DDeviceImpl_7_SetTextureStageState_FPUSetup,
6617 IDirect3DDeviceImpl_7_ValidateDevice_FPUSetup,
6618 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUSetup,
6619 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUSetup,
6620 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUSetup,
6621 IDirect3DDeviceImpl_7_CreateStateBlock_FPUSetup,
6622 IDirect3DDeviceImpl_7_Load_FPUSetup,
6623 IDirect3DDeviceImpl_7_LightEnable_FPUSetup,
6624 IDirect3DDeviceImpl_7_GetLightEnable_FPUSetup,
6625 IDirect3DDeviceImpl_7_SetClipPlane_FPUSetup,
6626 IDirect3DDeviceImpl_7_GetClipPlane_FPUSetup,
6627 IDirect3DDeviceImpl_7_GetInfo
6630 static const struct IDirect3DDevice7Vtbl d3d_device7_fpu_preserve_vtbl =
6632 /*** IUnknown Methods ***/
6633 IDirect3DDeviceImpl_7_QueryInterface,
6634 IDirect3DDeviceImpl_7_AddRef,
6635 IDirect3DDeviceImpl_7_Release,
6636 /*** IDirect3DDevice7 ***/
6637 IDirect3DDeviceImpl_7_GetCaps_FPUPreserve,
6638 IDirect3DDeviceImpl_7_EnumTextureFormats_FPUPreserve,
6639 IDirect3DDeviceImpl_7_BeginScene_FPUPreserve,
6640 IDirect3DDeviceImpl_7_EndScene_FPUPreserve,
6641 IDirect3DDeviceImpl_7_GetDirect3D,
6642 IDirect3DDeviceImpl_7_SetRenderTarget_FPUPreserve,
6643 IDirect3DDeviceImpl_7_GetRenderTarget,
6644 IDirect3DDeviceImpl_7_Clear_FPUPreserve,
6645 IDirect3DDeviceImpl_7_SetTransform_FPUPreserve,
6646 IDirect3DDeviceImpl_7_GetTransform_FPUPreserve,
6647 IDirect3DDeviceImpl_7_SetViewport_FPUPreserve,
6648 IDirect3DDeviceImpl_7_MultiplyTransform_FPUPreserve,
6649 IDirect3DDeviceImpl_7_GetViewport_FPUPreserve,
6650 IDirect3DDeviceImpl_7_SetMaterial_FPUPreserve,
6651 IDirect3DDeviceImpl_7_GetMaterial_FPUPreserve,
6652 IDirect3DDeviceImpl_7_SetLight_FPUPreserve,
6653 IDirect3DDeviceImpl_7_GetLight_FPUPreserve,
6654 IDirect3DDeviceImpl_7_SetRenderState_FPUPreserve,
6655 IDirect3DDeviceImpl_7_GetRenderState_FPUPreserve,
6656 IDirect3DDeviceImpl_7_BeginStateBlock_FPUPreserve,
6657 IDirect3DDeviceImpl_7_EndStateBlock_FPUPreserve,
6658 IDirect3DDeviceImpl_7_PreLoad_FPUPreserve,
6659 IDirect3DDeviceImpl_7_DrawPrimitive_FPUPreserve,
6660 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUPreserve,
6661 IDirect3DDeviceImpl_7_SetClipStatus,
6662 IDirect3DDeviceImpl_7_GetClipStatus,
6663 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUPreserve,
6664 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUPreserve,
6665 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUPreserve,
6666 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUPreserve,
6667 IDirect3DDeviceImpl_7_ComputeSphereVisibility,
6668 IDirect3DDeviceImpl_7_GetTexture_FPUPreserve,
6669 IDirect3DDeviceImpl_7_SetTexture_FPUPreserve,
6670 IDirect3DDeviceImpl_7_GetTextureStageState_FPUPreserve,
6671 IDirect3DDeviceImpl_7_SetTextureStageState_FPUPreserve,
6672 IDirect3DDeviceImpl_7_ValidateDevice_FPUPreserve,
6673 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUPreserve,
6674 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUPreserve,
6675 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUPreserve,
6676 IDirect3DDeviceImpl_7_CreateStateBlock_FPUPreserve,
6677 IDirect3DDeviceImpl_7_Load_FPUPreserve,
6678 IDirect3DDeviceImpl_7_LightEnable_FPUPreserve,
6679 IDirect3DDeviceImpl_7_GetLightEnable_FPUPreserve,
6680 IDirect3DDeviceImpl_7_SetClipPlane_FPUPreserve,
6681 IDirect3DDeviceImpl_7_GetClipPlane_FPUPreserve,
6682 IDirect3DDeviceImpl_7_GetInfo
6685 static const struct IDirect3DDevice3Vtbl d3d_device3_vtbl =
6687 /*** IUnknown Methods ***/
6688 IDirect3DDeviceImpl_3_QueryInterface,
6689 IDirect3DDeviceImpl_3_AddRef,
6690 IDirect3DDeviceImpl_3_Release,
6691 /*** IDirect3DDevice3 ***/
6692 IDirect3DDeviceImpl_3_GetCaps,
6693 IDirect3DDeviceImpl_3_GetStats,
6694 IDirect3DDeviceImpl_3_AddViewport,
6695 IDirect3DDeviceImpl_3_DeleteViewport,
6696 IDirect3DDeviceImpl_3_NextViewport,
6697 IDirect3DDeviceImpl_3_EnumTextureFormats,
6698 IDirect3DDeviceImpl_3_BeginScene,
6699 IDirect3DDeviceImpl_3_EndScene,
6700 IDirect3DDeviceImpl_3_GetDirect3D,
6701 IDirect3DDeviceImpl_3_SetCurrentViewport,
6702 IDirect3DDeviceImpl_3_GetCurrentViewport,
6703 IDirect3DDeviceImpl_3_SetRenderTarget,
6704 IDirect3DDeviceImpl_3_GetRenderTarget,
6705 IDirect3DDeviceImpl_3_Begin,
6706 IDirect3DDeviceImpl_3_BeginIndexed,
6707 IDirect3DDeviceImpl_3_Vertex,
6708 IDirect3DDeviceImpl_3_Index,
6709 IDirect3DDeviceImpl_3_End,
6710 IDirect3DDeviceImpl_3_GetRenderState,
6711 IDirect3DDeviceImpl_3_SetRenderState,
6712 IDirect3DDeviceImpl_3_GetLightState,
6713 IDirect3DDeviceImpl_3_SetLightState,
6714 IDirect3DDeviceImpl_3_SetTransform,
6715 IDirect3DDeviceImpl_3_GetTransform,
6716 IDirect3DDeviceImpl_3_MultiplyTransform,
6717 IDirect3DDeviceImpl_3_DrawPrimitive,
6718 IDirect3DDeviceImpl_3_DrawIndexedPrimitive,
6719 IDirect3DDeviceImpl_3_SetClipStatus,
6720 IDirect3DDeviceImpl_3_GetClipStatus,
6721 IDirect3DDeviceImpl_3_DrawPrimitiveStrided,
6722 IDirect3DDeviceImpl_3_DrawIndexedPrimitiveStrided,
6723 IDirect3DDeviceImpl_3_DrawPrimitiveVB,
6724 IDirect3DDeviceImpl_3_DrawIndexedPrimitiveVB,
6725 IDirect3DDeviceImpl_3_ComputeSphereVisibility,
6726 IDirect3DDeviceImpl_3_GetTexture,
6727 IDirect3DDeviceImpl_3_SetTexture,
6728 IDirect3DDeviceImpl_3_GetTextureStageState,
6729 IDirect3DDeviceImpl_3_SetTextureStageState,
6730 IDirect3DDeviceImpl_3_ValidateDevice
6733 static const struct IDirect3DDevice2Vtbl d3d_device2_vtbl =
6735 /*** IUnknown Methods ***/
6736 IDirect3DDeviceImpl_2_QueryInterface,
6737 IDirect3DDeviceImpl_2_AddRef,
6738 IDirect3DDeviceImpl_2_Release,
6739 /*** IDirect3DDevice2 ***/
6740 IDirect3DDeviceImpl_2_GetCaps,
6741 IDirect3DDeviceImpl_2_SwapTextureHandles,
6742 IDirect3DDeviceImpl_2_GetStats,
6743 IDirect3DDeviceImpl_2_AddViewport,
6744 IDirect3DDeviceImpl_2_DeleteViewport,
6745 IDirect3DDeviceImpl_2_NextViewport,
6746 IDirect3DDeviceImpl_2_EnumTextureFormats,
6747 IDirect3DDeviceImpl_2_BeginScene,
6748 IDirect3DDeviceImpl_2_EndScene,
6749 IDirect3DDeviceImpl_2_GetDirect3D,
6750 IDirect3DDeviceImpl_2_SetCurrentViewport,
6751 IDirect3DDeviceImpl_2_GetCurrentViewport,
6752 IDirect3DDeviceImpl_2_SetRenderTarget,
6753 IDirect3DDeviceImpl_2_GetRenderTarget,
6754 IDirect3DDeviceImpl_2_Begin,
6755 IDirect3DDeviceImpl_2_BeginIndexed,
6756 IDirect3DDeviceImpl_2_Vertex,
6757 IDirect3DDeviceImpl_2_Index,
6758 IDirect3DDeviceImpl_2_End,
6759 IDirect3DDeviceImpl_2_GetRenderState,
6760 IDirect3DDeviceImpl_2_SetRenderState,
6761 IDirect3DDeviceImpl_2_GetLightState,
6762 IDirect3DDeviceImpl_2_SetLightState,
6763 IDirect3DDeviceImpl_2_SetTransform,
6764 IDirect3DDeviceImpl_2_GetTransform,
6765 IDirect3DDeviceImpl_2_MultiplyTransform,
6766 IDirect3DDeviceImpl_2_DrawPrimitive,
6767 IDirect3DDeviceImpl_2_DrawIndexedPrimitive,
6768 IDirect3DDeviceImpl_2_SetClipStatus,
6769 IDirect3DDeviceImpl_2_GetClipStatus
6772 static const struct IDirect3DDeviceVtbl d3d_device1_vtbl =
6774 /*** IUnknown Methods ***/
6775 IDirect3DDeviceImpl_1_QueryInterface,
6776 IDirect3DDeviceImpl_1_AddRef,
6777 IDirect3DDeviceImpl_1_Release,
6778 /*** IDirect3DDevice1 ***/
6779 IDirect3DDeviceImpl_1_Initialize,
6780 IDirect3DDeviceImpl_1_GetCaps,
6781 IDirect3DDeviceImpl_1_SwapTextureHandles,
6782 IDirect3DDeviceImpl_1_CreateExecuteBuffer,
6783 IDirect3DDeviceImpl_1_GetStats,
6784 IDirect3DDeviceImpl_1_Execute,
6785 IDirect3DDeviceImpl_1_AddViewport,
6786 IDirect3DDeviceImpl_1_DeleteViewport,
6787 IDirect3DDeviceImpl_1_NextViewport,
6788 IDirect3DDeviceImpl_1_Pick,
6789 IDirect3DDeviceImpl_1_GetPickRecords,
6790 IDirect3DDeviceImpl_1_EnumTextureFormats,
6791 IDirect3DDeviceImpl_1_CreateMatrix,
6792 IDirect3DDeviceImpl_1_SetMatrix,
6793 IDirect3DDeviceImpl_1_GetMatrix,
6794 IDirect3DDeviceImpl_1_DeleteMatrix,
6795 IDirect3DDeviceImpl_1_BeginScene,
6796 IDirect3DDeviceImpl_1_EndScene,
6797 IDirect3DDeviceImpl_1_GetDirect3D
6800 IDirect3DDeviceImpl *unsafe_impl_from_IDirect3DDevice7(IDirect3DDevice7 *iface)
6802 if (!iface) return NULL;
6803 assert((iface->lpVtbl == &d3d_device7_fpu_preserve_vtbl) || (iface->lpVtbl == &d3d_device7_fpu_setup_vtbl));
6804 return CONTAINING_RECORD(iface, IDirect3DDeviceImpl, IDirect3DDevice7_iface);
6807 IDirect3DDeviceImpl *unsafe_impl_from_IDirect3DDevice3(IDirect3DDevice3 *iface)
6809 if (!iface) return NULL;
6810 assert(iface->lpVtbl == &d3d_device3_vtbl);
6811 return CONTAINING_RECORD(iface, IDirect3DDeviceImpl, IDirect3DDevice3_iface);
6814 IDirect3DDeviceImpl *unsafe_impl_from_IDirect3DDevice2(IDirect3DDevice2 *iface)
6816 if (!iface) return NULL;
6817 assert(iface->lpVtbl == &d3d_device2_vtbl);
6818 return CONTAINING_RECORD(iface, IDirect3DDeviceImpl, IDirect3DDevice2_iface);
6821 IDirect3DDeviceImpl *unsafe_impl_from_IDirect3DDevice(IDirect3DDevice *iface)
6823 if (!iface) return NULL;
6824 assert(iface->lpVtbl == &d3d_device1_vtbl);
6825 return CONTAINING_RECORD(iface, IDirect3DDeviceImpl, IDirect3DDevice_iface);
6828 /*****************************************************************************
6829 * IDirect3DDeviceImpl_UpdateDepthStencil
6831 * Checks the current render target for attached depth stencils and sets the
6832 * WineD3D depth stencil accordingly.
6835 * The depth stencil state to set if creating the device
6837 *****************************************************************************/
6839 IDirect3DDeviceImpl_UpdateDepthStencil(IDirect3DDeviceImpl *This)
6841 IDirectDrawSurface7 *depthStencil = NULL;
6842 IDirectDrawSurfaceImpl *dsi;
6843 static DDSCAPS2 depthcaps = { DDSCAPS_ZBUFFER, 0, 0, 0 };
6845 IDirectDrawSurface7_GetAttachedSurface(&This->target->IDirectDrawSurface7_iface, &depthcaps, &depthStencil);
6848 TRACE("Setting wined3d depth stencil to NULL\n");
6849 wined3d_device_set_depth_stencil(This->wined3d_device, NULL);
6850 return WINED3DZB_FALSE;
6853 dsi = impl_from_IDirectDrawSurface7(depthStencil);
6854 TRACE("Setting wined3d depth stencil to %p (wined3d %p)\n", dsi, dsi->wined3d_surface);
6855 wined3d_device_set_depth_stencil(This->wined3d_device, dsi->wined3d_surface);
6857 IDirectDrawSurface7_Release(depthStencil);
6858 return WINED3DZB_TRUE;
6861 HRESULT d3d_device_init(IDirect3DDeviceImpl *device, IDirectDrawImpl *ddraw, IDirectDrawSurfaceImpl *target)
6865 if (ddraw->cooperative_level & DDSCL_FPUPRESERVE)
6866 device->IDirect3DDevice7_iface.lpVtbl = &d3d_device7_fpu_preserve_vtbl;
6868 device->IDirect3DDevice7_iface.lpVtbl = &d3d_device7_fpu_setup_vtbl;
6870 device->IDirect3DDevice3_iface.lpVtbl = &d3d_device3_vtbl;
6871 device->IDirect3DDevice2_iface.lpVtbl = &d3d_device2_vtbl;
6872 device->IDirect3DDevice_iface.lpVtbl = &d3d_device1_vtbl;
6874 device->ddraw = ddraw;
6875 device->target = target;
6876 list_init(&device->viewport_list);
6878 if (!ddraw_handle_table_init(&device->handle_table, 64))
6880 ERR("Failed to initialize handle table.\n");
6881 return DDERR_OUTOFMEMORY;
6884 device->legacyTextureBlending = FALSE;
6886 /* Create an index buffer, it's needed for indexed drawing */
6887 hr = wined3d_buffer_create_ib(ddraw->wined3d_device, 0x40000 /* Length. Don't know how long it should be */,
6888 WINED3DUSAGE_DYNAMIC /* Usage */, WINED3DPOOL_DEFAULT, NULL,
6889 &ddraw_null_wined3d_parent_ops, &device->indexbuffer);
6892 ERR("Failed to create an index buffer, hr %#x.\n", hr);
6893 ddraw_handle_table_destroy(&device->handle_table);
6897 /* This is for convenience. */
6898 device->wined3d_device = ddraw->wined3d_device;
6899 wined3d_device_incref(ddraw->wined3d_device);
6901 /* Render to the back buffer */
6902 hr = wined3d_device_set_render_target(ddraw->wined3d_device, 0, target->wined3d_surface, TRUE);
6905 ERR("Failed to set render target, hr %#x.\n", hr);
6906 wined3d_buffer_decref(device->indexbuffer);
6907 ddraw_handle_table_destroy(&device->handle_table);
6911 /* FIXME: This is broken. The target AddRef() makes some sense, because
6912 * we store a pointer during initialization, but then that's also where
6913 * the AddRef() should be. We don't store ddraw->d3d_target anywhere. */
6914 /* AddRef the render target. Also AddRef the render target from ddraw,
6915 * because if it is released before the app releases the D3D device, the
6916 * D3D capabilities of wined3d will be uninitialized, which has bad effects.
6918 * In most cases, those surfaces are the same anyway, but this will simply
6919 * add another ref which is released when the device is destroyed. */
6920 IDirectDrawSurface7_AddRef(&target->IDirectDrawSurface7_iface);
6921 IDirectDrawSurface7_AddRef(&ddraw->d3d_target->IDirectDrawSurface7_iface);
6923 ddraw->d3ddevice = device;
6925 wined3d_device_set_render_state(ddraw->wined3d_device, WINED3DRS_ZENABLE,
6926 IDirect3DDeviceImpl_UpdateDepthStencil(device));