ntdll/tests: Fix a number of test failures on Wow64.
[wine/multimedia.git] / dlls / ddraw / device.c
blob136d73e2a3897656da0fc67d4db6448b80690b1f
1 /*
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
26 * D3D7 and D3D9.
30 #include "config.h"
31 #include "wine/port.h"
33 #include <assert.h>
34 #include <stdarg.h>
35 #include <string.h>
36 #include <stdlib.h>
38 #define COBJMACROS
39 #define NONAMELESSUNION
41 #include "windef.h"
42 #include "winbase.h"
43 #include "winerror.h"
44 #include "wingdi.h"
45 #include "wine/exception.h"
47 #include "ddraw.h"
48 #include "d3d.h"
50 #include "ddraw_private.h"
51 #include "wine/debug.h"
53 WINE_DEFAULT_DEBUG_CHANNEL(d3d7);
54 WINE_DECLARE_DEBUG_CHANNEL(ddraw_thunk);
56 /* The device ID */
57 const GUID IID_D3DDEVICE_WineD3D = {
58 0xaef72d43,
59 0xb09a,
60 0x4b7b,
61 { 0xb7,0x98,0xc6,0x8a,0x77,0x2d,0x72,0x2a }
64 static inline void set_fpu_control_word(WORD fpucw)
66 #if defined(__i386__) && defined(__GNUC__)
67 __asm__ volatile ("fldcw %0" : : "m" (fpucw));
68 #elif defined(__i386__) && defined(_MSC_VER)
69 __asm fldcw fpucw;
70 #endif
73 static inline WORD d3d_fpu_setup(void)
75 WORD oldcw;
77 #if defined(__i386__) && defined(__GNUC__)
78 __asm__ volatile ("fnstcw %0" : "=m" (oldcw));
79 #elif defined(__i386__) && defined(_MSC_VER)
80 __asm fnstcw oldcw;
81 #else
82 static BOOL warned = FALSE;
83 if(!warned)
85 FIXME("FPUPRESERVE not implemented for this platform / compiler\n");
86 warned = TRUE;
88 return 0;
89 #endif
91 set_fpu_control_word(0x37f);
93 return oldcw;
96 /*****************************************************************************
97 * IUnknown Methods. Common for Version 1, 2, 3 and 7
98 *****************************************************************************/
100 /*****************************************************************************
101 * IDirect3DDevice7::QueryInterface
103 * Used to query other interfaces from a Direct3DDevice interface.
104 * It can return interface pointers to all Direct3DDevice versions as well
105 * as IDirectDraw and IDirect3D. For a link to QueryInterface
106 * rules see ddraw.c, IDirectDraw7::QueryInterface
108 * Exists in Version 1, 2, 3 and 7
110 * Params:
111 * refiid: Interface ID queried for
112 * obj: Used to return the interface pointer
114 * Returns:
115 * D3D_OK or E_NOINTERFACE
117 *****************************************************************************/
118 static HRESULT WINAPI
119 IDirect3DDeviceImpl_7_QueryInterface(IDirect3DDevice7 *iface,
120 REFIID refiid,
121 void **obj)
123 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
124 TRACE("(%p)->(%s,%p)\n", This, debugstr_guid(refiid), obj);
126 /* According to COM docs, if the QueryInterface fails, obj should be set to NULL */
127 *obj = NULL;
129 if(!refiid)
130 return DDERR_INVALIDPARAMS;
132 if ( IsEqualGUID( &IID_IUnknown, refiid ) )
134 *obj = iface;
137 /* Check DirectDraw Interfac\x01s */
138 else if( IsEqualGUID( &IID_IDirectDraw7, refiid ) )
140 *obj = This->ddraw;
141 TRACE("(%p) Returning IDirectDraw7 interface at %p\n", This, *obj);
143 else if ( IsEqualGUID( &IID_IDirectDraw4, refiid ) )
145 *obj = &This->ddraw->IDirectDraw4_vtbl;
146 TRACE("(%p) Returning IDirectDraw4 interface at %p\n", This, *obj);
148 else if ( IsEqualGUID( &IID_IDirectDraw2, refiid ) )
150 *obj = &This->ddraw->IDirectDraw2_vtbl;
151 TRACE("(%p) Returning IDirectDraw2 interface at %p\n", This, *obj);
153 else if( IsEqualGUID( &IID_IDirectDraw, refiid ) )
155 *obj = &This->ddraw->IDirectDraw_vtbl;
156 TRACE("(%p) Returning IDirectDraw interface at %p\n", This, *obj);
159 /* Direct3D */
160 else if ( IsEqualGUID( &IID_IDirect3D , refiid ) )
162 *obj = &This->ddraw->IDirect3D_vtbl;
163 TRACE("(%p) Returning IDirect3D interface at %p\n", This, *obj);
165 else if ( IsEqualGUID( &IID_IDirect3D2 , refiid ) )
167 *obj = &This->ddraw->IDirect3D2_vtbl;
168 TRACE("(%p) Returning IDirect3D2 interface at %p\n", This, *obj);
170 else if ( IsEqualGUID( &IID_IDirect3D3 , refiid ) )
172 *obj = &This->ddraw->IDirect3D3_vtbl;
173 TRACE("(%p) Returning IDirect3D3 interface at %p\n", This, *obj);
175 else if ( IsEqualGUID( &IID_IDirect3D7 , refiid ) )
177 *obj = &This->ddraw->IDirect3D7_vtbl;
178 TRACE("(%p) Returning IDirect3D7 interface at %p\n", This, *obj);
181 /* Direct3DDevice */
182 else if ( IsEqualGUID( &IID_IDirect3DDevice , refiid ) )
184 *obj = &This->IDirect3DDevice_vtbl;
185 TRACE("(%p) Returning IDirect3DDevice interface at %p\n", This, *obj);
187 else if ( IsEqualGUID( &IID_IDirect3DDevice2 , refiid ) ) {
188 *obj = &This->IDirect3DDevice2_vtbl;
189 TRACE("(%p) Returning IDirect3DDevice2 interface at %p\n", This, *obj);
191 else if ( IsEqualGUID( &IID_IDirect3DDevice3 , refiid ) ) {
192 *obj = &This->IDirect3DDevice3_vtbl;
193 TRACE("(%p) Returning IDirect3DDevice3 interface at %p\n", This, *obj);
195 else if ( IsEqualGUID( &IID_IDirect3DDevice7 , refiid ) ) {
196 *obj = This;
197 TRACE("(%p) Returning IDirect3DDevice7 interface at %p\n", This, *obj);
200 /* Unknown interface */
201 else
203 ERR("(%p)->(%s, %p): No interface found\n", This, debugstr_guid(refiid), obj);
204 return E_NOINTERFACE;
207 /* AddRef the returned interface */
208 IUnknown_AddRef( (IUnknown *) *obj);
209 return D3D_OK;
212 static HRESULT WINAPI
213 Thunk_IDirect3DDeviceImpl_3_QueryInterface(IDirect3DDevice3 *iface,
214 REFIID riid,
215 void **obj)
217 IDirect3DDeviceImpl *This = device_from_device3(iface);
218 TRACE_(ddraw_thunk)("(%p)->(%s,%p) thunking to IDirect3DDevice7 interface.\n", This, debugstr_guid(riid), obj);
219 return IDirect3DDevice7_QueryInterface((IDirect3DDevice7 *)This, riid, obj);
222 static HRESULT WINAPI
223 Thunk_IDirect3DDeviceImpl_2_QueryInterface(IDirect3DDevice2 *iface,
224 REFIID riid,
225 void **obj)
227 IDirect3DDeviceImpl *This = device_from_device2(iface);
228 TRACE_(ddraw_thunk)("(%p)->(%s,%p) thunking to IDirect3DDevice7 interface.\n", This, debugstr_guid(riid), obj);
229 return IDirect3DDevice7_QueryInterface((IDirect3DDevice7 *)This, riid, obj);
232 static HRESULT WINAPI
233 Thunk_IDirect3DDeviceImpl_1_QueryInterface(IDirect3DDevice *iface,
234 REFIID riid,
235 void **obp)
237 IDirect3DDeviceImpl *This = device_from_device1(iface);
238 TRACE_(ddraw_thunk)("(%p)->(%s,%p) thunking to IDirect3DDevice7 interface.\n", This, debugstr_guid(riid), obp);
239 return IDirect3DDevice7_QueryInterface((IDirect3DDevice7 *)This, riid, obp);
242 /*****************************************************************************
243 * IDirect3DDevice7::AddRef
245 * Increases the refcount....
246 * The most exciting Method, definitely
248 * Exists in Version 1, 2, 3 and 7
250 * Returns:
251 * The new refcount
253 *****************************************************************************/
254 static ULONG WINAPI
255 IDirect3DDeviceImpl_7_AddRef(IDirect3DDevice7 *iface)
257 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
258 ULONG ref = InterlockedIncrement(&This->ref);
260 TRACE("(%p) : incrementing from %u.\n", This, ref -1);
262 return ref;
265 static ULONG WINAPI
266 Thunk_IDirect3DDeviceImpl_3_AddRef(IDirect3DDevice3 *iface)
268 IDirect3DDeviceImpl *This = device_from_device3(iface);
269 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
270 return IDirect3DDevice7_AddRef((IDirect3DDevice7 *)This);
273 static ULONG WINAPI
274 Thunk_IDirect3DDeviceImpl_2_AddRef(IDirect3DDevice2 *iface)
276 IDirect3DDeviceImpl *This = device_from_device2(iface);
277 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
278 return IDirect3DDevice7_AddRef((IDirect3DDevice7 *)This);
281 static ULONG WINAPI
282 Thunk_IDirect3DDeviceImpl_1_AddRef(IDirect3DDevice *iface)
284 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", iface);
285 return IDirect3DDevice7_AddRef((IDirect3DDevice7 *)device_from_device1(iface));
288 /*****************************************************************************
289 * IDirect3DDevice7::Release
291 * Decreases the refcount of the interface
292 * When the refcount is reduced to 0, the object is destroyed.
294 * Exists in Version 1, 2, 3 and 7
296 * Returns:d
297 * The new refcount
299 *****************************************************************************/
300 static ULONG WINAPI
301 IDirect3DDeviceImpl_7_Release(IDirect3DDevice7 *iface)
303 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
304 ULONG ref = InterlockedDecrement(&This->ref);
306 TRACE("(%p)->() decrementing from %u.\n", This, ref +1);
308 /* This method doesn't destroy the WineD3DDevice, because it's still in use for
309 * 2D rendering. IDirectDrawSurface7::Release will destroy the WineD3DDevice
310 * when the render target is released
312 if (ref == 0)
314 IParent *IndexBufferParent;
315 DWORD i;
317 EnterCriticalSection(&ddraw_cs);
318 /* Free the index buffer. */
319 IWineD3DDevice_SetIndexBuffer(This->wineD3DDevice, NULL, WINED3DFMT_UNKNOWN);
320 IWineD3DBuffer_GetParent(This->indexbuffer,
321 (IUnknown **) &IndexBufferParent);
322 IParent_Release(IndexBufferParent); /* Once for the getParent */
323 if( IParent_Release(IndexBufferParent) != 0) /* And now to destroy it */
325 ERR(" (%p) Something is still holding the index buffer parent %p\n", This, IndexBufferParent);
328 /* There is no need to unset the vertex buffer here, IWineD3DDevice_Uninit3D will do that when
329 * destroying the primary stateblock. If a vertex buffer is destroyed while it is bound
330 * IDirect3DVertexBuffer::Release will unset it.
333 /* Restore the render targets */
334 if(This->OffScreenTarget)
336 WINED3DVIEWPORT vp;
338 vp.X = 0;
339 vp.Y = 0;
340 vp.Width = This->ddraw->d3d_target->surface_desc.dwWidth;
341 vp.Height = This->ddraw->d3d_target->surface_desc.dwHeight;
342 vp.MinZ = 0.0;
343 vp.MaxZ = 1.0;
344 IWineD3DDevice_SetViewport(This->wineD3DDevice,
345 &vp);
347 /* Set the device up to render to the front buffer since the back buffer will
348 * vanish soon.
350 IWineD3DDevice_SetRenderTarget(This->wineD3DDevice, 0,
351 This->ddraw->d3d_target->WineD3DSurface,
352 FALSE);
353 /* This->target is the offscreen target.
354 * This->ddraw->d3d_target is the target used by DDraw
356 TRACE("(%p) Release: Using %p as front buffer, %p as back buffer\n", This, This->ddraw->d3d_target, NULL);
357 IWineD3DDevice_SetFrontBackBuffers(This->wineD3DDevice,
358 This->ddraw->d3d_target->WineD3DSurface,
359 NULL);
362 /* Release the WineD3DDevice. This won't destroy it */
363 if(IWineD3DDevice_Release(This->wineD3DDevice) <= 0)
365 ERR(" (%p) The wineD3D device %p was destroyed unexpectedly. Prepare for trouble\n", This, This->wineD3DDevice);
368 /* The texture handles should be unset by now, but there might be some bits
369 * missing in our reference counting(needs test). Do a sanity check
371 for(i = 0; i < This->numHandles; i++)
373 if(This->Handles[i].ptr)
375 switch(This->Handles[i].type)
377 case DDrawHandle_Texture:
379 IDirectDrawSurfaceImpl *surf = This->Handles[i].ptr;
380 FIXME("Texture Handle %d not unset properly\n", i + 1);
381 surf->Handle = 0;
383 break;
385 case DDrawHandle_Material:
387 IDirect3DMaterialImpl *mat = This->Handles[i].ptr;
388 FIXME("Material handle %d not unset properly\n", i + 1);
389 mat->Handle = 0;
391 break;
393 case DDrawHandle_Matrix:
395 /* No fixme here because this might happen because of sloppy apps */
396 WARN("Leftover matrix handle %d, deleting\n", i + 1);
397 IDirect3DDevice_DeleteMatrix((IDirect3DDevice *)&This->IDirect3DDevice_vtbl, i + 1);
399 break;
401 case DDrawHandle_StateBlock:
403 /* No fixme here because this might happen because of sloppy apps */
404 WARN("Leftover stateblock handle %d, deleting\n", i + 1);
405 IDirect3DDevice7_DeleteStateBlock((IDirect3DDevice7 *)This, i + 1);
407 break;
409 default:
410 FIXME("Unknown handle %d not unset properly\n", i + 1);
415 HeapFree(GetProcessHeap(), 0, This->Handles);
417 TRACE("Releasing target %p %p\n", This->target, This->ddraw->d3d_target);
418 /* Release the render target and the WineD3D render target
419 * (See IDirect3D7::CreateDevice for more comments on this)
421 IDirectDrawSurface7_Release((IDirectDrawSurface7 *)This->target);
422 IDirectDrawSurface7_Release((IDirectDrawSurface7 *)This->ddraw->d3d_target);
423 TRACE("Target release done\n");
425 This->ddraw->d3ddevice = NULL;
427 /* Now free the structure */
428 HeapFree(GetProcessHeap(), 0, This);
429 LeaveCriticalSection(&ddraw_cs);
432 TRACE("Done\n");
433 return ref;
436 static ULONG WINAPI
437 Thunk_IDirect3DDeviceImpl_3_Release(IDirect3DDevice3 *iface)
439 IDirect3DDeviceImpl *This = device_from_device3(iface);
440 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
441 return IDirect3DDevice7_Release((IDirect3DDevice7 *)This);
444 static ULONG WINAPI
445 Thunk_IDirect3DDeviceImpl_2_Release(IDirect3DDevice2 *iface)
447 IDirect3DDeviceImpl *This = device_from_device2(iface);
448 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
449 return IDirect3DDevice7_Release((IDirect3DDevice7 *)This);
452 static ULONG WINAPI
453 Thunk_IDirect3DDeviceImpl_1_Release(IDirect3DDevice *iface)
455 IDirect3DDeviceImpl *This = device_from_device1(iface);
456 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
457 return IDirect3DDevice7_Release((IDirect3DDevice7 *)This);
460 /*****************************************************************************
461 * IDirect3DDevice Methods
462 *****************************************************************************/
464 /*****************************************************************************
465 * IDirect3DDevice::Initialize
467 * Initializes a Direct3DDevice. This implementation is a no-op, as all
468 * initialization is done at create time.
470 * Exists in Version 1
472 * Parameters:
473 * No idea what they mean, as the MSDN page is gone
475 * Returns: DD_OK
477 *****************************************************************************/
478 static HRESULT WINAPI
479 IDirect3DDeviceImpl_1_Initialize(IDirect3DDevice *iface,
480 IDirect3D *Direct3D, GUID *guid,
481 D3DDEVICEDESC *Desc)
483 IDirect3DDeviceImpl *This = device_from_device1(iface);
485 /* It shouldn't be crucial, but print a FIXME, I'm interested if
486 * any game calls it and when
488 FIXME("(%p)->(%p,%p,%p): No-op!\n", This, Direct3D, guid, Desc);
490 return D3D_OK;
493 /*****************************************************************************
494 * IDirect3DDevice7::GetCaps
496 * Retrieves the device's capabilities
498 * This implementation is used for Version 7 only, the older versions have
499 * their own implementation.
501 * Parameters:
502 * Desc: Pointer to a D3DDEVICEDESC7 structure to fill
504 * Returns:
505 * D3D_OK on success
506 * D3DERR_* if a problem occurs. See WineD3D
508 *****************************************************************************/
509 static HRESULT
510 IDirect3DDeviceImpl_7_GetCaps(IDirect3DDevice7 *iface,
511 D3DDEVICEDESC7 *Desc)
513 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
514 D3DDEVICEDESC OldDesc;
515 TRACE("(%p)->(%p)\n", This, Desc);
517 /* Call the same function used by IDirect3D, this saves code */
518 return IDirect3DImpl_GetCaps(This->ddraw->wineD3D, &OldDesc, Desc);
521 static HRESULT WINAPI
522 IDirect3DDeviceImpl_7_GetCaps_FPUSetup(IDirect3DDevice7 *iface,
523 D3DDEVICEDESC7 *Desc)
525 return IDirect3DDeviceImpl_7_GetCaps(iface, Desc);
528 static HRESULT WINAPI
529 IDirect3DDeviceImpl_7_GetCaps_FPUPreserve(IDirect3DDevice7 *iface,
530 D3DDEVICEDESC7 *Desc)
532 HRESULT hr;
533 WORD old_fpucw;
535 old_fpucw = d3d_fpu_setup();
536 hr = IDirect3DDeviceImpl_7_GetCaps(iface, Desc);
537 set_fpu_control_word(old_fpucw);
539 return hr;
541 /*****************************************************************************
542 * IDirect3DDevice3::GetCaps
544 * Retrieves the capabilities of the hardware device and the emulation
545 * device. For Wine, hardware and emulation are the same (it's all HW).
547 * This implementation is used for Version 1, 2, and 3. Version 7 has its own
549 * Parameters:
550 * HWDesc: Structure to fill with the HW caps
551 * HelDesc: Structure to fill with the hardware emulation caps
553 * Returns:
554 * D3D_OK on success
555 * D3DERR_* if a problem occurs. See WineD3D
557 *****************************************************************************/
558 static HRESULT WINAPI
559 IDirect3DDeviceImpl_3_GetCaps(IDirect3DDevice3 *iface,
560 D3DDEVICEDESC *HWDesc,
561 D3DDEVICEDESC *HelDesc)
563 IDirect3DDeviceImpl *This = device_from_device3(iface);
564 D3DDEVICEDESC7 newDesc;
565 HRESULT hr;
566 TRACE("(%p)->(%p,%p)\n", iface, HWDesc, HelDesc);
568 hr = IDirect3DImpl_GetCaps(This->ddraw->wineD3D, HWDesc, &newDesc);
569 if(hr != D3D_OK) return hr;
571 *HelDesc = *HWDesc;
572 return D3D_OK;
575 static HRESULT WINAPI
576 Thunk_IDirect3DDeviceImpl_2_GetCaps(IDirect3DDevice2 *iface,
577 D3DDEVICEDESC *D3DHWDevDesc,
578 D3DDEVICEDESC *D3DHELDevDesc)
580 IDirect3DDeviceImpl *This = device_from_device2(iface);
581 TRACE_(ddraw_thunk)("(%p)->(%p,%p) thunking to IDirect3DDevice3 interface.\n", This, D3DHWDevDesc, D3DHELDevDesc);
582 return IDirect3DDevice3_GetCaps((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl, D3DHWDevDesc, D3DHELDevDesc);
585 static HRESULT WINAPI
586 Thunk_IDirect3DDeviceImpl_1_GetCaps(IDirect3DDevice *iface,
587 D3DDEVICEDESC *D3DHWDevDesc,
588 D3DDEVICEDESC *D3DHELDevDesc)
590 IDirect3DDeviceImpl *This = device_from_device1(iface);
591 TRACE_(ddraw_thunk)("(%p)->(%p,%p) thunking to IDirect3DDevice3 interface.\n", This, D3DHWDevDesc, D3DHELDevDesc);
592 return IDirect3DDevice3_GetCaps((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl, D3DHWDevDesc, D3DHELDevDesc);
595 /*****************************************************************************
596 * IDirect3DDevice2::SwapTextureHandles
598 * Swaps the texture handles of 2 Texture interfaces. Version 1 and 2
600 * Parameters:
601 * Tex1, Tex2: The 2 Textures to swap
603 * Returns:
604 * D3D_OK
606 *****************************************************************************/
607 static HRESULT WINAPI
608 IDirect3DDeviceImpl_2_SwapTextureHandles(IDirect3DDevice2 *iface,
609 IDirect3DTexture2 *Tex1,
610 IDirect3DTexture2 *Tex2)
612 IDirect3DDeviceImpl *This = device_from_device2(iface);
613 DWORD swap;
614 IDirectDrawSurfaceImpl *surf1 = surface_from_texture2(Tex1);
615 IDirectDrawSurfaceImpl *surf2 = surface_from_texture2(Tex2);
616 TRACE("(%p)->(%p,%p)\n", This, surf1, surf2);
618 EnterCriticalSection(&ddraw_cs);
619 This->Handles[surf1->Handle - 1].ptr = surf2;
620 This->Handles[surf2->Handle - 1].ptr = surf1;
622 swap = surf2->Handle;
623 surf2->Handle = surf1->Handle;
624 surf1->Handle = swap;
625 LeaveCriticalSection(&ddraw_cs);
627 return D3D_OK;
630 static HRESULT WINAPI
631 Thunk_IDirect3DDeviceImpl_1_SwapTextureHandles(IDirect3DDevice *iface,
632 IDirect3DTexture *D3DTex1,
633 IDirect3DTexture *D3DTex2)
635 IDirect3DDeviceImpl *This = device_from_device1(iface);
636 IDirectDrawSurfaceImpl *surf1 = surface_from_texture1(D3DTex1);
637 IDirectDrawSurfaceImpl *surf2 = surface_from_texture1(D3DTex2);
638 IDirect3DTexture2 *t1 = surf1 ? (IDirect3DTexture2 *)&surf1->IDirect3DTexture2_vtbl : NULL;
639 IDirect3DTexture2 *t2 = surf2 ? (IDirect3DTexture2 *)&surf2->IDirect3DTexture2_vtbl : NULL;
640 TRACE_(ddraw_thunk)("(%p)->(%p,%p) thunking to IDirect3DDevice2 interface.\n", This, surf1, surf2);
641 return IDirect3DDevice2_SwapTextureHandles((IDirect3DDevice2 *)&This->IDirect3DDevice2_vtbl, t1, t2);
644 /*****************************************************************************
645 * IDirect3DDevice3::GetStats
647 * This method seems to retrieve some stats from the device.
648 * The MSDN documentation doesn't exist any more, but the D3DSTATS
649 * structure suggests that the amount of drawn primitives and processed
650 * vertices is returned.
652 * Exists in Version 1, 2 and 3
654 * Parameters:
655 * Stats: Pointer to a D3DSTATS structure to be filled
657 * Returns:
658 * D3D_OK on success
659 * DDERR_INVALIDPARAMS if Stats == NULL
661 *****************************************************************************/
662 static HRESULT WINAPI
663 IDirect3DDeviceImpl_3_GetStats(IDirect3DDevice3 *iface,
664 D3DSTATS *Stats)
666 IDirect3DDeviceImpl *This = device_from_device3(iface);
667 FIXME("(%p)->(%p): Stub!\n", This, Stats);
669 if(!Stats)
670 return DDERR_INVALIDPARAMS;
672 /* Fill the Stats with 0 */
673 Stats->dwTrianglesDrawn = 0;
674 Stats->dwLinesDrawn = 0;
675 Stats->dwPointsDrawn = 0;
676 Stats->dwSpansDrawn = 0;
677 Stats->dwVerticesProcessed = 0;
679 return D3D_OK;
682 static HRESULT WINAPI
683 Thunk_IDirect3DDeviceImpl_2_GetStats(IDirect3DDevice2 *iface,
684 D3DSTATS *Stats)
686 IDirect3DDeviceImpl *This = device_from_device2(iface);
687 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, Stats);
688 return IDirect3DDevice3_GetStats((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl, Stats);
691 static HRESULT WINAPI
692 Thunk_IDirect3DDeviceImpl_1_GetStats(IDirect3DDevice *iface,
693 D3DSTATS *Stats)
695 IDirect3DDeviceImpl *This = device_from_device1(iface);
696 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, Stats);
697 return IDirect3DDevice3_GetStats((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl, Stats);
700 /*****************************************************************************
701 * IDirect3DDevice::CreateExecuteBuffer
703 * Creates an IDirect3DExecuteBuffer, used for rendering with a
704 * Direct3DDevice.
706 * Version 1 only.
708 * Params:
709 * Desc: Buffer description
710 * ExecuteBuffer: Address to return the Interface pointer at
711 * UnkOuter: Must be NULL. Basically for aggregation, which ddraw doesn't
712 * support
714 * Returns:
715 * CLASS_E_NOAGGREGATION if UnkOuter != NULL
716 * DDERR_OUTOFMEMORY if we ran out of memory
717 * D3D_OK on success
719 *****************************************************************************/
720 static HRESULT WINAPI
721 IDirect3DDeviceImpl_1_CreateExecuteBuffer(IDirect3DDevice *iface,
722 D3DEXECUTEBUFFERDESC *Desc,
723 IDirect3DExecuteBuffer **ExecuteBuffer,
724 IUnknown *UnkOuter)
726 IDirect3DDeviceImpl *This = device_from_device1(iface);
727 IDirect3DExecuteBufferImpl* object;
728 TRACE("(%p)->(%p,%p,%p)!\n", This, Desc, ExecuteBuffer, UnkOuter);
730 if(UnkOuter)
731 return CLASS_E_NOAGGREGATION;
733 /* Allocate the new Execute Buffer */
734 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DExecuteBufferImpl));
735 if(!object)
737 ERR("Out of memory when allocating a IDirect3DExecuteBufferImpl structure\n");
738 return DDERR_OUTOFMEMORY;
741 object->lpVtbl = &IDirect3DExecuteBuffer_Vtbl;
742 object->ref = 1;
743 object->d3ddev = This;
745 /* Initializes memory */
746 memcpy(&object->desc, Desc, Desc->dwSize);
748 /* No buffer given */
749 if ((object->desc.dwFlags & D3DDEB_LPDATA) == 0)
750 object->desc.lpData = NULL;
752 /* No buffer size given */
753 if ((object->desc.dwFlags & D3DDEB_BUFSIZE) == 0)
754 object->desc.dwBufferSize = 0;
756 /* Create buffer if asked */
757 if ((object->desc.lpData == NULL) && (object->desc.dwBufferSize > 0))
759 object->need_free = TRUE;
760 object->desc.lpData = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,object->desc.dwBufferSize);
761 if(!object->desc.lpData)
763 ERR("Out of memory when allocating the execute buffer data\n");
764 HeapFree(GetProcessHeap(), 0, object);
765 return DDERR_OUTOFMEMORY;
768 else
770 object->need_free = FALSE;
773 /* No vertices for the moment */
774 object->vertex_data = NULL;
776 object->desc.dwFlags |= D3DDEB_LPDATA;
778 object->indices = NULL;
779 object->nb_indices = 0;
781 *ExecuteBuffer = (IDirect3DExecuteBuffer *)object;
783 TRACE(" Returning IDirect3DExecuteBuffer at %p, implementation is at %p\n", *ExecuteBuffer, object);
785 return D3D_OK;
788 /*****************************************************************************
789 * IDirect3DDevice::Execute
791 * Executes all the stuff in an execute buffer.
793 * Params:
794 * ExecuteBuffer: The buffer to execute
795 * Viewport: The viewport used for rendering
796 * Flags: Some flags
798 * Returns:
799 * DDERR_INVALIDPARAMS if ExecuteBuffer == NULL
800 * D3D_OK on success
802 *****************************************************************************/
803 static HRESULT WINAPI
804 IDirect3DDeviceImpl_1_Execute(IDirect3DDevice *iface,
805 IDirect3DExecuteBuffer *ExecuteBuffer,
806 IDirect3DViewport *Viewport,
807 DWORD Flags)
809 IDirect3DDeviceImpl *This = device_from_device1(iface);
810 IDirect3DExecuteBufferImpl *Direct3DExecuteBufferImpl = (IDirect3DExecuteBufferImpl *)ExecuteBuffer;
811 IDirect3DViewportImpl *Direct3DViewportImpl = (IDirect3DViewportImpl *)Viewport;
813 TRACE("(%p)->(%p,%p,%08x)\n", This, Direct3DExecuteBufferImpl, Direct3DViewportImpl, Flags);
815 if(!Direct3DExecuteBufferImpl)
816 return DDERR_INVALIDPARAMS;
818 /* Execute... */
819 EnterCriticalSection(&ddraw_cs);
820 IDirect3DExecuteBufferImpl_Execute(Direct3DExecuteBufferImpl, This, Direct3DViewportImpl);
821 LeaveCriticalSection(&ddraw_cs);
823 return D3D_OK;
826 /*****************************************************************************
827 * IDirect3DDevice3::AddViewport
829 * Add a Direct3DViewport to the device's viewport list. These viewports
830 * are wrapped to IDirect3DDevice7 viewports in viewport.c
832 * Exists in Version 1, 2 and 3. Note that IDirect3DViewport 1, 2 and 3
833 * are the same interfaces.
835 * Params:
836 * Viewport: The viewport to add
838 * Returns:
839 * DDERR_INVALIDPARAMS if Viewport == NULL
840 * D3D_OK on success
842 *****************************************************************************/
843 static HRESULT WINAPI
844 IDirect3DDeviceImpl_3_AddViewport(IDirect3DDevice3 *iface,
845 IDirect3DViewport3 *Viewport)
847 IDirect3DDeviceImpl *This = device_from_device3(iface);
848 IDirect3DViewportImpl *vp = (IDirect3DViewportImpl *)Viewport;
850 TRACE("(%p)->(%p)\n", This, vp);
852 /* Sanity check */
853 if(!vp)
854 return DDERR_INVALIDPARAMS;
856 EnterCriticalSection(&ddraw_cs);
857 vp->next = This->viewport_list;
858 This->viewport_list = vp;
859 vp->active_device = This; /* Viewport must be usable for Clear() after AddViewport,
860 so set active_device here. */
861 LeaveCriticalSection(&ddraw_cs);
863 return D3D_OK;
866 static HRESULT WINAPI
867 Thunk_IDirect3DDeviceImpl_2_AddViewport(IDirect3DDevice2 *iface,
868 IDirect3DViewport2 *Direct3DViewport2)
870 IDirect3DDeviceImpl *This = device_from_device2(iface);
871 IDirect3DViewportImpl *vp = (IDirect3DViewportImpl *)Direct3DViewport2;
872 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, vp);
873 return IDirect3DDevice3_AddViewport((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl, (IDirect3DViewport3 *)vp);
876 static HRESULT WINAPI
877 Thunk_IDirect3DDeviceImpl_1_AddViewport(IDirect3DDevice *iface,
878 IDirect3DViewport *Direct3DViewport)
880 IDirect3DDeviceImpl *This = device_from_device1(iface);
881 IDirect3DViewportImpl *vp = (IDirect3DViewportImpl *)Direct3DViewport;
882 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, vp);
883 return IDirect3DDevice3_AddViewport((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl, (IDirect3DViewport3 *)vp);
886 /*****************************************************************************
887 * IDirect3DDevice3::DeleteViewport
889 * Deletes a Direct3DViewport from the device's viewport list.
891 * Exists in Version 1, 2 and 3. Note that all Viewport interface versions
892 * are equal.
894 * Params:
895 * Viewport: The viewport to delete
897 * Returns:
898 * D3D_OK on success
899 * DDERR_INVALIDPARAMS if the viewport wasn't found in the list
901 *****************************************************************************/
902 static HRESULT WINAPI
903 IDirect3DDeviceImpl_3_DeleteViewport(IDirect3DDevice3 *iface,
904 IDirect3DViewport3 *Viewport)
906 IDirect3DDeviceImpl *This = device_from_device3(iface);
907 IDirect3DViewportImpl *vp = (IDirect3DViewportImpl *) Viewport;
908 IDirect3DViewportImpl *cur_viewport, *prev_viewport = NULL;
910 TRACE("(%p)->(%p)\n", This, vp);
912 EnterCriticalSection(&ddraw_cs);
913 cur_viewport = This->viewport_list;
914 while (cur_viewport != NULL)
916 if (cur_viewport == vp)
918 if (prev_viewport == NULL) This->viewport_list = cur_viewport->next;
919 else prev_viewport->next = cur_viewport->next;
920 /* TODO : add desactivate of the viewport and all associated lights... */
921 LeaveCriticalSection(&ddraw_cs);
922 return D3D_OK;
924 prev_viewport = cur_viewport;
925 cur_viewport = cur_viewport->next;
928 LeaveCriticalSection(&ddraw_cs);
929 return DDERR_INVALIDPARAMS;
932 static HRESULT WINAPI
933 Thunk_IDirect3DDeviceImpl_2_DeleteViewport(IDirect3DDevice2 *iface,
934 IDirect3DViewport2 *Direct3DViewport2)
936 IDirect3DDeviceImpl *This = device_from_device2(iface);
937 IDirect3DViewportImpl *vp = (IDirect3DViewportImpl *)Direct3DViewport2;
938 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, vp);
939 return IDirect3DDevice3_DeleteViewport((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl, (IDirect3DViewport3 *)vp);
942 static HRESULT WINAPI
943 Thunk_IDirect3DDeviceImpl_1_DeleteViewport(IDirect3DDevice *iface,
944 IDirect3DViewport *Direct3DViewport)
946 IDirect3DDeviceImpl *This = device_from_device1(iface);
947 IDirect3DViewportImpl *vp = (IDirect3DViewportImpl *)Direct3DViewport;
948 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, vp);
949 return IDirect3DDevice3_DeleteViewport((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl, (IDirect3DViewport3 *)vp);
952 /*****************************************************************************
953 * IDirect3DDevice3::NextViewport
955 * Returns a viewport from the viewport list, depending on the
956 * passed viewport and the flags.
958 * Exists in Version 1, 2 and 3. Note that all Viewport interface versions
959 * are equal.
961 * Params:
962 * Viewport: Viewport to use for beginning the search
963 * Flags: D3DNEXT_NEXT, D3DNEXT_HEAD or D3DNEXT_TAIL
965 * Returns:
966 * D3D_OK on success
967 * DDERR_INVALIDPARAMS if the flags were wrong, or Viewport was NULL
969 *****************************************************************************/
970 static HRESULT WINAPI
971 IDirect3DDeviceImpl_3_NextViewport(IDirect3DDevice3 *iface,
972 IDirect3DViewport3 *Viewport3,
973 IDirect3DViewport3 **lplpDirect3DViewport3,
974 DWORD Flags)
976 IDirect3DDeviceImpl *This = device_from_device3(iface);
977 IDirect3DViewportImpl *vp = (IDirect3DViewportImpl *)Viewport3;
978 IDirect3DViewportImpl *res = NULL;
980 TRACE("(%p)->(%p,%p,%08x)\n", This, vp, lplpDirect3DViewport3, Flags);
982 if(!vp)
984 *lplpDirect3DViewport3 = NULL;
985 return DDERR_INVALIDPARAMS;
989 EnterCriticalSection(&ddraw_cs);
990 switch (Flags)
992 case D3DNEXT_NEXT:
994 res = vp->next;
996 break;
997 case D3DNEXT_HEAD:
999 res = This->viewport_list;
1001 break;
1002 case D3DNEXT_TAIL:
1004 IDirect3DViewportImpl *cur_viewport = This->viewport_list;
1005 if (cur_viewport != NULL)
1007 while (cur_viewport->next != NULL) cur_viewport = cur_viewport->next;
1009 res = cur_viewport;
1011 break;
1012 default:
1013 *lplpDirect3DViewport3 = NULL;
1014 LeaveCriticalSection(&ddraw_cs);
1015 return DDERR_INVALIDPARAMS;
1018 *lplpDirect3DViewport3 = (IDirect3DViewport3 *)res;
1019 LeaveCriticalSection(&ddraw_cs);
1020 return D3D_OK;
1023 static HRESULT WINAPI
1024 Thunk_IDirect3DDeviceImpl_2_NextViewport(IDirect3DDevice2 *iface,
1025 IDirect3DViewport2 *Viewport2,
1026 IDirect3DViewport2 **lplpDirect3DViewport2,
1027 DWORD Flags)
1029 IDirect3DDeviceImpl *This = device_from_device2(iface);
1030 IDirect3DViewportImpl *vp = (IDirect3DViewportImpl *)Viewport2;
1031 IDirect3DViewport3 *res;
1032 HRESULT hr;
1033 TRACE_(ddraw_thunk)("(%p)->(%p,%p,%08x) thunking to IDirect3DDevice3 interface.\n", This, vp, lplpDirect3DViewport2, Flags);
1034 hr = IDirect3DDevice3_NextViewport((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl,
1035 (IDirect3DViewport3 *)vp, &res, Flags);
1036 *lplpDirect3DViewport2 = (IDirect3DViewport2 *)res;
1037 return hr;
1040 static HRESULT WINAPI
1041 Thunk_IDirect3DDeviceImpl_1_NextViewport(IDirect3DDevice *iface,
1042 IDirect3DViewport *Viewport,
1043 IDirect3DViewport **lplpDirect3DViewport,
1044 DWORD Flags)
1046 IDirect3DDeviceImpl *This = device_from_device1(iface);
1047 IDirect3DViewportImpl *vp = (IDirect3DViewportImpl *)Viewport;
1048 IDirect3DViewport3 *res;
1049 HRESULT hr;
1050 TRACE_(ddraw_thunk)("(%p)->(%p,%p,%08x) thunking to IDirect3DDevice3 interface.\n", This, vp, lplpDirect3DViewport, Flags);
1051 hr = IDirect3DDevice3_NextViewport((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl,
1052 (IDirect3DViewport3 *)vp, &res, Flags);
1053 *lplpDirect3DViewport = (IDirect3DViewport *)res;
1054 return hr;
1057 /*****************************************************************************
1058 * IDirect3DDevice::Pick
1060 * Executes an execute buffer without performing rendering. Instead, a
1061 * list of primitives that intersect with (x1,y1) of the passed rectangle
1062 * is created. IDirect3DDevice::GetPickRecords can be used to retrieve
1063 * this list.
1065 * Version 1 only
1067 * Params:
1068 * ExecuteBuffer: Buffer to execute
1069 * Viewport: Viewport to use for execution
1070 * Flags: None are defined, according to the SDK
1071 * Rect: Specifies the coordinates to be picked. Only x1 and y2 are used,
1072 * x2 and y2 are ignored.
1074 * Returns:
1075 * D3D_OK because it's a stub
1077 *****************************************************************************/
1078 static HRESULT WINAPI
1079 IDirect3DDeviceImpl_1_Pick(IDirect3DDevice *iface,
1080 IDirect3DExecuteBuffer *ExecuteBuffer,
1081 IDirect3DViewport *Viewport,
1082 DWORD Flags,
1083 D3DRECT *Rect)
1085 IDirect3DDeviceImpl *This = device_from_device1(iface);
1086 IDirect3DExecuteBufferImpl *execbuf = (IDirect3DExecuteBufferImpl *)ExecuteBuffer;
1087 IDirect3DViewportImpl *vp = (IDirect3DViewportImpl *)Viewport;
1088 FIXME("(%p)->(%p,%p,%08x,%p): stub!\n", This, execbuf, vp, Flags, Rect);
1090 return D3D_OK;
1093 /*****************************************************************************
1094 * IDirect3DDevice::GetPickRecords
1096 * Retrieves the pick records generated by IDirect3DDevice::GetPickRecords
1098 * Version 1 only
1100 * Params:
1101 * Count: Pointer to a DWORD containing the numbers of pick records to
1102 * retrieve
1103 * D3DPickRec: Address to store the resulting D3DPICKRECORD array.
1105 * Returns:
1106 * D3D_OK, because it's a stub
1108 *****************************************************************************/
1109 static HRESULT WINAPI
1110 IDirect3DDeviceImpl_1_GetPickRecords(IDirect3DDevice *iface,
1111 DWORD *Count,
1112 D3DPICKRECORD *D3DPickRec)
1114 IDirect3DDeviceImpl *This = device_from_device1(iface);
1115 FIXME("(%p)->(%p,%p): stub!\n", This, Count, D3DPickRec);
1117 return D3D_OK;
1120 /*****************************************************************************
1121 * IDirect3DDevice7::EnumTextureformats
1123 * Enumerates the supported texture formats. It has a list of all possible
1124 * formats and calls IWineD3D::CheckDeviceFormat for each format to see if
1125 * WineD3D supports it. If so, then it is passed to the app.
1127 * This is for Version 7 and 3, older versions have a different
1128 * callback function and their own implementation
1130 * Params:
1131 * Callback: Callback to call for each enumerated format
1132 * Arg: Argument to pass to the callback
1134 * Returns:
1135 * D3D_OK on success
1136 * DDERR_INVALIDPARAMS if Callback == NULL
1138 *****************************************************************************/
1139 static HRESULT
1140 IDirect3DDeviceImpl_7_EnumTextureFormats(IDirect3DDevice7 *iface,
1141 LPD3DENUMPIXELFORMATSCALLBACK Callback,
1142 void *Arg)
1144 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
1145 HRESULT hr;
1146 WINED3DDISPLAYMODE mode;
1147 unsigned int i;
1149 WINED3DFORMAT FormatList[] = {
1150 /* 32 bit */
1151 WINED3DFMT_B8G8R8A8_UNORM,
1152 WINED3DFMT_B8G8R8X8_UNORM,
1153 /* 24 bit */
1154 WINED3DFMT_B8G8R8_UNORM,
1155 /* 16 Bit */
1156 WINED3DFMT_B5G5R5A1_UNORM,
1157 WINED3DFMT_B4G4R4A4_UNORM,
1158 WINED3DFMT_B5G6R5_UNORM,
1159 WINED3DFMT_B5G5R5X1_UNORM,
1160 /* 8 Bit */
1161 WINED3DFMT_B2G3R3_UNORM,
1162 WINED3DFMT_P8_UINT,
1163 /* FOURCC codes */
1164 WINED3DFMT_DXT1,
1165 WINED3DFMT_DXT3,
1166 WINED3DFMT_DXT5,
1169 WINED3DFORMAT BumpFormatList[] = {
1170 WINED3DFMT_R8G8_SNORM,
1171 WINED3DFMT_R5G5_SNORM_L6_UNORM,
1172 WINED3DFMT_R8G8_SNORM_L8X8_UNORM,
1173 WINED3DFMT_R8G8B8A8_SNORM,
1174 WINED3DFMT_R16G16_SNORM,
1175 WINED3DFMT_R10G11B11_SNORM,
1176 WINED3DFMT_R10G10B10_SNORM_A2_UNORM
1179 TRACE("(%p)->(%p,%p): Relay\n", This, Callback, Arg);
1181 if(!Callback)
1182 return DDERR_INVALIDPARAMS;
1184 EnterCriticalSection(&ddraw_cs);
1186 memset(&mode, 0, sizeof(mode));
1187 hr = IWineD3DDevice_GetDisplayMode(This->ddraw->wineD3DDevice,
1189 &mode);
1190 if(FAILED(hr)) {
1191 LeaveCriticalSection(&ddraw_cs);
1192 WARN("Cannot get the current adapter format\n");
1193 return hr;
1196 for(i = 0; i < sizeof(FormatList) / sizeof(WINED3DFORMAT); i++)
1198 hr = IWineD3D_CheckDeviceFormat(This->ddraw->wineD3D,
1199 WINED3DADAPTER_DEFAULT,
1200 WINED3DDEVTYPE_HAL,
1201 mode.Format,
1202 0 /* Usage */,
1203 WINED3DRTYPE_TEXTURE,
1204 FormatList[i],
1205 SURFACE_OPENGL);
1206 if(hr == D3D_OK)
1208 DDPIXELFORMAT pformat;
1210 memset(&pformat, 0, sizeof(pformat));
1211 pformat.dwSize = sizeof(pformat);
1212 PixelFormat_WineD3DtoDD(&pformat, FormatList[i]);
1214 TRACE("Enumerating WineD3DFormat %d\n", FormatList[i]);
1215 hr = Callback(&pformat, Arg);
1216 if(hr != DDENUMRET_OK)
1218 TRACE("Format enumeration cancelled by application\n");
1219 LeaveCriticalSection(&ddraw_cs);
1220 return D3D_OK;
1225 for(i = 0; i < sizeof(BumpFormatList) / sizeof(WINED3DFORMAT); i++)
1227 hr = IWineD3D_CheckDeviceFormat(This->ddraw->wineD3D,
1228 WINED3DADAPTER_DEFAULT,
1229 WINED3DDEVTYPE_HAL,
1230 mode.Format,
1231 WINED3DUSAGE_QUERY_LEGACYBUMPMAP,
1232 WINED3DRTYPE_TEXTURE,
1233 BumpFormatList[i],
1234 SURFACE_OPENGL);
1235 if(hr == D3D_OK)
1237 DDPIXELFORMAT pformat;
1239 memset(&pformat, 0, sizeof(pformat));
1240 pformat.dwSize = sizeof(pformat);
1241 PixelFormat_WineD3DtoDD(&pformat, BumpFormatList[i]);
1243 TRACE("Enumerating WineD3DFormat %d\n", BumpFormatList[i]);
1244 hr = Callback(&pformat, Arg);
1245 if(hr != DDENUMRET_OK)
1247 TRACE("Format enumeration cancelled by application\n");
1248 LeaveCriticalSection(&ddraw_cs);
1249 return D3D_OK;
1253 TRACE("End of enumeration\n");
1254 LeaveCriticalSection(&ddraw_cs);
1255 return D3D_OK;
1258 static HRESULT WINAPI
1259 IDirect3DDeviceImpl_7_EnumTextureFormats_FPUSetup(IDirect3DDevice7 *iface,
1260 LPD3DENUMPIXELFORMATSCALLBACK Callback,
1261 void *Arg)
1263 return IDirect3DDeviceImpl_7_EnumTextureFormats(iface, Callback, Arg);
1266 static HRESULT WINAPI
1267 IDirect3DDeviceImpl_7_EnumTextureFormats_FPUPreserve(IDirect3DDevice7 *iface,
1268 LPD3DENUMPIXELFORMATSCALLBACK Callback,
1269 void *Arg)
1271 HRESULT hr;
1272 WORD old_fpucw;
1274 old_fpucw = d3d_fpu_setup();
1275 hr = IDirect3DDeviceImpl_7_EnumTextureFormats(iface, Callback, Arg);
1276 set_fpu_control_word(old_fpucw);
1278 return hr;
1281 static HRESULT WINAPI
1282 Thunk_IDirect3DDeviceImpl_3_EnumTextureFormats(IDirect3DDevice3 *iface,
1283 LPD3DENUMPIXELFORMATSCALLBACK Callback,
1284 void *Arg)
1286 IDirect3DDeviceImpl *This = device_from_device3(iface);
1287 TRACE_(ddraw_thunk)("(%p)->(%p,%p) thunking to IDirect3DDevice7 interface.\n", This, Callback, Arg);
1288 return IDirect3DDevice7_EnumTextureFormats((IDirect3DDevice7 *)This, Callback, Arg);
1291 /*****************************************************************************
1292 * IDirect3DDevice2::EnumTextureformats
1294 * EnumTextureFormats for Version 1 and 2, see
1295 * IDirect3DDevice7::EnumTexureFormats for a more detailed description.
1297 * This version has a different callback and does not enumerate FourCC
1298 * formats
1300 *****************************************************************************/
1301 static HRESULT WINAPI
1302 IDirect3DDeviceImpl_2_EnumTextureFormats(IDirect3DDevice2 *iface,
1303 LPD3DENUMTEXTUREFORMATSCALLBACK Callback,
1304 void *Arg)
1306 IDirect3DDeviceImpl *This = device_from_device2(iface);
1307 HRESULT hr;
1308 unsigned int i;
1309 WINED3DDISPLAYMODE mode;
1311 WINED3DFORMAT FormatList[] = {
1312 /* 32 bit */
1313 WINED3DFMT_B8G8R8A8_UNORM,
1314 WINED3DFMT_B8G8R8X8_UNORM,
1315 /* 24 bit */
1316 WINED3DFMT_B8G8R8_UNORM,
1317 /* 16 Bit */
1318 WINED3DFMT_B5G5R5A1_UNORM,
1319 WINED3DFMT_B4G4R4A4_UNORM,
1320 WINED3DFMT_B5G6R5_UNORM,
1321 WINED3DFMT_B5G5R5X1_UNORM,
1322 /* 8 Bit */
1323 WINED3DFMT_B2G3R3_UNORM,
1324 WINED3DFMT_P8_UINT,
1325 /* FOURCC codes - Not in this version*/
1328 TRACE("(%p)->(%p,%p): Relay\n", This, Callback, Arg);
1330 if(!Callback)
1331 return DDERR_INVALIDPARAMS;
1333 EnterCriticalSection(&ddraw_cs);
1335 memset(&mode, 0, sizeof(mode));
1336 hr = IWineD3DDevice_GetDisplayMode(This->ddraw->wineD3DDevice,
1338 &mode);
1339 if(FAILED(hr)) {
1340 LeaveCriticalSection(&ddraw_cs);
1341 WARN("Cannot get the current adapter format\n");
1342 return hr;
1345 for(i = 0; i < sizeof(FormatList) / sizeof(WINED3DFORMAT); i++)
1347 hr = IWineD3D_CheckDeviceFormat(This->ddraw->wineD3D,
1348 0 /* Adapter */,
1349 WINED3DDEVTYPE_HAL,
1350 mode.Format,
1351 0 /* Usage */,
1352 WINED3DRTYPE_TEXTURE,
1353 FormatList[i],
1354 SURFACE_OPENGL);
1355 if(hr == D3D_OK)
1357 DDSURFACEDESC sdesc;
1359 memset(&sdesc, 0, sizeof(sdesc));
1360 sdesc.dwSize = sizeof(sdesc);
1361 sdesc.dwFlags = DDSD_PIXELFORMAT | DDSD_CAPS;
1362 sdesc.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
1363 sdesc.ddpfPixelFormat.dwSize = sizeof(sdesc.ddpfPixelFormat);
1364 PixelFormat_WineD3DtoDD(&sdesc.ddpfPixelFormat, FormatList[i]);
1366 TRACE("Enumerating WineD3DFormat %d\n", FormatList[i]);
1367 hr = Callback(&sdesc, Arg);
1368 if(hr != DDENUMRET_OK)
1370 TRACE("Format enumeration cancelled by application\n");
1371 LeaveCriticalSection(&ddraw_cs);
1372 return D3D_OK;
1376 TRACE("End of enumeration\n");
1377 LeaveCriticalSection(&ddraw_cs);
1378 return D3D_OK;
1381 static HRESULT WINAPI
1382 Thunk_IDirect3DDeviceImpl_1_EnumTextureFormats(IDirect3DDevice *iface,
1383 LPD3DENUMTEXTUREFORMATSCALLBACK Callback,
1384 void *Arg)
1386 IDirect3DDeviceImpl *This = device_from_device1(iface);
1387 TRACE_(ddraw_thunk)("(%p)->(%p,%p) thunking to IDirect3DDevice2 interface.\n", This, Callback, Arg);
1388 return IDirect3DDevice2_EnumTextureFormats((IDirect3DDevice2 *)&This->IDirect3DDevice2_vtbl, Callback, Arg);
1391 /*****************************************************************************
1392 * IDirect3DDevice::CreateMatrix
1394 * Creates a matrix handle. A handle is created and memory for a D3DMATRIX is
1395 * allocated for the handle.
1397 * Version 1 only
1399 * Params
1400 * D3DMatHandle: Address to return the handle at
1402 * Returns:
1403 * D3D_OK on success
1404 * DDERR_INVALIDPARAMS if D3DMatHandle = NULL
1406 *****************************************************************************/
1407 static HRESULT WINAPI
1408 IDirect3DDeviceImpl_1_CreateMatrix(IDirect3DDevice *iface, D3DMATRIXHANDLE *D3DMatHandle)
1410 IDirect3DDeviceImpl *This = device_from_device1(iface);
1411 D3DMATRIX *Matrix;
1412 TRACE("(%p)->(%p)\n", This, D3DMatHandle);
1414 if(!D3DMatHandle)
1415 return DDERR_INVALIDPARAMS;
1417 Matrix = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(D3DMATRIX));
1418 if(!Matrix)
1420 ERR("Out of memory when allocating a D3DMATRIX\n");
1421 return DDERR_OUTOFMEMORY;
1424 EnterCriticalSection(&ddraw_cs);
1425 *D3DMatHandle = IDirect3DDeviceImpl_CreateHandle(This);
1426 if(!(*D3DMatHandle))
1428 ERR("Failed to create a matrix handle\n");
1429 HeapFree(GetProcessHeap(), 0, Matrix);
1430 LeaveCriticalSection(&ddraw_cs);
1431 return DDERR_OUTOFMEMORY;
1433 This->Handles[*D3DMatHandle - 1].ptr = Matrix;
1434 This->Handles[*D3DMatHandle - 1].type = DDrawHandle_Matrix;
1435 TRACE(" returning matrix handle %d\n", *D3DMatHandle);
1437 LeaveCriticalSection(&ddraw_cs);
1438 return D3D_OK;
1441 /*****************************************************************************
1442 * IDirect3DDevice::SetMatrix
1444 * Sets a matrix for a matrix handle. The matrix is copied into the memory
1445 * allocated for the handle
1447 * Version 1 only
1449 * Params:
1450 * D3DMatHandle: Handle to set the matrix to
1451 * D3DMatrix: Matrix to set
1453 * Returns:
1454 * D3D_OK on success
1455 * DDERR_INVALIDPARAMS if the handle of the matrix is invalid or the matrix
1456 * to set is NULL
1458 *****************************************************************************/
1459 static HRESULT WINAPI
1460 IDirect3DDeviceImpl_1_SetMatrix(IDirect3DDevice *iface,
1461 D3DMATRIXHANDLE D3DMatHandle,
1462 D3DMATRIX *D3DMatrix)
1464 IDirect3DDeviceImpl *This = device_from_device1(iface);
1465 TRACE("(%p)->(%08x,%p)\n", This, D3DMatHandle, D3DMatrix);
1467 if( (!D3DMatHandle) || (!D3DMatrix) )
1468 return DDERR_INVALIDPARAMS;
1470 EnterCriticalSection(&ddraw_cs);
1471 if(D3DMatHandle > This->numHandles)
1473 ERR("Handle %d out of range\n", D3DMatHandle);
1474 LeaveCriticalSection(&ddraw_cs);
1475 return DDERR_INVALIDPARAMS;
1477 else if(This->Handles[D3DMatHandle - 1].type != DDrawHandle_Matrix)
1479 ERR("Handle %d is not a matrix handle\n", D3DMatHandle);
1480 LeaveCriticalSection(&ddraw_cs);
1481 return DDERR_INVALIDPARAMS;
1484 if (TRACE_ON(d3d7))
1485 dump_D3DMATRIX(D3DMatrix);
1487 *((D3DMATRIX *) This->Handles[D3DMatHandle - 1].ptr) = *D3DMatrix;
1489 if(This->world == D3DMatHandle)
1491 IWineD3DDevice_SetTransform(This->wineD3DDevice,
1492 WINED3DTS_WORLDMATRIX(0),
1493 (WINED3DMATRIX *) D3DMatrix);
1495 if(This->view == D3DMatHandle)
1497 IWineD3DDevice_SetTransform(This->wineD3DDevice,
1498 WINED3DTS_VIEW,
1499 (WINED3DMATRIX *) D3DMatrix);
1501 if(This->proj == D3DMatHandle)
1503 IWineD3DDevice_SetTransform(This->wineD3DDevice,
1504 WINED3DTS_PROJECTION,
1505 (WINED3DMATRIX *) D3DMatrix);
1508 LeaveCriticalSection(&ddraw_cs);
1509 return D3D_OK;
1512 /*****************************************************************************
1513 * IDirect3DDevice::SetMatrix
1515 * Returns the content of a D3DMATRIX handle
1517 * Version 1 only
1519 * Params:
1520 * D3DMatHandle: Matrix handle to read the content from
1521 * D3DMatrix: Address to store the content at
1523 * Returns:
1524 * D3D_OK on success
1525 * DDERR_INVALIDPARAMS if D3DMatHandle is invalid or D3DMatrix is NULL
1527 *****************************************************************************/
1528 static HRESULT WINAPI
1529 IDirect3DDeviceImpl_1_GetMatrix(IDirect3DDevice *iface,
1530 D3DMATRIXHANDLE D3DMatHandle,
1531 D3DMATRIX *D3DMatrix)
1533 IDirect3DDeviceImpl *This = device_from_device1(iface);
1534 TRACE("(%p)->(%08x,%p)\n", This, D3DMatHandle, D3DMatrix);
1536 if(!D3DMatrix)
1537 return DDERR_INVALIDPARAMS;
1538 if(!D3DMatHandle)
1539 return DDERR_INVALIDPARAMS;
1541 EnterCriticalSection(&ddraw_cs);
1542 if(D3DMatHandle > This->numHandles)
1544 ERR("Handle %d out of range\n", D3DMatHandle);
1545 LeaveCriticalSection(&ddraw_cs);
1546 return DDERR_INVALIDPARAMS;
1548 else if(This->Handles[D3DMatHandle - 1].type != DDrawHandle_Matrix)
1550 ERR("Handle %d is not a matrix handle\n", D3DMatHandle);
1551 LeaveCriticalSection(&ddraw_cs);
1552 return DDERR_INVALIDPARAMS;
1555 /* The handle is simply a pointer to a D3DMATRIX structure */
1556 *D3DMatrix = *((D3DMATRIX *) This->Handles[D3DMatHandle - 1].ptr);
1558 LeaveCriticalSection(&ddraw_cs);
1559 return D3D_OK;
1562 /*****************************************************************************
1563 * IDirect3DDevice::DeleteMatrix
1565 * Destroys a Matrix handle. Frees the memory and unsets the handle data
1567 * Version 1 only
1569 * Params:
1570 * D3DMatHandle: Handle to destroy
1572 * Returns:
1573 * D3D_OK on success
1574 * DDERR_INVALIDPARAMS if D3DMatHandle is invalid
1576 *****************************************************************************/
1577 static HRESULT WINAPI
1578 IDirect3DDeviceImpl_1_DeleteMatrix(IDirect3DDevice *iface,
1579 D3DMATRIXHANDLE D3DMatHandle)
1581 IDirect3DDeviceImpl *This = device_from_device1(iface);
1582 TRACE("(%p)->(%08x)\n", This, D3DMatHandle);
1584 if(!D3DMatHandle)
1585 return DDERR_INVALIDPARAMS;
1587 EnterCriticalSection(&ddraw_cs);
1588 if(D3DMatHandle > This->numHandles)
1590 ERR("Handle %d out of range\n", D3DMatHandle);
1591 LeaveCriticalSection(&ddraw_cs);
1592 return DDERR_INVALIDPARAMS;
1594 else if(This->Handles[D3DMatHandle - 1].type != DDrawHandle_Matrix)
1596 ERR("Handle %d is not a matrix handle\n", D3DMatHandle);
1597 LeaveCriticalSection(&ddraw_cs);
1598 return DDERR_INVALIDPARAMS;
1601 HeapFree(GetProcessHeap(), 0, This->Handles[D3DMatHandle - 1].ptr);
1602 This->Handles[D3DMatHandle - 1].ptr = NULL;
1603 This->Handles[D3DMatHandle - 1].type = DDrawHandle_Unknown;
1605 LeaveCriticalSection(&ddraw_cs);
1606 return D3D_OK;
1609 /*****************************************************************************
1610 * IDirect3DDevice7::BeginScene
1612 * This method must be called before any rendering is performed.
1613 * IDirect3DDevice::EndScene has to be called after the scene is complete
1615 * Version 1, 2, 3 and 7
1617 * Returns:
1618 * D3D_OK on success, for details see IWineD3DDevice::BeginScene
1619 * D3DERR_SCENE_IN_SCENE if WineD3D returns an error(Only in case of an already
1620 * started scene).
1622 *****************************************************************************/
1623 static HRESULT
1624 IDirect3DDeviceImpl_7_BeginScene(IDirect3DDevice7 *iface)
1626 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
1627 HRESULT hr;
1628 TRACE("(%p): Relay\n", This);
1630 EnterCriticalSection(&ddraw_cs);
1631 hr = IWineD3DDevice_BeginScene(This->wineD3DDevice);
1632 LeaveCriticalSection(&ddraw_cs);
1633 if(hr == WINED3D_OK) return D3D_OK;
1634 else return D3DERR_SCENE_IN_SCENE; /* TODO: Other possible causes of failure */
1637 static HRESULT WINAPI
1638 IDirect3DDeviceImpl_7_BeginScene_FPUSetup(IDirect3DDevice7 *iface)
1640 return IDirect3DDeviceImpl_7_BeginScene(iface);
1643 static HRESULT WINAPI
1644 IDirect3DDeviceImpl_7_BeginScene_FPUPreserve(IDirect3DDevice7 *iface)
1646 HRESULT hr;
1647 WORD old_fpucw;
1649 old_fpucw = d3d_fpu_setup();
1650 hr = IDirect3DDeviceImpl_7_BeginScene(iface);
1651 set_fpu_control_word(old_fpucw);
1653 return hr;
1656 static HRESULT WINAPI
1657 Thunk_IDirect3DDeviceImpl_3_BeginScene(IDirect3DDevice3 *iface)
1659 IDirect3DDeviceImpl *This = device_from_device3(iface);
1660 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
1661 return IDirect3DDevice7_BeginScene((IDirect3DDevice7 *)This);
1664 static HRESULT WINAPI
1665 Thunk_IDirect3DDeviceImpl_2_BeginScene(IDirect3DDevice2 *iface)
1667 IDirect3DDeviceImpl *This = device_from_device2(iface);
1668 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
1669 return IDirect3DDevice7_BeginScene((IDirect3DDevice7 *)This);
1672 static HRESULT WINAPI
1673 Thunk_IDirect3DDeviceImpl_1_BeginScene(IDirect3DDevice *iface)
1675 IDirect3DDeviceImpl *This = device_from_device1(iface);
1676 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
1677 return IDirect3DDevice7_BeginScene((IDirect3DDevice7 *)This);
1680 /*****************************************************************************
1681 * IDirect3DDevice7::EndScene
1683 * Ends a scene that has been begun with IDirect3DDevice7::BeginScene.
1684 * This method must be called after rendering is finished.
1686 * Version 1, 2, 3 and 7
1688 * Returns:
1689 * D3D_OK on success, for details see IWineD3DDevice::EndScene
1690 * D3DERR_SCENE_NOT_IN_SCENE is returned if WineD3D returns an error. It does
1691 * that only if the scene was already ended.
1693 *****************************************************************************/
1694 static HRESULT
1695 IDirect3DDeviceImpl_7_EndScene(IDirect3DDevice7 *iface)
1697 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
1698 HRESULT hr;
1699 TRACE("(%p): Relay\n", This);
1701 EnterCriticalSection(&ddraw_cs);
1702 hr = IWineD3DDevice_EndScene(This->wineD3DDevice);
1703 LeaveCriticalSection(&ddraw_cs);
1704 if(hr == WINED3D_OK) return D3D_OK;
1705 else return D3DERR_SCENE_NOT_IN_SCENE;
1708 static HRESULT WINAPI DECLSPEC_HOTPATCH
1709 IDirect3DDeviceImpl_7_EndScene_FPUSetup(IDirect3DDevice7 *iface)
1711 return IDirect3DDeviceImpl_7_EndScene(iface);
1714 static HRESULT WINAPI DECLSPEC_HOTPATCH
1715 IDirect3DDeviceImpl_7_EndScene_FPUPreserve(IDirect3DDevice7 *iface)
1717 HRESULT hr;
1718 WORD old_fpucw;
1720 old_fpucw = d3d_fpu_setup();
1721 hr = IDirect3DDeviceImpl_7_EndScene(iface);
1722 set_fpu_control_word(old_fpucw);
1724 return hr;
1727 static HRESULT WINAPI DECLSPEC_HOTPATCH
1728 Thunk_IDirect3DDeviceImpl_3_EndScene(IDirect3DDevice3 *iface)
1730 IDirect3DDeviceImpl *This = device_from_device3(iface);
1731 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
1732 return IDirect3DDevice7_EndScene((IDirect3DDevice7 *)This);
1735 static HRESULT WINAPI DECLSPEC_HOTPATCH
1736 Thunk_IDirect3DDeviceImpl_2_EndScene(IDirect3DDevice2 *iface)
1738 IDirect3DDeviceImpl *This = device_from_device2(iface);
1739 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
1740 return IDirect3DDevice7_EndScene((IDirect3DDevice7 *)This);
1743 static HRESULT WINAPI DECLSPEC_HOTPATCH
1744 Thunk_IDirect3DDeviceImpl_1_EndScene(IDirect3DDevice *iface)
1746 IDirect3DDeviceImpl *This = device_from_device1(iface);
1747 TRACE_(ddraw_thunk)("(%p)->() thunking to IDirect3DDevice7 interface.\n", This);
1748 return IDirect3DDevice7_EndScene((IDirect3DDevice7 *)This);
1751 /*****************************************************************************
1752 * IDirect3DDevice7::GetDirect3D
1754 * Returns the IDirect3D(= interface to the DirectDraw object) used to create
1755 * this device.
1757 * Params:
1758 * Direct3D7: Address to store the interface pointer at
1760 * Returns:
1761 * D3D_OK on success
1762 * DDERR_INVALIDPARAMS if Direct3D7 == NULL
1764 *****************************************************************************/
1765 static HRESULT WINAPI
1766 IDirect3DDeviceImpl_7_GetDirect3D(IDirect3DDevice7 *iface,
1767 IDirect3D7 **Direct3D7)
1769 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
1770 TRACE("(%p)->(%p)\n", This, Direct3D7);
1772 if(!Direct3D7)
1773 return DDERR_INVALIDPARAMS;
1775 *Direct3D7 = (IDirect3D7 *)&This->ddraw->IDirect3D7_vtbl;
1776 IDirect3D7_AddRef(*Direct3D7);
1778 TRACE(" returning interface %p\n", *Direct3D7);
1779 return D3D_OK;
1782 static HRESULT WINAPI
1783 Thunk_IDirect3DDeviceImpl_3_GetDirect3D(IDirect3DDevice3 *iface,
1784 IDirect3D3 **Direct3D3)
1786 IDirect3DDeviceImpl *This = device_from_device3(iface);
1787 HRESULT ret;
1788 IDirect3D7 *ret_ptr;
1790 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, Direct3D3);
1791 ret = IDirect3DDevice7_GetDirect3D((IDirect3DDevice7 *)This, &ret_ptr);
1792 if(ret != D3D_OK)
1793 return ret;
1794 *Direct3D3 = ret_ptr ? (IDirect3D3 *)&ddraw_from_d3d7(ret_ptr)->IDirect3D3_vtbl : NULL;
1795 TRACE(" returning interface %p\n", *Direct3D3);
1796 return D3D_OK;
1799 static HRESULT WINAPI
1800 Thunk_IDirect3DDeviceImpl_2_GetDirect3D(IDirect3DDevice2 *iface,
1801 IDirect3D2 **Direct3D2)
1803 IDirect3DDeviceImpl *This = device_from_device2(iface);
1804 HRESULT ret;
1805 IDirect3D7 *ret_ptr;
1807 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, Direct3D2);
1808 ret = IDirect3DDevice7_GetDirect3D((IDirect3DDevice7 *)This, &ret_ptr);
1809 if(ret != D3D_OK)
1810 return ret;
1811 *Direct3D2 = ret_ptr ? (IDirect3D2 *)&ddraw_from_d3d7(ret_ptr)->IDirect3D2_vtbl : NULL;
1812 TRACE(" returning interface %p\n", *Direct3D2);
1813 return D3D_OK;
1816 static HRESULT WINAPI
1817 Thunk_IDirect3DDeviceImpl_1_GetDirect3D(IDirect3DDevice *iface,
1818 IDirect3D **Direct3D)
1820 IDirect3DDeviceImpl *This = device_from_device1(iface);
1821 HRESULT ret;
1822 IDirect3D7 *ret_ptr;
1824 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, Direct3D);
1825 ret = IDirect3DDevice7_GetDirect3D((IDirect3DDevice7 *)This, &ret_ptr);
1826 if(ret != D3D_OK)
1827 return ret;
1828 *Direct3D = ret_ptr ? (IDirect3D *)&ddraw_from_d3d7(ret_ptr)->IDirect3D_vtbl : NULL;
1829 TRACE(" returning interface %p\n", *Direct3D);
1830 return D3D_OK;
1833 /*****************************************************************************
1834 * IDirect3DDevice3::SetCurrentViewport
1836 * Sets a Direct3DViewport as the current viewport.
1837 * For the thunks note that all viewport interface versions are equal
1839 * Params:
1840 * Direct3DViewport3: The viewport to set
1842 * Version 2 and 3
1844 * Returns:
1845 * D3D_OK on success
1846 * (Is a NULL viewport valid?)
1848 *****************************************************************************/
1849 static HRESULT WINAPI
1850 IDirect3DDeviceImpl_3_SetCurrentViewport(IDirect3DDevice3 *iface,
1851 IDirect3DViewport3 *Direct3DViewport3)
1853 IDirect3DDeviceImpl *This = device_from_device3(iface);
1854 IDirect3DViewportImpl *vp = (IDirect3DViewportImpl *)Direct3DViewport3;
1855 TRACE("(%p)->(%p)\n", This, Direct3DViewport3);
1857 EnterCriticalSection(&ddraw_cs);
1858 /* Do nothing if the specified viewport is the same as the current one */
1859 if (This->current_viewport == vp )
1861 LeaveCriticalSection(&ddraw_cs);
1862 return D3D_OK;
1865 /* Should check if the viewport was added or not */
1867 /* Release previous viewport and AddRef the new one */
1868 if (This->current_viewport)
1870 TRACE("ViewportImpl is at %p, interface is at %p\n", This->current_viewport,
1871 (IDirect3DViewport3 *)This->current_viewport);
1872 IDirect3DViewport3_Release((IDirect3DViewport3 *)This->current_viewport);
1874 IDirect3DViewport3_AddRef(Direct3DViewport3);
1876 /* Set this viewport as the current viewport */
1877 This->current_viewport = vp;
1879 /* Activate this viewport */
1880 This->current_viewport->active_device = This;
1881 This->current_viewport->activate(This->current_viewport, FALSE);
1883 LeaveCriticalSection(&ddraw_cs);
1884 return D3D_OK;
1887 static HRESULT WINAPI
1888 Thunk_IDirect3DDeviceImpl_2_SetCurrentViewport(IDirect3DDevice2 *iface,
1889 IDirect3DViewport2 *Direct3DViewport2)
1891 IDirect3DDeviceImpl *This = device_from_device2(iface);
1892 IDirect3DViewportImpl *vp = (IDirect3DViewportImpl *)Direct3DViewport2;
1893 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, vp);
1894 return IDirect3DDevice3_SetCurrentViewport((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl,
1895 (IDirect3DViewport3 *)vp);
1898 /*****************************************************************************
1899 * IDirect3DDevice3::GetCurrentViewport
1901 * Returns the currently active viewport.
1903 * Version 2 and 3
1905 * Params:
1906 * Direct3DViewport3: Address to return the interface pointer at
1908 * Returns:
1909 * D3D_OK on success
1910 * DDERR_INVALIDPARAMS if Direct3DViewport == NULL
1912 *****************************************************************************/
1913 static HRESULT WINAPI
1914 IDirect3DDeviceImpl_3_GetCurrentViewport(IDirect3DDevice3 *iface,
1915 IDirect3DViewport3 **Direct3DViewport3)
1917 IDirect3DDeviceImpl *This = device_from_device3(iface);
1918 TRACE("(%p)->(%p)\n", This, Direct3DViewport3);
1920 if(!Direct3DViewport3)
1921 return DDERR_INVALIDPARAMS;
1923 EnterCriticalSection(&ddraw_cs);
1924 *Direct3DViewport3 = (IDirect3DViewport3 *)This->current_viewport;
1926 /* AddRef the returned viewport */
1927 if(*Direct3DViewport3) IDirect3DViewport3_AddRef(*Direct3DViewport3);
1929 TRACE(" returning interface %p\n", *Direct3DViewport3);
1931 LeaveCriticalSection(&ddraw_cs);
1932 return D3D_OK;
1935 static HRESULT WINAPI
1936 Thunk_IDirect3DDeviceImpl_2_GetCurrentViewport(IDirect3DDevice2 *iface,
1937 IDirect3DViewport2 **Direct3DViewport2)
1939 IDirect3DDeviceImpl *This = device_from_device2(iface);
1940 HRESULT hr;
1941 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, Direct3DViewport2);
1942 hr = IDirect3DDevice3_GetCurrentViewport((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl,
1943 (IDirect3DViewport3 **)Direct3DViewport2);
1944 if(hr != D3D_OK) return hr;
1945 return D3D_OK;
1948 /*****************************************************************************
1949 * IDirect3DDevice7::SetRenderTarget
1951 * Sets the render target for the Direct3DDevice.
1952 * For the thunks note that IDirectDrawSurface7 == IDirectDrawSurface4 and
1953 * IDirectDrawSurface3 == IDirectDrawSurface
1955 * Version 2, 3 and 7
1957 * Params:
1958 * NewTarget: Pointer to an IDirectDrawSurface7 interface to set as the new
1959 * render target
1960 * Flags: Some flags
1962 * Returns:
1963 * D3D_OK on success, for details see IWineD3DDevice::SetRenderTarget
1965 *****************************************************************************/
1966 static HRESULT
1967 IDirect3DDeviceImpl_7_SetRenderTarget(IDirect3DDevice7 *iface,
1968 IDirectDrawSurface7 *NewTarget,
1969 DWORD Flags)
1971 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
1972 IDirectDrawSurfaceImpl *Target = (IDirectDrawSurfaceImpl *)NewTarget;
1973 HRESULT hr;
1974 TRACE("(%p)->(%p,%08x): Relay\n", This, NewTarget, Flags);
1976 EnterCriticalSection(&ddraw_cs);
1977 /* Flags: Not used */
1979 if(This->target == Target)
1981 TRACE("No-op SetRenderTarget operation, not doing anything\n");
1982 LeaveCriticalSection(&ddraw_cs);
1983 return D3D_OK;
1986 hr = IWineD3DDevice_SetRenderTarget(This->wineD3DDevice,
1988 Target ? Target->WineD3DSurface : NULL,
1989 FALSE);
1990 if(hr != D3D_OK)
1992 LeaveCriticalSection(&ddraw_cs);
1993 return hr;
1995 IDirectDrawSurface7_AddRef(NewTarget);
1996 IDirectDrawSurface7_Release((IDirectDrawSurface7 *)This->target);
1997 This->target = Target;
1998 IDirect3DDeviceImpl_UpdateDepthStencil(This);
1999 LeaveCriticalSection(&ddraw_cs);
2000 return D3D_OK;
2003 static HRESULT WINAPI
2004 IDirect3DDeviceImpl_7_SetRenderTarget_FPUSetup(IDirect3DDevice7 *iface,
2005 IDirectDrawSurface7 *NewTarget,
2006 DWORD Flags)
2008 return IDirect3DDeviceImpl_7_SetRenderTarget(iface, NewTarget, Flags);
2011 static HRESULT WINAPI
2012 IDirect3DDeviceImpl_7_SetRenderTarget_FPUPreserve(IDirect3DDevice7 *iface,
2013 IDirectDrawSurface7 *NewTarget,
2014 DWORD Flags)
2016 HRESULT hr;
2017 WORD old_fpucw;
2019 old_fpucw = d3d_fpu_setup();
2020 hr = IDirect3DDeviceImpl_7_SetRenderTarget(iface, NewTarget, Flags);
2021 set_fpu_control_word(old_fpucw);
2023 return hr;
2026 static HRESULT WINAPI
2027 Thunk_IDirect3DDeviceImpl_3_SetRenderTarget(IDirect3DDevice3 *iface,
2028 IDirectDrawSurface4 *NewRenderTarget,
2029 DWORD Flags)
2031 IDirect3DDeviceImpl *This = device_from_device3(iface);
2032 IDirectDrawSurfaceImpl *Target = (IDirectDrawSurfaceImpl *)NewRenderTarget;
2033 TRACE_(ddraw_thunk)("(%p)->(%p,%08x) thunking to IDirect3DDevice7 interface.\n", This, Target, Flags);
2034 return IDirect3DDevice7_SetRenderTarget((IDirect3DDevice7 *)This, (IDirectDrawSurface7 *)Target, Flags);
2037 static HRESULT WINAPI
2038 Thunk_IDirect3DDeviceImpl_2_SetRenderTarget(IDirect3DDevice2 *iface,
2039 IDirectDrawSurface *NewRenderTarget,
2040 DWORD Flags)
2042 IDirect3DDeviceImpl *This = device_from_device2(iface);
2043 IDirectDrawSurfaceImpl *Target = (IDirectDrawSurfaceImpl *)NewRenderTarget;
2044 TRACE_(ddraw_thunk)("(%p)->(%p,%08x) thunking to IDirect3DDevice7 interface.\n", This, Target, Flags);
2045 return IDirect3DDevice7_SetRenderTarget((IDirect3DDevice7 *)This, (IDirectDrawSurface7 *)Target, Flags);
2048 /*****************************************************************************
2049 * IDirect3DDevice7::GetRenderTarget
2051 * Returns the current render target.
2052 * This is handled locally, because the WineD3D render target's parent
2053 * is an IParent
2055 * Version 2, 3 and 7
2057 * Params:
2058 * RenderTarget: Address to store the surface interface pointer
2060 * Returns:
2061 * D3D_OK on success
2062 * DDERR_INVALIDPARAMS if RenderTarget == NULL
2064 *****************************************************************************/
2065 static HRESULT WINAPI
2066 IDirect3DDeviceImpl_7_GetRenderTarget(IDirect3DDevice7 *iface,
2067 IDirectDrawSurface7 **RenderTarget)
2069 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
2070 TRACE("(%p)->(%p): Relay\n", This, RenderTarget);
2072 if(!RenderTarget)
2073 return DDERR_INVALIDPARAMS;
2075 EnterCriticalSection(&ddraw_cs);
2076 *RenderTarget = (IDirectDrawSurface7 *)This->target;
2077 IDirectDrawSurface7_AddRef(*RenderTarget);
2079 LeaveCriticalSection(&ddraw_cs);
2080 return D3D_OK;
2083 static HRESULT WINAPI
2084 Thunk_IDirect3DDeviceImpl_3_GetRenderTarget(IDirect3DDevice3 *iface,
2085 IDirectDrawSurface4 **RenderTarget)
2087 IDirect3DDeviceImpl *This = device_from_device3(iface);
2088 HRESULT hr;
2089 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, RenderTarget);
2090 hr = IDirect3DDevice7_GetRenderTarget((IDirect3DDevice7 *)This, (IDirectDrawSurface7 **)RenderTarget);
2091 if(hr != D3D_OK) return hr;
2092 return D3D_OK;
2095 static HRESULT WINAPI
2096 Thunk_IDirect3DDeviceImpl_2_GetRenderTarget(IDirect3DDevice2 *iface,
2097 IDirectDrawSurface **RenderTarget)
2099 IDirect3DDeviceImpl *This = device_from_device2(iface);
2100 HRESULT hr;
2101 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, RenderTarget);
2102 hr = IDirect3DDevice7_GetRenderTarget((IDirect3DDevice7 *)This, (IDirectDrawSurface7 **)RenderTarget);
2103 if(hr != D3D_OK) return hr;
2104 *RenderTarget = *RenderTarget ?
2105 (IDirectDrawSurface *)&((IDirectDrawSurfaceImpl *)*RenderTarget)->IDirectDrawSurface3_vtbl : NULL;
2106 return D3D_OK;
2109 /*****************************************************************************
2110 * IDirect3DDevice3::Begin
2112 * Begins a description block of vertices. This is similar to glBegin()
2113 * and glEnd(). After a call to IDirect3DDevice3::End, the vertices
2114 * described with IDirect3DDevice::Vertex are drawn.
2116 * Version 2 and 3
2118 * Params:
2119 * PrimitiveType: The type of primitives to draw
2120 * VertexTypeDesc: A flexible vertex format description of the vertices
2121 * Flags: Some flags..
2123 * Returns:
2124 * D3D_OK on success
2126 *****************************************************************************/
2127 static HRESULT WINAPI
2128 IDirect3DDeviceImpl_3_Begin(IDirect3DDevice3 *iface,
2129 D3DPRIMITIVETYPE PrimitiveType,
2130 DWORD VertexTypeDesc,
2131 DWORD Flags)
2133 IDirect3DDeviceImpl *This = device_from_device3(iface);
2134 TRACE("(%p)->(%d,%d,%08x)\n", This, PrimitiveType, VertexTypeDesc, Flags);
2136 EnterCriticalSection(&ddraw_cs);
2137 This->primitive_type = PrimitiveType;
2138 This->vertex_type = VertexTypeDesc;
2139 This->render_flags = Flags;
2140 This->vertex_size = get_flexible_vertex_size(This->vertex_type);
2141 This->nb_vertices = 0;
2142 LeaveCriticalSection(&ddraw_cs);
2144 return D3D_OK;
2147 static HRESULT WINAPI
2148 Thunk_IDirect3DDeviceImpl_2_Begin(IDirect3DDevice2 *iface,
2149 D3DPRIMITIVETYPE d3dpt,
2150 D3DVERTEXTYPE dwVertexTypeDesc,
2151 DWORD dwFlags)
2153 DWORD FVF;
2154 IDirect3DDeviceImpl *This = device_from_device2(iface);
2155 TRACE_(ddraw_thunk)("(%p/%p)->(%08x,%08x,%08x): Thunking to IDirect3DDevice3\n", This, iface, d3dpt, dwVertexTypeDesc, dwFlags);
2157 switch(dwVertexTypeDesc)
2159 case D3DVT_VERTEX: FVF = D3DFVF_VERTEX; break;
2160 case D3DVT_LVERTEX: FVF = D3DFVF_LVERTEX; break;
2161 case D3DVT_TLVERTEX: FVF = D3DFVF_TLVERTEX; break;
2162 default:
2163 ERR("Unexpected vertex type %d\n", dwVertexTypeDesc);
2164 return DDERR_INVALIDPARAMS; /* Should never happen */
2167 return IDirect3DDevice3_Begin((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl, d3dpt, FVF, dwFlags);
2170 /*****************************************************************************
2171 * IDirect3DDevice3::BeginIndexed
2173 * Draws primitives based on vertices in a vertex array which are specified
2174 * by indices.
2176 * Version 2 and 3
2178 * Params:
2179 * PrimitiveType: Primitive type to draw
2180 * VertexType: A FVF description of the vertex format
2181 * Vertices: pointer to an array containing the vertices
2182 * NumVertices: The number of vertices in the vertex array
2183 * Flags: Some flags ...
2185 * Returns:
2186 * D3D_OK, because it's a stub
2188 *****************************************************************************/
2189 static HRESULT WINAPI
2190 IDirect3DDeviceImpl_3_BeginIndexed(IDirect3DDevice3 *iface,
2191 D3DPRIMITIVETYPE PrimitiveType,
2192 DWORD VertexType,
2193 void *Vertices,
2194 DWORD NumVertices,
2195 DWORD Flags)
2197 IDirect3DDeviceImpl *This = device_from_device3(iface);
2198 FIXME("(%p)->(%08x,%08x,%p,%08x,%08x): stub!\n", This, PrimitiveType, VertexType, Vertices, NumVertices, Flags);
2199 return D3D_OK;
2203 static HRESULT WINAPI
2204 Thunk_IDirect3DDeviceImpl_2_BeginIndexed(IDirect3DDevice2 *iface,
2205 D3DPRIMITIVETYPE d3dptPrimitiveType,
2206 D3DVERTEXTYPE d3dvtVertexType,
2207 void *lpvVertices,
2208 DWORD dwNumVertices,
2209 DWORD dwFlags)
2211 DWORD FVF;
2212 IDirect3DDeviceImpl *This = device_from_device2(iface);
2213 TRACE_(ddraw_thunk)("(%p/%p)->(%08x,%08x,%p,%08x,%08x): Thunking to IDirect3DDevice3\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwNumVertices, dwFlags);
2215 switch(d3dvtVertexType)
2217 case D3DVT_VERTEX: FVF = D3DFVF_VERTEX; break;
2218 case D3DVT_LVERTEX: FVF = D3DFVF_LVERTEX; break;
2219 case D3DVT_TLVERTEX: FVF = D3DFVF_TLVERTEX; break;
2220 default:
2221 ERR("Unexpected vertex type %d\n", d3dvtVertexType);
2222 return DDERR_INVALIDPARAMS; /* Should never happen */
2225 return IDirect3DDevice3_BeginIndexed((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl,
2226 d3dptPrimitiveType, FVF, lpvVertices, dwNumVertices, dwFlags);
2229 /*****************************************************************************
2230 * IDirect3DDevice3::Vertex
2232 * Draws a vertex as described by IDirect3DDevice3::Begin. It places all
2233 * drawn vertices in a vertex buffer. If the buffer is too small, its
2234 * size is increased.
2236 * Version 2 and 3
2238 * Params:
2239 * Vertex: Pointer to the vertex
2241 * Returns:
2242 * D3D_OK, on success
2243 * DDERR_INVALIDPARAMS if Vertex is NULL
2245 *****************************************************************************/
2246 static HRESULT WINAPI
2247 IDirect3DDeviceImpl_3_Vertex(IDirect3DDevice3 *iface,
2248 void *Vertex)
2250 IDirect3DDeviceImpl *This = device_from_device3(iface);
2251 TRACE("(%p)->(%p)\n", This, Vertex);
2253 if(!Vertex)
2254 return DDERR_INVALIDPARAMS;
2256 EnterCriticalSection(&ddraw_cs);
2257 if ((This->nb_vertices+1)*This->vertex_size > This->buffer_size)
2259 BYTE *old_buffer;
2260 This->buffer_size = This->buffer_size ? This->buffer_size * 2 : This->vertex_size * 3;
2261 old_buffer = This->vertex_buffer;
2262 This->vertex_buffer = HeapAlloc(GetProcessHeap(), 0, This->buffer_size);
2263 if (old_buffer)
2265 CopyMemory(This->vertex_buffer, old_buffer, This->nb_vertices * This->vertex_size);
2266 HeapFree(GetProcessHeap(), 0, old_buffer);
2270 CopyMemory(This->vertex_buffer + This->nb_vertices++ * This->vertex_size, Vertex, This->vertex_size);
2272 LeaveCriticalSection(&ddraw_cs);
2273 return D3D_OK;
2276 static HRESULT WINAPI
2277 Thunk_IDirect3DDeviceImpl_2_Vertex(IDirect3DDevice2 *iface,
2278 void *lpVertexType)
2280 IDirect3DDeviceImpl *This = device_from_device2(iface);
2281 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice3 interface.\n", This, lpVertexType);
2282 return IDirect3DDevice3_Vertex((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl, lpVertexType);
2285 /*****************************************************************************
2286 * IDirect3DDevice3::Index
2288 * Specifies an index to a vertex to be drawn. The vertex array has to
2289 * be specified with BeginIndexed first.
2291 * Parameters:
2292 * VertexIndex: The index of the vertex to draw
2294 * Returns:
2295 * D3D_OK because it's a stub
2297 *****************************************************************************/
2298 static HRESULT WINAPI
2299 IDirect3DDeviceImpl_3_Index(IDirect3DDevice3 *iface,
2300 WORD VertexIndex)
2302 IDirect3DDeviceImpl *This = device_from_device3(iface);
2303 FIXME("(%p)->(%04x): stub!\n", This, VertexIndex);
2304 return D3D_OK;
2307 static HRESULT WINAPI
2308 Thunk_IDirect3DDeviceImpl_2_Index(IDirect3DDevice2 *iface,
2309 WORD wVertexIndex)
2311 IDirect3DDeviceImpl *This = device_from_device2(iface);
2312 TRACE_(ddraw_thunk)("(%p)->(%04x) thunking to IDirect3DDevice3 interface.\n", This, wVertexIndex);
2313 return IDirect3DDevice3_Index((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl, wVertexIndex);
2316 /*****************************************************************************
2317 * IDirect3DDevice3::End
2319 * Ends a draw begun with IDirect3DDevice3::Begin or
2320 * IDirect3DDevice::BeginIndexed. The vertices specified with
2321 * IDirect3DDevice::Vertex or IDirect3DDevice::Index are drawn using
2322 * the IDirect3DDevice7::DrawPrimitive method. So far only
2323 * non-indexed mode is supported
2325 * Version 2 and 3
2327 * Params:
2328 * Flags: Some flags, as usual. Don't know which are defined
2330 * Returns:
2331 * The return value of IDirect3DDevice7::DrawPrimitive
2333 *****************************************************************************/
2334 static HRESULT WINAPI
2335 IDirect3DDeviceImpl_3_End(IDirect3DDevice3 *iface,
2336 DWORD Flags)
2338 IDirect3DDeviceImpl *This = device_from_device3(iface);
2339 TRACE("(%p)->(%08x)\n", This, Flags);
2341 return IDirect3DDevice7_DrawPrimitive((IDirect3DDevice7 *)This, This->primitive_type,
2342 This->vertex_type, This->vertex_buffer, This->nb_vertices, This->render_flags);
2345 static HRESULT WINAPI
2346 Thunk_IDirect3DDeviceImpl_2_End(IDirect3DDevice2 *iface,
2347 DWORD dwFlags)
2349 IDirect3DDeviceImpl *This = device_from_device2(iface);
2350 TRACE_(ddraw_thunk)("(%p)->(%08x) thunking to IDirect3DDevice3 interface.\n", This, dwFlags);
2351 return IDirect3DDevice3_End((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl, dwFlags);
2354 /*****************************************************************************
2355 * IDirect3DDevice7::GetRenderState
2357 * Returns the value of a render state. The possible render states are
2358 * defined in include/d3dtypes.h
2360 * Version 2, 3 and 7
2362 * Params:
2363 * RenderStateType: Render state to return the current setting of
2364 * Value: Address to store the value at
2366 * Returns:
2367 * D3D_OK on success, for details see IWineD3DDevice::GetRenderState
2368 * DDERR_INVALIDPARAMS if Value == NULL
2370 *****************************************************************************/
2371 static HRESULT
2372 IDirect3DDeviceImpl_7_GetRenderState(IDirect3DDevice7 *iface,
2373 D3DRENDERSTATETYPE RenderStateType,
2374 DWORD *Value)
2376 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
2377 HRESULT hr;
2378 TRACE("(%p)->(%08x,%p): Relay\n", This, RenderStateType, Value);
2380 if(!Value)
2381 return DDERR_INVALIDPARAMS;
2383 EnterCriticalSection(&ddraw_cs);
2384 switch(RenderStateType)
2386 case D3DRENDERSTATE_TEXTUREMAG:
2388 WINED3DTEXTUREFILTERTYPE tex_mag;
2390 hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice,
2391 0, WINED3DSAMP_MAGFILTER,
2392 &tex_mag);
2394 switch (tex_mag)
2396 case WINED3DTEXF_POINT:
2397 *Value = D3DFILTER_NEAREST;
2398 break;
2399 case WINED3DTEXF_LINEAR:
2400 *Value = D3DFILTER_LINEAR;
2401 break;
2402 default:
2403 ERR("Unhandled texture mag %d !\n",tex_mag);
2404 *Value = 0;
2406 break;
2409 case D3DRENDERSTATE_TEXTUREMIN:
2411 WINED3DTEXTUREFILTERTYPE tex_min;
2413 hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice,
2414 0, WINED3DSAMP_MINFILTER,
2415 &tex_min);
2417 switch (tex_min)
2419 case WINED3DTEXF_POINT:
2420 *Value = D3DFILTER_NEAREST;
2421 break;
2422 case WINED3DTEXF_LINEAR:
2423 *Value = D3DFILTER_LINEAR;
2424 break;
2425 default:
2426 ERR("Unhandled texture mag %d !\n",tex_min);
2427 *Value = 0;
2429 break;
2432 case D3DRENDERSTATE_TEXTUREADDRESS:
2433 case D3DRENDERSTATE_TEXTUREADDRESSU:
2434 hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice,
2435 0, WINED3DSAMP_ADDRESSU,
2436 Value);
2437 break;
2438 case D3DRENDERSTATE_TEXTUREADDRESSV:
2439 hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice,
2440 0, WINED3DSAMP_ADDRESSV,
2441 Value);
2442 break;
2444 default:
2445 /* FIXME: Unhandled: D3DRENDERSTATE_STIPPLEPATTERN00 - 31 */
2446 hr = IWineD3DDevice_GetRenderState(This->wineD3DDevice,
2447 RenderStateType,
2448 Value);
2450 LeaveCriticalSection(&ddraw_cs);
2451 return hr;
2454 static HRESULT WINAPI
2455 IDirect3DDeviceImpl_7_GetRenderState_FPUSetup(IDirect3DDevice7 *iface,
2456 D3DRENDERSTATETYPE RenderStateType,
2457 DWORD *Value)
2459 return IDirect3DDeviceImpl_7_GetRenderState(iface, RenderStateType, Value);
2462 static HRESULT WINAPI
2463 IDirect3DDeviceImpl_7_GetRenderState_FPUPreserve(IDirect3DDevice7 *iface,
2464 D3DRENDERSTATETYPE RenderStateType,
2465 DWORD *Value)
2467 HRESULT hr;
2468 WORD old_fpucw;
2470 old_fpucw = d3d_fpu_setup();
2471 hr = IDirect3DDeviceImpl_7_GetRenderState(iface, RenderStateType, Value);
2472 set_fpu_control_word(old_fpucw);
2474 return hr;
2477 static HRESULT WINAPI
2478 IDirect3DDeviceImpl_3_GetRenderState(IDirect3DDevice3 *iface,
2479 D3DRENDERSTATETYPE dwRenderStateType,
2480 DWORD *lpdwRenderState)
2482 IDirect3DDeviceImpl *This = device_from_device3(iface);
2483 HRESULT hr;
2484 TRACE("(%p)->(%08x,%p)\n", This, dwRenderStateType, lpdwRenderState);
2486 switch(dwRenderStateType)
2488 case D3DRENDERSTATE_TEXTUREHANDLE:
2490 /* This state is wrapped to SetTexture in SetRenderState, so
2491 * it has to be wrapped to GetTexture here
2493 IWineD3DBaseTexture *tex = NULL;
2494 *lpdwRenderState = 0;
2496 EnterCriticalSection(&ddraw_cs);
2498 hr = IWineD3DDevice_GetTexture(This->wineD3DDevice,
2500 &tex);
2502 if(hr == WINED3D_OK && tex)
2504 IDirectDrawSurface7 *parent = NULL;
2505 hr = IWineD3DBaseTexture_GetParent(tex,
2506 (IUnknown **) &parent);
2507 if(parent)
2509 /* The parent of the texture is the IDirectDrawSurface7 interface
2510 * of the ddraw surface
2512 IDirectDrawSurfaceImpl *texImpl = (IDirectDrawSurfaceImpl *)parent;
2513 *lpdwRenderState = texImpl->Handle;
2514 IDirectDrawSurface7_Release(parent);
2516 IWineD3DBaseTexture_Release(tex);
2519 LeaveCriticalSection(&ddraw_cs);
2521 return hr;
2524 case D3DRENDERSTATE_TEXTUREMAPBLEND:
2526 /* D3DRENDERSTATE_TEXTUREMAPBLEND is mapped to texture state stages in SetRenderState; reverse
2527 the mapping to get the value. */
2528 DWORD colorop, colorarg1, colorarg2;
2529 DWORD alphaop, alphaarg1, alphaarg2;
2531 EnterCriticalSection(&ddraw_cs);
2533 This->legacyTextureBlending = TRUE;
2535 IWineD3DDevice_GetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLOROP, &colorop);
2536 IWineD3DDevice_GetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG1, &colorarg1);
2537 IWineD3DDevice_GetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG2, &colorarg2);
2538 IWineD3DDevice_GetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAOP, &alphaop);
2539 IWineD3DDevice_GetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG1, &alphaarg1);
2540 IWineD3DDevice_GetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG2, &alphaarg2);
2542 if (colorop == WINED3DTOP_SELECTARG1 && colorarg1 == WINED3DTA_TEXTURE &&
2543 alphaop == WINED3DTOP_SELECTARG1 && alphaarg1 == WINED3DTA_TEXTURE)
2545 *lpdwRenderState = D3DTBLEND_DECAL;
2547 else if (colorop == WINED3DTOP_SELECTARG1 && colorarg1 == WINED3DTA_TEXTURE &&
2548 alphaop == WINED3DTOP_MODULATE && alphaarg1 == WINED3DTA_TEXTURE && alphaarg2 == WINED3DTA_CURRENT)
2550 *lpdwRenderState = D3DTBLEND_DECALALPHA;
2552 else if (colorop == WINED3DTOP_MODULATE && colorarg1 == WINED3DTA_TEXTURE && colorarg2 == WINED3DTA_CURRENT &&
2553 alphaop == WINED3DTOP_MODULATE && alphaarg1 == WINED3DTA_TEXTURE && alphaarg2 == WINED3DTA_CURRENT)
2555 *lpdwRenderState = D3DTBLEND_MODULATEALPHA;
2557 else
2559 HRESULT hr;
2560 BOOL tex_alpha = FALSE;
2561 IWineD3DBaseTexture *tex = NULL;
2562 WINED3DSURFACE_DESC desc;
2563 DDPIXELFORMAT ddfmt;
2565 hr = IWineD3DDevice_GetTexture(This->wineD3DDevice,
2567 &tex);
2569 if(hr == WINED3D_OK && tex)
2571 hr = IWineD3DTexture_GetLevelDesc((IWineD3DTexture*) tex, 0, &desc);
2572 if (SUCCEEDED(hr))
2574 ddfmt.dwSize = sizeof(ddfmt);
2575 PixelFormat_WineD3DtoDD(&ddfmt, desc.format);
2576 if (ddfmt.u5.dwRGBAlphaBitMask) tex_alpha = TRUE;
2579 IWineD3DBaseTexture_Release(tex);
2582 if (!(colorop == WINED3DTOP_MODULATE && colorarg1 == WINED3DTA_TEXTURE && colorarg2 == WINED3DTA_CURRENT &&
2583 alphaop == (tex_alpha ? WINED3DTOP_SELECTARG1 : WINED3DTOP_SELECTARG2) &&
2584 alphaarg1 == WINED3DTA_TEXTURE && alphaarg2 == WINED3DTA_CURRENT))
2586 ERR("Unexpected texture stage state setup, returning D3DTBLEND_MODULATE - likely erroneous\n");
2589 *lpdwRenderState = D3DTBLEND_MODULATE;
2592 LeaveCriticalSection(&ddraw_cs);
2594 return D3D_OK;
2597 default:
2598 return IDirect3DDevice7_GetRenderState((IDirect3DDevice7 *)This, dwRenderStateType, lpdwRenderState);
2602 static HRESULT WINAPI
2603 Thunk_IDirect3DDeviceImpl_2_GetRenderState(IDirect3DDevice2 *iface,
2604 D3DRENDERSTATETYPE dwRenderStateType,
2605 DWORD *lpdwRenderState)
2607 IDirect3DDeviceImpl *This = device_from_device2(iface);
2608 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice3 interface.\n", This, dwRenderStateType, lpdwRenderState);
2609 return IDirect3DDevice3_GetRenderState((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl,
2610 dwRenderStateType, lpdwRenderState);
2613 /*****************************************************************************
2614 * IDirect3DDevice7::SetRenderState
2616 * Sets a render state. The possible render states are defined in
2617 * include/d3dtypes.h
2619 * Version 2, 3 and 7
2621 * Params:
2622 * RenderStateType: State to set
2623 * Value: Value to assign to that state
2625 * Returns:
2626 * D3D_OK on success,
2627 * for details see IWineD3DDevice::SetRenderState
2629 *****************************************************************************/
2630 static HRESULT
2631 IDirect3DDeviceImpl_7_SetRenderState(IDirect3DDevice7 *iface,
2632 D3DRENDERSTATETYPE RenderStateType,
2633 DWORD Value)
2635 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
2636 HRESULT hr;
2637 TRACE("(%p)->(%08x,%d): Relay\n", This, RenderStateType, Value);
2639 EnterCriticalSection(&ddraw_cs);
2640 /* Some render states need special care */
2641 switch(RenderStateType)
2643 case D3DRENDERSTATE_TEXTUREMAG:
2645 WINED3DTEXTUREFILTERTYPE tex_mag = WINED3DTEXF_POINT;
2647 switch ((D3DTEXTUREFILTER) Value)
2649 case D3DFILTER_NEAREST:
2650 case D3DFILTER_LINEARMIPNEAREST:
2651 tex_mag = WINED3DTEXF_POINT;
2652 break;
2653 case D3DFILTER_LINEAR:
2654 case D3DFILTER_LINEARMIPLINEAR:
2655 tex_mag = WINED3DTEXF_LINEAR;
2656 break;
2657 default:
2658 ERR("Unhandled texture mag %d !\n",Value);
2661 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
2662 0, WINED3DSAMP_MAGFILTER,
2663 tex_mag);
2664 break;
2667 case D3DRENDERSTATE_TEXTUREMIN:
2669 WINED3DTEXTUREFILTERTYPE tex_min = WINED3DTEXF_POINT;
2670 WINED3DTEXTUREFILTERTYPE tex_mip = WINED3DTEXF_NONE;
2672 switch ((D3DTEXTUREFILTER) Value)
2674 case D3DFILTER_NEAREST:
2675 tex_min = WINED3DTEXF_POINT;
2676 break;
2677 case D3DFILTER_LINEAR:
2678 tex_min = WINED3DTEXF_LINEAR;
2679 break;
2680 case D3DFILTER_MIPNEAREST:
2681 tex_min = WINED3DTEXF_POINT;
2682 tex_mip = WINED3DTEXF_POINT;
2683 break;
2684 case D3DFILTER_MIPLINEAR:
2685 tex_min = WINED3DTEXF_POINT;
2686 tex_mip = WINED3DTEXF_LINEAR;
2687 break;
2688 case D3DFILTER_LINEARMIPNEAREST:
2689 tex_min = WINED3DTEXF_POINT;
2690 tex_mip = WINED3DTEXF_LINEAR;
2691 break;
2692 case D3DFILTER_LINEARMIPLINEAR:
2693 tex_min = WINED3DTEXF_LINEAR;
2694 tex_mip = WINED3DTEXF_LINEAR;
2695 break;
2697 default:
2698 ERR("Unhandled texture min %d !\n",Value);
2701 IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
2702 0, WINED3DSAMP_MIPFILTER,
2703 tex_mip);
2704 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
2705 0, WINED3DSAMP_MINFILTER,
2706 tex_min);
2707 break;
2710 case D3DRENDERSTATE_TEXTUREADDRESS:
2711 IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
2712 0, WINED3DSAMP_ADDRESSV,
2713 Value);
2714 /* Drop through */
2715 case D3DRENDERSTATE_TEXTUREADDRESSU:
2716 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
2717 0, WINED3DSAMP_ADDRESSU,
2718 Value);
2719 break;
2720 case D3DRENDERSTATE_TEXTUREADDRESSV:
2721 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice,
2722 0, WINED3DSAMP_ADDRESSV,
2723 Value);
2724 break;
2726 default:
2728 /* FIXME: Unhandled: D3DRENDERSTATE_STIPPLEPATTERN00 - 31 */
2730 hr = IWineD3DDevice_SetRenderState(This->wineD3DDevice,
2731 RenderStateType,
2732 Value);
2733 break;
2735 LeaveCriticalSection(&ddraw_cs);
2736 return hr;
2739 static HRESULT WINAPI
2740 IDirect3DDeviceImpl_7_SetRenderState_FPUSetup(IDirect3DDevice7 *iface,
2741 D3DRENDERSTATETYPE RenderStateType,
2742 DWORD Value)
2744 return IDirect3DDeviceImpl_7_SetRenderState(iface, RenderStateType, Value);
2747 static HRESULT WINAPI
2748 IDirect3DDeviceImpl_7_SetRenderState_FPUPreserve(IDirect3DDevice7 *iface,
2749 D3DRENDERSTATETYPE RenderStateType,
2750 DWORD Value)
2752 HRESULT hr;
2753 WORD old_fpucw;
2755 old_fpucw = d3d_fpu_setup();
2756 hr = IDirect3DDeviceImpl_7_SetRenderState(iface, RenderStateType, Value);
2757 set_fpu_control_word(old_fpucw);
2759 return hr;
2762 static HRESULT WINAPI
2763 IDirect3DDeviceImpl_3_SetRenderState(IDirect3DDevice3 *iface,
2764 D3DRENDERSTATETYPE RenderStateType,
2765 DWORD Value)
2767 /* Note about D3DRENDERSTATE_TEXTUREMAPBLEND implementation: most of values
2768 for this state can be directly mapped to texture stage colorop and alphaop, but
2769 D3DTBLEND_MODULATE is tricky: it uses alpha from texture when available and alpha
2770 from diffuse otherwise. So changing the texture must be monitored in SetTexture to modify
2771 alphaarg when needed.
2773 Aliens vs Predator 1 depends on accurate D3DTBLEND_MODULATE emulation
2775 Legacy texture blending (TEXTUREMAPBLEND) and texture stage states: directx6 docs state that
2776 TEXTUREMAPBLEND is deprecated, yet can still be used. Games must not use both or results
2777 are undefined. D3DTBLEND_MODULATE mode in particular is dependent on texture pixel format and
2778 requires fixup of stage 0 texture states when texture changes, but this fixup can interfere
2779 with games not using this deprecated state. So a flag 'legacyTextureBlending' has to be kept
2780 in device - TRUE if the app is using TEXTUREMAPBLEND.
2782 Tests show that setting TEXTUREMAPBLEND on native doesn't seem to change values returned by
2783 GetTextureStageState and vice versa. Not so on Wine, but it is 'undefined' anyway so, probably, ok,
2784 unless some broken game will be found that cares. */
2786 HRESULT hr;
2787 IDirect3DDeviceImpl *This = device_from_device3(iface);
2788 TRACE("(%p)->(%08x,%d)\n", This, RenderStateType, Value);
2790 EnterCriticalSection(&ddraw_cs);
2792 switch(RenderStateType)
2794 case D3DRENDERSTATE_TEXTUREHANDLE:
2796 if(Value == 0)
2798 hr = IWineD3DDevice_SetTexture(This->wineD3DDevice,
2800 NULL);
2801 break;
2804 if(Value > This->numHandles)
2806 FIXME("Specified handle %d out of range\n", Value);
2807 hr = DDERR_INVALIDPARAMS;
2808 break;
2810 if(This->Handles[Value - 1].type != DDrawHandle_Texture)
2812 FIXME("Handle %d isn't a texture handle\n", Value);
2813 hr = DDERR_INVALIDPARAMS;
2814 break;
2816 else
2818 IDirectDrawSurfaceImpl *surf = This->Handles[Value - 1].ptr;
2819 IDirect3DTexture2 *tex = surf ? (IDirect3DTexture2 *)&surf->IDirect3DTexture2_vtbl : NULL;
2820 hr = IDirect3DDevice3_SetTexture(iface, 0, tex);
2821 break;
2825 case D3DRENDERSTATE_TEXTUREMAPBLEND:
2827 This->legacyTextureBlending = TRUE;
2829 switch ( (D3DTEXTUREBLEND) Value)
2831 case D3DTBLEND_MODULATE:
2833 BOOL tex_alpha = FALSE;
2834 IWineD3DBaseTexture *tex = NULL;
2835 WINED3DSURFACE_DESC desc;
2836 DDPIXELFORMAT ddfmt;
2838 hr = IWineD3DDevice_GetTexture(This->wineD3DDevice,
2840 &tex);
2842 if(hr == WINED3D_OK && tex)
2844 memset(&desc, 0, sizeof(desc));
2845 hr = IWineD3DTexture_GetLevelDesc((IWineD3DTexture*) tex, 0, &desc);
2846 if (SUCCEEDED(hr))
2848 ddfmt.dwSize = sizeof(ddfmt);
2849 PixelFormat_WineD3DtoDD(&ddfmt, desc.format);
2850 if (ddfmt.u5.dwRGBAlphaBitMask) tex_alpha = TRUE;
2853 IWineD3DBaseTexture_Release(tex);
2856 if (tex_alpha)
2857 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAOP, WINED3DTOP_SELECTARG1);
2858 else
2859 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAOP, WINED3DTOP_SELECTARG2);
2860 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG1, WINED3DTA_TEXTURE);
2861 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG2, WINED3DTA_CURRENT);
2862 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG1, WINED3DTA_TEXTURE);
2863 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG2, WINED3DTA_CURRENT);
2864 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLOROP, WINED3DTOP_MODULATE);
2866 break;
2869 case D3DTBLEND_ADD:
2870 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLOROP, WINED3DTOP_ADD);
2871 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG1, WINED3DTA_TEXTURE);
2872 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG2, WINED3DTA_CURRENT);
2873 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAOP, WINED3DTOP_SELECTARG2);
2874 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG2, WINED3DTA_CURRENT);
2875 break;
2877 case D3DTBLEND_MODULATEALPHA:
2878 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG1, WINED3DTA_TEXTURE);
2879 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG1, WINED3DTA_TEXTURE);
2880 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG2, WINED3DTA_CURRENT);
2881 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG2, WINED3DTA_CURRENT);
2882 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLOROP, WINED3DTOP_MODULATE);
2883 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAOP, WINED3DTOP_MODULATE);
2884 break;
2886 case D3DTBLEND_COPY:
2887 case D3DTBLEND_DECAL:
2888 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG1, WINED3DTA_TEXTURE);
2889 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG1, WINED3DTA_TEXTURE);
2890 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLOROP, WINED3DTOP_SELECTARG1);
2891 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAOP, WINED3DTOP_SELECTARG1);
2892 break;
2894 case D3DTBLEND_DECALALPHA:
2895 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLOROP, WINED3DTOP_BLENDTEXTUREALPHA);
2896 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG1, WINED3DTA_TEXTURE);
2897 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_COLORARG2, WINED3DTA_CURRENT);
2898 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAOP, WINED3DTOP_SELECTARG2);
2899 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAARG2, WINED3DTA_CURRENT);
2900 break;
2902 default:
2903 ERR("Unhandled texture environment %d !\n",Value);
2906 hr = D3D_OK;
2907 break;
2910 default:
2911 hr = IDirect3DDevice7_SetRenderState((IDirect3DDevice7 *)This, RenderStateType, Value);
2912 break;
2915 LeaveCriticalSection(&ddraw_cs);
2917 return hr;
2920 static HRESULT WINAPI
2921 Thunk_IDirect3DDeviceImpl_2_SetRenderState(IDirect3DDevice2 *iface,
2922 D3DRENDERSTATETYPE RenderStateType,
2923 DWORD Value)
2925 IDirect3DDeviceImpl *This = device_from_device2(iface);
2926 TRACE_(ddraw_thunk)("(%p)->(%08x,%d) thunking to IDirect3DDevice3 interface.\n", This, RenderStateType, Value);
2927 return IDirect3DDevice3_SetRenderState((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl, RenderStateType, Value);
2930 /*****************************************************************************
2931 * Direct3DDevice3::SetLightState
2933 * Sets a light state for Direct3DDevice3 and Direct3DDevice2. The
2934 * light states are forwarded to Direct3DDevice7 render states
2936 * Version 2 and 3
2938 * Params:
2939 * LightStateType: The light state to change
2940 * Value: The value to assign to that light state
2942 * Returns:
2943 * D3D_OK on success
2944 * DDERR_INVALIDPARAMS if the parameters were incorrect
2945 * Also check IDirect3DDevice7::SetRenderState
2947 *****************************************************************************/
2948 static HRESULT WINAPI
2949 IDirect3DDeviceImpl_3_SetLightState(IDirect3DDevice3 *iface,
2950 D3DLIGHTSTATETYPE LightStateType,
2951 DWORD Value)
2953 IDirect3DDeviceImpl *This = device_from_device3(iface);
2954 HRESULT hr;
2956 TRACE("(%p)->(%08x,%08x)\n", This, LightStateType, Value);
2958 if (!LightStateType || (LightStateType > D3DLIGHTSTATE_COLORVERTEX))
2960 TRACE("Unexpected Light State Type\n");
2961 return DDERR_INVALIDPARAMS;
2964 EnterCriticalSection(&ddraw_cs);
2965 if (LightStateType == D3DLIGHTSTATE_MATERIAL /* 1 */)
2967 IDirect3DMaterialImpl *mat;
2969 if(Value == 0) mat = NULL;
2970 else if(Value > This->numHandles)
2972 ERR("Material handle out of range(%d)\n", Value);
2973 LeaveCriticalSection(&ddraw_cs);
2974 return DDERR_INVALIDPARAMS;
2976 else if(This->Handles[Value - 1].type != DDrawHandle_Material)
2978 ERR("Invalid handle %d\n", Value);
2979 LeaveCriticalSection(&ddraw_cs);
2980 return DDERR_INVALIDPARAMS;
2982 else
2984 mat = This->Handles[Value - 1].ptr;
2987 if (mat != NULL)
2989 TRACE(" activating material %p.\n", mat);
2990 mat->activate(mat);
2992 else
2994 FIXME(" D3DLIGHTSTATE_MATERIAL called with NULL material !!!\n");
2996 This->material = Value;
2998 else if (LightStateType == D3DLIGHTSTATE_COLORMODEL /* 3 */)
3000 switch (Value)
3002 case D3DCOLOR_MONO:
3003 ERR("DDCOLOR_MONO should not happen!\n");
3004 break;
3005 case D3DCOLOR_RGB:
3006 /* We are already in this mode */
3007 TRACE("Setting color model to RGB (no-op).\n");
3008 break;
3009 default:
3010 ERR("Unknown color model!\n");
3011 LeaveCriticalSection(&ddraw_cs);
3012 return DDERR_INVALIDPARAMS;
3015 else
3017 D3DRENDERSTATETYPE rs;
3018 switch (LightStateType)
3020 case D3DLIGHTSTATE_AMBIENT: /* 2 */
3021 rs = D3DRENDERSTATE_AMBIENT;
3022 break;
3023 case D3DLIGHTSTATE_FOGMODE: /* 4 */
3024 rs = D3DRENDERSTATE_FOGVERTEXMODE;
3025 break;
3026 case D3DLIGHTSTATE_FOGSTART: /* 5 */
3027 rs = D3DRENDERSTATE_FOGSTART;
3028 break;
3029 case D3DLIGHTSTATE_FOGEND: /* 6 */
3030 rs = D3DRENDERSTATE_FOGEND;
3031 break;
3032 case D3DLIGHTSTATE_FOGDENSITY: /* 7 */
3033 rs = D3DRENDERSTATE_FOGDENSITY;
3034 break;
3035 case D3DLIGHTSTATE_COLORVERTEX: /* 8 */
3036 rs = D3DRENDERSTATE_COLORVERTEX;
3037 break;
3038 default:
3039 ERR("Unknown D3DLIGHTSTATETYPE %d.\n", LightStateType);
3040 LeaveCriticalSection(&ddraw_cs);
3041 return DDERR_INVALIDPARAMS;
3044 hr = IDirect3DDevice7_SetRenderState((IDirect3DDevice7 *)This, rs, Value);
3045 LeaveCriticalSection(&ddraw_cs);
3046 return hr;
3049 LeaveCriticalSection(&ddraw_cs);
3050 return D3D_OK;
3053 static HRESULT WINAPI
3054 Thunk_IDirect3DDeviceImpl_2_SetLightState(IDirect3DDevice2 *iface,
3055 D3DLIGHTSTATETYPE LightStateType,
3056 DWORD Value)
3058 IDirect3DDeviceImpl *This = device_from_device2(iface);
3059 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x) thunking to IDirect3DDevice3 interface.\n", This, LightStateType, Value);
3060 return IDirect3DDevice3_SetLightState((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl, LightStateType, Value);
3063 /*****************************************************************************
3064 * IDirect3DDevice3::GetLightState
3066 * Returns the current setting of a light state. The state is read from
3067 * the Direct3DDevice7 render state.
3069 * Version 2 and 3
3071 * Params:
3072 * LightStateType: The light state to return
3073 * Value: The address to store the light state setting at
3075 * Returns:
3076 * D3D_OK on success
3077 * DDDERR_INVALIDPARAMS if the parameters were incorrect
3078 * Also see IDirect3DDevice7::GetRenderState
3080 *****************************************************************************/
3081 static HRESULT WINAPI
3082 IDirect3DDeviceImpl_3_GetLightState(IDirect3DDevice3 *iface,
3083 D3DLIGHTSTATETYPE LightStateType,
3084 DWORD *Value)
3086 IDirect3DDeviceImpl *This = device_from_device3(iface);
3087 HRESULT hr;
3089 TRACE("(%p)->(%08x,%p)\n", This, LightStateType, Value);
3091 if (!LightStateType || (LightStateType > D3DLIGHTSTATE_COLORVERTEX))
3093 TRACE("Unexpected Light State Type\n");
3094 return DDERR_INVALIDPARAMS;
3097 if(!Value)
3098 return DDERR_INVALIDPARAMS;
3100 EnterCriticalSection(&ddraw_cs);
3101 if (LightStateType == D3DLIGHTSTATE_MATERIAL /* 1 */)
3103 *Value = This->material;
3105 else if (LightStateType == D3DLIGHTSTATE_COLORMODEL /* 3 */)
3107 *Value = D3DCOLOR_RGB;
3109 else
3111 D3DRENDERSTATETYPE rs;
3112 switch (LightStateType)
3114 case D3DLIGHTSTATE_AMBIENT: /* 2 */
3115 rs = D3DRENDERSTATE_AMBIENT;
3116 break;
3117 case D3DLIGHTSTATE_FOGMODE: /* 4 */
3118 rs = D3DRENDERSTATE_FOGVERTEXMODE;
3119 break;
3120 case D3DLIGHTSTATE_FOGSTART: /* 5 */
3121 rs = D3DRENDERSTATE_FOGSTART;
3122 break;
3123 case D3DLIGHTSTATE_FOGEND: /* 6 */
3124 rs = D3DRENDERSTATE_FOGEND;
3125 break;
3126 case D3DLIGHTSTATE_FOGDENSITY: /* 7 */
3127 rs = D3DRENDERSTATE_FOGDENSITY;
3128 break;
3129 case D3DLIGHTSTATE_COLORVERTEX: /* 8 */
3130 rs = D3DRENDERSTATE_COLORVERTEX;
3131 break;
3132 default:
3133 ERR("Unknown D3DLIGHTSTATETYPE %d.\n", LightStateType);
3134 LeaveCriticalSection(&ddraw_cs);
3135 return DDERR_INVALIDPARAMS;
3138 hr = IDirect3DDevice7_GetRenderState((IDirect3DDevice7 *)This, rs, Value);
3139 LeaveCriticalSection(&ddraw_cs);
3140 return hr;
3143 LeaveCriticalSection(&ddraw_cs);
3144 return D3D_OK;
3147 static HRESULT WINAPI
3148 Thunk_IDirect3DDeviceImpl_2_GetLightState(IDirect3DDevice2 *iface,
3149 D3DLIGHTSTATETYPE LightStateType,
3150 DWORD *Value)
3152 IDirect3DDeviceImpl *This = device_from_device2(iface);
3153 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice3 interface.\n", This, LightStateType, Value);
3154 return IDirect3DDevice3_GetLightState((IDirect3DDevice3 *)&This->IDirect3DDevice3_vtbl, LightStateType, Value);
3157 /*****************************************************************************
3158 * IDirect3DDevice7::SetTransform
3160 * Assigns a D3DMATRIX to a transform type. The transform types are defined
3161 * in include/d3dtypes.h.
3162 * The D3DTRANSFORMSTATE_WORLD (=1) is translated to D3DTS_WORLDMATRIX(0)
3163 * (=255) for wined3d, because the 1 transform state was removed in d3d8
3164 * and WineD3D already understands the replacement D3DTS_WORLDMATRIX(0)
3166 * Version 2, 3 and 7
3168 * Params:
3169 * TransformStateType: transform state to set
3170 * Matrix: Matrix to assign to the state
3172 * Returns:
3173 * D3D_OK on success
3174 * DDERR_INVALIDPARAMS if Matrix == NULL
3175 * For details see IWineD3DDevice::SetTransform
3177 *****************************************************************************/
3178 static HRESULT
3179 IDirect3DDeviceImpl_7_SetTransform(IDirect3DDevice7 *iface,
3180 D3DTRANSFORMSTATETYPE TransformStateType,
3181 D3DMATRIX *Matrix)
3183 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
3184 D3DTRANSFORMSTATETYPE type;
3185 HRESULT hr;
3186 TRACE("(%p)->(%08x,%p): Relay\n", This, TransformStateType, Matrix);
3188 switch(TransformStateType)
3190 case D3DTRANSFORMSTATE_WORLD : type = WINED3DTS_WORLDMATRIX(0); break;
3191 case D3DTRANSFORMSTATE_WORLD1: type = WINED3DTS_WORLDMATRIX(1); break;
3192 case D3DTRANSFORMSTATE_WORLD2: type = WINED3DTS_WORLDMATRIX(2); break;
3193 case D3DTRANSFORMSTATE_WORLD3: type = WINED3DTS_WORLDMATRIX(3); break;
3194 default: type = TransformStateType;
3197 if(!Matrix)
3198 return DDERR_INVALIDPARAMS;
3200 /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
3201 EnterCriticalSection(&ddraw_cs);
3202 hr = IWineD3DDevice_SetTransform(This->wineD3DDevice,
3203 type,
3204 (WINED3DMATRIX*) Matrix);
3205 LeaveCriticalSection(&ddraw_cs);
3206 return hr;
3209 static HRESULT WINAPI
3210 IDirect3DDeviceImpl_7_SetTransform_FPUSetup(IDirect3DDevice7 *iface,
3211 D3DTRANSFORMSTATETYPE TransformStateType,
3212 D3DMATRIX *Matrix)
3214 return IDirect3DDeviceImpl_7_SetTransform(iface, TransformStateType, Matrix);
3217 static HRESULT WINAPI
3218 IDirect3DDeviceImpl_7_SetTransform_FPUPreserve(IDirect3DDevice7 *iface,
3219 D3DTRANSFORMSTATETYPE TransformStateType,
3220 D3DMATRIX *Matrix)
3222 HRESULT hr;
3223 WORD old_fpucw;
3225 old_fpucw = d3d_fpu_setup();
3226 hr = IDirect3DDeviceImpl_7_SetTransform(iface, TransformStateType, Matrix);
3227 set_fpu_control_word(old_fpucw);
3229 return hr;
3232 static HRESULT WINAPI
3233 Thunk_IDirect3DDeviceImpl_3_SetTransform(IDirect3DDevice3 *iface,
3234 D3DTRANSFORMSTATETYPE TransformStateType,
3235 D3DMATRIX *D3DMatrix)
3237 IDirect3DDeviceImpl *This = device_from_device3(iface);
3238 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, TransformStateType, D3DMatrix);
3239 return IDirect3DDevice7_SetTransform((IDirect3DDevice7 *)This, TransformStateType, D3DMatrix);
3242 static HRESULT WINAPI
3243 Thunk_IDirect3DDeviceImpl_2_SetTransform(IDirect3DDevice2 *iface,
3244 D3DTRANSFORMSTATETYPE TransformStateType,
3245 D3DMATRIX *D3DMatrix)
3247 IDirect3DDeviceImpl *This = device_from_device2(iface);
3248 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, TransformStateType, D3DMatrix);
3249 return IDirect3DDevice7_SetTransform((IDirect3DDevice7 *)This, TransformStateType, D3DMatrix);
3252 /*****************************************************************************
3253 * IDirect3DDevice7::GetTransform
3255 * Returns the matrix assigned to a transform state
3256 * D3DTRANSFORMSTATE_WORLD is translated to D3DTS_WORLDMATRIX(0), see
3257 * SetTransform
3259 * Params:
3260 * TransformStateType: State to read the matrix from
3261 * Matrix: Address to store the matrix at
3263 * Returns:
3264 * D3D_OK on success
3265 * DDERR_INVALIDPARAMS if Matrix == NULL
3266 * For details, see IWineD3DDevice::GetTransform
3268 *****************************************************************************/
3269 static HRESULT
3270 IDirect3DDeviceImpl_7_GetTransform(IDirect3DDevice7 *iface,
3271 D3DTRANSFORMSTATETYPE TransformStateType,
3272 D3DMATRIX *Matrix)
3274 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
3275 D3DTRANSFORMSTATETYPE type;
3276 HRESULT hr;
3277 TRACE("(%p)->(%08x,%p): Relay\n", This, TransformStateType, Matrix);
3279 switch(TransformStateType)
3281 case D3DTRANSFORMSTATE_WORLD : type = WINED3DTS_WORLDMATRIX(0); break;
3282 case D3DTRANSFORMSTATE_WORLD1: type = WINED3DTS_WORLDMATRIX(1); break;
3283 case D3DTRANSFORMSTATE_WORLD2: type = WINED3DTS_WORLDMATRIX(2); break;
3284 case D3DTRANSFORMSTATE_WORLD3: type = WINED3DTS_WORLDMATRIX(3); break;
3285 default: type = TransformStateType;
3288 if(!Matrix)
3289 return DDERR_INVALIDPARAMS;
3291 /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
3292 EnterCriticalSection(&ddraw_cs);
3293 hr = IWineD3DDevice_GetTransform(This->wineD3DDevice, type, (WINED3DMATRIX*) Matrix);
3294 LeaveCriticalSection(&ddraw_cs);
3295 return hr;
3298 static HRESULT WINAPI
3299 IDirect3DDeviceImpl_7_GetTransform_FPUSetup(IDirect3DDevice7 *iface,
3300 D3DTRANSFORMSTATETYPE TransformStateType,
3301 D3DMATRIX *Matrix)
3303 return IDirect3DDeviceImpl_7_GetTransform(iface, TransformStateType, Matrix);
3306 static HRESULT WINAPI
3307 IDirect3DDeviceImpl_7_GetTransform_FPUPreserve(IDirect3DDevice7 *iface,
3308 D3DTRANSFORMSTATETYPE TransformStateType,
3309 D3DMATRIX *Matrix)
3311 HRESULT hr;
3312 WORD old_fpucw;
3314 old_fpucw = d3d_fpu_setup();
3315 hr = IDirect3DDeviceImpl_7_GetTransform(iface, TransformStateType, Matrix);
3316 set_fpu_control_word(old_fpucw);
3318 return hr;
3321 static HRESULT WINAPI
3322 Thunk_IDirect3DDeviceImpl_3_GetTransform(IDirect3DDevice3 *iface,
3323 D3DTRANSFORMSTATETYPE TransformStateType,
3324 D3DMATRIX *D3DMatrix)
3326 IDirect3DDeviceImpl *This = device_from_device3(iface);
3327 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, TransformStateType, D3DMatrix);
3328 return IDirect3DDevice7_GetTransform((IDirect3DDevice7 *)This, TransformStateType, D3DMatrix);
3331 static HRESULT WINAPI
3332 Thunk_IDirect3DDeviceImpl_2_GetTransform(IDirect3DDevice2 *iface,
3333 D3DTRANSFORMSTATETYPE TransformStateType,
3334 D3DMATRIX *D3DMatrix)
3336 IDirect3DDeviceImpl *This = device_from_device2(iface);
3337 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, TransformStateType, D3DMatrix);
3338 return IDirect3DDevice7_GetTransform((IDirect3DDevice7 *)This, TransformStateType, D3DMatrix);
3341 /*****************************************************************************
3342 * IDirect3DDevice7::MultiplyTransform
3344 * Multiplies the already-set transform matrix of a transform state
3345 * with another matrix. For the world matrix, see SetTransform
3347 * Version 2, 3 and 7
3349 * Params:
3350 * TransformStateType: Transform state to multiply
3351 * D3DMatrix Matrix to multiply with.
3353 * Returns
3354 * D3D_OK on success
3355 * DDERR_INVALIDPARAMS if D3DMatrix is NULL
3356 * For details, see IWineD3DDevice::MultiplyTransform
3358 *****************************************************************************/
3359 static HRESULT
3360 IDirect3DDeviceImpl_7_MultiplyTransform(IDirect3DDevice7 *iface,
3361 D3DTRANSFORMSTATETYPE TransformStateType,
3362 D3DMATRIX *D3DMatrix)
3364 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
3365 HRESULT hr;
3366 D3DTRANSFORMSTATETYPE type;
3367 TRACE("(%p)->(%08x,%p): Relay\n", This, TransformStateType, D3DMatrix);
3369 switch(TransformStateType)
3371 case D3DTRANSFORMSTATE_WORLD : type = WINED3DTS_WORLDMATRIX(0); break;
3372 case D3DTRANSFORMSTATE_WORLD1: type = WINED3DTS_WORLDMATRIX(1); break;
3373 case D3DTRANSFORMSTATE_WORLD2: type = WINED3DTS_WORLDMATRIX(2); break;
3374 case D3DTRANSFORMSTATE_WORLD3: type = WINED3DTS_WORLDMATRIX(3); break;
3375 default: type = TransformStateType;
3378 /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
3379 EnterCriticalSection(&ddraw_cs);
3380 hr = IWineD3DDevice_MultiplyTransform(This->wineD3DDevice,
3381 type,
3382 (WINED3DMATRIX*) D3DMatrix);
3383 LeaveCriticalSection(&ddraw_cs);
3384 return hr;
3387 static HRESULT WINAPI
3388 IDirect3DDeviceImpl_7_MultiplyTransform_FPUSetup(IDirect3DDevice7 *iface,
3389 D3DTRANSFORMSTATETYPE TransformStateType,
3390 D3DMATRIX *D3DMatrix)
3392 return IDirect3DDeviceImpl_7_MultiplyTransform(iface, TransformStateType, D3DMatrix);
3395 static HRESULT WINAPI
3396 IDirect3DDeviceImpl_7_MultiplyTransform_FPUPreserve(IDirect3DDevice7 *iface,
3397 D3DTRANSFORMSTATETYPE TransformStateType,
3398 D3DMATRIX *D3DMatrix)
3400 HRESULT hr;
3401 WORD old_fpucw;
3403 old_fpucw = d3d_fpu_setup();
3404 hr = IDirect3DDeviceImpl_7_MultiplyTransform(iface, TransformStateType, D3DMatrix);
3405 set_fpu_control_word(old_fpucw);
3407 return hr;
3410 static HRESULT WINAPI
3411 Thunk_IDirect3DDeviceImpl_3_MultiplyTransform(IDirect3DDevice3 *iface,
3412 D3DTRANSFORMSTATETYPE TransformStateType,
3413 D3DMATRIX *D3DMatrix)
3415 IDirect3DDeviceImpl *This = device_from_device3(iface);
3416 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, TransformStateType, D3DMatrix);
3417 return IDirect3DDevice7_MultiplyTransform((IDirect3DDevice7 *)This, TransformStateType, D3DMatrix);
3420 static HRESULT WINAPI
3421 Thunk_IDirect3DDeviceImpl_2_MultiplyTransform(IDirect3DDevice2 *iface,
3422 D3DTRANSFORMSTATETYPE TransformStateType,
3423 D3DMATRIX *D3DMatrix)
3425 IDirect3DDeviceImpl *This = device_from_device2(iface);
3426 TRACE_(ddraw_thunk)("(%p)->(%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, TransformStateType, D3DMatrix);
3427 return IDirect3DDevice7_MultiplyTransform((IDirect3DDevice7 *)This, TransformStateType, D3DMatrix);
3430 /*****************************************************************************
3431 * IDirect3DDevice7::DrawPrimitive
3433 * Draws primitives based on vertices in an application-provided pointer
3435 * Version 2, 3 and 7. The IDirect3DDevice2 thunk converts the fixed vertex type into
3436 * an FVF format for D3D7
3438 * Params:
3439 * PrimitiveType: The type of the primitives to draw
3440 * Vertex type: Flexible vertex format vertex description
3441 * Vertices: Pointer to the vertex array
3442 * VertexCount: The number of vertices to draw
3443 * Flags: As usual a few flags
3445 * Returns:
3446 * D3D_OK on success
3447 * DDERR_INVALIDPARAMS if Vertices is NULL
3448 * For details, see IWineD3DDevice::DrawPrimitiveUP
3450 *****************************************************************************/
3451 static HRESULT
3452 IDirect3DDeviceImpl_7_DrawPrimitive(IDirect3DDevice7 *iface,
3453 D3DPRIMITIVETYPE PrimitiveType,
3454 DWORD VertexType,
3455 void *Vertices,
3456 DWORD VertexCount,
3457 DWORD Flags)
3459 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
3460 UINT stride;
3461 HRESULT hr;
3462 TRACE("(%p)->(%08x,%08x,%p,%08x,%08x): Relay!\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Flags);
3464 if(!Vertices)
3465 return DDERR_INVALIDPARAMS;
3467 /* Get the stride */
3468 stride = get_flexible_vertex_size(VertexType);
3470 /* Set the FVF */
3471 EnterCriticalSection(&ddraw_cs);
3472 hr = IWineD3DDevice_SetVertexDeclaration(This->wineD3DDevice,
3473 IDirectDrawImpl_FindDecl(This->ddraw, VertexType));
3474 if(hr != D3D_OK)
3476 LeaveCriticalSection(&ddraw_cs);
3477 return hr;
3480 /* This method translates to the user pointer draw of WineD3D */
3481 IWineD3DDevice_SetPrimitiveType(This->wineD3DDevice, PrimitiveType);
3482 hr = IWineD3DDevice_DrawPrimitiveUP(This->wineD3DDevice, VertexCount, Vertices, stride);
3483 LeaveCriticalSection(&ddraw_cs);
3484 return hr;
3487 static HRESULT WINAPI
3488 IDirect3DDeviceImpl_7_DrawPrimitive_FPUSetup(IDirect3DDevice7 *iface,
3489 D3DPRIMITIVETYPE PrimitiveType,
3490 DWORD VertexType,
3491 void *Vertices,
3492 DWORD VertexCount,
3493 DWORD Flags)
3495 return IDirect3DDeviceImpl_7_DrawPrimitive(iface, PrimitiveType, VertexType, Vertices, VertexCount, Flags);
3498 static HRESULT WINAPI
3499 IDirect3DDeviceImpl_7_DrawPrimitive_FPUPreserve(IDirect3DDevice7 *iface,
3500 D3DPRIMITIVETYPE PrimitiveType,
3501 DWORD VertexType,
3502 void *Vertices,
3503 DWORD VertexCount,
3504 DWORD Flags)
3506 HRESULT hr;
3507 WORD old_fpucw;
3509 old_fpucw = d3d_fpu_setup();
3510 hr = IDirect3DDeviceImpl_7_DrawPrimitive(iface, PrimitiveType, VertexType, Vertices, VertexCount, Flags);
3511 set_fpu_control_word(old_fpucw);
3513 return hr;
3516 static HRESULT WINAPI
3517 Thunk_IDirect3DDeviceImpl_3_DrawPrimitive(IDirect3DDevice3 *iface,
3518 D3DPRIMITIVETYPE PrimitiveType,
3519 DWORD VertexType,
3520 void *Vertices,
3521 DWORD VertexCount,
3522 DWORD Flags)
3524 IDirect3DDeviceImpl *This = device_from_device3(iface);
3525 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Flags);
3526 return IDirect3DDevice7_DrawPrimitive((IDirect3DDevice7 *)This,
3527 PrimitiveType, VertexType, Vertices, VertexCount, Flags);
3530 static HRESULT WINAPI
3531 Thunk_IDirect3DDeviceImpl_2_DrawPrimitive(IDirect3DDevice2 *iface,
3532 D3DPRIMITIVETYPE PrimitiveType,
3533 D3DVERTEXTYPE VertexType,
3534 void *Vertices,
3535 DWORD VertexCount,
3536 DWORD Flags)
3538 IDirect3DDeviceImpl *This = device_from_device2(iface);
3539 DWORD FVF;
3540 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Flags);
3542 switch(VertexType)
3544 case D3DVT_VERTEX: FVF = D3DFVF_VERTEX; break;
3545 case D3DVT_LVERTEX: FVF = D3DFVF_LVERTEX; break;
3546 case D3DVT_TLVERTEX: FVF = D3DFVF_TLVERTEX; break;
3547 default:
3548 ERR("Unexpected vertex type %d\n", VertexType);
3549 return DDERR_INVALIDPARAMS; /* Should never happen */
3552 return IDirect3DDevice7_DrawPrimitive((IDirect3DDevice7 *)This, PrimitiveType, FVF, Vertices, VertexCount, Flags);
3555 /*****************************************************************************
3556 * IDirect3DDevice7::DrawIndexedPrimitive
3558 * Draws vertices from an application-provided pointer, based on the index
3559 * numbers in a WORD array.
3561 * Version 2, 3 and 7. The version 7 thunk translates the vertex type into
3562 * an FVF format for D3D7
3564 * Params:
3565 * PrimitiveType: The primitive type to draw
3566 * VertexType: The FVF vertex description
3567 * Vertices: Pointer to the vertex array
3568 * VertexCount: ?
3569 * Indices: Pointer to the index array
3570 * IndexCount: Number of indices = Number of vertices to draw
3571 * Flags: As usual, some flags
3573 * Returns:
3574 * D3D_OK on success
3575 * DDERR_INVALIDPARAMS if Vertices or Indices is NULL
3576 * For details, see IWineD3DDevice::DrawIndexedPrimitiveUP
3578 *****************************************************************************/
3579 static HRESULT
3580 IDirect3DDeviceImpl_7_DrawIndexedPrimitive(IDirect3DDevice7 *iface,
3581 D3DPRIMITIVETYPE PrimitiveType,
3582 DWORD VertexType,
3583 void *Vertices,
3584 DWORD VertexCount,
3585 WORD *Indices,
3586 DWORD IndexCount,
3587 DWORD Flags)
3589 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
3590 HRESULT hr;
3591 TRACE("(%p)->(%08x,%08x,%p,%08x,%p,%08x,%08x): Relay!\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Indices, IndexCount, Flags);
3593 /* Set the D3DDevice's FVF */
3594 EnterCriticalSection(&ddraw_cs);
3595 hr = IWineD3DDevice_SetVertexDeclaration(This->wineD3DDevice,
3596 IDirectDrawImpl_FindDecl(This->ddraw, VertexType));
3597 if(FAILED(hr))
3599 ERR(" (%p) Setting the FVF failed, hr = %x!\n", This, hr);
3600 LeaveCriticalSection(&ddraw_cs);
3601 return hr;
3604 IWineD3DDevice_SetPrimitiveType(This->wineD3DDevice, PrimitiveType);
3605 hr = IWineD3DDevice_DrawIndexedPrimitiveUP(This->wineD3DDevice, IndexCount, Indices,
3606 WINED3DFMT_R16_UINT, Vertices, get_flexible_vertex_size(VertexType));
3607 LeaveCriticalSection(&ddraw_cs);
3608 return hr;
3611 static HRESULT WINAPI
3612 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUSetup(IDirect3DDevice7 *iface,
3613 D3DPRIMITIVETYPE PrimitiveType,
3614 DWORD VertexType,
3615 void *Vertices,
3616 DWORD VertexCount,
3617 WORD *Indices,
3618 DWORD IndexCount,
3619 DWORD Flags)
3621 return IDirect3DDeviceImpl_7_DrawIndexedPrimitive(iface, PrimitiveType, VertexType, Vertices, VertexCount, Indices, IndexCount, Flags);
3624 static HRESULT WINAPI
3625 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUPreserve(IDirect3DDevice7 *iface,
3626 D3DPRIMITIVETYPE PrimitiveType,
3627 DWORD VertexType,
3628 void *Vertices,
3629 DWORD VertexCount,
3630 WORD *Indices,
3631 DWORD IndexCount,
3632 DWORD Flags)
3634 HRESULT hr;
3635 WORD old_fpucw;
3637 old_fpucw = d3d_fpu_setup();
3638 hr = IDirect3DDeviceImpl_7_DrawIndexedPrimitive(iface, PrimitiveType, VertexType, Vertices, VertexCount, Indices, IndexCount, Flags);
3639 set_fpu_control_word(old_fpucw);
3641 return hr;
3644 static HRESULT WINAPI
3645 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitive(IDirect3DDevice3 *iface,
3646 D3DPRIMITIVETYPE PrimitiveType,
3647 DWORD VertexType,
3648 void *Vertices,
3649 DWORD VertexCount,
3650 WORD *Indices,
3651 DWORD IndexCount,
3652 DWORD Flags)
3654 IDirect3DDeviceImpl *This = device_from_device3(iface);
3655 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Indices, IndexCount, Flags);
3656 return IDirect3DDevice7_DrawIndexedPrimitive((IDirect3DDevice7 *)This,
3657 PrimitiveType, VertexType, Vertices, VertexCount, Indices, IndexCount, Flags);
3660 static HRESULT WINAPI
3661 Thunk_IDirect3DDeviceImpl_2_DrawIndexedPrimitive(IDirect3DDevice2 *iface,
3662 D3DPRIMITIVETYPE PrimitiveType,
3663 D3DVERTEXTYPE VertexType,
3664 void *Vertices,
3665 DWORD VertexCount,
3666 WORD *Indices,
3667 DWORD IndexCount,
3668 DWORD Flags)
3670 DWORD FVF;
3671 IDirect3DDeviceImpl *This = device_from_device2(iface);
3672 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, VertexType, Vertices, VertexCount, Indices, IndexCount, Flags);
3674 switch(VertexType)
3676 case D3DVT_VERTEX: FVF = D3DFVF_VERTEX; break;
3677 case D3DVT_LVERTEX: FVF = D3DFVF_LVERTEX; break;
3678 case D3DVT_TLVERTEX: FVF = D3DFVF_TLVERTEX; break;
3679 default:
3680 ERR("Unexpected vertex type %d\n", VertexType);
3681 return DDERR_INVALIDPARAMS; /* Should never happen */
3684 return IDirect3DDevice7_DrawIndexedPrimitive((IDirect3DDevice7 *)This,
3685 PrimitiveType, FVF, Vertices, VertexCount, Indices, IndexCount, Flags);
3688 /*****************************************************************************
3689 * IDirect3DDevice7::SetClipStatus
3691 * Sets the clip status. This defines things as clipping conditions and
3692 * the extents of the clipping region.
3694 * Version 2, 3 and 7
3696 * Params:
3697 * ClipStatus:
3699 * Returns:
3700 * D3D_OK because it's a stub
3701 * (DDERR_INVALIDPARAMS if ClipStatus == NULL)
3703 *****************************************************************************/
3704 static HRESULT WINAPI
3705 IDirect3DDeviceImpl_7_SetClipStatus(IDirect3DDevice7 *iface,
3706 D3DCLIPSTATUS *ClipStatus)
3708 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
3709 FIXME("(%p)->(%p): Stub!\n", This, ClipStatus);
3711 /* D3DCLIPSTATUS and WINED3DCLIPSTATUS are different. I don't know how to convert them
3712 * Perhaps this needs a new data type and an additional IWineD3DDevice method
3714 /* return IWineD3DDevice_SetClipStatus(This->wineD3DDevice, ClipStatus);*/
3715 return D3D_OK;
3718 static HRESULT WINAPI
3719 Thunk_IDirect3DDeviceImpl_3_SetClipStatus(IDirect3DDevice3 *iface,
3720 D3DCLIPSTATUS *ClipStatus)
3722 IDirect3DDeviceImpl *This = device_from_device3(iface);
3723 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, ClipStatus);
3724 return IDirect3DDevice7_SetClipStatus((IDirect3DDevice7 *)This, ClipStatus);
3727 static HRESULT WINAPI
3728 Thunk_IDirect3DDeviceImpl_2_SetClipStatus(IDirect3DDevice2 *iface,
3729 D3DCLIPSTATUS *ClipStatus)
3731 IDirect3DDeviceImpl *This = device_from_device2(iface);
3732 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, ClipStatus);
3733 return IDirect3DDevice7_SetClipStatus((IDirect3DDevice7 *)This, ClipStatus);
3736 /*****************************************************************************
3737 * IDirect3DDevice7::GetClipStatus
3739 * Returns the clip status
3741 * Params:
3742 * ClipStatus: Address to write the clip status to
3744 * Returns:
3745 * D3D_OK because it's a stub
3747 *****************************************************************************/
3748 static HRESULT WINAPI
3749 IDirect3DDeviceImpl_7_GetClipStatus(IDirect3DDevice7 *iface,
3750 D3DCLIPSTATUS *ClipStatus)
3752 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
3753 FIXME("(%p)->(%p): Stub!\n", This, ClipStatus);
3755 /* D3DCLIPSTATUS and WINED3DCLIPSTATUS are different. I don't know how to convert them */
3756 /* return IWineD3DDevice_GetClipStatus(This->wineD3DDevice, ClipStatus);*/
3757 return D3D_OK;
3760 static HRESULT WINAPI
3761 Thunk_IDirect3DDeviceImpl_3_GetClipStatus(IDirect3DDevice3 *iface,
3762 D3DCLIPSTATUS *ClipStatus)
3764 IDirect3DDeviceImpl *This = device_from_device3(iface);
3765 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, ClipStatus);
3766 return IDirect3DDevice7_GetClipStatus((IDirect3DDevice7 *)This, ClipStatus);
3769 static HRESULT WINAPI
3770 Thunk_IDirect3DDeviceImpl_2_GetClipStatus(IDirect3DDevice2 *iface,
3771 D3DCLIPSTATUS *ClipStatus)
3773 IDirect3DDeviceImpl *This = device_from_device2(iface);
3774 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, ClipStatus);
3775 return IDirect3DDevice7_GetClipStatus((IDirect3DDevice7 *)This, ClipStatus);
3778 /*****************************************************************************
3779 * IDirect3DDevice::DrawPrimitiveStrided
3781 * Draws vertices described by a D3DDRAWPRIMITIVESTRIDEDDATA structure.
3783 * Version 3 and 7
3785 * Params:
3786 * PrimitiveType: The primitive type to draw
3787 * VertexType: The FVF description of the vertices to draw (for the stride??)
3788 * D3DDrawPrimStrideData: A D3DDRAWPRIMITIVESTRIDEDDATA structure describing
3789 * the vertex data locations
3790 * VertexCount: The number of vertices to draw
3791 * Flags: Some flags
3793 * Returns:
3794 * D3D_OK, because it's a stub
3795 * (DDERR_INVALIDPARAMS if D3DDrawPrimStrideData is NULL)
3796 * (For details, see IWineD3DDevice::DrawPrimitiveStrided)
3798 *****************************************************************************/
3799 static HRESULT
3800 IDirect3DDeviceImpl_7_DrawPrimitiveStrided(IDirect3DDevice7 *iface,
3801 D3DPRIMITIVETYPE PrimitiveType,
3802 DWORD VertexType,
3803 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
3804 DWORD VertexCount,
3805 DWORD Flags)
3807 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
3808 WineDirect3DVertexStridedData WineD3DStrided;
3809 DWORD i;
3810 HRESULT hr;
3812 TRACE("(%p)->(%08x,%08x,%p,%08x,%08x): stub!\n", This, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Flags);
3814 memset(&WineD3DStrided, 0, sizeof(WineD3DStrided));
3815 /* Get the strided data right. the wined3d structure is a bit bigger
3816 * Watch out: The contents of the strided data are determined by the fvf,
3817 * not by the members set in D3DDrawPrimStrideData. So it's valid
3818 * to have diffuse.lpvData set to 0xdeadbeef if the diffuse flag is
3819 * not set in the fvf.
3821 if(VertexType & D3DFVF_POSITION_MASK)
3823 WineD3DStrided.position.format = WINED3DFMT_R32G32B32_FLOAT;
3824 WineD3DStrided.position.lpData = D3DDrawPrimStrideData->position.lpvData;
3825 WineD3DStrided.position.dwStride = D3DDrawPrimStrideData->position.dwStride;
3826 if (VertexType & D3DFVF_XYZRHW)
3828 WineD3DStrided.position.format = WINED3DFMT_R32G32B32A32_FLOAT;
3829 WineD3DStrided.position_transformed = TRUE;
3830 } else
3831 WineD3DStrided.position_transformed = FALSE;
3834 if(VertexType & D3DFVF_NORMAL)
3836 WineD3DStrided.normal.format = WINED3DFMT_R32G32B32_FLOAT;
3837 WineD3DStrided.normal.lpData = D3DDrawPrimStrideData->normal.lpvData;
3838 WineD3DStrided.normal.dwStride = D3DDrawPrimStrideData->normal.dwStride;
3841 if(VertexType & D3DFVF_DIFFUSE)
3843 WineD3DStrided.diffuse.format = WINED3DFMT_B8G8R8A8_UNORM;
3844 WineD3DStrided.diffuse.lpData = D3DDrawPrimStrideData->diffuse.lpvData;
3845 WineD3DStrided.diffuse.dwStride = D3DDrawPrimStrideData->diffuse.dwStride;
3848 if(VertexType & D3DFVF_SPECULAR)
3850 WineD3DStrided.specular.format = WINED3DFMT_B8G8R8A8_UNORM;
3851 WineD3DStrided.specular.lpData = D3DDrawPrimStrideData->specular.lpvData;
3852 WineD3DStrided.specular.dwStride = D3DDrawPrimStrideData->specular.dwStride;
3855 for( i = 0; i < GET_TEXCOUNT_FROM_FVF(VertexType); i++)
3857 switch(GET_TEXCOORD_SIZE_FROM_FVF(VertexType, i))
3859 case 1: WineD3DStrided.texCoords[i].format = WINED3DFMT_R32_FLOAT; break;
3860 case 2: WineD3DStrided.texCoords[i].format = WINED3DFMT_R32G32_FLOAT; break;
3861 case 3: WineD3DStrided.texCoords[i].format = WINED3DFMT_R32G32B32_FLOAT; break;
3862 case 4: WineD3DStrided.texCoords[i].format = WINED3DFMT_R32G32B32A32_FLOAT; break;
3863 default: ERR("Unexpected texture coordinate size %d\n",
3864 GET_TEXCOORD_SIZE_FROM_FVF(VertexType, i));
3866 WineD3DStrided.texCoords[i].lpData = D3DDrawPrimStrideData->textureCoords[i].lpvData;
3867 WineD3DStrided.texCoords[i].dwStride = D3DDrawPrimStrideData->textureCoords[i].dwStride;
3870 /* WineD3D doesn't need the FVF here */
3871 EnterCriticalSection(&ddraw_cs);
3872 IWineD3DDevice_SetPrimitiveType(This->wineD3DDevice, PrimitiveType);
3873 hr = IWineD3DDevice_DrawPrimitiveStrided(This->wineD3DDevice, VertexCount, &WineD3DStrided);
3874 LeaveCriticalSection(&ddraw_cs);
3875 return hr;
3878 static HRESULT WINAPI
3879 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUSetup(IDirect3DDevice7 *iface,
3880 D3DPRIMITIVETYPE PrimitiveType,
3881 DWORD VertexType,
3882 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
3883 DWORD VertexCount,
3884 DWORD Flags)
3886 return IDirect3DDeviceImpl_7_DrawPrimitiveStrided(iface, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Flags);
3889 static HRESULT WINAPI
3890 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUPreserve(IDirect3DDevice7 *iface,
3891 D3DPRIMITIVETYPE PrimitiveType,
3892 DWORD VertexType,
3893 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
3894 DWORD VertexCount,
3895 DWORD Flags)
3897 HRESULT hr;
3898 WORD old_fpucw;
3900 old_fpucw = d3d_fpu_setup();
3901 hr = IDirect3DDeviceImpl_7_DrawPrimitiveStrided(iface, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Flags);
3902 set_fpu_control_word(old_fpucw);
3904 return hr;
3907 static HRESULT WINAPI
3908 Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveStrided(IDirect3DDevice3 *iface,
3909 D3DPRIMITIVETYPE PrimitiveType,
3910 DWORD VertexType,
3911 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
3912 DWORD VertexCount,
3913 DWORD Flags)
3915 IDirect3DDeviceImpl *This = device_from_device3(iface);
3916 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Flags);
3917 return IDirect3DDevice7_DrawPrimitiveStrided((IDirect3DDevice7 *)This,
3918 PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Flags);
3921 /*****************************************************************************
3922 * IDirect3DDevice7::DrawIndexedPrimitiveStrided
3924 * Draws primitives specified by strided data locations based on indices
3926 * Version 3 and 7
3928 * Params:
3929 * PrimitiveType:
3931 * Returns:
3932 * D3D_OK, because it's a stub
3933 * (DDERR_INVALIDPARAMS if D3DDrawPrimStrideData is NULL)
3934 * (DDERR_INVALIDPARAMS if Indices is NULL)
3935 * (For more details, see IWineD3DDevice::DrawIndexedPrimitiveStrided)
3937 *****************************************************************************/
3938 static HRESULT
3939 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided(IDirect3DDevice7 *iface,
3940 D3DPRIMITIVETYPE PrimitiveType,
3941 DWORD VertexType,
3942 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
3943 DWORD VertexCount,
3944 WORD *Indices,
3945 DWORD IndexCount,
3946 DWORD Flags)
3948 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
3949 WineDirect3DVertexStridedData WineD3DStrided;
3950 DWORD i;
3951 HRESULT hr;
3953 TRACE("(%p)->(%08x,%08x,%p,%08x,%p,%08x,%08x)\n", This, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Indices, IndexCount, Flags);
3955 memset(&WineD3DStrided, 0, sizeof(WineD3DStrided));
3956 /* Get the strided data right. the wined3d structure is a bit bigger
3957 * Watch out: The contents of the strided data are determined by the fvf,
3958 * not by the members set in D3DDrawPrimStrideData. So it's valid
3959 * to have diffuse.lpvData set to 0xdeadbeef if the diffuse flag is
3960 * not set in the fvf.
3962 if(VertexType & D3DFVF_POSITION_MASK)
3964 WineD3DStrided.position.format = WINED3DFMT_R32G32B32_FLOAT;
3965 WineD3DStrided.position.lpData = D3DDrawPrimStrideData->position.lpvData;
3966 WineD3DStrided.position.dwStride = D3DDrawPrimStrideData->position.dwStride;
3967 if (VertexType & D3DFVF_XYZRHW)
3969 WineD3DStrided.position.format = WINED3DFMT_R32G32B32A32_FLOAT;
3970 WineD3DStrided.position_transformed = TRUE;
3971 } else
3972 WineD3DStrided.position_transformed = FALSE;
3975 if(VertexType & D3DFVF_NORMAL)
3977 WineD3DStrided.normal.format = WINED3DFMT_R32G32B32_FLOAT;
3978 WineD3DStrided.normal.lpData = D3DDrawPrimStrideData->normal.lpvData;
3979 WineD3DStrided.normal.dwStride = D3DDrawPrimStrideData->normal.dwStride;
3982 if(VertexType & D3DFVF_DIFFUSE)
3984 WineD3DStrided.diffuse.format = WINED3DFMT_B8G8R8A8_UNORM;
3985 WineD3DStrided.diffuse.lpData = D3DDrawPrimStrideData->diffuse.lpvData;
3986 WineD3DStrided.diffuse.dwStride = D3DDrawPrimStrideData->diffuse.dwStride;
3989 if(VertexType & D3DFVF_SPECULAR)
3991 WineD3DStrided.specular.format = WINED3DFMT_B8G8R8A8_UNORM;
3992 WineD3DStrided.specular.lpData = D3DDrawPrimStrideData->specular.lpvData;
3993 WineD3DStrided.specular.dwStride = D3DDrawPrimStrideData->specular.dwStride;
3996 for( i = 0; i < GET_TEXCOUNT_FROM_FVF(VertexType); i++)
3998 switch(GET_TEXCOORD_SIZE_FROM_FVF(VertexType, i))
4000 case 1: WineD3DStrided.texCoords[i].format = WINED3DFMT_R32_FLOAT; break;
4001 case 2: WineD3DStrided.texCoords[i].format = WINED3DFMT_R32G32_FLOAT; break;
4002 case 3: WineD3DStrided.texCoords[i].format = WINED3DFMT_R32G32B32_FLOAT; break;
4003 case 4: WineD3DStrided.texCoords[i].format = WINED3DFMT_R32G32B32A32_FLOAT; break;
4004 default: ERR("Unexpected texture coordinate size %d\n",
4005 GET_TEXCOORD_SIZE_FROM_FVF(VertexType, i));
4007 WineD3DStrided.texCoords[i].lpData = D3DDrawPrimStrideData->textureCoords[i].lpvData;
4008 WineD3DStrided.texCoords[i].dwStride = D3DDrawPrimStrideData->textureCoords[i].dwStride;
4011 /* WineD3D doesn't need the FVF here */
4012 EnterCriticalSection(&ddraw_cs);
4013 IWineD3DDevice_SetPrimitiveType(This->wineD3DDevice, PrimitiveType);
4014 hr = IWineD3DDevice_DrawIndexedPrimitiveStrided(This->wineD3DDevice,
4015 IndexCount, &WineD3DStrided, VertexCount, Indices, WINED3DFMT_R16_UINT);
4016 LeaveCriticalSection(&ddraw_cs);
4017 return hr;
4020 static HRESULT WINAPI
4021 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUSetup(IDirect3DDevice7 *iface,
4022 D3DPRIMITIVETYPE PrimitiveType,
4023 DWORD VertexType,
4024 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
4025 DWORD VertexCount,
4026 WORD *Indices,
4027 DWORD IndexCount,
4028 DWORD Flags)
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,
4036 DWORD VertexType,
4037 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
4038 DWORD VertexCount,
4039 WORD *Indices,
4040 DWORD IndexCount,
4041 DWORD Flags)
4043 HRESULT hr;
4044 WORD old_fpucw;
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);
4050 return hr;
4053 static HRESULT WINAPI
4054 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveStrided(IDirect3DDevice3 *iface,
4055 D3DPRIMITIVETYPE PrimitiveType,
4056 DWORD VertexType,
4057 D3DDRAWPRIMITIVESTRIDEDDATA *D3DDrawPrimStrideData,
4058 DWORD VertexCount,
4059 WORD *Indices,
4060 DWORD IndexCount,
4061 DWORD Flags)
4063 IDirect3DDeviceImpl *This = device_from_device3(iface);
4064 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p,%08x,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", iface, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Indices, IndexCount, Flags);
4065 return IDirect3DDevice7_DrawIndexedPrimitiveStrided((IDirect3DDevice7 *)This, PrimitiveType,
4066 VertexType, D3DDrawPrimStrideData, VertexCount, Indices, IndexCount, Flags);
4069 /*****************************************************************************
4070 * IDirect3DDevice7::DrawPrimitiveVB
4072 * Draws primitives from a vertex buffer to the screen.
4074 * Version 3 and 7
4076 * Params:
4077 * PrimitiveType: Type of primitive to be rendered.
4078 * D3DVertexBuf: Source Vertex Buffer
4079 * StartVertex: Index of the first vertex from the buffer to be rendered
4080 * NumVertices: Number of vertices to be rendered
4081 * Flags: Can be D3DDP_WAIT to wait until rendering has finished
4083 * Return values
4084 * D3D_OK on success
4085 * DDERR_INVALIDPARAMS if D3DVertexBuf is NULL
4087 *****************************************************************************/
4088 static HRESULT
4089 IDirect3DDeviceImpl_7_DrawPrimitiveVB(IDirect3DDevice7 *iface,
4090 D3DPRIMITIVETYPE PrimitiveType,
4091 IDirect3DVertexBuffer7 *D3DVertexBuf,
4092 DWORD StartVertex,
4093 DWORD NumVertices,
4094 DWORD Flags)
4096 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
4097 IDirect3DVertexBufferImpl *vb = (IDirect3DVertexBufferImpl *)D3DVertexBuf;
4098 HRESULT hr;
4099 DWORD stride;
4101 TRACE("(%p)->(%08x,%p,%08x,%08x,%08x)\n", This, PrimitiveType, D3DVertexBuf, StartVertex, NumVertices, Flags);
4103 /* Sanity checks */
4104 if(!vb)
4106 ERR("(%p) No Vertex buffer specified\n", This);
4107 return DDERR_INVALIDPARAMS;
4109 stride = get_flexible_vertex_size(vb->fvf);
4111 EnterCriticalSection(&ddraw_cs);
4112 hr = IWineD3DDevice_SetVertexDeclaration(This->wineD3DDevice,
4113 vb->wineD3DVertexDeclaration);
4114 if(FAILED(hr))
4116 ERR(" (%p) Setting the FVF failed, hr = %x!\n", This, hr);
4117 LeaveCriticalSection(&ddraw_cs);
4118 return hr;
4121 /* Set the vertex stream source */
4122 hr = IWineD3DDevice_SetStreamSource(This->wineD3DDevice,
4123 0 /* StreamNumber */,
4124 vb->wineD3DVertexBuffer,
4125 0 /* StartVertex - we pass this to DrawPrimitive */,
4126 stride);
4127 if(hr != D3D_OK)
4129 ERR("(%p) IDirect3DDevice::SetStreamSource failed with hr = %08x\n", This, hr);
4130 LeaveCriticalSection(&ddraw_cs);
4131 return hr;
4134 /* Now draw the primitives */
4135 IWineD3DDevice_SetPrimitiveType(This->wineD3DDevice, PrimitiveType);
4136 hr = IWineD3DDevice_DrawPrimitive(This->wineD3DDevice, StartVertex, NumVertices);
4137 LeaveCriticalSection(&ddraw_cs);
4138 return hr;
4141 static HRESULT WINAPI
4142 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUSetup(IDirect3DDevice7 *iface,
4143 D3DPRIMITIVETYPE PrimitiveType,
4144 IDirect3DVertexBuffer7 *D3DVertexBuf,
4145 DWORD StartVertex,
4146 DWORD NumVertices,
4147 DWORD Flags)
4149 return IDirect3DDeviceImpl_7_DrawPrimitiveVB(iface, PrimitiveType, D3DVertexBuf, StartVertex, NumVertices, Flags);
4152 static HRESULT WINAPI
4153 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUPreserve(IDirect3DDevice7 *iface,
4154 D3DPRIMITIVETYPE PrimitiveType,
4155 IDirect3DVertexBuffer7 *D3DVertexBuf,
4156 DWORD StartVertex,
4157 DWORD NumVertices,
4158 DWORD Flags)
4160 HRESULT hr;
4161 WORD old_fpucw;
4163 old_fpucw = d3d_fpu_setup();
4164 hr = IDirect3DDeviceImpl_7_DrawPrimitiveVB(iface, PrimitiveType, D3DVertexBuf, StartVertex, NumVertices, Flags);
4165 set_fpu_control_word(old_fpucw);
4167 return hr;
4170 static HRESULT WINAPI
4171 Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveVB(IDirect3DDevice3 *iface,
4172 D3DPRIMITIVETYPE PrimitiveType,
4173 IDirect3DVertexBuffer *D3DVertexBuf,
4174 DWORD StartVertex,
4175 DWORD NumVertices,
4176 DWORD Flags)
4178 IDirect3DDeviceImpl *This = device_from_device3(iface);
4179 IDirect3DVertexBufferImpl *vb = D3DVertexBuf ? vb_from_vb1(D3DVertexBuf) : NULL;
4180 TRACE_(ddraw_thunk)("(%p)->(%08x,%p,%08x,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, vb, StartVertex, NumVertices, Flags);
4181 return IDirect3DDevice7_DrawPrimitiveVB((IDirect3DDevice7 *)This, PrimitiveType,
4182 (IDirect3DVertexBuffer7 *)vb, StartVertex, NumVertices, Flags);
4186 /*****************************************************************************
4187 * IDirect3DDevice7::DrawIndexedPrimitiveVB
4189 * Draws primitives from a vertex buffer to the screen
4191 * Params:
4192 * PrimitiveType: Type of primitive to be rendered.
4193 * D3DVertexBuf: Source Vertex Buffer
4194 * StartVertex: Index of the first vertex from the buffer to be rendered
4195 * NumVertices: Number of vertices to be rendered
4196 * Indices: Array of DWORDs used to index into the Vertices
4197 * IndexCount: Number of indices in Indices
4198 * Flags: Can be D3DDP_WAIT to wait until rendering has finished
4200 * Return values
4202 *****************************************************************************/
4203 static HRESULT
4204 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB(IDirect3DDevice7 *iface,
4205 D3DPRIMITIVETYPE PrimitiveType,
4206 IDirect3DVertexBuffer7 *D3DVertexBuf,
4207 DWORD StartVertex,
4208 DWORD NumVertices,
4209 WORD *Indices,
4210 DWORD IndexCount,
4211 DWORD Flags)
4213 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
4214 IDirect3DVertexBufferImpl *vb = (IDirect3DVertexBufferImpl *)D3DVertexBuf;
4215 DWORD stride = get_flexible_vertex_size(vb->fvf);
4216 WORD *LockedIndices;
4217 HRESULT hr;
4219 TRACE("(%p)->(%08x,%p,%d,%d,%p,%d,%08x)\n", This, PrimitiveType, vb, StartVertex, NumVertices, Indices, IndexCount, Flags);
4221 /* Steps:
4222 * 1) Upload the Indices to the index buffer
4223 * 2) Set the index source
4224 * 3) Set the Vertex Buffer as the Stream source
4225 * 4) Call IWineD3DDevice::DrawIndexedPrimitive
4228 EnterCriticalSection(&ddraw_cs);
4230 hr = IWineD3DDevice_SetVertexDeclaration(This->wineD3DDevice,
4231 vb->wineD3DVertexDeclaration);
4232 if(FAILED(hr))
4234 ERR(" (%p) Setting the FVF failed, hr = %x!\n", This, hr);
4235 LeaveCriticalSection(&ddraw_cs);
4236 return hr;
4239 /* copy the index stream into the index buffer.
4240 * A new IWineD3DDevice method could be created
4241 * which takes an user pointer containing the indices
4242 * or a SetData-Method for the index buffer, which
4243 * overrides the index buffer data with our pointer.
4245 hr = IWineD3DBuffer_Map(This->indexbuffer,
4246 0 /* OffSetToLock */,
4247 IndexCount * sizeof(WORD),
4248 (BYTE **) &LockedIndices,
4249 0 /* Flags */);
4250 assert(IndexCount < 0x100000);
4251 if(hr != D3D_OK)
4253 ERR("(%p) IWineD3DBuffer::Map failed with hr = %08x\n", This, hr);
4254 LeaveCriticalSection(&ddraw_cs);
4255 return hr;
4257 memcpy(LockedIndices, Indices, IndexCount * sizeof(WORD));
4258 hr = IWineD3DBuffer_Unmap(This->indexbuffer);
4259 if(hr != D3D_OK)
4261 ERR("(%p) IWineD3DBuffer::Unmap failed with hr = %08x\n", This, hr);
4262 LeaveCriticalSection(&ddraw_cs);
4263 return hr;
4266 /* Set the index stream */
4267 IWineD3DDevice_SetBaseVertexIndex(This->wineD3DDevice, StartVertex);
4268 hr = IWineD3DDevice_SetIndexBuffer(This->wineD3DDevice, This->indexbuffer,
4269 WINED3DFMT_R16_UINT);
4271 /* Set the vertex stream source */
4272 hr = IWineD3DDevice_SetStreamSource(This->wineD3DDevice,
4273 0 /* StreamNumber */,
4274 vb->wineD3DVertexBuffer,
4275 0 /* offset, we pass this to DrawIndexedPrimitive */,
4276 stride);
4277 if(hr != D3D_OK)
4279 ERR("(%p) IDirect3DDevice::SetStreamSource failed with hr = %08x\n", This, hr);
4280 LeaveCriticalSection(&ddraw_cs);
4281 return hr;
4285 IWineD3DDevice_SetPrimitiveType(This->wineD3DDevice, PrimitiveType);
4286 hr = IWineD3DDevice_DrawIndexedPrimitive(This->wineD3DDevice, 0 /* StartIndex */, IndexCount);
4288 LeaveCriticalSection(&ddraw_cs);
4289 return hr;
4292 static HRESULT WINAPI
4293 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUSetup(IDirect3DDevice7 *iface,
4294 D3DPRIMITIVETYPE PrimitiveType,
4295 IDirect3DVertexBuffer7 *D3DVertexBuf,
4296 DWORD StartVertex,
4297 DWORD NumVertices,
4298 WORD *Indices,
4299 DWORD IndexCount,
4300 DWORD Flags)
4302 return IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB(iface, PrimitiveType, D3DVertexBuf, StartVertex, NumVertices, Indices, IndexCount, Flags);
4305 static HRESULT WINAPI
4306 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUPreserve(IDirect3DDevice7 *iface,
4307 D3DPRIMITIVETYPE PrimitiveType,
4308 IDirect3DVertexBuffer7 *D3DVertexBuf,
4309 DWORD StartVertex,
4310 DWORD NumVertices,
4311 WORD *Indices,
4312 DWORD IndexCount,
4313 DWORD Flags)
4315 HRESULT hr;
4316 WORD old_fpucw;
4318 old_fpucw = d3d_fpu_setup();
4319 hr = IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB(iface, PrimitiveType, D3DVertexBuf, StartVertex, NumVertices, Indices, IndexCount, Flags);
4320 set_fpu_control_word(old_fpucw);
4322 return hr;
4325 static HRESULT WINAPI
4326 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveVB(IDirect3DDevice3 *iface,
4327 D3DPRIMITIVETYPE PrimitiveType,
4328 IDirect3DVertexBuffer *D3DVertexBuf,
4329 WORD *Indices,
4330 DWORD IndexCount,
4331 DWORD Flags)
4333 IDirect3DDeviceImpl *This = device_from_device3(iface);
4334 IDirect3DVertexBufferImpl *VB = vb_from_vb1(D3DVertexBuf);
4335 TRACE_(ddraw_thunk)("(%p)->(%08x,%p,%p,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, PrimitiveType, VB, Indices, IndexCount, Flags);
4337 return IDirect3DDevice7_DrawIndexedPrimitiveVB((IDirect3DDevice7 *)This, PrimitiveType,
4338 (IDirect3DVertexBuffer7 *)VB, 0, IndexCount, Indices, IndexCount, Flags);
4341 /*****************************************************************************
4342 * IDirect3DDevice7::ComputeSphereVisibility
4344 * Calculates the visibility of spheres in the current viewport. The spheres
4345 * are passed in the Centers and Radii arrays, the results are passed back
4346 * in the ReturnValues array. Return values are either completely visible,
4347 * partially visible or completely invisible.
4348 * The return value consist of a combination of D3DCLIP_* flags, or it's
4349 * 0 if the sphere is completely visible(according to the SDK, not checked)
4351 * Version 3 and 7
4353 * Params:
4354 * Centers: Array containing the sphere centers
4355 * Radii: Array containing the sphere radii
4356 * NumSpheres: The number of centers and radii in the arrays
4357 * Flags: Some flags
4358 * ReturnValues: Array to write the results to
4360 * Returns:
4361 * D3D_OK
4362 * (DDERR_INVALIDPARAMS if Centers, Radii or ReturnValues are NULL)
4363 * (D3DERR_INVALIDMATRIX if the combined world, view and proj matrix
4364 * is singular)
4366 *****************************************************************************/
4368 static DWORD in_plane(UINT plane, D3DVECTOR normal, D3DVALUE origin_plane, D3DVECTOR center, D3DVALUE radius)
4370 float distance, norm;
4372 norm = sqrt( normal.u1.x * normal.u1.x + normal.u2.y * normal.u2.y + normal.u3.z * normal.u3.z );
4373 distance = ( origin_plane + normal.u1.x * center.u1.x + normal.u2.y * center.u2.y + normal.u3.z * center.u3.z ) / norm;
4375 if ( fabs( distance ) < radius ) return D3DSTATUS_CLIPUNIONLEFT << plane;
4376 if ( distance < -radius ) return (D3DSTATUS_CLIPUNIONLEFT | D3DSTATUS_CLIPINTERSECTIONLEFT) << plane;
4377 return 0;
4380 static HRESULT WINAPI
4381 IDirect3DDeviceImpl_7_ComputeSphereVisibility(IDirect3DDevice7 *iface,
4382 D3DVECTOR *Centers,
4383 D3DVALUE *Radii,
4384 DWORD NumSpheres,
4385 DWORD Flags,
4386 DWORD *ReturnValues)
4388 D3DMATRIX m, temp;
4389 D3DVALUE origin_plane[6];
4390 D3DVECTOR vec[6];
4391 HRESULT hr;
4392 UINT i, j;
4394 TRACE("(%p)->(%p,%p,%08x,%08x,%p)\n", iface, Centers, Radii, NumSpheres, Flags, ReturnValues);
4396 hr = IDirect3DDeviceImpl_7_GetTransform(iface, D3DTRANSFORMSTATE_WORLD, &m);
4397 if ( hr != DD_OK ) return DDERR_INVALIDPARAMS;
4398 hr = IDirect3DDeviceImpl_7_GetTransform(iface, D3DTRANSFORMSTATE_VIEW, &temp);
4399 if ( hr != DD_OK ) return DDERR_INVALIDPARAMS;
4400 multiply_matrix_D3D_way(&m, &m, &temp);
4402 hr = IDirect3DDeviceImpl_7_GetTransform(iface, D3DTRANSFORMSTATE_PROJECTION, &temp);
4403 if ( hr != DD_OK ) return DDERR_INVALIDPARAMS;
4404 multiply_matrix_D3D_way(&m, &m, &temp);
4406 /* Left plane */
4407 vec[0].u1.x = m._14 + m._11;
4408 vec[0].u2.y = m._24 + m._21;
4409 vec[0].u3.z = m._34 + m._31;
4410 origin_plane[0] = m._44 + m._41;
4412 /* Right plane */
4413 vec[1].u1.x = m._14 - m._11;
4414 vec[1].u2.y = m._24 - m._21;
4415 vec[1].u3.z = m._34 - m._31;
4416 origin_plane[1] = m._44 - m._41;
4418 /* Top plane */
4419 vec[2].u1.x = m._14 - m._12;
4420 vec[2].u2.y = m._24 - m._22;
4421 vec[2].u3.z = m._34 - m._32;
4422 origin_plane[2] = m._44 - m._42;
4424 /* Bottom plane */
4425 vec[3].u1.x = m._14 + m._12;
4426 vec[3].u2.y = m._24 + m._22;
4427 vec[3].u3.z = m._34 + m._32;
4428 origin_plane[3] = m._44 + m._42;
4430 /* Front plane */
4431 vec[4].u1.x = m._13;
4432 vec[4].u2.y = m._23;
4433 vec[4].u3.z = m._33;
4434 origin_plane[4] = m._43;
4436 /* Back plane*/
4437 vec[5].u1.x = m._14 - m._13;
4438 vec[5].u2.y = m._24 - m._23;
4439 vec[5].u3.z = m._34 - m._33;
4440 origin_plane[5] = m._44 - m._43;
4442 for(i=0; i<NumSpheres; i++)
4444 ReturnValues[i] = 0;
4445 for(j=0; j<6; j++) ReturnValues[i] |= in_plane(j, vec[j], origin_plane[j], Centers[i], Radii[i]);
4448 return D3D_OK;
4451 static HRESULT WINAPI
4452 Thunk_IDirect3DDeviceImpl_3_ComputeSphereVisibility(IDirect3DDevice3 *iface,
4453 D3DVECTOR *Centers,
4454 D3DVALUE *Radii,
4455 DWORD NumSpheres,
4456 DWORD Flags,
4457 DWORD *ReturnValues)
4459 IDirect3DDeviceImpl *This = device_from_device3(iface);
4460 TRACE_(ddraw_thunk)("(%p)->(%p,%p,%08x,%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, Centers, Radii, NumSpheres, Flags, ReturnValues);
4461 return IDirect3DDevice7_ComputeSphereVisibility((IDirect3DDevice7 *)This,
4462 Centers, Radii, NumSpheres, Flags, ReturnValues);
4465 /*****************************************************************************
4466 * IDirect3DDevice7::GetTexture
4468 * Returns the texture interface handle assigned to a texture stage.
4469 * The returned texture is AddRefed. This is taken from old ddraw,
4470 * not checked in Windows.
4472 * Version 3 and 7
4474 * Params:
4475 * Stage: Texture stage to read the texture from
4476 * Texture: Address to store the interface pointer at
4478 * Returns:
4479 * D3D_OK on success
4480 * DDERR_INVALIDPARAMS if Texture is NULL
4481 * For details, see IWineD3DDevice::GetTexture
4483 *****************************************************************************/
4484 static HRESULT
4485 IDirect3DDeviceImpl_7_GetTexture(IDirect3DDevice7 *iface,
4486 DWORD Stage,
4487 IDirectDrawSurface7 **Texture)
4489 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
4490 IWineD3DBaseTexture *Surf;
4491 HRESULT hr;
4492 TRACE("(%p)->(%d,%p): Relay\n", This, Stage, Texture);
4494 if(!Texture)
4496 TRACE("Texture == NULL, failing with DDERR_INVALIDPARAMS\n");
4497 return DDERR_INVALIDPARAMS;
4500 EnterCriticalSection(&ddraw_cs);
4501 hr = IWineD3DDevice_GetTexture(This->wineD3DDevice, Stage, &Surf);
4502 if( (hr != D3D_OK) || (!Surf) )
4504 *Texture = NULL;
4505 LeaveCriticalSection(&ddraw_cs);
4506 return hr;
4509 /* GetParent AddRef()s, which is perfectly OK.
4510 * We have passed the IDirectDrawSurface7 interface to WineD3D, so that's OK too.
4512 hr = IWineD3DBaseTexture_GetParent(Surf,
4513 (IUnknown **) Texture);
4514 LeaveCriticalSection(&ddraw_cs);
4515 return hr;
4518 static HRESULT WINAPI
4519 IDirect3DDeviceImpl_7_GetTexture_FPUSetup(IDirect3DDevice7 *iface,
4520 DWORD Stage,
4521 IDirectDrawSurface7 **Texture)
4523 return IDirect3DDeviceImpl_7_GetTexture(iface, Stage, Texture);
4526 static HRESULT WINAPI
4527 IDirect3DDeviceImpl_7_GetTexture_FPUPreserve(IDirect3DDevice7 *iface,
4528 DWORD Stage,
4529 IDirectDrawSurface7 **Texture)
4531 HRESULT hr;
4532 WORD old_fpucw;
4534 old_fpucw = d3d_fpu_setup();
4535 hr = IDirect3DDeviceImpl_7_GetTexture(iface, Stage, Texture);
4536 set_fpu_control_word(old_fpucw);
4538 return hr;
4541 static HRESULT WINAPI
4542 Thunk_IDirect3DDeviceImpl_3_GetTexture(IDirect3DDevice3 *iface,
4543 DWORD Stage,
4544 IDirect3DTexture2 **Texture2)
4546 IDirect3DDeviceImpl *This = device_from_device3(iface);
4547 HRESULT ret;
4548 IDirectDrawSurface7 *ret_val;
4550 TRACE_(ddraw_thunk)("(%p)->(%d,%p) thunking to IDirect3DDevice7 interface.\n", This, Stage, Texture2);
4551 ret = IDirect3DDevice7_GetTexture((IDirect3DDevice7 *)This, Stage, &ret_val);
4553 *Texture2 = ret_val ? (IDirect3DTexture2 *)&((IDirectDrawSurfaceImpl *)ret_val)->IDirect3DTexture2_vtbl : NULL;
4555 TRACE_(ddraw_thunk)(" returning interface %p.\n", *Texture2);
4557 return ret;
4560 /*****************************************************************************
4561 * IDirect3DDevice7::SetTexture
4563 * Assigns a texture to a texture stage. Is the texture AddRef-ed?
4565 * Version 3 and 7
4567 * Params:
4568 * Stage: The stage to assign the texture to
4569 * Texture: Interface pointer to the texture surface
4571 * Returns
4572 * D3D_OK on success
4573 * For details, see IWineD3DDevice::SetTexture
4575 *****************************************************************************/
4576 static HRESULT
4577 IDirect3DDeviceImpl_7_SetTexture(IDirect3DDevice7 *iface,
4578 DWORD Stage,
4579 IDirectDrawSurface7 *Texture)
4581 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
4582 IDirectDrawSurfaceImpl *surf = (IDirectDrawSurfaceImpl *)Texture;
4583 HRESULT hr;
4584 TRACE("(%p)->(%08x,%p): Relay!\n", This, Stage, surf);
4586 /* Texture may be NULL here */
4587 EnterCriticalSection(&ddraw_cs);
4588 hr = IWineD3DDevice_SetTexture(This->wineD3DDevice,
4589 Stage,
4590 surf ? surf->wineD3DTexture : NULL);
4591 LeaveCriticalSection(&ddraw_cs);
4592 return hr;
4595 static HRESULT WINAPI
4596 IDirect3DDeviceImpl_7_SetTexture_FPUSetup(IDirect3DDevice7 *iface,
4597 DWORD Stage,
4598 IDirectDrawSurface7 *Texture)
4600 return IDirect3DDeviceImpl_7_SetTexture(iface, Stage, Texture);
4603 static HRESULT WINAPI
4604 IDirect3DDeviceImpl_7_SetTexture_FPUPreserve(IDirect3DDevice7 *iface,
4605 DWORD Stage,
4606 IDirectDrawSurface7 *Texture)
4608 HRESULT hr;
4609 WORD old_fpucw;
4611 old_fpucw = d3d_fpu_setup();
4612 hr = IDirect3DDeviceImpl_7_SetTexture(iface, Stage, Texture);
4613 set_fpu_control_word(old_fpucw);
4615 return hr;
4618 static HRESULT WINAPI
4619 IDirect3DDeviceImpl_3_SetTexture(IDirect3DDevice3 *iface,
4620 DWORD Stage,
4621 IDirect3DTexture2 *Texture2)
4623 IDirect3DDeviceImpl *This = device_from_device3(iface);
4624 IDirectDrawSurfaceImpl *tex = Texture2 ? surface_from_texture2(Texture2) : NULL;
4625 DWORD texmapblend;
4626 HRESULT hr;
4627 TRACE("(%p)->(%d,%p)\n", This, Stage, tex);
4629 EnterCriticalSection(&ddraw_cs);
4631 if (This->legacyTextureBlending)
4632 IDirect3DDevice3_GetRenderState(iface, D3DRENDERSTATE_TEXTUREMAPBLEND, &texmapblend);
4634 hr = IDirect3DDevice7_SetTexture((IDirect3DDevice7 *)This, Stage, (IDirectDrawSurface7 *)tex);
4636 if (This->legacyTextureBlending && texmapblend == D3DTBLEND_MODULATE)
4638 /* This fixup is required by the way D3DTBLEND_MODULATE maps to texture stage states.
4639 See IDirect3DDeviceImpl_3_SetRenderState for details. */
4640 BOOL tex_alpha = FALSE;
4641 IWineD3DBaseTexture *tex = NULL;
4642 WINED3DSURFACE_DESC desc;
4643 DDPIXELFORMAT ddfmt;
4644 HRESULT result;
4646 result = IWineD3DDevice_GetTexture(This->wineD3DDevice,
4648 &tex);
4650 if(result == WINED3D_OK && tex)
4652 memset(&desc, 0, sizeof(desc));
4653 result = IWineD3DTexture_GetLevelDesc((IWineD3DTexture*) tex, 0, &desc);
4654 if (SUCCEEDED(result))
4656 ddfmt.dwSize = sizeof(ddfmt);
4657 PixelFormat_WineD3DtoDD(&ddfmt, desc.format);
4658 if (ddfmt.u5.dwRGBAlphaBitMask) tex_alpha = TRUE;
4661 IWineD3DBaseTexture_Release(tex);
4664 /* Arg 1/2 are already set to WINED3DTA_TEXTURE/WINED3DTA_CURRENT in case of D3DTBLEND_MODULATE */
4665 if (tex_alpha)
4666 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAOP, WINED3DTOP_SELECTARG1);
4667 else
4668 IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, 0, WINED3DTSS_ALPHAOP, WINED3DTOP_SELECTARG2);
4671 LeaveCriticalSection(&ddraw_cs);
4673 return hr;
4676 static const struct tss_lookup
4678 BOOL sampler_state;
4679 DWORD state;
4681 tss_lookup[] =
4683 {FALSE, WINED3DTSS_FORCE_DWORD}, /* 0, unused */
4684 {FALSE, WINED3DTSS_COLOROP}, /* 1, D3DTSS_COLOROP */
4685 {FALSE, WINED3DTSS_COLORARG1}, /* 2, D3DTSS_COLORARG1 */
4686 {FALSE, WINED3DTSS_COLORARG2}, /* 3, D3DTSS_COLORARG2 */
4687 {FALSE, WINED3DTSS_ALPHAOP}, /* 4, D3DTSS_ALPHAOP */
4688 {FALSE, WINED3DTSS_ALPHAARG1}, /* 5, D3DTSS_ALPHAARG1 */
4689 {FALSE, WINED3DTSS_ALPHAARG2}, /* 6, D3DTSS_ALPHAARG2 */
4690 {FALSE, WINED3DTSS_BUMPENVMAT00}, /* 7, D3DTSS_BUMPENVMAT00 */
4691 {FALSE, WINED3DTSS_BUMPENVMAT01}, /* 8, D3DTSS_BUMPENVMAT01 */
4692 {FALSE, WINED3DTSS_BUMPENVMAT10}, /* 9, D3DTSS_BUMPENVMAT10 */
4693 {FALSE, WINED3DTSS_BUMPENVMAT11}, /* 10, D3DTSS_BUMPENVMAT11 */
4694 {FALSE, WINED3DTSS_TEXCOORDINDEX}, /* 11, D3DTSS_TEXCOORDINDEX */
4695 {TRUE, WINED3DSAMP_ADDRESSU}, /* 12, D3DTSS_ADDRESS */
4696 {TRUE, WINED3DSAMP_ADDRESSU}, /* 13, D3DTSS_ADDRESSU */
4697 {TRUE, WINED3DSAMP_ADDRESSV}, /* 14, D3DTSS_ADDRESSV */
4698 {TRUE, WINED3DSAMP_BORDERCOLOR}, /* 15, D3DTSS_BORDERCOLOR */
4699 {TRUE, WINED3DSAMP_MAGFILTER}, /* 16, D3DTSS_MAGFILTER */
4700 {TRUE, WINED3DSAMP_MINFILTER}, /* 17, D3DTSS_MINFILTER */
4701 {TRUE, WINED3DSAMP_MIPFILTER}, /* 18, D3DTSS_MIPFILTER */
4702 {TRUE, WINED3DSAMP_MIPMAPLODBIAS}, /* 19, D3DTSS_MIPMAPLODBIAS */
4703 {TRUE, WINED3DSAMP_MAXMIPLEVEL}, /* 20, D3DTSS_MAXMIPLEVEL */
4704 {TRUE, WINED3DSAMP_MAXANISOTROPY}, /* 21, D3DTSS_MAXANISOTROPY */
4705 {FALSE, WINED3DTSS_BUMPENVLSCALE}, /* 22, D3DTSS_BUMPENVLSCALE */
4706 {FALSE, WINED3DTSS_BUMPENVLOFFSET}, /* 23, D3DTSS_BUMPENVLOFFSET */
4707 {FALSE, WINED3DTSS_TEXTURETRANSFORMFLAGS}, /* 24, D3DTSS_TEXTURETRANSFORMFLAGS */
4710 /*****************************************************************************
4711 * IDirect3DDevice7::GetTextureStageState
4713 * Retrieves a state from a texture stage.
4715 * Version 3 and 7
4717 * Params:
4718 * Stage: The stage to retrieve the state from
4719 * TexStageStateType: The state type to retrieve
4720 * State: Address to store the state's value at
4722 * Returns:
4723 * D3D_OK on success
4724 * DDERR_INVALIDPARAMS if State is NULL
4725 * For details, see IWineD3DDevice::GetTextureStageState
4727 *****************************************************************************/
4728 static HRESULT
4729 IDirect3DDeviceImpl_7_GetTextureStageState(IDirect3DDevice7 *iface,
4730 DWORD Stage,
4731 D3DTEXTURESTAGESTATETYPE TexStageStateType,
4732 DWORD *State)
4734 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
4735 HRESULT hr;
4736 const struct tss_lookup *l = &tss_lookup[TexStageStateType];
4737 TRACE("(%p)->(%08x,%08x,%p): Relay!\n", This, Stage, TexStageStateType, State);
4739 if(!State)
4740 return DDERR_INVALIDPARAMS;
4742 if (TexStageStateType > D3DTSS_TEXTURETRANSFORMFLAGS)
4744 WARN("Invalid TexStageStateType %#x passed.\n", TexStageStateType);
4745 *State = 0;
4746 return DD_OK;
4749 EnterCriticalSection(&ddraw_cs);
4751 if (l->sampler_state)
4753 hr = IWineD3DDevice_GetSamplerState(This->wineD3DDevice, Stage, l->state, State);
4755 switch(TexStageStateType)
4757 /* Mipfilter is a sampler state with different values */
4758 case D3DTSS_MIPFILTER:
4760 switch(*State)
4762 case WINED3DTEXF_NONE: *State = D3DTFP_NONE; break;
4763 case WINED3DTEXF_POINT: *State = D3DTFP_POINT; break;
4764 case WINED3DTEXF_LINEAR: *State = D3DTFP_LINEAR; break;
4765 default:
4766 ERR("Unexpected mipfilter value %#x\n", *State);
4767 *State = D3DTFP_NONE;
4768 break;
4770 break;
4773 /* Magfilter has slightly different values */
4774 case D3DTSS_MAGFILTER:
4776 switch(*State)
4778 case WINED3DTEXF_POINT: *State = D3DTFG_POINT; break;
4779 case WINED3DTEXF_LINEAR: *State = D3DTFG_LINEAR; break;
4780 case WINED3DTEXF_ANISOTROPIC: *State = D3DTFG_ANISOTROPIC; break;
4781 case WINED3DTEXF_FLATCUBIC: *State = D3DTFG_FLATCUBIC; break;
4782 case WINED3DTEXF_GAUSSIANCUBIC: *State = D3DTFG_GAUSSIANCUBIC; break;
4783 default:
4784 ERR("Unexpected wined3d mag filter value %#x\n", *State);
4785 *State = D3DTFG_POINT;
4786 break;
4788 break;
4791 default:
4792 break;
4795 else
4797 hr = IWineD3DDevice_GetTextureStageState(This->wineD3DDevice, Stage, l->state, State);
4800 LeaveCriticalSection(&ddraw_cs);
4801 return hr;
4804 static HRESULT WINAPI
4805 IDirect3DDeviceImpl_7_GetTextureStageState_FPUSetup(IDirect3DDevice7 *iface,
4806 DWORD Stage,
4807 D3DTEXTURESTAGESTATETYPE TexStageStateType,
4808 DWORD *State)
4810 return IDirect3DDeviceImpl_7_GetTextureStageState(iface, Stage, TexStageStateType, State);
4813 static HRESULT WINAPI
4814 IDirect3DDeviceImpl_7_GetTextureStageState_FPUPreserve(IDirect3DDevice7 *iface,
4815 DWORD Stage,
4816 D3DTEXTURESTAGESTATETYPE TexStageStateType,
4817 DWORD *State)
4819 HRESULT hr;
4820 WORD old_fpucw;
4822 old_fpucw = d3d_fpu_setup();
4823 hr = IDirect3DDeviceImpl_7_GetTextureStageState(iface, Stage, TexStageStateType, State);
4824 set_fpu_control_word(old_fpucw);
4826 return hr;
4829 static HRESULT WINAPI
4830 Thunk_IDirect3DDeviceImpl_3_GetTextureStageState(IDirect3DDevice3 *iface,
4831 DWORD Stage,
4832 D3DTEXTURESTAGESTATETYPE TexStageStateType,
4833 DWORD *State)
4835 IDirect3DDeviceImpl *This = device_from_device3(iface);
4836 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%p) thunking to IDirect3DDevice7 interface.\n", This, Stage, TexStageStateType, State);
4837 return IDirect3DDevice7_GetTextureStageState((IDirect3DDevice7 *)This, Stage, TexStageStateType, State);
4840 /*****************************************************************************
4841 * IDirect3DDevice7::SetTextureStageState
4843 * Sets a texture stage state. Some stage types need to be handled specially,
4844 * because they do not exist in WineD3D and were moved to another place
4846 * Version 3 and 7
4848 * Params:
4849 * Stage: The stage to modify
4850 * TexStageStateType: The state to change
4851 * State: The new value for the state
4853 * Returns:
4854 * D3D_OK on success
4855 * For details, see IWineD3DDevice::SetTextureStageState
4857 *****************************************************************************/
4858 static HRESULT
4859 IDirect3DDeviceImpl_7_SetTextureStageState(IDirect3DDevice7 *iface,
4860 DWORD Stage,
4861 D3DTEXTURESTAGESTATETYPE TexStageStateType,
4862 DWORD State)
4864 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
4865 const struct tss_lookup *l = &tss_lookup[TexStageStateType];
4866 HRESULT hr;
4867 TRACE("(%p)->(%08x,%08x,%08x): Relay!\n", This, Stage, TexStageStateType, State);
4869 if (TexStageStateType > D3DTSS_TEXTURETRANSFORMFLAGS)
4871 WARN("Invalid TexStageStateType %#x passed.\n", TexStageStateType);
4872 return DD_OK;
4875 EnterCriticalSection(&ddraw_cs);
4877 if (l->sampler_state)
4879 switch(TexStageStateType)
4881 /* Mipfilter is a sampler state with different values */
4882 case D3DTSS_MIPFILTER:
4884 switch(State)
4886 case D3DTFP_NONE: State = WINED3DTEXF_NONE; break;
4887 case D3DTFP_POINT: State = WINED3DTEXF_POINT; break;
4888 case 0: /* Unchecked */
4889 case D3DTFP_LINEAR: State = WINED3DTEXF_LINEAR; break;
4890 default:
4891 ERR("Unexpected mipfilter value %d\n", State);
4892 State = WINED3DTEXF_NONE;
4893 break;
4895 break;
4898 /* Magfilter has slightly different values */
4899 case D3DTSS_MAGFILTER:
4901 switch(State)
4903 case D3DTFG_POINT: State = WINED3DTEXF_POINT; break;
4904 case D3DTFG_LINEAR: State = WINED3DTEXF_LINEAR; break;
4905 case D3DTFG_FLATCUBIC: State = WINED3DTEXF_FLATCUBIC; break;
4906 case D3DTFG_GAUSSIANCUBIC: State = WINED3DTEXF_GAUSSIANCUBIC; break;
4907 case D3DTFG_ANISOTROPIC: State = WINED3DTEXF_ANISOTROPIC; break;
4908 default:
4909 ERR("Unexpected d3d7 mag filter type %d\n", State);
4910 State = WINED3DTEXF_POINT;
4911 break;
4913 break;
4916 case D3DTSS_ADDRESS:
4917 IWineD3DDevice_SetSamplerState(This->wineD3DDevice, Stage, WINED3DSAMP_ADDRESSV, State);
4918 break;
4920 default:
4921 break;
4924 hr = IWineD3DDevice_SetSamplerState(This->wineD3DDevice, Stage, l->state, State);
4926 else
4928 hr = IWineD3DDevice_SetTextureStageState(This->wineD3DDevice, Stage, l->state, State);
4931 LeaveCriticalSection(&ddraw_cs);
4932 return hr;
4935 static HRESULT WINAPI
4936 IDirect3DDeviceImpl_7_SetTextureStageState_FPUSetup(IDirect3DDevice7 *iface,
4937 DWORD Stage,
4938 D3DTEXTURESTAGESTATETYPE TexStageStateType,
4939 DWORD State)
4941 return IDirect3DDeviceImpl_7_SetTextureStageState(iface, Stage, TexStageStateType, State);
4944 static HRESULT WINAPI
4945 IDirect3DDeviceImpl_7_SetTextureStageState_FPUPreserve(IDirect3DDevice7 *iface,
4946 DWORD Stage,
4947 D3DTEXTURESTAGESTATETYPE TexStageStateType,
4948 DWORD State)
4950 HRESULT hr;
4951 WORD old_fpucw;
4953 old_fpucw = d3d_fpu_setup();
4954 hr = IDirect3DDeviceImpl_7_SetTextureStageState(iface, Stage, TexStageStateType, State);
4955 set_fpu_control_word(old_fpucw);
4957 return hr;
4960 static HRESULT WINAPI
4961 Thunk_IDirect3DDeviceImpl_3_SetTextureStageState(IDirect3DDevice3 *iface,
4962 DWORD Stage,
4963 D3DTEXTURESTAGESTATETYPE TexStageStateType,
4964 DWORD State)
4966 IDirect3DDeviceImpl *This = device_from_device3(iface);
4967 TRACE_(ddraw_thunk)("(%p)->(%08x,%08x,%08x) thunking to IDirect3DDevice7 interface.\n", This, Stage, TexStageStateType, State);
4968 return IDirect3DDevice7_SetTextureStageState((IDirect3DDevice7 *)This, Stage, TexStageStateType, State);
4971 /*****************************************************************************
4972 * IDirect3DDevice7::ValidateDevice
4974 * SDK: "Reports the device's ability to render the currently set
4975 * texture-blending operations in a single pass". Whatever that means
4976 * exactly...
4978 * Version 3 and 7
4980 * Params:
4981 * NumPasses: Address to write the number of necessary passes for the
4982 * desired effect to.
4984 * Returns:
4985 * D3D_OK on success
4986 * See IWineD3DDevice::ValidateDevice for more details
4988 *****************************************************************************/
4989 static HRESULT
4990 IDirect3DDeviceImpl_7_ValidateDevice(IDirect3DDevice7 *iface,
4991 DWORD *NumPasses)
4993 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
4994 HRESULT hr;
4995 TRACE("(%p)->(%p): Relay\n", This, NumPasses);
4997 EnterCriticalSection(&ddraw_cs);
4998 hr = IWineD3DDevice_ValidateDevice(This->wineD3DDevice, NumPasses);
4999 LeaveCriticalSection(&ddraw_cs);
5000 return hr;
5003 static HRESULT WINAPI
5004 IDirect3DDeviceImpl_7_ValidateDevice_FPUSetup(IDirect3DDevice7 *iface,
5005 DWORD *NumPasses)
5007 return IDirect3DDeviceImpl_7_ValidateDevice(iface, NumPasses);
5010 static HRESULT WINAPI
5011 IDirect3DDeviceImpl_7_ValidateDevice_FPUPreserve(IDirect3DDevice7 *iface,
5012 DWORD *NumPasses)
5014 HRESULT hr;
5015 WORD old_fpucw;
5017 old_fpucw = d3d_fpu_setup();
5018 hr = IDirect3DDeviceImpl_7_ValidateDevice(iface, NumPasses);
5019 set_fpu_control_word(old_fpucw);
5021 return hr;
5024 static HRESULT WINAPI
5025 Thunk_IDirect3DDeviceImpl_3_ValidateDevice(IDirect3DDevice3 *iface,
5026 DWORD *Passes)
5028 IDirect3DDeviceImpl *This = device_from_device3(iface);
5029 TRACE_(ddraw_thunk)("(%p)->(%p) thunking to IDirect3DDevice7 interface.\n", This, Passes);
5030 return IDirect3DDevice7_ValidateDevice((IDirect3DDevice7 *)This, Passes);
5033 /*****************************************************************************
5034 * IDirect3DDevice7::Clear
5036 * Fills the render target, the z buffer and the stencil buffer with a
5037 * clear color / value
5039 * Version 7 only
5041 * Params:
5042 * Count: Number of rectangles in Rects must be 0 if Rects is NULL
5043 * Rects: Rectangles to clear. If NULL, the whole surface is cleared
5044 * Flags: Some flags, as usual
5045 * Color: Clear color for the render target
5046 * Z: Clear value for the Z buffer
5047 * Stencil: Clear value to store in each stencil buffer entry
5049 * Returns:
5050 * D3D_OK on success
5051 * For details, see IWineD3DDevice::Clear
5053 *****************************************************************************/
5054 static HRESULT
5055 IDirect3DDeviceImpl_7_Clear(IDirect3DDevice7 *iface,
5056 DWORD Count,
5057 D3DRECT *Rects,
5058 DWORD Flags,
5059 D3DCOLOR Color,
5060 D3DVALUE Z,
5061 DWORD Stencil)
5063 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5064 HRESULT hr;
5065 TRACE("(%p)->(%08x,%p,%08x,%08x,%f,%08x): Relay\n", This, Count, Rects, Flags, Color, Z, Stencil);
5067 /* Note; D3DRECT is compatible with WINED3DRECT */
5068 EnterCriticalSection(&ddraw_cs);
5069 hr = IWineD3DDevice_Clear(This->wineD3DDevice, Count, (WINED3DRECT*) Rects, Flags, Color, Z, Stencil);
5070 LeaveCriticalSection(&ddraw_cs);
5071 return hr;
5074 static HRESULT WINAPI
5075 IDirect3DDeviceImpl_7_Clear_FPUSetup(IDirect3DDevice7 *iface,
5076 DWORD Count,
5077 D3DRECT *Rects,
5078 DWORD Flags,
5079 D3DCOLOR Color,
5080 D3DVALUE Z,
5081 DWORD Stencil)
5083 return IDirect3DDeviceImpl_7_Clear(iface, Count, Rects, Flags, Color, Z, Stencil);
5086 static HRESULT WINAPI
5087 IDirect3DDeviceImpl_7_Clear_FPUPreserve(IDirect3DDevice7 *iface,
5088 DWORD Count,
5089 D3DRECT *Rects,
5090 DWORD Flags,
5091 D3DCOLOR Color,
5092 D3DVALUE Z,
5093 DWORD Stencil)
5095 HRESULT hr;
5096 WORD old_fpucw;
5098 old_fpucw = d3d_fpu_setup();
5099 hr = IDirect3DDeviceImpl_7_Clear(iface, Count, Rects, Flags, Color, Z, Stencil);
5100 set_fpu_control_word(old_fpucw);
5102 return hr;
5105 /*****************************************************************************
5106 * IDirect3DDevice7::SetViewport
5108 * Sets the current viewport.
5110 * Version 7 only, but IDirect3DViewport uses this call for older
5111 * versions
5113 * Params:
5114 * Data: The new viewport to set
5116 * Returns:
5117 * D3D_OK on success
5118 * DDERR_INVALIDPARAMS if Data is NULL
5119 * For more details, see IWineDDDevice::SetViewport
5121 *****************************************************************************/
5122 static HRESULT
5123 IDirect3DDeviceImpl_7_SetViewport(IDirect3DDevice7 *iface,
5124 D3DVIEWPORT7 *Data)
5126 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5127 HRESULT hr;
5128 TRACE("(%p)->(%p) Relay!\n", This, Data);
5130 if(!Data)
5131 return DDERR_INVALIDPARAMS;
5133 /* Note: D3DVIEWPORT7 is compatible with WINED3DVIEWPORT */
5134 EnterCriticalSection(&ddraw_cs);
5135 hr = IWineD3DDevice_SetViewport(This->wineD3DDevice,
5136 (WINED3DVIEWPORT*) Data);
5137 LeaveCriticalSection(&ddraw_cs);
5138 return hr;
5141 static HRESULT WINAPI
5142 IDirect3DDeviceImpl_7_SetViewport_FPUSetup(IDirect3DDevice7 *iface,
5143 D3DVIEWPORT7 *Data)
5145 return IDirect3DDeviceImpl_7_SetViewport(iface, Data);
5148 static HRESULT WINAPI
5149 IDirect3DDeviceImpl_7_SetViewport_FPUPreserve(IDirect3DDevice7 *iface,
5150 D3DVIEWPORT7 *Data)
5152 HRESULT hr;
5153 WORD old_fpucw;
5155 old_fpucw = d3d_fpu_setup();
5156 hr = IDirect3DDeviceImpl_7_SetViewport(iface, Data);
5157 set_fpu_control_word(old_fpucw);
5159 return hr;
5162 /*****************************************************************************
5163 * IDirect3DDevice::GetViewport
5165 * Returns the current viewport
5167 * Version 7
5169 * Params:
5170 * Data: D3D7Viewport structure to write the viewport information to
5172 * Returns:
5173 * D3D_OK on success
5174 * DDERR_INVALIDPARAMS if Data is NULL
5175 * For more details, see IWineD3DDevice::GetViewport
5177 *****************************************************************************/
5178 static HRESULT
5179 IDirect3DDeviceImpl_7_GetViewport(IDirect3DDevice7 *iface,
5180 D3DVIEWPORT7 *Data)
5182 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5183 HRESULT hr;
5184 TRACE("(%p)->(%p) Relay!\n", This, Data);
5186 if(!Data)
5187 return DDERR_INVALIDPARAMS;
5189 /* Note: D3DVIEWPORT7 is compatible with WINED3DVIEWPORT */
5190 EnterCriticalSection(&ddraw_cs);
5191 hr = IWineD3DDevice_GetViewport(This->wineD3DDevice,
5192 (WINED3DVIEWPORT*) Data);
5194 LeaveCriticalSection(&ddraw_cs);
5195 return hr_ddraw_from_wined3d(hr);
5198 static HRESULT WINAPI
5199 IDirect3DDeviceImpl_7_GetViewport_FPUSetup(IDirect3DDevice7 *iface,
5200 D3DVIEWPORT7 *Data)
5202 return IDirect3DDeviceImpl_7_GetViewport(iface, Data);
5205 static HRESULT WINAPI
5206 IDirect3DDeviceImpl_7_GetViewport_FPUPreserve(IDirect3DDevice7 *iface,
5207 D3DVIEWPORT7 *Data)
5209 HRESULT hr;
5210 WORD old_fpucw;
5212 old_fpucw = d3d_fpu_setup();
5213 hr = IDirect3DDeviceImpl_7_GetViewport(iface, Data);
5214 set_fpu_control_word(old_fpucw);
5216 return hr;
5219 /*****************************************************************************
5220 * IDirect3DDevice7::SetMaterial
5222 * Sets the Material
5224 * Version 7
5226 * Params:
5227 * Mat: The material to set
5229 * Returns:
5230 * D3D_OK on success
5231 * DDERR_INVALIDPARAMS if Mat is NULL.
5232 * For more details, see IWineD3DDevice::SetMaterial
5234 *****************************************************************************/
5235 static HRESULT
5236 IDirect3DDeviceImpl_7_SetMaterial(IDirect3DDevice7 *iface,
5237 D3DMATERIAL7 *Mat)
5239 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5240 HRESULT hr;
5241 TRACE("(%p)->(%p): Relay!\n", This, Mat);
5243 if (!Mat) return DDERR_INVALIDPARAMS;
5244 /* Note: D3DMATERIAL7 is compatible with WINED3DMATERIAL */
5245 EnterCriticalSection(&ddraw_cs);
5246 hr = IWineD3DDevice_SetMaterial(This->wineD3DDevice,
5247 (WINED3DMATERIAL*) Mat);
5248 LeaveCriticalSection(&ddraw_cs);
5249 return hr_ddraw_from_wined3d(hr);
5252 static HRESULT WINAPI
5253 IDirect3DDeviceImpl_7_SetMaterial_FPUSetup(IDirect3DDevice7 *iface,
5254 D3DMATERIAL7 *Mat)
5256 return IDirect3DDeviceImpl_7_SetMaterial(iface, Mat);
5259 static HRESULT WINAPI
5260 IDirect3DDeviceImpl_7_SetMaterial_FPUPreserve(IDirect3DDevice7 *iface,
5261 D3DMATERIAL7 *Mat)
5263 HRESULT hr;
5264 WORD old_fpucw;
5266 old_fpucw = d3d_fpu_setup();
5267 hr = IDirect3DDeviceImpl_7_SetMaterial(iface, Mat);
5268 set_fpu_control_word(old_fpucw);
5270 return hr;
5273 /*****************************************************************************
5274 * IDirect3DDevice7::GetMaterial
5276 * Returns the current material
5278 * Version 7
5280 * Params:
5281 * Mat: D3DMATERIAL7 structure to write the material parameters to
5283 * Returns:
5284 * D3D_OK on success
5285 * DDERR_INVALIDPARAMS if Mat is NULL
5286 * For more details, see IWineD3DDevice::GetMaterial
5288 *****************************************************************************/
5289 static HRESULT
5290 IDirect3DDeviceImpl_7_GetMaterial(IDirect3DDevice7 *iface,
5291 D3DMATERIAL7 *Mat)
5293 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5294 HRESULT hr;
5295 TRACE("(%p)->(%p): Relay!\n", This, Mat);
5297 EnterCriticalSection(&ddraw_cs);
5298 /* Note: D3DMATERIAL7 is compatible with WINED3DMATERIAL */
5299 hr = IWineD3DDevice_GetMaterial(This->wineD3DDevice,
5300 (WINED3DMATERIAL*) Mat);
5301 LeaveCriticalSection(&ddraw_cs);
5302 return hr_ddraw_from_wined3d(hr);
5305 static HRESULT WINAPI
5306 IDirect3DDeviceImpl_7_GetMaterial_FPUSetup(IDirect3DDevice7 *iface,
5307 D3DMATERIAL7 *Mat)
5309 return IDirect3DDeviceImpl_7_GetMaterial(iface, Mat);
5312 static HRESULT WINAPI
5313 IDirect3DDeviceImpl_7_GetMaterial_FPUPreserve(IDirect3DDevice7 *iface,
5314 D3DMATERIAL7 *Mat)
5316 HRESULT hr;
5317 WORD old_fpucw;
5319 old_fpucw = d3d_fpu_setup();
5320 hr = IDirect3DDeviceImpl_7_GetMaterial(iface, Mat);
5321 set_fpu_control_word(old_fpucw);
5323 return hr;
5326 /*****************************************************************************
5327 * IDirect3DDevice7::SetLight
5329 * Assigns a light to a light index, but doesn't activate it yet.
5331 * Version 7, IDirect3DLight uses this method for older versions
5333 * Params:
5334 * LightIndex: The index of the new light
5335 * Light: A D3DLIGHT7 structure describing the light
5337 * Returns:
5338 * D3D_OK on success
5339 * For more details, see IWineD3DDevice::SetLight
5341 *****************************************************************************/
5342 static HRESULT
5343 IDirect3DDeviceImpl_7_SetLight(IDirect3DDevice7 *iface,
5344 DWORD LightIndex,
5345 D3DLIGHT7 *Light)
5347 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5348 HRESULT hr;
5349 TRACE("(%p)->(%08x,%p): Relay!\n", This, LightIndex, Light);
5351 EnterCriticalSection(&ddraw_cs);
5352 /* Note: D3DLIGHT7 is compatible with WINED3DLIGHT */
5353 hr = IWineD3DDevice_SetLight(This->wineD3DDevice,
5354 LightIndex,
5355 (WINED3DLIGHT*) Light);
5356 LeaveCriticalSection(&ddraw_cs);
5357 return hr_ddraw_from_wined3d(hr);
5360 static HRESULT WINAPI
5361 IDirect3DDeviceImpl_7_SetLight_FPUSetup(IDirect3DDevice7 *iface,
5362 DWORD LightIndex,
5363 D3DLIGHT7 *Light)
5365 return IDirect3DDeviceImpl_7_SetLight(iface, LightIndex, Light);
5368 static HRESULT WINAPI
5369 IDirect3DDeviceImpl_7_SetLight_FPUPreserve(IDirect3DDevice7 *iface,
5370 DWORD LightIndex,
5371 D3DLIGHT7 *Light)
5373 HRESULT hr;
5374 WORD old_fpucw;
5376 old_fpucw = d3d_fpu_setup();
5377 hr = IDirect3DDeviceImpl_7_SetLight(iface, LightIndex, Light);
5378 set_fpu_control_word(old_fpucw);
5380 return hr;
5383 /*****************************************************************************
5384 * IDirect3DDevice7::GetLight
5386 * Returns the light assigned to a light index
5388 * Params:
5389 * Light: Structure to write the light information to
5391 * Returns:
5392 * D3D_OK on success
5393 * DDERR_INVALIDPARAMS if Light is NULL
5394 * For details, see IWineD3DDevice::GetLight
5396 *****************************************************************************/
5397 static HRESULT
5398 IDirect3DDeviceImpl_7_GetLight(IDirect3DDevice7 *iface,
5399 DWORD LightIndex,
5400 D3DLIGHT7 *Light)
5402 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5403 HRESULT rc;
5404 TRACE("(%p)->(%08x,%p): Relay!\n", This, LightIndex, Light);
5406 EnterCriticalSection(&ddraw_cs);
5407 /* Note: D3DLIGHT7 is compatible with WINED3DLIGHT */
5408 rc = IWineD3DDevice_GetLight(This->wineD3DDevice,
5409 LightIndex,
5410 (WINED3DLIGHT*) Light);
5412 /* Translate the result. WineD3D returns other values than D3D7 */
5413 LeaveCriticalSection(&ddraw_cs);
5414 return hr_ddraw_from_wined3d(rc);
5417 static HRESULT WINAPI
5418 IDirect3DDeviceImpl_7_GetLight_FPUSetup(IDirect3DDevice7 *iface,
5419 DWORD LightIndex,
5420 D3DLIGHT7 *Light)
5422 return IDirect3DDeviceImpl_7_GetLight(iface, LightIndex, Light);
5425 static HRESULT WINAPI
5426 IDirect3DDeviceImpl_7_GetLight_FPUPreserve(IDirect3DDevice7 *iface,
5427 DWORD LightIndex,
5428 D3DLIGHT7 *Light)
5430 HRESULT hr;
5431 WORD old_fpucw;
5433 old_fpucw = d3d_fpu_setup();
5434 hr = IDirect3DDeviceImpl_7_GetLight(iface, LightIndex, Light);
5435 set_fpu_control_word(old_fpucw);
5437 return hr;
5440 /*****************************************************************************
5441 * IDirect3DDevice7::BeginStateBlock
5443 * Begins recording to a stateblock
5445 * Version 7
5447 * Returns:
5448 * D3D_OK on success
5449 * For details see IWineD3DDevice::BeginStateBlock
5451 *****************************************************************************/
5452 static HRESULT
5453 IDirect3DDeviceImpl_7_BeginStateBlock(IDirect3DDevice7 *iface)
5455 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5456 HRESULT hr;
5457 TRACE("(%p)->(): Relay!\n", This);
5459 EnterCriticalSection(&ddraw_cs);
5460 hr = IWineD3DDevice_BeginStateBlock(This->wineD3DDevice);
5461 LeaveCriticalSection(&ddraw_cs);
5462 return hr_ddraw_from_wined3d(hr);
5465 static HRESULT WINAPI
5466 IDirect3DDeviceImpl_7_BeginStateBlock_FPUSetup(IDirect3DDevice7 *iface)
5468 return IDirect3DDeviceImpl_7_BeginStateBlock(iface);
5471 static HRESULT WINAPI
5472 IDirect3DDeviceImpl_7_BeginStateBlock_FPUPreserve(IDirect3DDevice7 *iface)
5474 HRESULT hr;
5475 WORD old_fpucw;
5477 old_fpucw = d3d_fpu_setup();
5478 hr = IDirect3DDeviceImpl_7_BeginStateBlock(iface);
5479 set_fpu_control_word(old_fpucw);
5481 return hr;
5484 /*****************************************************************************
5485 * IDirect3DDevice7::EndStateBlock
5487 * Stops recording to a state block and returns the created stateblock
5488 * handle.
5490 * Version 7
5492 * Params:
5493 * BlockHandle: Address to store the stateblock's handle to
5495 * Returns:
5496 * D3D_OK on success
5497 * DDERR_INVALIDPARAMS if BlockHandle is NULL
5498 * See IWineD3DDevice::EndStateBlock for more details
5500 *****************************************************************************/
5501 static HRESULT
5502 IDirect3DDeviceImpl_7_EndStateBlock(IDirect3DDevice7 *iface,
5503 DWORD *BlockHandle)
5505 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5506 HRESULT hr;
5507 TRACE("(%p)->(%p): Relay!\n", This, BlockHandle);
5509 if(!BlockHandle)
5511 WARN("BlockHandle == NULL, returning DDERR_INVALIDPARAMS\n");
5512 return DDERR_INVALIDPARAMS;
5515 EnterCriticalSection(&ddraw_cs);
5516 *BlockHandle = IDirect3DDeviceImpl_CreateHandle(This);
5517 if(!*BlockHandle)
5519 ERR("Cannot get a handle number for the stateblock\n");
5520 LeaveCriticalSection(&ddraw_cs);
5521 return DDERR_OUTOFMEMORY;
5523 This->Handles[*BlockHandle - 1].type = DDrawHandle_StateBlock;
5524 hr = IWineD3DDevice_EndStateBlock(This->wineD3DDevice,
5525 (IWineD3DStateBlock **) &This->Handles[*BlockHandle - 1].ptr);
5526 LeaveCriticalSection(&ddraw_cs);
5527 return hr_ddraw_from_wined3d(hr);
5530 static HRESULT WINAPI
5531 IDirect3DDeviceImpl_7_EndStateBlock_FPUSetup(IDirect3DDevice7 *iface,
5532 DWORD *BlockHandle)
5534 return IDirect3DDeviceImpl_7_EndStateBlock(iface, BlockHandle);
5537 static HRESULT WINAPI
5538 IDirect3DDeviceImpl_7_EndStateBlock_FPUPreserve(IDirect3DDevice7 *iface,
5539 DWORD *BlockHandle)
5541 HRESULT hr;
5542 WORD old_fpucw;
5544 old_fpucw = d3d_fpu_setup();
5545 hr = IDirect3DDeviceImpl_7_EndStateBlock(iface, BlockHandle);
5546 set_fpu_control_word(old_fpucw);
5548 return hr;
5551 /*****************************************************************************
5552 * IDirect3DDevice7::PreLoad
5554 * Allows the app to signal that a texture will be used soon, to allow
5555 * the Direct3DDevice to load it to the video card in the meantime.
5557 * Version 7
5559 * Params:
5560 * Texture: The texture to preload
5562 * Returns:
5563 * D3D_OK on success
5564 * DDERR_INVALIDPARAMS if Texture is NULL
5565 * See IWineD3DSurface::PreLoad for details
5567 *****************************************************************************/
5568 static HRESULT
5569 IDirect3DDeviceImpl_7_PreLoad(IDirect3DDevice7 *iface,
5570 IDirectDrawSurface7 *Texture)
5572 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5573 IDirectDrawSurfaceImpl *surf = (IDirectDrawSurfaceImpl *)Texture;
5575 TRACE("(%p)->(%p): Relay!\n", This, surf);
5577 if(!Texture)
5578 return DDERR_INVALIDPARAMS;
5580 EnterCriticalSection(&ddraw_cs);
5581 IWineD3DSurface_PreLoad(surf->WineD3DSurface);
5582 LeaveCriticalSection(&ddraw_cs);
5583 return D3D_OK;
5586 static HRESULT WINAPI
5587 IDirect3DDeviceImpl_7_PreLoad_FPUSetup(IDirect3DDevice7 *iface,
5588 IDirectDrawSurface7 *Texture)
5590 return IDirect3DDeviceImpl_7_PreLoad(iface, Texture);
5593 static HRESULT WINAPI
5594 IDirect3DDeviceImpl_7_PreLoad_FPUPreserve(IDirect3DDevice7 *iface,
5595 IDirectDrawSurface7 *Texture)
5597 HRESULT hr;
5598 WORD old_fpucw;
5600 old_fpucw = d3d_fpu_setup();
5601 hr = IDirect3DDeviceImpl_7_PreLoad(iface, Texture);
5602 set_fpu_control_word(old_fpucw);
5604 return hr;
5607 /*****************************************************************************
5608 * IDirect3DDevice7::ApplyStateBlock
5610 * Activates the state stored in a state block handle.
5612 * Params:
5613 * BlockHandle: The stateblock handle to activate
5615 * Returns:
5616 * D3D_OK on success
5617 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is NULL
5619 *****************************************************************************/
5620 static HRESULT
5621 IDirect3DDeviceImpl_7_ApplyStateBlock(IDirect3DDevice7 *iface,
5622 DWORD BlockHandle)
5624 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5625 HRESULT hr;
5626 TRACE("(%p)->(%08x): Relay!\n", This, BlockHandle);
5628 EnterCriticalSection(&ddraw_cs);
5629 if(!BlockHandle || BlockHandle > This->numHandles)
5631 WARN("Out of range handle %d, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle);
5632 LeaveCriticalSection(&ddraw_cs);
5633 return D3DERR_INVALIDSTATEBLOCK;
5635 if(This->Handles[BlockHandle - 1].type != DDrawHandle_StateBlock)
5637 WARN("Handle %d is not a stateblock, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle);
5638 LeaveCriticalSection(&ddraw_cs);
5639 return D3DERR_INVALIDSTATEBLOCK;
5642 hr = IWineD3DStateBlock_Apply((IWineD3DStateBlock *) This->Handles[BlockHandle - 1].ptr);
5643 LeaveCriticalSection(&ddraw_cs);
5644 return hr_ddraw_from_wined3d(hr);
5647 static HRESULT WINAPI
5648 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUSetup(IDirect3DDevice7 *iface,
5649 DWORD BlockHandle)
5651 return IDirect3DDeviceImpl_7_ApplyStateBlock(iface, BlockHandle);
5654 static HRESULT WINAPI
5655 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUPreserve(IDirect3DDevice7 *iface,
5656 DWORD BlockHandle)
5658 HRESULT hr;
5659 WORD old_fpucw;
5661 old_fpucw = d3d_fpu_setup();
5662 hr = IDirect3DDeviceImpl_7_ApplyStateBlock(iface, BlockHandle);
5663 set_fpu_control_word(old_fpucw);
5665 return hr;
5668 /*****************************************************************************
5669 * IDirect3DDevice7::CaptureStateBlock
5671 * Updates a stateblock's values to the values currently set for the device
5673 * Version 7
5675 * Params:
5676 * BlockHandle: Stateblock to update
5678 * Returns:
5679 * D3D_OK on success
5680 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is NULL
5681 * See IWineD3DDevice::CaptureStateBlock for more details
5683 *****************************************************************************/
5684 static HRESULT
5685 IDirect3DDeviceImpl_7_CaptureStateBlock(IDirect3DDevice7 *iface,
5686 DWORD BlockHandle)
5688 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5689 HRESULT hr;
5690 TRACE("(%p)->(%08x): Relay!\n", This, BlockHandle);
5692 EnterCriticalSection(&ddraw_cs);
5693 if(BlockHandle == 0 || BlockHandle > This->numHandles)
5695 WARN("Out of range handle %d, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle);
5696 LeaveCriticalSection(&ddraw_cs);
5697 return D3DERR_INVALIDSTATEBLOCK;
5699 if(This->Handles[BlockHandle - 1].type != DDrawHandle_StateBlock)
5701 WARN("Handle %d is not a stateblock, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle);
5702 LeaveCriticalSection(&ddraw_cs);
5703 return D3DERR_INVALIDSTATEBLOCK;
5706 hr = IWineD3DStateBlock_Capture((IWineD3DStateBlock *) This->Handles[BlockHandle - 1].ptr);
5707 LeaveCriticalSection(&ddraw_cs);
5708 return hr_ddraw_from_wined3d(hr);
5711 static HRESULT WINAPI
5712 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUSetup(IDirect3DDevice7 *iface,
5713 DWORD BlockHandle)
5715 return IDirect3DDeviceImpl_7_CaptureStateBlock(iface, BlockHandle);
5718 static HRESULT WINAPI
5719 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUPreserve(IDirect3DDevice7 *iface,
5720 DWORD BlockHandle)
5722 HRESULT hr;
5723 WORD old_fpucw;
5725 old_fpucw = d3d_fpu_setup();
5726 hr = IDirect3DDeviceImpl_7_CaptureStateBlock(iface, BlockHandle);
5727 set_fpu_control_word(old_fpucw);
5729 return hr;
5732 /*****************************************************************************
5733 * IDirect3DDevice7::DeleteStateBlock
5735 * Deletes a stateblock handle. This means releasing the WineD3DStateBlock
5737 * Version 7
5739 * Params:
5740 * BlockHandle: Stateblock handle to delete
5742 * Returns:
5743 * D3D_OK on success
5744 * D3DERR_INVALIDSTATEBLOCK if BlockHandle is 0
5746 *****************************************************************************/
5747 static HRESULT
5748 IDirect3DDeviceImpl_7_DeleteStateBlock(IDirect3DDevice7 *iface,
5749 DWORD BlockHandle)
5751 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5752 ULONG ref;
5753 TRACE("(%p)->(%08x): Relay!\n", This, BlockHandle);
5755 EnterCriticalSection(&ddraw_cs);
5756 if(BlockHandle == 0 || BlockHandle > This->numHandles)
5758 WARN("Out of range handle %d, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle);
5759 LeaveCriticalSection(&ddraw_cs);
5760 return D3DERR_INVALIDSTATEBLOCK;
5762 if(This->Handles[BlockHandle - 1].type != DDrawHandle_StateBlock)
5764 WARN("Handle %d is not a stateblock, returning D3DERR_INVALIDSTATEBLOCK\n", BlockHandle);
5765 LeaveCriticalSection(&ddraw_cs);
5766 return D3DERR_INVALIDSTATEBLOCK;
5769 ref = IWineD3DStateBlock_Release((IWineD3DStateBlock *) This->Handles[BlockHandle - 1].ptr);
5770 if(ref)
5772 ERR("Something is still holding the stateblock %p(Handle %d). Ref = %d\n", This->Handles[BlockHandle - 1].ptr, BlockHandle, ref);
5774 This->Handles[BlockHandle - 1].ptr = NULL;
5775 This->Handles[BlockHandle - 1].type = DDrawHandle_Unknown;
5777 LeaveCriticalSection(&ddraw_cs);
5778 return D3D_OK;
5781 static HRESULT WINAPI
5782 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUSetup(IDirect3DDevice7 *iface,
5783 DWORD BlockHandle)
5785 return IDirect3DDeviceImpl_7_DeleteStateBlock(iface, BlockHandle);
5788 static HRESULT WINAPI
5789 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUPreserve(IDirect3DDevice7 *iface,
5790 DWORD BlockHandle)
5792 HRESULT hr;
5793 WORD old_fpucw;
5795 old_fpucw = d3d_fpu_setup();
5796 hr = IDirect3DDeviceImpl_7_DeleteStateBlock(iface, BlockHandle);
5797 set_fpu_control_word(old_fpucw);
5799 return hr;
5802 /*****************************************************************************
5803 * IDirect3DDevice7::CreateStateBlock
5805 * Creates a new state block handle.
5807 * Version 7
5809 * Params:
5810 * Type: The state block type
5811 * BlockHandle: Address to write the created handle to
5813 * Returns:
5814 * D3D_OK on success
5815 * DDERR_INVALIDPARAMS if BlockHandle is NULL
5817 *****************************************************************************/
5818 static HRESULT
5819 IDirect3DDeviceImpl_7_CreateStateBlock(IDirect3DDevice7 *iface,
5820 D3DSTATEBLOCKTYPE Type,
5821 DWORD *BlockHandle)
5823 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
5824 HRESULT hr;
5825 TRACE("(%p)->(%08x,%p)!\n", This, Type, BlockHandle);
5827 if(!BlockHandle)
5829 WARN("BlockHandle == NULL, returning DDERR_INVALIDPARAMS\n");
5830 return DDERR_INVALIDPARAMS;
5832 if(Type != D3DSBT_ALL && Type != D3DSBT_PIXELSTATE &&
5833 Type != D3DSBT_VERTEXSTATE ) {
5834 WARN("Unexpected stateblock type, returning DDERR_INVALIDPARAMS\n");
5835 return DDERR_INVALIDPARAMS;
5838 EnterCriticalSection(&ddraw_cs);
5839 *BlockHandle = IDirect3DDeviceImpl_CreateHandle(This);
5840 if(!*BlockHandle)
5842 ERR("Cannot get a handle number for the stateblock\n");
5843 LeaveCriticalSection(&ddraw_cs);
5844 return DDERR_OUTOFMEMORY;
5846 This->Handles[*BlockHandle - 1].type = DDrawHandle_StateBlock;
5848 /* The D3DSTATEBLOCKTYPE enum is fine here */
5849 hr = IWineD3DDevice_CreateStateBlock(This->wineD3DDevice,
5850 Type,
5851 (IWineD3DStateBlock **) &This->Handles[*BlockHandle - 1].ptr,
5852 NULL /* Parent, hope that works */);
5853 LeaveCriticalSection(&ddraw_cs);
5854 return hr_ddraw_from_wined3d(hr);
5857 static HRESULT WINAPI
5858 IDirect3DDeviceImpl_7_CreateStateBlock_FPUSetup(IDirect3DDevice7 *iface,
5859 D3DSTATEBLOCKTYPE Type,
5860 DWORD *BlockHandle)
5862 return IDirect3DDeviceImpl_7_CreateStateBlock(iface, Type, BlockHandle);
5865 static HRESULT WINAPI
5866 IDirect3DDeviceImpl_7_CreateStateBlock_FPUPreserve(IDirect3DDevice7 *iface,
5867 D3DSTATEBLOCKTYPE Type,
5868 DWORD *BlockHandle)
5870 HRESULT hr;
5871 WORD old_fpucw;
5873 old_fpucw = d3d_fpu_setup();
5874 hr =IDirect3DDeviceImpl_7_CreateStateBlock(iface, Type, BlockHandle);
5875 set_fpu_control_word(old_fpucw);
5877 return hr;
5880 /* Helper function for IDirect3DDeviceImpl_7_Load. */
5881 static BOOL is_mip_level_subset(IDirectDrawSurfaceImpl *dest,
5882 IDirectDrawSurfaceImpl *src)
5884 IDirectDrawSurfaceImpl *src_level, *dest_level;
5885 IDirectDrawSurface7 *temp;
5886 DDSURFACEDESC2 ddsd;
5887 BOOL levelFound; /* at least one suitable sublevel in dest found */
5889 /* To satisfy "destination is mip level subset of source" criteria (regular texture counts as 1 level),
5890 * 1) there must be at least one mip level in destination that matched dimensions of some mip level in source and
5891 * 2) there must be no destination levels that don't match any levels in source. Otherwise it's INVALIDPARAMS.
5893 levelFound = FALSE;
5895 src_level = src;
5896 dest_level = dest;
5898 for (;src_level && dest_level;)
5900 if (src_level->surface_desc.dwWidth == dest_level->surface_desc.dwWidth &&
5901 src_level->surface_desc.dwHeight == dest_level->surface_desc.dwHeight)
5903 levelFound = TRUE;
5905 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
5906 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_MIPMAPSUBLEVEL;
5907 IDirectDrawSurface7_GetAttachedSurface((IDirectDrawSurface7 *)dest_level, &ddsd.ddsCaps, &temp);
5909 if (dest_level != dest) IDirectDrawSurface7_Release((IDirectDrawSurface7 *)dest_level);
5911 dest_level = (IDirectDrawSurfaceImpl *)temp;
5914 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
5915 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_MIPMAPSUBLEVEL;
5916 IDirectDrawSurface7_GetAttachedSurface((IDirectDrawSurface7 *)src_level, &ddsd.ddsCaps, &temp);
5918 if (src_level != src) IDirectDrawSurface7_Release((IDirectDrawSurface7 *)src_level);
5920 src_level = (IDirectDrawSurfaceImpl *)temp;
5923 if (src_level && src_level != src) IDirectDrawSurface7_Release((IDirectDrawSurface7 *)src_level);
5924 if (dest_level && dest_level != dest) IDirectDrawSurface7_Release((IDirectDrawSurface7 *)dest_level);
5926 return !dest_level && levelFound;
5929 /* Helper function for IDirect3DDeviceImpl_7_Load. */
5930 static void copy_mipmap_chain(IDirect3DDeviceImpl *device,
5931 IDirectDrawSurfaceImpl *dest,
5932 IDirectDrawSurfaceImpl *src,
5933 const POINT *DestPoint,
5934 const RECT *SrcRect)
5936 IDirectDrawSurfaceImpl *src_level, *dest_level;
5937 IDirectDrawSurface7 *temp;
5938 DDSURFACEDESC2 ddsd;
5939 POINT point;
5940 RECT rect;
5941 HRESULT hr;
5942 IDirectDrawPalette *pal = NULL, *pal_src = NULL;
5943 DWORD ckeyflag;
5944 DDCOLORKEY ddckey;
5945 BOOL palette_missing = FALSE;
5947 /* Copy palette, if possible. */
5948 IDirectDrawSurface7_GetPalette((IDirectDrawSurface7 *)src, &pal_src);
5949 IDirectDrawSurface7_GetPalette((IDirectDrawSurface7 *)dest, &pal);
5951 if (pal_src != NULL && pal != NULL)
5953 PALETTEENTRY palent[256];
5955 IDirectDrawPalette_GetEntries(pal_src, 0, 0, 256, palent);
5956 IDirectDrawPalette_SetEntries(pal, 0, 0, 256, palent);
5959 if (dest->surface_desc.u4.ddpfPixelFormat.dwFlags & (DDPF_PALETTEINDEXED1 | DDPF_PALETTEINDEXED2 |
5960 DDPF_PALETTEINDEXED4 | DDPF_PALETTEINDEXED8 | DDPF_PALETTEINDEXEDTO8) && !pal)
5962 palette_missing = TRUE;
5965 if (pal) IDirectDrawPalette_Release(pal);
5966 if (pal_src) IDirectDrawPalette_Release(pal_src);
5968 /* Copy colorkeys, if present. */
5969 for (ckeyflag = DDCKEY_DESTBLT; ckeyflag <= DDCKEY_SRCOVERLAY; ckeyflag <<= 1)
5971 hr = IDirectDrawSurface7_GetColorKey((IDirectDrawSurface7 *)src, ckeyflag, &ddckey);
5973 if (SUCCEEDED(hr))
5975 IDirectDrawSurface7_SetColorKey((IDirectDrawSurface7 *)dest, ckeyflag, &ddckey);
5979 src_level = src;
5980 dest_level = dest;
5982 point = *DestPoint;
5983 rect = *SrcRect;
5985 for (;src_level && dest_level;)
5987 if (src_level->surface_desc.dwWidth == dest_level->surface_desc.dwWidth &&
5988 src_level->surface_desc.dwHeight == dest_level->surface_desc.dwHeight)
5990 /* Try UpdateSurface that may perform a more direct opengl loading. But skip this if destination is paletted texture and has no palette.
5991 * Some games like Sacrifice set palette after Load, and it is a waste of effort to try to load texture without palette and generates
5992 * warnings in wined3d. */
5993 if (!palette_missing)
5994 hr = IWineD3DDevice_UpdateSurface(device->wineD3DDevice, src_level->WineD3DSurface, &rect, dest_level->WineD3DSurface,
5995 &point);
5997 if (palette_missing || FAILED(hr))
5999 /* UpdateSurface may fail e.g. if dest is in system memory. Fall back to BltFast that is less strict. */
6000 IWineD3DSurface_BltFast(dest_level->WineD3DSurface,
6001 point.x, point.y,
6002 src_level->WineD3DSurface, &rect, 0);
6005 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
6006 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_MIPMAPSUBLEVEL;
6007 IDirectDrawSurface7_GetAttachedSurface((IDirectDrawSurface7 *)dest_level, &ddsd.ddsCaps, &temp);
6009 if (dest_level != dest) IDirectDrawSurface7_Release((IDirectDrawSurface7 *)dest_level);
6011 dest_level = (IDirectDrawSurfaceImpl *)temp;
6014 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
6015 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_MIPMAPSUBLEVEL;
6016 IDirectDrawSurface7_GetAttachedSurface((IDirectDrawSurface7 *)src_level, &ddsd.ddsCaps, &temp);
6018 if (src_level != src) IDirectDrawSurface7_Release((IDirectDrawSurface7 *)src_level);
6020 src_level = (IDirectDrawSurfaceImpl *)temp;
6022 point.x /= 2;
6023 point.y /= 2;
6025 rect.top /= 2;
6026 rect.left /= 2;
6027 rect.right = (rect.right + 1) / 2;
6028 rect.bottom = (rect.bottom + 1) / 2;
6031 if (src_level && src_level != src) IDirectDrawSurface7_Release((IDirectDrawSurface7 *)src_level);
6032 if (dest_level && dest_level != dest) IDirectDrawSurface7_Release((IDirectDrawSurface7 *)dest_level);
6035 /*****************************************************************************
6036 * IDirect3DDevice7::Load
6038 * Loads a rectangular area from the source into the destination texture.
6039 * It can also copy the source to the faces of a cubic environment map
6041 * Version 7
6043 * Params:
6044 * DestTex: Destination texture
6045 * DestPoint: Point in the destination where the source image should be
6046 * written to
6047 * SrcTex: Source texture
6048 * SrcRect: Source rectangle
6049 * Flags: Cubemap faces to load (DDSCAPS2_CUBEMAP_ALLFACES, DDSCAPS2_CUBEMAP_POSITIVEX,
6050 * DDSCAPS2_CUBEMAP_NEGATIVEX, DDSCAPS2_CUBEMAP_POSITIVEY, DDSCAPS2_CUBEMAP_NEGATIVEY,
6051 * DDSCAPS2_CUBEMAP_POSITIVEZ, DDSCAPS2_CUBEMAP_NEGATIVEZ)
6053 * Returns:
6054 * D3D_OK on success
6055 * DDERR_INVALIDPARAMS if DestTex or SrcTex are NULL, broken coordinates or anything unexpected.
6058 *****************************************************************************/
6060 static HRESULT
6061 IDirect3DDeviceImpl_7_Load(IDirect3DDevice7 *iface,
6062 IDirectDrawSurface7 *DestTex,
6063 POINT *DestPoint,
6064 IDirectDrawSurface7 *SrcTex,
6065 RECT *SrcRect,
6066 DWORD Flags)
6068 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
6069 IDirectDrawSurfaceImpl *dest = (IDirectDrawSurfaceImpl *)DestTex;
6070 IDirectDrawSurfaceImpl *src = (IDirectDrawSurfaceImpl *)SrcTex;
6071 POINT destpoint;
6072 RECT srcrect;
6073 TRACE("(%p)->(%p,%p,%p,%p,%08x)\n", This, dest, DestPoint, src, SrcRect, Flags);
6075 if( (!src) || (!dest) )
6076 return DDERR_INVALIDPARAMS;
6078 EnterCriticalSection(&ddraw_cs);
6080 if (SrcRect) srcrect = *SrcRect;
6081 else
6083 srcrect.left = srcrect.top = 0;
6084 srcrect.right = src->surface_desc.dwWidth;
6085 srcrect.bottom = src->surface_desc.dwHeight;
6088 if (DestPoint) destpoint = *DestPoint;
6089 else
6091 destpoint.x = destpoint.y = 0;
6093 /* Check bad dimensions. DestPoint is validated against src, not dest, because
6094 * destination can be a subset of mip levels, in which case actual coordinates used
6095 * for it may be divided. If any dimension of dest is larger than source, it can't be
6096 * mip level subset, so an error can be returned early.
6098 if (srcrect.left >= srcrect.right || srcrect.top >= srcrect.bottom ||
6099 srcrect.right > src->surface_desc.dwWidth ||
6100 srcrect.bottom > src->surface_desc.dwHeight ||
6101 destpoint.x + srcrect.right - srcrect.left > src->surface_desc.dwWidth ||
6102 destpoint.y + srcrect.bottom - srcrect.top > src->surface_desc.dwHeight ||
6103 dest->surface_desc.dwWidth > src->surface_desc.dwWidth ||
6104 dest->surface_desc.dwHeight > src->surface_desc.dwHeight)
6106 LeaveCriticalSection(&ddraw_cs);
6107 return DDERR_INVALIDPARAMS;
6110 /* Must be top level surfaces. */
6111 if (src->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_MIPMAPSUBLEVEL ||
6112 dest->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_MIPMAPSUBLEVEL)
6114 LeaveCriticalSection(&ddraw_cs);
6115 return DDERR_INVALIDPARAMS;
6118 if (src->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP)
6120 DWORD src_face_flag, dest_face_flag;
6121 IDirectDrawSurfaceImpl *src_face, *dest_face;
6122 IDirectDrawSurface7 *temp;
6123 DDSURFACEDESC2 ddsd;
6124 int i;
6126 if (!(dest->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP))
6128 LeaveCriticalSection(&ddraw_cs);
6129 return DDERR_INVALIDPARAMS;
6132 /* Iterate through cube faces 2 times. First time is just to check INVALIDPARAMS conditions, second
6133 * time it's actual surface loading. */
6134 for (i = 0; i < 2; i++)
6136 dest_face = dest;
6137 src_face = src;
6139 for (;dest_face && src_face;)
6141 src_face_flag = src_face->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP_ALLFACES;
6142 dest_face_flag = dest_face->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP_ALLFACES;
6144 if (src_face_flag == dest_face_flag)
6146 if (i == 0)
6148 /* Destination mip levels must be subset of source mip levels. */
6149 if (!is_mip_level_subset(dest_face, src_face))
6151 LeaveCriticalSection(&ddraw_cs);
6152 return DDERR_INVALIDPARAMS;
6155 else if (Flags & dest_face_flag)
6157 copy_mipmap_chain(This, dest_face, src_face, &destpoint, &srcrect);
6160 if (src_face_flag < DDSCAPS2_CUBEMAP_NEGATIVEZ)
6162 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
6163 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | (src_face_flag << 1);
6164 IDirectDrawSurface7_GetAttachedSurface((IDirectDrawSurface7 *)src, &ddsd.ddsCaps, &temp);
6166 if (src_face != src) IDirectDrawSurface7_Release((IDirectDrawSurface7 *)src_face);
6168 src_face = (IDirectDrawSurfaceImpl *)temp;
6170 else
6172 if (src_face != src) IDirectDrawSurface7_Release((IDirectDrawSurface7 *)src_face);
6174 src_face = NULL;
6178 if (dest_face_flag < DDSCAPS2_CUBEMAP_NEGATIVEZ)
6180 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
6181 ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP | (dest_face_flag << 1);
6182 IDirectDrawSurface7_GetAttachedSurface((IDirectDrawSurface7 *)dest, &ddsd.ddsCaps, &temp);
6184 if (dest_face != dest) IDirectDrawSurface7_Release((IDirectDrawSurface7 *)dest_face);
6186 dest_face = (IDirectDrawSurfaceImpl *)temp;
6188 else
6190 if (dest_face != dest) IDirectDrawSurface7_Release((IDirectDrawSurface7 *)dest_face);
6192 dest_face = NULL;
6196 if (i == 0)
6198 /* Native returns error if src faces are not subset of dest faces. */
6199 if (src_face)
6201 LeaveCriticalSection(&ddraw_cs);
6202 return DDERR_INVALIDPARAMS;
6207 LeaveCriticalSection(&ddraw_cs);
6208 return D3D_OK;
6210 else if (dest->surface_desc.ddsCaps.dwCaps2 & DDSCAPS2_CUBEMAP)
6212 LeaveCriticalSection(&ddraw_cs);
6213 return DDERR_INVALIDPARAMS;
6216 /* Handle non cube map textures. */
6218 /* Destination mip levels must be subset of source mip levels. */
6219 if (!is_mip_level_subset(dest, src))
6221 LeaveCriticalSection(&ddraw_cs);
6222 return DDERR_INVALIDPARAMS;
6225 copy_mipmap_chain(This, dest, src, &destpoint, &srcrect);
6227 LeaveCriticalSection(&ddraw_cs);
6228 return D3D_OK;
6231 static HRESULT WINAPI
6232 IDirect3DDeviceImpl_7_Load_FPUSetup(IDirect3DDevice7 *iface,
6233 IDirectDrawSurface7 *DestTex,
6234 POINT *DestPoint,
6235 IDirectDrawSurface7 *SrcTex,
6236 RECT *SrcRect,
6237 DWORD Flags)
6239 return IDirect3DDeviceImpl_7_Load(iface, DestTex, DestPoint, SrcTex, SrcRect, Flags);
6242 static HRESULT WINAPI
6243 IDirect3DDeviceImpl_7_Load_FPUPreserve(IDirect3DDevice7 *iface,
6244 IDirectDrawSurface7 *DestTex,
6245 POINT *DestPoint,
6246 IDirectDrawSurface7 *SrcTex,
6247 RECT *SrcRect,
6248 DWORD Flags)
6250 HRESULT hr;
6251 WORD old_fpucw;
6253 old_fpucw = d3d_fpu_setup();
6254 hr = IDirect3DDeviceImpl_7_Load(iface, DestTex, DestPoint, SrcTex, SrcRect, Flags);
6255 set_fpu_control_word(old_fpucw);
6257 return hr;
6260 /*****************************************************************************
6261 * IDirect3DDevice7::LightEnable
6263 * Enables or disables a light
6265 * Version 7, IDirect3DLight uses this method too.
6267 * Params:
6268 * LightIndex: The index of the light to enable / disable
6269 * Enable: Enable or disable the light
6271 * Returns:
6272 * D3D_OK on success
6273 * For more details, see IWineD3DDevice::SetLightEnable
6275 *****************************************************************************/
6276 static HRESULT
6277 IDirect3DDeviceImpl_7_LightEnable(IDirect3DDevice7 *iface,
6278 DWORD LightIndex,
6279 BOOL Enable)
6281 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
6282 HRESULT hr;
6283 TRACE("(%p)->(%08x,%d): Relay!\n", This, LightIndex, Enable);
6285 EnterCriticalSection(&ddraw_cs);
6286 hr = IWineD3DDevice_SetLightEnable(This->wineD3DDevice, LightIndex, Enable);
6287 LeaveCriticalSection(&ddraw_cs);
6288 return hr_ddraw_from_wined3d(hr);
6291 static HRESULT WINAPI
6292 IDirect3DDeviceImpl_7_LightEnable_FPUSetup(IDirect3DDevice7 *iface,
6293 DWORD LightIndex,
6294 BOOL Enable)
6296 return IDirect3DDeviceImpl_7_LightEnable(iface, LightIndex, Enable);
6299 static HRESULT WINAPI
6300 IDirect3DDeviceImpl_7_LightEnable_FPUPreserve(IDirect3DDevice7 *iface,
6301 DWORD LightIndex,
6302 BOOL Enable)
6304 HRESULT hr;
6305 WORD old_fpucw;
6307 old_fpucw = d3d_fpu_setup();
6308 hr = IDirect3DDeviceImpl_7_LightEnable(iface, LightIndex, Enable);
6309 set_fpu_control_word(old_fpucw);
6311 return hr;
6314 /*****************************************************************************
6315 * IDirect3DDevice7::GetLightEnable
6317 * Retrieves if the light with the given index is enabled or not
6319 * Version 7
6321 * Params:
6322 * LightIndex: Index of desired light
6323 * Enable: Pointer to a BOOL which contains the result
6325 * Returns:
6326 * D3D_OK on success
6327 * DDERR_INVALIDPARAMS if Enable is NULL
6328 * See IWineD3DDevice::GetLightEnable for more details
6330 *****************************************************************************/
6331 static HRESULT
6332 IDirect3DDeviceImpl_7_GetLightEnable(IDirect3DDevice7 *iface,
6333 DWORD LightIndex,
6334 BOOL* Enable)
6336 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
6337 HRESULT hr;
6338 TRACE("(%p)->(%08x,%p): Relay\n", This, LightIndex, Enable);
6340 if(!Enable)
6341 return DDERR_INVALIDPARAMS;
6343 EnterCriticalSection(&ddraw_cs);
6344 hr = IWineD3DDevice_GetLightEnable(This->wineD3DDevice, LightIndex, Enable);
6345 LeaveCriticalSection(&ddraw_cs);
6346 return hr_ddraw_from_wined3d(hr);
6349 static HRESULT WINAPI
6350 IDirect3DDeviceImpl_7_GetLightEnable_FPUSetup(IDirect3DDevice7 *iface,
6351 DWORD LightIndex,
6352 BOOL* Enable)
6354 return IDirect3DDeviceImpl_7_GetLightEnable(iface, LightIndex, Enable);
6357 static HRESULT WINAPI
6358 IDirect3DDeviceImpl_7_GetLightEnable_FPUPreserve(IDirect3DDevice7 *iface,
6359 DWORD LightIndex,
6360 BOOL* Enable)
6362 HRESULT hr;
6363 WORD old_fpucw;
6365 old_fpucw = d3d_fpu_setup();
6366 hr = IDirect3DDeviceImpl_7_GetLightEnable(iface, LightIndex, Enable);
6367 set_fpu_control_word(old_fpucw);
6369 return hr;
6372 /*****************************************************************************
6373 * IDirect3DDevice7::SetClipPlane
6375 * Sets custom clipping plane
6377 * Version 7
6379 * Params:
6380 * Index: The index of the clipping plane
6381 * PlaneEquation: An equation defining the clipping plane
6383 * Returns:
6384 * D3D_OK on success
6385 * DDERR_INVALIDPARAMS if PlaneEquation is NULL
6386 * See IWineD3DDevice::SetClipPlane for more details
6388 *****************************************************************************/
6389 static HRESULT
6390 IDirect3DDeviceImpl_7_SetClipPlane(IDirect3DDevice7 *iface,
6391 DWORD Index,
6392 D3DVALUE* PlaneEquation)
6394 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
6395 HRESULT hr;
6396 TRACE("(%p)->(%08x,%p): Relay!\n", This, Index, PlaneEquation);
6398 if(!PlaneEquation)
6399 return DDERR_INVALIDPARAMS;
6401 EnterCriticalSection(&ddraw_cs);
6402 hr = IWineD3DDevice_SetClipPlane(This->wineD3DDevice, Index, PlaneEquation);
6403 LeaveCriticalSection(&ddraw_cs);
6404 return hr;
6407 static HRESULT WINAPI
6408 IDirect3DDeviceImpl_7_SetClipPlane_FPUSetup(IDirect3DDevice7 *iface,
6409 DWORD Index,
6410 D3DVALUE* PlaneEquation)
6412 return IDirect3DDeviceImpl_7_SetClipPlane(iface, Index, PlaneEquation);
6415 static HRESULT WINAPI
6416 IDirect3DDeviceImpl_7_SetClipPlane_FPUPreserve(IDirect3DDevice7 *iface,
6417 DWORD Index,
6418 D3DVALUE* PlaneEquation)
6420 HRESULT hr;
6421 WORD old_fpucw;
6423 old_fpucw = d3d_fpu_setup();
6424 hr = IDirect3DDeviceImpl_7_SetClipPlane(iface, Index, PlaneEquation);
6425 set_fpu_control_word(old_fpucw);
6427 return hr;
6430 /*****************************************************************************
6431 * IDirect3DDevice7::GetClipPlane
6433 * Returns the clipping plane with a specific index
6435 * Params:
6436 * Index: The index of the desired plane
6437 * PlaneEquation: Address to store the plane equation to
6439 * Returns:
6440 * D3D_OK on success
6441 * DDERR_INVALIDPARAMS if PlaneEquation is NULL
6442 * See IWineD3DDevice::GetClipPlane for more details
6444 *****************************************************************************/
6445 static HRESULT
6446 IDirect3DDeviceImpl_7_GetClipPlane(IDirect3DDevice7 *iface,
6447 DWORD Index,
6448 D3DVALUE* PlaneEquation)
6450 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
6451 HRESULT hr;
6452 TRACE("(%p)->(%d,%p): Relay!\n", This, Index, PlaneEquation);
6454 if(!PlaneEquation)
6455 return DDERR_INVALIDPARAMS;
6457 EnterCriticalSection(&ddraw_cs);
6458 hr = IWineD3DDevice_GetClipPlane(This->wineD3DDevice, Index, PlaneEquation);
6459 LeaveCriticalSection(&ddraw_cs);
6460 return hr;
6463 static HRESULT WINAPI
6464 IDirect3DDeviceImpl_7_GetClipPlane_FPUSetup(IDirect3DDevice7 *iface,
6465 DWORD Index,
6466 D3DVALUE* PlaneEquation)
6468 return IDirect3DDeviceImpl_7_GetClipPlane(iface, Index, PlaneEquation);
6471 static HRESULT WINAPI
6472 IDirect3DDeviceImpl_7_GetClipPlane_FPUPreserve(IDirect3DDevice7 *iface,
6473 DWORD Index,
6474 D3DVALUE* PlaneEquation)
6476 HRESULT hr;
6477 WORD old_fpucw;
6479 old_fpucw = d3d_fpu_setup();
6480 hr = IDirect3DDeviceImpl_7_GetClipPlane(iface, Index, PlaneEquation);
6481 set_fpu_control_word(old_fpucw);
6483 return hr;
6486 /*****************************************************************************
6487 * IDirect3DDevice7::GetInfo
6489 * Retrieves some information about the device. The DirectX sdk says that
6490 * this version returns S_FALSE for all retail builds of DirectX, that's what
6491 * this implementation does.
6493 * Params:
6494 * DevInfoID: Information type requested
6495 * DevInfoStruct: Pointer to a structure to store the info to
6496 * Size: Size of the structure
6498 * Returns:
6499 * S_FALSE, because it's a non-debug driver
6501 *****************************************************************************/
6502 static HRESULT WINAPI
6503 IDirect3DDeviceImpl_7_GetInfo(IDirect3DDevice7 *iface,
6504 DWORD DevInfoID,
6505 void *DevInfoStruct,
6506 DWORD Size)
6508 IDirect3DDeviceImpl *This = (IDirect3DDeviceImpl *)iface;
6509 TRACE("(%p)->(%08x,%p,%08x)\n", This, DevInfoID, DevInfoStruct, Size);
6511 if (TRACE_ON(d3d7))
6513 TRACE(" info requested : ");
6514 switch (DevInfoID)
6516 case D3DDEVINFOID_TEXTUREMANAGER: TRACE("D3DDEVINFOID_TEXTUREMANAGER\n"); break;
6517 case D3DDEVINFOID_D3DTEXTUREMANAGER: TRACE("D3DDEVINFOID_D3DTEXTUREMANAGER\n"); break;
6518 case D3DDEVINFOID_TEXTURING: TRACE("D3DDEVINFOID_TEXTURING\n"); break;
6519 default: ERR(" invalid flag !!!\n"); return DDERR_INVALIDPARAMS;
6523 return S_FALSE; /* According to MSDN, this is valid for a non-debug driver */
6526 /* For performance optimization, devices created in FPUSETUP and FPUPRESERVE modes
6527 * have separate vtables. Simple functions where this doesn't matter like GetDirect3D
6528 * are not duplicated.
6530 * Device created with DDSCL_FPUSETUP (d3d7 default) - device methods assume that FPU
6531 * has already been setup for optimal d3d operation.
6533 * Device created with DDSCL_FPUPRESERVE - resets and restores FPU mode when necessary in
6534 * d3d calls (FPU may be in a mode non-suitable for d3d when the app calls d3d). Required
6535 * by Sacrifice (game). */
6536 const IDirect3DDevice7Vtbl IDirect3DDevice7_FPUSetup_Vtbl =
6538 /*** IUnknown Methods ***/
6539 IDirect3DDeviceImpl_7_QueryInterface,
6540 IDirect3DDeviceImpl_7_AddRef,
6541 IDirect3DDeviceImpl_7_Release,
6542 /*** IDirect3DDevice7 ***/
6543 IDirect3DDeviceImpl_7_GetCaps_FPUSetup,
6544 IDirect3DDeviceImpl_7_EnumTextureFormats_FPUSetup,
6545 IDirect3DDeviceImpl_7_BeginScene_FPUSetup,
6546 IDirect3DDeviceImpl_7_EndScene_FPUSetup,
6547 IDirect3DDeviceImpl_7_GetDirect3D,
6548 IDirect3DDeviceImpl_7_SetRenderTarget_FPUSetup,
6549 IDirect3DDeviceImpl_7_GetRenderTarget,
6550 IDirect3DDeviceImpl_7_Clear_FPUSetup,
6551 IDirect3DDeviceImpl_7_SetTransform_FPUSetup,
6552 IDirect3DDeviceImpl_7_GetTransform_FPUSetup,
6553 IDirect3DDeviceImpl_7_SetViewport_FPUSetup,
6554 IDirect3DDeviceImpl_7_MultiplyTransform_FPUSetup,
6555 IDirect3DDeviceImpl_7_GetViewport_FPUSetup,
6556 IDirect3DDeviceImpl_7_SetMaterial_FPUSetup,
6557 IDirect3DDeviceImpl_7_GetMaterial_FPUSetup,
6558 IDirect3DDeviceImpl_7_SetLight_FPUSetup,
6559 IDirect3DDeviceImpl_7_GetLight_FPUSetup,
6560 IDirect3DDeviceImpl_7_SetRenderState_FPUSetup,
6561 IDirect3DDeviceImpl_7_GetRenderState_FPUSetup,
6562 IDirect3DDeviceImpl_7_BeginStateBlock_FPUSetup,
6563 IDirect3DDeviceImpl_7_EndStateBlock_FPUSetup,
6564 IDirect3DDeviceImpl_7_PreLoad_FPUSetup,
6565 IDirect3DDeviceImpl_7_DrawPrimitive_FPUSetup,
6566 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUSetup,
6567 IDirect3DDeviceImpl_7_SetClipStatus,
6568 IDirect3DDeviceImpl_7_GetClipStatus,
6569 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUSetup,
6570 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUSetup,
6571 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUSetup,
6572 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUSetup,
6573 IDirect3DDeviceImpl_7_ComputeSphereVisibility,
6574 IDirect3DDeviceImpl_7_GetTexture_FPUSetup,
6575 IDirect3DDeviceImpl_7_SetTexture_FPUSetup,
6576 IDirect3DDeviceImpl_7_GetTextureStageState_FPUSetup,
6577 IDirect3DDeviceImpl_7_SetTextureStageState_FPUSetup,
6578 IDirect3DDeviceImpl_7_ValidateDevice_FPUSetup,
6579 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUSetup,
6580 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUSetup,
6581 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUSetup,
6582 IDirect3DDeviceImpl_7_CreateStateBlock_FPUSetup,
6583 IDirect3DDeviceImpl_7_Load_FPUSetup,
6584 IDirect3DDeviceImpl_7_LightEnable_FPUSetup,
6585 IDirect3DDeviceImpl_7_GetLightEnable_FPUSetup,
6586 IDirect3DDeviceImpl_7_SetClipPlane_FPUSetup,
6587 IDirect3DDeviceImpl_7_GetClipPlane_FPUSetup,
6588 IDirect3DDeviceImpl_7_GetInfo
6591 const IDirect3DDevice7Vtbl IDirect3DDevice7_FPUPreserve_Vtbl =
6593 /*** IUnknown Methods ***/
6594 IDirect3DDeviceImpl_7_QueryInterface,
6595 IDirect3DDeviceImpl_7_AddRef,
6596 IDirect3DDeviceImpl_7_Release,
6597 /*** IDirect3DDevice7 ***/
6598 IDirect3DDeviceImpl_7_GetCaps_FPUPreserve,
6599 IDirect3DDeviceImpl_7_EnumTextureFormats_FPUPreserve,
6600 IDirect3DDeviceImpl_7_BeginScene_FPUPreserve,
6601 IDirect3DDeviceImpl_7_EndScene_FPUPreserve,
6602 IDirect3DDeviceImpl_7_GetDirect3D,
6603 IDirect3DDeviceImpl_7_SetRenderTarget_FPUPreserve,
6604 IDirect3DDeviceImpl_7_GetRenderTarget,
6605 IDirect3DDeviceImpl_7_Clear_FPUPreserve,
6606 IDirect3DDeviceImpl_7_SetTransform_FPUPreserve,
6607 IDirect3DDeviceImpl_7_GetTransform_FPUPreserve,
6608 IDirect3DDeviceImpl_7_SetViewport_FPUPreserve,
6609 IDirect3DDeviceImpl_7_MultiplyTransform_FPUPreserve,
6610 IDirect3DDeviceImpl_7_GetViewport_FPUPreserve,
6611 IDirect3DDeviceImpl_7_SetMaterial_FPUPreserve,
6612 IDirect3DDeviceImpl_7_GetMaterial_FPUPreserve,
6613 IDirect3DDeviceImpl_7_SetLight_FPUPreserve,
6614 IDirect3DDeviceImpl_7_GetLight_FPUPreserve,
6615 IDirect3DDeviceImpl_7_SetRenderState_FPUPreserve,
6616 IDirect3DDeviceImpl_7_GetRenderState_FPUPreserve,
6617 IDirect3DDeviceImpl_7_BeginStateBlock_FPUPreserve,
6618 IDirect3DDeviceImpl_7_EndStateBlock_FPUPreserve,
6619 IDirect3DDeviceImpl_7_PreLoad_FPUPreserve,
6620 IDirect3DDeviceImpl_7_DrawPrimitive_FPUPreserve,
6621 IDirect3DDeviceImpl_7_DrawIndexedPrimitive_FPUPreserve,
6622 IDirect3DDeviceImpl_7_SetClipStatus,
6623 IDirect3DDeviceImpl_7_GetClipStatus,
6624 IDirect3DDeviceImpl_7_DrawPrimitiveStrided_FPUPreserve,
6625 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided_FPUPreserve,
6626 IDirect3DDeviceImpl_7_DrawPrimitiveVB_FPUPreserve,
6627 IDirect3DDeviceImpl_7_DrawIndexedPrimitiveVB_FPUPreserve,
6628 IDirect3DDeviceImpl_7_ComputeSphereVisibility,
6629 IDirect3DDeviceImpl_7_GetTexture_FPUPreserve,
6630 IDirect3DDeviceImpl_7_SetTexture_FPUPreserve,
6631 IDirect3DDeviceImpl_7_GetTextureStageState_FPUPreserve,
6632 IDirect3DDeviceImpl_7_SetTextureStageState_FPUPreserve,
6633 IDirect3DDeviceImpl_7_ValidateDevice_FPUPreserve,
6634 IDirect3DDeviceImpl_7_ApplyStateBlock_FPUPreserve,
6635 IDirect3DDeviceImpl_7_CaptureStateBlock_FPUPreserve,
6636 IDirect3DDeviceImpl_7_DeleteStateBlock_FPUPreserve,
6637 IDirect3DDeviceImpl_7_CreateStateBlock_FPUPreserve,
6638 IDirect3DDeviceImpl_7_Load_FPUPreserve,
6639 IDirect3DDeviceImpl_7_LightEnable_FPUPreserve,
6640 IDirect3DDeviceImpl_7_GetLightEnable_FPUPreserve,
6641 IDirect3DDeviceImpl_7_SetClipPlane_FPUPreserve,
6642 IDirect3DDeviceImpl_7_GetClipPlane_FPUPreserve,
6643 IDirect3DDeviceImpl_7_GetInfo
6646 const IDirect3DDevice3Vtbl IDirect3DDevice3_Vtbl =
6648 /*** IUnknown Methods ***/
6649 Thunk_IDirect3DDeviceImpl_3_QueryInterface,
6650 Thunk_IDirect3DDeviceImpl_3_AddRef,
6651 Thunk_IDirect3DDeviceImpl_3_Release,
6652 /*** IDirect3DDevice3 ***/
6653 IDirect3DDeviceImpl_3_GetCaps,
6654 IDirect3DDeviceImpl_3_GetStats,
6655 IDirect3DDeviceImpl_3_AddViewport,
6656 IDirect3DDeviceImpl_3_DeleteViewport,
6657 IDirect3DDeviceImpl_3_NextViewport,
6658 Thunk_IDirect3DDeviceImpl_3_EnumTextureFormats,
6659 Thunk_IDirect3DDeviceImpl_3_BeginScene,
6660 Thunk_IDirect3DDeviceImpl_3_EndScene,
6661 Thunk_IDirect3DDeviceImpl_3_GetDirect3D,
6662 IDirect3DDeviceImpl_3_SetCurrentViewport,
6663 IDirect3DDeviceImpl_3_GetCurrentViewport,
6664 Thunk_IDirect3DDeviceImpl_3_SetRenderTarget,
6665 Thunk_IDirect3DDeviceImpl_3_GetRenderTarget,
6666 IDirect3DDeviceImpl_3_Begin,
6667 IDirect3DDeviceImpl_3_BeginIndexed,
6668 IDirect3DDeviceImpl_3_Vertex,
6669 IDirect3DDeviceImpl_3_Index,
6670 IDirect3DDeviceImpl_3_End,
6671 IDirect3DDeviceImpl_3_GetRenderState,
6672 IDirect3DDeviceImpl_3_SetRenderState,
6673 IDirect3DDeviceImpl_3_GetLightState,
6674 IDirect3DDeviceImpl_3_SetLightState,
6675 Thunk_IDirect3DDeviceImpl_3_SetTransform,
6676 Thunk_IDirect3DDeviceImpl_3_GetTransform,
6677 Thunk_IDirect3DDeviceImpl_3_MultiplyTransform,
6678 Thunk_IDirect3DDeviceImpl_3_DrawPrimitive,
6679 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitive,
6680 Thunk_IDirect3DDeviceImpl_3_SetClipStatus,
6681 Thunk_IDirect3DDeviceImpl_3_GetClipStatus,
6682 Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveStrided,
6683 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveStrided,
6684 Thunk_IDirect3DDeviceImpl_3_DrawPrimitiveVB,
6685 Thunk_IDirect3DDeviceImpl_3_DrawIndexedPrimitiveVB,
6686 Thunk_IDirect3DDeviceImpl_3_ComputeSphereVisibility,
6687 Thunk_IDirect3DDeviceImpl_3_GetTexture,
6688 IDirect3DDeviceImpl_3_SetTexture,
6689 Thunk_IDirect3DDeviceImpl_3_GetTextureStageState,
6690 Thunk_IDirect3DDeviceImpl_3_SetTextureStageState,
6691 Thunk_IDirect3DDeviceImpl_3_ValidateDevice
6694 const IDirect3DDevice2Vtbl IDirect3DDevice2_Vtbl =
6696 /*** IUnknown Methods ***/
6697 Thunk_IDirect3DDeviceImpl_2_QueryInterface,
6698 Thunk_IDirect3DDeviceImpl_2_AddRef,
6699 Thunk_IDirect3DDeviceImpl_2_Release,
6700 /*** IDirect3DDevice2 ***/
6701 Thunk_IDirect3DDeviceImpl_2_GetCaps,
6702 IDirect3DDeviceImpl_2_SwapTextureHandles,
6703 Thunk_IDirect3DDeviceImpl_2_GetStats,
6704 Thunk_IDirect3DDeviceImpl_2_AddViewport,
6705 Thunk_IDirect3DDeviceImpl_2_DeleteViewport,
6706 Thunk_IDirect3DDeviceImpl_2_NextViewport,
6707 IDirect3DDeviceImpl_2_EnumTextureFormats,
6708 Thunk_IDirect3DDeviceImpl_2_BeginScene,
6709 Thunk_IDirect3DDeviceImpl_2_EndScene,
6710 Thunk_IDirect3DDeviceImpl_2_GetDirect3D,
6711 Thunk_IDirect3DDeviceImpl_2_SetCurrentViewport,
6712 Thunk_IDirect3DDeviceImpl_2_GetCurrentViewport,
6713 Thunk_IDirect3DDeviceImpl_2_SetRenderTarget,
6714 Thunk_IDirect3DDeviceImpl_2_GetRenderTarget,
6715 Thunk_IDirect3DDeviceImpl_2_Begin,
6716 Thunk_IDirect3DDeviceImpl_2_BeginIndexed,
6717 Thunk_IDirect3DDeviceImpl_2_Vertex,
6718 Thunk_IDirect3DDeviceImpl_2_Index,
6719 Thunk_IDirect3DDeviceImpl_2_End,
6720 Thunk_IDirect3DDeviceImpl_2_GetRenderState,
6721 Thunk_IDirect3DDeviceImpl_2_SetRenderState,
6722 Thunk_IDirect3DDeviceImpl_2_GetLightState,
6723 Thunk_IDirect3DDeviceImpl_2_SetLightState,
6724 Thunk_IDirect3DDeviceImpl_2_SetTransform,
6725 Thunk_IDirect3DDeviceImpl_2_GetTransform,
6726 Thunk_IDirect3DDeviceImpl_2_MultiplyTransform,
6727 Thunk_IDirect3DDeviceImpl_2_DrawPrimitive,
6728 Thunk_IDirect3DDeviceImpl_2_DrawIndexedPrimitive,
6729 Thunk_IDirect3DDeviceImpl_2_SetClipStatus,
6730 Thunk_IDirect3DDeviceImpl_2_GetClipStatus
6733 const IDirect3DDeviceVtbl IDirect3DDevice1_Vtbl =
6735 /*** IUnknown Methods ***/
6736 Thunk_IDirect3DDeviceImpl_1_QueryInterface,
6737 Thunk_IDirect3DDeviceImpl_1_AddRef,
6738 Thunk_IDirect3DDeviceImpl_1_Release,
6739 /*** IDirect3DDevice1 ***/
6740 IDirect3DDeviceImpl_1_Initialize,
6741 Thunk_IDirect3DDeviceImpl_1_GetCaps,
6742 Thunk_IDirect3DDeviceImpl_1_SwapTextureHandles,
6743 IDirect3DDeviceImpl_1_CreateExecuteBuffer,
6744 Thunk_IDirect3DDeviceImpl_1_GetStats,
6745 IDirect3DDeviceImpl_1_Execute,
6746 Thunk_IDirect3DDeviceImpl_1_AddViewport,
6747 Thunk_IDirect3DDeviceImpl_1_DeleteViewport,
6748 Thunk_IDirect3DDeviceImpl_1_NextViewport,
6749 IDirect3DDeviceImpl_1_Pick,
6750 IDirect3DDeviceImpl_1_GetPickRecords,
6751 Thunk_IDirect3DDeviceImpl_1_EnumTextureFormats,
6752 IDirect3DDeviceImpl_1_CreateMatrix,
6753 IDirect3DDeviceImpl_1_SetMatrix,
6754 IDirect3DDeviceImpl_1_GetMatrix,
6755 IDirect3DDeviceImpl_1_DeleteMatrix,
6756 Thunk_IDirect3DDeviceImpl_1_BeginScene,
6757 Thunk_IDirect3DDeviceImpl_1_EndScene,
6758 Thunk_IDirect3DDeviceImpl_1_GetDirect3D
6761 /*****************************************************************************
6762 * IDirect3DDeviceImpl_CreateHandle
6764 * Not called from the VTable
6766 * Some older interface versions operate with handles, which are basically
6767 * DWORDs which identify an interface, for example
6768 * IDirect3DDevice::SetRenderState with DIRECT3DRENDERSTATE_TEXTUREHANDLE
6770 * Those handle could be just casts to the interface pointers or vice versa,
6771 * but that is not 64 bit safe and would mean blindly derefering a DWORD
6772 * passed by the app. Instead there is a dynamic array in the device which
6773 * keeps a DWORD to pointer information and a type for the handle.
6775 * Basically this array only grows, when a handle is freed its pointer is
6776 * just set to NULL. There will be much more reads from the array than
6777 * insertion operations, so a dynamic array is fine.
6779 * Params:
6780 * This: D3DDevice implementation for which this handle should be created
6782 * Returns:
6783 * A free handle on success
6784 * 0 on failure
6786 *****************************************************************************/
6787 DWORD
6788 IDirect3DDeviceImpl_CreateHandle(IDirect3DDeviceImpl *This)
6790 DWORD i;
6791 struct HandleEntry *oldHandles = This->Handles;
6793 TRACE("(%p)\n", This);
6795 for(i = 0; i < This->numHandles; i++)
6797 if(This->Handles[i].ptr == NULL &&
6798 This->Handles[i].type == DDrawHandle_Unknown)
6800 TRACE("Reusing freed handle %d\n", i + 1);
6801 return i + 1;
6805 TRACE("Growing the handle array\n");
6807 This->numHandles++;
6808 This->Handles = HeapAlloc(GetProcessHeap(), 0, sizeof(struct HandleEntry) * This->numHandles);
6809 if(!This->Handles)
6811 ERR("Out of memory\n");
6812 This->Handles = oldHandles;
6813 This->numHandles--;
6814 return 0;
6816 if(oldHandles)
6818 memcpy(This->Handles, oldHandles, (This->numHandles - 1) * sizeof(struct HandleEntry));
6819 HeapFree(GetProcessHeap(), 0, oldHandles);
6822 TRACE("Returning %d\n", This->numHandles);
6823 return This->numHandles;
6826 /*****************************************************************************
6827 * IDirect3DDeviceImpl_UpdateDepthStencil
6829 * Checks the current render target for attached depth stencils and sets the
6830 * WineD3D depth stencil accordingly.
6832 * Returns:
6833 * The depth stencil state to set if creating the device
6835 *****************************************************************************/
6836 WINED3DZBUFFERTYPE
6837 IDirect3DDeviceImpl_UpdateDepthStencil(IDirect3DDeviceImpl *This)
6839 IDirectDrawSurface7 *depthStencil = NULL;
6840 IDirectDrawSurfaceImpl *dsi;
6841 static DDSCAPS2 depthcaps = { DDSCAPS_ZBUFFER, 0, 0, 0 };
6843 IDirectDrawSurface7_GetAttachedSurface((IDirectDrawSurface7 *)This->target, &depthcaps, &depthStencil);
6844 if(!depthStencil)
6846 TRACE("Setting wined3d depth stencil to NULL\n");
6847 IWineD3DDevice_SetDepthStencilSurface(This->wineD3DDevice,
6848 NULL);
6849 return WINED3DZB_FALSE;
6852 dsi = (IDirectDrawSurfaceImpl *)depthStencil;
6853 TRACE("Setting wined3d depth stencil to %p (wined3d %p)\n", dsi, dsi->WineD3DSurface);
6854 IWineD3DDevice_SetDepthStencilSurface(This->wineD3DDevice,
6855 dsi->WineD3DSurface);
6857 IDirectDrawSurface7_Release(depthStencil);
6858 return WINED3DZB_TRUE;